271 lines
8.2 KiB
TypeScript
Executable File
271 lines
8.2 KiB
TypeScript
Executable File
/**
|
|
* End-to-End tests for the Docker environment
|
|
* These tests verify the full application flow in the Docker stack
|
|
*/
|
|
|
|
describe('Docker E2E Tests', () => {
|
|
const APP_URL = 'http://localhost:3000'
|
|
|
|
beforeAll(() => {
|
|
// Skip E2E tests if not in Docker environment
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
console.log('Skipping E2E tests - use E2E_TESTS=1 to enable')
|
|
return
|
|
}
|
|
})
|
|
|
|
describe('Navigation Flow', () => {
|
|
it('should navigate through all main pages', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
// Test homepage
|
|
let response = await fetch(APP_URL)
|
|
expect(response.status).toBe(200)
|
|
let html = await response.text()
|
|
expect(html).toContain('mozdIT Bt.')
|
|
|
|
// Test navigation links exist in homepage
|
|
expect(html).toContain('href="/rolunk"')
|
|
expect(html).toContain('href="/szolgaltatasok"')
|
|
expect(html).toContain('href="/kapcsolat"')
|
|
|
|
// Test about page
|
|
response = await fetch(`${APP_URL}/rolunk`)
|
|
expect(response.status).toBe(200)
|
|
html = await response.text()
|
|
expect(html).toContain('Rólunk')
|
|
|
|
// Test services page
|
|
response = await fetch(`${APP_URL}/szolgaltatasok`)
|
|
expect(response.status).toBe(200)
|
|
html = await response.text()
|
|
expect(html).toContain('Szolgáltatásaink')
|
|
|
|
// Test contact page
|
|
response = await fetch(`${APP_URL}/kapcsolat`)
|
|
expect(response.status).toBe(200)
|
|
html = await response.text()
|
|
expect(html).toContain('Kapcsolat')
|
|
})
|
|
})
|
|
|
|
describe('Contact Form Flow', () => {
|
|
it('should handle complete contact form submission flow', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
// Valid submission
|
|
const validData = {
|
|
name: 'E2E Test User',
|
|
email: 'e2e@test.com',
|
|
subject: 'E2E Test Subject',
|
|
message: 'This is a comprehensive end-to-end test message',
|
|
gdprConsent: true
|
|
}
|
|
|
|
const response = await fetch(`${APP_URL}/api/contact`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(validData)
|
|
})
|
|
|
|
// Might be rate limited due to previous tests
|
|
expect([200, 429]).toContain(response.status)
|
|
const result = await response.json()
|
|
if (response.status === 200) {
|
|
expect(result.message).toBe('Üzenet sikeresen elküldve!')
|
|
} else {
|
|
expect(result.error).toContain('Túl sok')
|
|
}
|
|
})
|
|
|
|
it('should handle validation errors properly', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
// Test missing required fields
|
|
const invalidData = {
|
|
name: '',
|
|
email: 'invalid-email',
|
|
subject: '',
|
|
message: 'Short',
|
|
gdprConsent: false
|
|
}
|
|
|
|
const response = await fetch(`${APP_URL}/api/contact`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(invalidData)
|
|
})
|
|
|
|
// Might be rate limited or validation error
|
|
expect([400, 429]).toContain(response.status)
|
|
const result = await response.json()
|
|
if (response.status === 400) {
|
|
expect(result.error).toContain('validációs hiba')
|
|
} else {
|
|
expect(result.error).toContain('Túl sok')
|
|
}
|
|
})
|
|
|
|
it('should handle rate limiting correctly', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
const testData = {
|
|
name: 'Rate Limit E2E Test',
|
|
email: 'ratelimit-e2e@test.com',
|
|
subject: 'Rate Limit Test',
|
|
message: 'Testing rate limiting in E2E environment',
|
|
gdprConsent: true
|
|
}
|
|
|
|
// Send multiple requests to trigger rate limiting
|
|
const requests = []
|
|
for (let i = 0; i < 5; i++) {
|
|
requests.push(
|
|
fetch(`${APP_URL}/api/contact`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
...testData,
|
|
message: `${testData.message} - Request ${i + 1}`
|
|
})
|
|
})
|
|
)
|
|
}
|
|
|
|
const responses = await Promise.all(requests)
|
|
const statusCodes = responses.map(r => r.status)
|
|
|
|
// Due to previous tests, all might be rate limited
|
|
// Just check that rate limiting is working
|
|
expect(statusCodes).toContain(429)
|
|
|
|
// If any succeeded, that's also fine
|
|
const hasSuccess = statusCodes.includes(200)
|
|
const hasRateLimit = statusCodes.includes(429)
|
|
expect(hasRateLimit).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('API Health and Monitoring', () => {
|
|
it('should provide comprehensive health information', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
const response = await fetch(`${APP_URL}/api/health`)
|
|
expect(response.status).toBe(200)
|
|
|
|
const health = await response.json()
|
|
expect(health).toHaveProperty('status', 'ok')
|
|
expect(health).toHaveProperty('timestamp')
|
|
expect(health).toHaveProperty('uptime')
|
|
expect(health).toHaveProperty('version', '0.1.0')
|
|
expect(health).toHaveProperty('environment')
|
|
|
|
// Uptime should be a positive number
|
|
expect(typeof health.uptime).toBe('number')
|
|
expect(health.uptime).toBeGreaterThan(0)
|
|
|
|
// Timestamp should be a valid ISO string
|
|
expect(() => new Date(health.timestamp)).not.toThrow()
|
|
})
|
|
|
|
it('should handle HEAD requests for health checks', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
const response = await fetch(`${APP_URL}/api/health`, {
|
|
method: 'HEAD'
|
|
})
|
|
|
|
expect(response.status).toBe(200)
|
|
expect(response.headers.get('cache-control')).toContain('no-cache')
|
|
|
|
// HEAD request should have no body
|
|
const text = await response.text()
|
|
expect(text).toBe('')
|
|
})
|
|
})
|
|
|
|
describe('SEO and Meta Tags', () => {
|
|
it('should have proper meta tags on all pages', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
const pages = [
|
|
{ url: '', title: 'mozdIT Bt.' },
|
|
{ url: '/rolunk', title: 'Rólunk' },
|
|
{ url: '/szolgaltatasok', title: 'Szolgáltatásaink' },
|
|
{ url: '/kapcsolat', title: 'Kapcsolatfelvétel' }
|
|
]
|
|
|
|
for (const page of pages) {
|
|
const response = await fetch(`${APP_URL}${page.url}`)
|
|
expect(response.status).toBe(200)
|
|
|
|
const html = await response.text()
|
|
|
|
// Check for essential meta tags
|
|
expect(html).toContain('<meta name="viewport"')
|
|
expect(html).toContain('<meta name="description"')
|
|
expect(html).toContain('mozdIT Bt.')
|
|
|
|
// Check for Open Graph tags
|
|
expect(html).toContain('<meta property="og:title"')
|
|
expect(html).toContain('<meta property="og:description"')
|
|
|
|
// Check for proper title
|
|
expect(html).toContain('<title>')
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('Performance and Caching', () => {
|
|
it('should have proper cache headers', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
// Test static assets caching
|
|
const response = await fetch(APP_URL)
|
|
expect(response.status).toBe(200)
|
|
|
|
// Health endpoint should have no-cache
|
|
const healthResponse = await fetch(`${APP_URL}/api/health`)
|
|
expect(healthResponse.headers.get('cache-control')).toContain('no-cache')
|
|
})
|
|
|
|
it('should load pages within reasonable time', async () => {
|
|
if (process.env.NODE_ENV === 'test' && !process.env.E2E_TESTS) {
|
|
return
|
|
}
|
|
|
|
const startTime = Date.now()
|
|
const response = await fetch(APP_URL)
|
|
const endTime = Date.now()
|
|
|
|
expect(response.status).toBe(200)
|
|
|
|
const loadTime = endTime - startTime
|
|
// Should load within 5 seconds (generous for Docker environment)
|
|
expect(loadTime).toBeLessThan(5000)
|
|
})
|
|
})
|
|
})
|