Backend Complete: Interface Refactoring & Service Container Enhancements
Repository Interface Optimization: - Created IBaseRepository.ts and IPaginatedRepository.ts - Refactored all 7 repository interfaces to extend base interfaces - Eliminated ~200 lines of redundant code (70% reduction) - Improved type safety and maintainability Dependency Injection Improvements: - Added EmailService and GameTokenService to DIContainer - Updated CreateUserCommandHandler constructor for DI - Updated RequestPasswordResetCommandHandler constructor for DI - Enhanced testability and service consistency Environment Configuration: - Created comprehensive .env.example with 40+ variables - Organized into 12 logical sections (Database, Security, Email, etc.) - Added security guidelines and best practices - Documented all backend environment requirements Documentation: - Added comprehensive codebase review - Created refactoring summary report - Added frontend implementation guide Impact: Improved code quality, reduced maintenance overhead, enhanced developer experience
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import { BoardGenerationService } from '../../../src/Application/Game/BoardGenerationService';
|
||||
|
||||
// Mock dependencies
|
||||
jest.mock('../../../src/Application/Services/LoggingService');
|
||||
|
||||
describe('BoardGenerationService', () => {
|
||||
let boardGenerationService: BoardGenerationService;
|
||||
|
||||
beforeEach(() => {
|
||||
boardGenerationService = new BoardGenerationService();
|
||||
});
|
||||
|
||||
describe('generateBoard', () => {
|
||||
it('should generate a board with the correct number of special fields', async () => {
|
||||
const positiveFields = 10;
|
||||
const negativeFields = 8;
|
||||
const luckFields = 5;
|
||||
|
||||
const result = await boardGenerationService.generateBoard(
|
||||
positiveFields,
|
||||
negativeFields,
|
||||
luckFields
|
||||
);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.fields).toHaveLength(100);
|
||||
|
||||
// Count special fields
|
||||
const actualPositive = result.fields.filter(f => f.type === 'positive').length;
|
||||
const actualNegative = result.fields.filter(f => f.type === 'negative').length;
|
||||
const actualLuck = result.fields.filter(f => f.type === 'luck').length;
|
||||
|
||||
expect(actualPositive).toBe(positiveFields);
|
||||
expect(actualNegative).toBe(negativeFields);
|
||||
expect(actualLuck).toBe(luckFields);
|
||||
});
|
||||
|
||||
it('should ensure positive fields have positive step values', async () => {
|
||||
const result = await boardGenerationService.generateBoard(5, 5, 2);
|
||||
|
||||
const positiveFields = result.fields.filter(f => f.type === 'positive');
|
||||
positiveFields.forEach(field => {
|
||||
expect(field.stepValue).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should ensure negative fields have negative step values', async () => {
|
||||
const result = await boardGenerationService.generateBoard(5, 5, 2);
|
||||
|
||||
const negativeFields = result.fields.filter(f => f.type === 'negative');
|
||||
negativeFields.forEach(field => {
|
||||
expect(field.stepValue).toBeLessThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should ensure luck fields do not have step values', async () => {
|
||||
const result = await boardGenerationService.generateBoard(5, 5, 2);
|
||||
|
||||
const luckFields = result.fields.filter(f => f.type === 'luck');
|
||||
luckFields.forEach(field => {
|
||||
expect(field.stepValue).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should produce validation results without -1 values', async () => {
|
||||
const result = await boardGenerationService.generateBoard(10, 8, 5);
|
||||
|
||||
// Check validation results for invalid moves (-1 values)
|
||||
let invalidMoves = 0;
|
||||
let totalMoves = 0;
|
||||
|
||||
Object.values(result.validationResults).forEach(diceOutcomes => {
|
||||
diceOutcomes.forEach(outcome => {
|
||||
totalMoves++;
|
||||
if (outcome === -1) {
|
||||
invalidMoves++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const errorRate = totalMoves > 0 ? (invalidMoves / totalMoves) * 100 : 0;
|
||||
|
||||
// Log the results for analysis
|
||||
console.log(`Error rate: ${errorRate}%`);
|
||||
console.log(`Invalid moves: ${invalidMoves}/${totalMoves}`);
|
||||
|
||||
// The new algorithm should produce much fewer invalid moves
|
||||
expect(errorRate).toBeLessThan(50); // Allow some errors but much better than before
|
||||
});
|
||||
|
||||
it('should respect the 20-30 movement rule in validation', async () => {
|
||||
const result = await boardGenerationService.generateBoard(10, 8, 5);
|
||||
|
||||
// Check each validation result to ensure it respects distance rules
|
||||
Object.entries(result.validationResults).forEach(([fieldPosition, diceOutcomes]) => {
|
||||
const currentPos = parseInt(fieldPosition);
|
||||
|
||||
diceOutcomes.forEach((outcome, diceIndex) => {
|
||||
if (outcome !== -1) { // Only check valid moves
|
||||
const distance = Math.abs(outcome - currentPos);
|
||||
|
||||
if (currentPos <= 85) {
|
||||
// Fields 1-85: max 20 in any direction
|
||||
expect(distance).toBeLessThanOrEqual(20);
|
||||
} else {
|
||||
// Fields 86-100: max 30 backward, max 20 forward
|
||||
if (outcome > currentPos) {
|
||||
expect(distance).toBeLessThanOrEqual(20); // forward
|
||||
} else {
|
||||
expect(distance).toBeLessThanOrEqual(30); // backward
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should position special fields safely within the safe range', async () => {
|
||||
const result = await boardGenerationService.generateBoard(10, 8, 5);
|
||||
|
||||
const specialFields = result.fields.filter(f => f.type !== 'regular');
|
||||
|
||||
// Most special fields should be in the safe range (11-90) for the new algorithm
|
||||
const safeFields = specialFields.filter(f => f.position >= 11 && f.position <= 90);
|
||||
const safePercentage = (safeFields.length / specialFields.length) * 100;
|
||||
|
||||
console.log(`Safe field percentage: ${safePercentage}%`);
|
||||
|
||||
// Expect most fields to be positioned safely
|
||||
expect(safePercentage).toBeGreaterThan(70);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user