Files
service-finder/frontend/tests/automated_flow_test.js
2026-03-26 07:09:44 +00:00

251 lines
7.7 KiB
JavaScript

#!/usr/bin/env node
/**
* Automated E2E Flow Test for Service Finder Frontend
*
* This script simulates:
* 1. Logging in and getting a token
* 2. Setting the Profile Mode (Personal/Fleet)
* 3. Fetching the User's Garage
* 4. Fetching Gamification stats
*
* Usage: node automated_flow_test.js
*/
import axios from 'axios'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
// Configuration
const API_BASE_URL = process.env.VITE_API_BASE_URL || 'https://dev.servicefinder.hu'
const TEST_USER_EMAIL = process.env.TEST_USER_EMAIL || 'test@example.com'
const TEST_USER_PASSWORD = process.env.TEST_USER_PASSWORD || 'password123'
// Create axios instance
const api = axios.create({
baseURL: API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
})
// Test state
let authToken = null
let userId = null
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function testLogin() {
console.log('🔐 Testing login...')
try {
// First, check if we need to register a test user
// For now, we'll try to login with provided credentials
const response = await api.post('/api/v2/auth/login', {
email: TEST_USER_EMAIL,
password: TEST_USER_PASSWORD,
})
if (response.data.access_token) {
authToken = response.data.access_token
userId = response.data.user_id
console.log('✅ Login successful')
console.log(` Token: ${authToken.substring(0, 20)}...`)
console.log(` User ID: ${userId}`)
// Set auth header for subsequent requests
api.defaults.headers.common['Authorization'] = `Bearer ${authToken}`
return true
}
} catch (error) {
console.error('❌ Login failed:', error.response?.data || error.message)
// If login fails due to invalid credentials, try to register
if (error.response?.status === 401 || error.response?.status === 404) {
console.log('⚠️ Attempting to register test user...')
try {
const registerResponse = await api.post('/api/v2/auth/register', null, {
params: {
email: TEST_USER_EMAIL,
password: TEST_USER_PASSWORD,
first_name: 'Test',
last_name: 'User',
phone: '+36123456789',
}
})
if (registerResponse.data.access_token) {
authToken = registerResponse.data.access_token
userId = registerResponse.data.user_id
console.log('✅ Test user registered and logged in')
api.defaults.headers.common['Authorization'] = `Bearer ${authToken}`
return true
}
} catch (registerError) {
console.error('❌ Registration failed:', registerError.response?.data || registerError.message)
}
}
}
return false
}
async function testSetProfileMode() {
console.log('\n🎯 Testing profile mode setting...')
try {
// First, get current user to check existing mode
const userResponse = await api.get('/api/v1/users/me')
console.log(` Current UI mode: ${userResponse.data.ui_mode || 'not set'}`)
// Set mode to 'personal' (private_garage)
const modeToSet = 'personal'
const response = await api.patch('/api/v1/users/me/preferences', {
ui_mode: modeToSet
})
console.log(`✅ Profile mode set to: ${modeToSet}`)
// Verify the mode was set
const verifyResponse = await api.get('/api/v1/users/me')
if (verifyResponse.data.ui_mode === modeToSet) {
console.log(`✅ Mode verified: ${verifyResponse.data.ui_mode}`)
return true
} else {
console.error(`❌ Mode mismatch: expected ${modeToSet}, got ${verifyResponse.data.ui_mode}`)
return false
}
} catch (error) {
console.error('❌ Failed to set profile mode:', error.response?.data || error.message)
return false
}
}
async function testFetchGarage() {
console.log('\n🚗 Testing garage fetch...')
try {
const response = await api.get('/api/v1/vehicles/my-garage')
if (Array.isArray(response.data)) {
console.log(`✅ Garage fetched successfully: ${response.data.length} vehicle(s)`)
if (response.data.length > 0) {
console.log(' Sample vehicle:', {
id: response.data[0].id,
make: response.data[0].make,
model: response.data[0].model,
license_plate: response.data[0].license_plate,
})
}
return true
} else {
console.error('❌ Unexpected garage response format:', response.data)
return false
}
} catch (error) {
// Garage might be empty (404) or other error
if (error.response?.status === 404) {
console.log('✅ Garage is empty (expected for new user)')
return true
}
console.error('❌ Failed to fetch garage:', error.response?.data || error.message)
return false
}
}
async function testFetchGamification() {
console.log('\n🏆 Testing gamification fetch...')
try {
// Test achievements endpoint
const achievementsResponse = await api.get('/api/v1/gamification/achievements')
console.log(`✅ Achievements fetched: ${achievementsResponse.data.achievements?.length || 0} total`)
// Test user stats
const statsResponse = await api.get('/api/v1/gamification/me')
console.log('✅ User stats fetched:', {
xp: statsResponse.data.xp,
level: statsResponse.data.level,
rank: statsResponse.data.rank,
})
// Test badges
const badgesResponse = await api.get('/api/v1/gamification/my-badges')
console.log(`✅ Badges fetched: ${badgesResponse.data?.length || 0} earned`)
return true
} catch (error) {
// Gamification might not be fully implemented
if (error.response?.status === 404 || error.response?.status === 501) {
console.log('⚠️ Gamification endpoints not fully implemented (expected during development)')
return true
}
console.error('❌ Failed to fetch gamification:', error.response?.data || error.message)
return false
}
}
async function runAllTests() {
console.log('🚀 Starting Service Finder E2E Flow Test')
console.log('=========================================')
console.log(`API Base URL: ${API_BASE_URL}`)
console.log(`Test User: ${TEST_USER_EMAIL}`)
console.log('')
const results = {
login: false,
profileMode: false,
garage: false,
gamification: false,
}
// Run tests sequentially
results.login = await testLogin()
if (!results.login) {
console.error('\n❌ Login failed, aborting further tests')
return results
}
await sleep(1000) // Small delay between tests
results.profileMode = await testSetProfileMode()
await sleep(500)
results.garage = await testFetchGarage()
await sleep(500)
results.gamification = await testFetchGamification()
// Summary
console.log('\n📊 Test Summary')
console.log('===============')
console.log(`Login: ${results.login ? '✅ PASS' : '❌ FAIL'}`)
console.log(`Profile Mode: ${results.profileMode ? '✅ PASS' : '❌ FAIL'}`)
console.log(`Garage Fetch: ${results.garage ? '✅ PASS' : '❌ FAIL'}`)
console.log(`Gamification: ${results.gamification ? '✅ PASS' : '❌ FAIL'}`)
const allPassed = Object.values(results).every(r => r)
console.log(`\n${allPassed ? '🎉 ALL TESTS PASSED' : '⚠️ SOME TESTS FAILED'}`)
return results
}
// Run tests if script is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
runAllTests().then(results => {
const allPassed = Object.values(results).every(r => r)
process.exit(allPassed ? 0 : 1)
}).catch(error => {
console.error('💥 Unhandled error in test runner:', error)
process.exit(1)
})
}
export { runAllTests }