Files
SerpentRace/SerpentRace_Backend/tests/Application/Deck/commands/CreateDeckCommandHandler.comprehensive.test.ts
T

208 lines
6.7 KiB
TypeScript

import { CreateDeckCommandHandler } from '../../../../src/Application/Deck/commands/CreateDeckCommandHandler';
import { CreateDeckCommand } from '../../../../src/Application/Deck/commands/CreateDeckCommand';
import { IDeckRepository } from '../../../../src/Domain/IRepository/IDeckRepository';
import { IUserRepository } from '../../../../src/Domain/IRepository/IUserRepository';
import { IOrganizationRepository } from '../../../../src/Domain/IRepository/IOrganizationRepository';
import { UserState } from '../../../../src/Domain/User/UserAggregate';
import { Type as DeckType } from '../../../../src/Domain/Deck/DeckAggregate';
import { createMockDeck, createMockDeckRepository, createMockUserRepository, createMockOrganizationRepository, createMockUser } from '../../../testUtils';
describe('CreateDeckCommandHandler', () => {
let handler: CreateDeckCommandHandler;
let mockDeckRepository: jest.Mocked<IDeckRepository>;
let mockUserRepository: jest.Mocked<IUserRepository>;
let mockOrganizationRepository: jest.Mocked<IOrganizationRepository>;
beforeEach(() => {
jest.clearAllMocks();
mockDeckRepository = createMockDeckRepository();
mockUserRepository = createMockUserRepository();
mockOrganizationRepository = createMockOrganizationRepository();
handler = new CreateDeckCommandHandler(mockDeckRepository, mockUserRepository, mockOrganizationRepository);
});
describe('execute', () => {
it('should successfully create a new deck with valid user', async () => {
// Arrange
const command: CreateDeckCommand = {
name: 'Test Deck',
type: DeckType.JOKER,
userid: 'user-123',
cards: [{ id: 'card-1', name: 'Test Card' }],
};
const mockUser = createMockUser({
id: command.userid,
state: UserState.VERIFIED_REGULAR,
type: 'user'
});
const mockDeck = createMockDeck({
name: command.name,
type: command.type,
userid: command.userid
});
mockUserRepository.findById.mockResolvedValue(mockUser);
mockDeckRepository.countActiveByUserId.mockResolvedValue(0);
mockDeckRepository.create.mockResolvedValue(mockDeck);
// Act
const result = await handler.execute(command);
// Assert
expect(result).toBeDefined();
expect(mockUserRepository.findById).toHaveBeenCalledWith(command.userid);
expect(mockDeckRepository.create).toHaveBeenCalled();
});
it('should throw error when user not found', async () => {
// Arrange
const command: CreateDeckCommand = {
name: 'Test Deck',
type: DeckType.JOKER,
userid: 'nonexistent-user',
cards: [],
};
mockUserRepository.findById.mockResolvedValue(null);
// Act & Assert
await expect(handler.execute(command)).rejects.toThrow('User not found');
expect(mockUserRepository.findById).toHaveBeenCalledWith(command.userid);
expect(mockDeckRepository.create).not.toHaveBeenCalled();
});
it('should handle admin user creating unlimited decks', async () => {
// Arrange
const command: CreateDeckCommand = {
name: 'Admin Deck',
type: DeckType.JOKER,
userid: 'admin-123',
cards: [],
};
const mockAdminUser = createMockUser({
id: command.userid,
state: UserState.VERIFIED_REGULAR,
type: 'admin'
});
const mockDeck = createMockDeck({
name: command.name,
type: command.type,
userid: command.userid
});
mockUserRepository.findById.mockResolvedValue(mockAdminUser);
mockDeckRepository.create.mockResolvedValue(mockDeck);
// Act
const result = await handler.execute(command);
// Assert
expect(result).toBeDefined();
expect(mockDeckRepository.countActiveByUserId).toHaveBeenCalled(); // Admin still checks but bypasses limits
});
it('should handle repository creation errors', async () => {
// Arrange
const command: CreateDeckCommand = {
name: 'Test Deck',
type: DeckType.JOKER,
userid: 'user-123',
cards: [],
};
const mockUser = createMockUser({ id: command.userid });
mockUserRepository.findById.mockResolvedValue(mockUser);
mockDeckRepository.countActiveByUserId.mockResolvedValue(0);
mockDeckRepository.create.mockRejectedValue(new Error('Database error'));
// Act & Assert
await expect(handler.execute(command)).rejects.toThrow('Database error');
});
it('should create deck with different types', async () => {
// Arrange
const command: CreateDeckCommand = {
name: 'Question Deck',
type: DeckType.QUESTION,
userid: 'user-123',
cards: [],
};
const mockUser = createMockUser({ id: command.userid });
const mockDeck = createMockDeck({
name: command.name,
type: command.type,
userid: command.userid
});
mockUserRepository.findById.mockResolvedValue(mockUser);
mockDeckRepository.countActiveByUserId.mockResolvedValue(0);
mockDeckRepository.create.mockResolvedValue(mockDeck);
// Act
const result = await handler.execute(command);
// Assert
expect(result).toBeDefined();
expect(mockDeckRepository.create).toHaveBeenCalledWith(expect.objectContaining({
type: DeckType.QUESTION
}));
});
it('should handle empty cards array', async () => {
// Arrange
const command: CreateDeckCommand = {
name: 'Empty Deck',
type: DeckType.JOKER,
userid: 'user-123',
cards: [],
};
const mockUser = createMockUser({ id: command.userid });
const mockDeck = createMockDeck(command);
mockUserRepository.findById.mockResolvedValue(mockUser);
mockDeckRepository.countActiveByUserId.mockResolvedValue(0);
mockDeckRepository.create.mockResolvedValue(mockDeck);
// Act
const result = await handler.execute(command);
// Assert
expect(result).toBeDefined();
});
it('should check deck limits for regular users', async () => {
// Arrange
const command: CreateDeckCommand = {
name: 'Test Deck',
type: DeckType.JOKER,
userid: 'user-123',
cards: [],
};
const mockUser = createMockUser({
id: command.userid,
type: 'user'
});
const mockDeck = createMockDeck({ userid: command.userid });
mockUserRepository.findById.mockResolvedValue(mockUser);
mockDeckRepository.countActiveByUserId.mockResolvedValue(0);
mockDeckRepository.create.mockResolvedValue(mockDeck);
// Act
await handler.execute(command);
// Assert
expect(mockDeckRepository.countActiveByUserId).toHaveBeenCalledWith(command.userid);
});
});
});