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,167 @@
|
||||
import { UserAggregate, UserState } from '../src/Domain/User/UserAggregate';
|
||||
import { OrganizationAggregate, OrganizationState } from '../src/Domain/Organization/OrganizationAggregate';
|
||||
import { DeckAggregate, State as DeckState, Type as DeckType, CType } from '../src/Domain/Deck/DeckAggregate';
|
||||
import { ContactAggregate, ContactState, ContactType } from '../src/Domain/Contact/ContactAggregate';
|
||||
import { IUserRepository } from '../src/Domain/IRepository/IUserRepository';
|
||||
import { IOrganizationRepository } from '../src/Domain/IRepository/IOrganizationRepository';
|
||||
import { IDeckRepository } from '../src/Domain/IRepository/IDeckRepository';
|
||||
import { IContactRepository } from '../src/Domain/IRepository/IContactRepository';
|
||||
|
||||
export const createMockUser = (overrides: Partial<UserAggregate> = {}): UserAggregate => ({
|
||||
id: '123e4567-e89b-12d3-a456-426614174000',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
password: 'hashedPassword',
|
||||
fname: 'Test',
|
||||
lname: 'User',
|
||||
orgid: null,
|
||||
token: null,
|
||||
TokenExpires: null,
|
||||
type: 'regular',
|
||||
phone: null,
|
||||
state: UserState.REGISTERED_NOT_VERIFIED,
|
||||
regdate: new Date('2025-01-01'),
|
||||
updatedate: new Date('2025-01-01'),
|
||||
Orglogindate: null,
|
||||
...overrides
|
||||
});
|
||||
|
||||
export const createMockOrganization = (overrides: Partial<OrganizationAggregate> = {}): OrganizationAggregate => ({
|
||||
id: '123e4567-e89b-12d3-a456-426614174001',
|
||||
name: 'Test Organization',
|
||||
contactfname: 'John',
|
||||
contactlname: 'Doe',
|
||||
contactphone: '+1234567890',
|
||||
contactemail: 'contact@testorg.com',
|
||||
state: OrganizationState.ACTIVE,
|
||||
regdate: new Date('2025-01-01'),
|
||||
updatedate: new Date('2025-01-01'),
|
||||
url: null,
|
||||
userinorg: 0,
|
||||
maxOrganizationalDecks: 10,
|
||||
users: [],
|
||||
...overrides
|
||||
});
|
||||
|
||||
export const createMockDeck = (overrides: Partial<DeckAggregate> = {}): DeckAggregate => ({
|
||||
id: '123e4567-e89b-12d3-a456-426614174002',
|
||||
name: 'Test Deck',
|
||||
type: DeckType.JOKER,
|
||||
userid: '123e4567-e89b-12d3-a456-426614174000',
|
||||
creationdate: new Date('2025-01-01'),
|
||||
cards: [],
|
||||
playedNumber: 0,
|
||||
ctype: CType.PUBLIC,
|
||||
updatedate: new Date('2025-01-01'),
|
||||
state: DeckState.ACTIVE,
|
||||
organization: null,
|
||||
...overrides
|
||||
});
|
||||
|
||||
export const createMockContact = (overrides: Partial<ContactAggregate> = {}): ContactAggregate => ({
|
||||
id: '123e4567-e89b-12d3-a456-426614174003',
|
||||
name: 'John Doe',
|
||||
email: 'john.doe@example.com',
|
||||
userid: '123e4567-e89b-12d3-a456-426614174000',
|
||||
type: ContactType.QUESTION,
|
||||
txt: 'This is a test contact message.',
|
||||
state: ContactState.ACTIVE,
|
||||
createDate: new Date('2025-01-01'),
|
||||
updateDate: new Date('2025-01-01'),
|
||||
adminResponse: null,
|
||||
responseDate: null,
|
||||
respondedBy: null,
|
||||
...overrides
|
||||
});
|
||||
|
||||
export const createMockDate = () => new Date('2025-01-01T00:00:00Z');
|
||||
|
||||
// Mock Repository Factory Functions
|
||||
export const createMockUserRepository = (): jest.Mocked<IUserRepository> => ({
|
||||
create: jest.fn(),
|
||||
findByPage: jest.fn(),
|
||||
findByPageIncludingDeleted: jest.fn(),
|
||||
findById: jest.fn(),
|
||||
findByIdIncludingDeleted: jest.fn(),
|
||||
findByUsername: jest.fn(),
|
||||
findByEmail: jest.fn(),
|
||||
findByToken: jest.fn(),
|
||||
search: jest.fn(),
|
||||
searchIncludingDeleted: jest.fn(),
|
||||
update: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
softDelete: jest.fn(),
|
||||
deactivate: jest.fn(),
|
||||
} as jest.Mocked<IUserRepository>);
|
||||
|
||||
export const createMockOrganizationRepository = (): jest.Mocked<IOrganizationRepository> => ({
|
||||
create: jest.fn(),
|
||||
findByPage: jest.fn(),
|
||||
findByPageIncludingDeleted: jest.fn(),
|
||||
findById: jest.fn(),
|
||||
findByIdIncludingDeleted: jest.fn(),
|
||||
search: jest.fn(),
|
||||
searchIncludingDeleted: jest.fn(),
|
||||
update: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
softDelete: jest.fn(),
|
||||
} as jest.Mocked<IOrganizationRepository>);
|
||||
|
||||
export const createMockDeckRepository = (): jest.Mocked<IDeckRepository> => ({
|
||||
create: jest.fn(),
|
||||
findByPage: jest.fn(),
|
||||
findByPageIncludingDeleted: jest.fn(),
|
||||
findById: jest.fn(),
|
||||
findByIdIncludingDeleted: jest.fn(),
|
||||
search: jest.fn(),
|
||||
searchIncludingDeleted: jest.fn(),
|
||||
update: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
softDelete: jest.fn(),
|
||||
countActiveByUserId: jest.fn(),
|
||||
countOrganizationalByUserId: jest.fn(),
|
||||
findFilteredDecks: jest.fn(),
|
||||
} as jest.Mocked<IDeckRepository>);
|
||||
|
||||
export const createMockContactRepository = (): jest.Mocked<IContactRepository> => ({
|
||||
create: jest.fn(),
|
||||
findById: jest.fn(),
|
||||
findByPage: jest.fn(),
|
||||
findByPageIncludingDeleted: jest.fn(),
|
||||
findByIdIncludingDeleted: jest.fn(),
|
||||
search: jest.fn(),
|
||||
searchIncludingDeleted: jest.fn(),
|
||||
update: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
softDelete: jest.fn(),
|
||||
} as jest.Mocked<IContactRepository>);
|
||||
|
||||
export const createMockJWTService = () => ({
|
||||
create: jest.fn(),
|
||||
verify: jest.fn(),
|
||||
shouldRefreshToken: jest.fn(),
|
||||
parseDuration: jest.fn(),
|
||||
} as any);
|
||||
|
||||
export const createMockTokenService = () => ({
|
||||
generateSecureToken: jest.fn(),
|
||||
generateVerificationToken: jest.fn(),
|
||||
generatePasswordResetToken: jest.fn(),
|
||||
isTokenExpired: jest.fn(),
|
||||
validateToken: jest.fn(),
|
||||
} as any);
|
||||
|
||||
export const createMockEmailService = () => ({
|
||||
sendEmail: jest.fn(),
|
||||
sendVerificationEmail: jest.fn(),
|
||||
sendPasswordResetEmail: jest.fn(),
|
||||
sendContactResponseEmail: jest.fn(),
|
||||
loadTemplate: jest.fn(),
|
||||
} as any);
|
||||
|
||||
export const createMockPasswordService = () => ({
|
||||
hashPassword: jest.fn(),
|
||||
verifyPassword: jest.fn(),
|
||||
validatePasswordStrength: jest.fn(),
|
||||
generateRandomPassword: jest.fn(),
|
||||
} as any);
|
||||
Reference in New Issue
Block a user