| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- /**
- * Integration tests for Mini-Games API endpoints
- * Tests backend API endpoints for mini-games scoring
- */
- describe('Mini-Games API Integration Tests', () => {
-
- const BASE_URL = process.env.API_BASE_URL || 'http://localhost:8080';
-
- describe('POST /api/mini-game/complete', () => {
-
- test('should successfully record game completion', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer test-token',
- 'X-User-Id': 'test-user'
- },
- body: JSON.stringify({
- childId: 'child-123',
- gameCode: 'schulte',
- completionTime: 45,
- score: 85
- })
- });
-
- const data = await response.json();
-
- expect(response.status).toBe(200);
- expect(data.code).toBe(200);
- expect(data.data).toHaveProperty('pointsEarned');
- expect(data.data).toHaveProperty('newBalance');
- });
- test('should handle different game types', async () => {
- const gameCodes = ['schulte', '1a2b', 'sudoku'];
-
- for (const gameCode of gameCodes) {
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer test-token'
- },
- body: JSON.stringify({
- childId: 'child-123',
- gameCode: gameCode,
- completionTime: 60,
- score: 75
- })
- });
-
- expect(response.status).toBe(200);
- }
- });
- test('should validate required fields', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({
- // Missing required fields
- gameCode: 'schulte'
- })
- });
-
- expect(response.status).toBe(400);
- });
- test('should handle invalid game code', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer test-token'
- },
- body: JSON.stringify({
- childId: 'child-123',
- gameCode: 'invalid-game',
- completionTime: 30,
- score: 50
- })
- });
-
- expect(response.status).toBe(400);
- });
- test('should calculate points based on score', async () => {
- // Test different score ranges
- const testCases = [
- { score: 100, expectedPoints: 10 }, // High score
- { score: 75, expectedPoints: 7.5 }, // Medium score
- { score: 60, expectedPoints: 6 }, // Low score
- { score: 30, expectedPoints: 3 } // Minimum score
- ];
-
- for (const testCase of testCases) {
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer test-token'
- },
- body: JSON.stringify({
- childId: 'child-123',
- gameCode: 'schulte',
- completionTime: 60,
- score: testCase.score
- })
- });
-
- const data = await response.json();
- if (response.status === 200) {
- expect(data.data.pointsEarned).toBeGreaterThanOrEqual(0);
- }
- }
- });
- });
- describe('GET /api/mini-game/list', () => {
-
- test('should return list of available games', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/list`, {
- method: 'GET',
- headers: {
- 'Authorization': 'Bearer test-token'
- }
- });
-
- const data = await response.json();
-
- expect(response.status).toBe(200);
- expect(data.code).toBe(200);
- expect(Array.isArray(data.data)).toBe(true);
- expect(data.data.length).toBeGreaterThan(0);
- });
- test('should include game details', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/list`, {
- method: 'GET',
- headers: {
- 'Authorization': 'Bearer test-token'
- }
- });
-
- const data = await response.json();
-
- if (data.data.length > 0) {
- const game = data.data[0];
- expect(game).toHaveProperty('code');
- expect(game).toHaveProperty('name');
- expect(game).toHaveProperty('basePoints');
- }
- });
- });
- describe('GET /api/mini-game/:gameCode', () => {
-
- test('should return game details by code', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/schulte`, {
- method: 'GET',
- headers: {
- 'Authorization': 'Bearer test-token'
- }
- });
-
- const data = await response.json();
-
- expect(response.status).toBe(200);
- expect(data.code).toBe(200);
- expect(data.data).toHaveProperty('code', 'schulte');
- });
- test('should return 404 for invalid game code', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/nonexistent`, {
- method: 'GET',
- headers: {
- 'Authorization': 'Bearer test-token'
- }
- });
-
- expect(response.status).toBe(404);
- });
- });
- describe('Authentication and Authorization', () => {
-
- test('should require authentication', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- // No Authorization header
- },
- body: JSON.stringify({
- childId: 'child-123',
- gameCode: 'schulte',
- completionTime: 45,
- score: 85
- })
- });
-
- expect(response.status).toBe(401);
- });
- test('should validate user has access to child', async () => {
- // Test with childId that doesn't belong to user
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer test-token'
- },
- body: JSON.stringify({
- childId: 'other-user-child',
- gameCode: 'schulte',
- completionTime: 45,
- score: 85
- })
- });
-
- expect(response.status).toBe(403);
- });
- });
- describe('Error Handling', () => {
-
- test('should handle database errors gracefully', async () => {
- // Test with invalid data that might cause DB error
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer test-token'
- },
- body: JSON.stringify({
- childId: 'child-123',
- gameCode: 'schulte',
- completionTime: -1, // Invalid time
- score: -10 // Invalid score
- })
- });
-
- expect(response.status).toBe(400);
- });
- test('should return meaningful error messages', async () => {
- const response = await fetch(`${BASE_URL}/api/mini-game/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer test-token'
- },
- body: JSON.stringify({
- childId: '',
- gameCode: '',
- completionTime: 0,
- score: 0
- })
- });
-
- const data = await response.json();
- expect(data).toHaveProperty('message');
- });
- });
- });
|