advanced-games-library
Version:
Advanced Gaming Library for React Native - Four Complete Games with iOS Compatibility Fixes
328 lines (276 loc) • 10.2 kB
text/typescript
import { PlayerService } from '../services/PlayerService';
import { StorageService } from '../services/StorageService';
import { PlayerData, GameLibraryError, GameErrorCode } from '../core/types';
// Mock StorageService
jest.mock('../services/StorageService');
describe('PlayerService', () => {
let playerService: PlayerService;
let mockStorageService: jest.Mocked<StorageService>;
beforeEach(() => {
mockStorageService = new StorageService() as jest.Mocked<StorageService>;
playerService = new PlayerService(mockStorageService);
// Setup default mocks
mockStorageService.getPlayerData.mockResolvedValue(null);
mockStorageService.savePlayerData.mockResolvedValue();
});
afterEach(() => {
jest.clearAllMocks();
});
describe('Initialization', () => {
it('should initialize without existing player data', async () => {
mockStorageService.getPlayerData.mockResolvedValue(null);
await expect(playerService.initialize()).resolves.not.toThrow();
expect(mockStorageService.getPlayerData).toHaveBeenCalled();
});
it('should load existing player data on initialization', async () => {
const existingPlayer: PlayerData = {
playerId: 'existing123',
firstName: 'Existing',
lastName: 'User',
createdAt: new Date('2023-01-01'),
lastActive: new Date('2023-01-02'),
totalGamesPlayed: 5,
achievements: []
};
mockStorageService.getPlayerData.mockResolvedValue(existingPlayer);
await playerService.initialize();
const playerData = playerService.getPlayerData();
expect(playerData).toEqual(existingPlayer);
});
it('should handle storage errors during initialization', async () => {
mockStorageService.getPlayerData.mockRejectedValue(new Error('Storage error'));
await expect(playerService.initialize()).resolves.not.toThrow();
// Should continue without throwing
});
});
describe('Player Data Validation', () => {
it('should accept valid player data', () => {
const validPlayerData: PlayerData = {
playerId: 'valid123',
firstName: 'שחר',
lastName: 'כהן',
age: 25,
phoneNumber: '050-1234567',
email: 'shahar@example.com',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => playerService.setPlayerData(validPlayerData)).not.toThrow();
});
it('should reject empty player ID', () => {
const invalidPlayerData: PlayerData = {
playerId: '',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow(GameLibraryError);
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow('Player ID is required');
});
it('should reject too short player ID', () => {
const invalidPlayerData: PlayerData = {
playerId: 'ab', // Too short
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow(GameLibraryError);
});
it('should reject invalid email format', () => {
const invalidPlayerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
email: 'invalid-email',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow(GameLibraryError);
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow('Invalid email format');
});
it('should reject invalid phone number', () => {
const invalidPlayerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
phoneNumber: 'abc-def-ghij',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow(GameLibraryError);
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow('Invalid phone number format');
});
it('should reject invalid age', () => {
const invalidPlayerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
age: -1,
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow(GameLibraryError);
expect(() => playerService.setPlayerData(invalidPlayerData)).toThrow('Age must be between 0 and 150');
});
});
describe('Player Data Management', () => {
it('should set and get player data', () => {
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
playerService.setPlayerData(playerData);
const retrievedData = playerService.getPlayerData();
expect(retrievedData).toEqual(playerData);
});
it('should return null when no player is set', () => {
const playerData = playerService.getPlayerData();
expect(playerData).toBeNull();
});
it('should auto-set creation date and last active', () => {
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
const beforeSet = new Date();
playerService.setPlayerData(playerData);
const afterSet = new Date();
const retrievedData = playerService.getPlayerData()!;
expect(retrievedData.lastActive.getTime()).toBeGreaterThanOrEqual(beforeSet.getTime());
expect(retrievedData.lastActive.getTime()).toBeLessThanOrEqual(afterSet.getTime());
});
});
describe('Game Statistics', () => {
it('should increment games played counter', () => {
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 5,
achievements: []
};
playerService.setPlayerData(playerData);
playerService.incrementGamesPlayed();
const updatedData = playerService.getPlayerData()!;
expect(updatedData.totalGamesPlayed).toBe(6);
});
it('should handle increment when no player is set', () => {
expect(() => playerService.incrementGamesPlayed()).not.toThrow();
});
});
describe('Achievements', () => {
beforeEach(() => {
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
playerService.setPlayerData(playerData);
});
it('should add new achievement', () => {
const achievement = {
id: 'first_win',
name: 'First Win',
description: 'Win your first game',
unlockedAt: new Date()
};
playerService.addAchievement(achievement);
const playerData = playerService.getPlayerData()!;
expect(playerData.achievements).toHaveLength(1);
expect(playerData.achievements[0].id).toBe('first_win');
});
it('should not add duplicate achievements', () => {
const achievement = {
id: 'first_win',
name: 'First Win',
description: 'Win your first game',
unlockedAt: new Date()
};
playerService.addAchievement(achievement);
playerService.addAchievement(achievement); // Try to add again
const playerData = playerService.getPlayerData()!;
expect(playerData.achievements).toHaveLength(1);
});
});
describe('Player Statistics', () => {
it('should return correct stats for existing player', () => {
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date('2023-01-01'),
lastActive: new Date('2023-01-02'),
totalGamesPlayed: 10,
achievements: [
{
id: 'test1',
name: 'Test Achievement',
description: 'Test',
unlockedAt: new Date()
}
]
};
playerService.setPlayerData(playerData);
const stats = playerService.getPlayerStats();
expect(stats.totalGames).toBe(10);
expect(stats.totalAchievements).toBe(1);
expect(stats.memberSince).toEqual(new Date('2023-01-01'));
expect(stats.lastPlayed).toEqual(new Date('2023-01-02'));
});
it('should return empty stats when no player is set', () => {
const stats = playerService.getPlayerStats();
expect(stats.totalGames).toBe(0);
expect(stats.totalAchievements).toBe(0);
expect(stats.memberSince).toBeNull();
expect(stats.lastPlayed).toBeNull();
});
});
describe('Clear Player Data', () => {
it('should clear player data', () => {
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
playerService.setPlayerData(playerData);
expect(playerService.getPlayerData()).not.toBeNull();
playerService.clearPlayerData();
expect(playerService.getPlayerData()).toBeNull();
expect(mockStorageService.clearPlayerData).toHaveBeenCalled();
});
});
});