136 lines
4.3 KiB
TypeScript
136 lines
4.3 KiB
TypeScript
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
|
import { Logger } from 'vite';
|
|
import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
|
|
import type { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
|
|
import type { TeamRepository } from '../../domain/repositories/TeamRepository';
|
|
import {
|
|
LeaveTeamUseCase,
|
|
type LeaveTeamErrorCode,
|
|
type LeaveTeamInput,
|
|
} from './LeaveTeamUseCase';
|
|
|
|
describe('LeaveTeamUseCase', () => {
|
|
let useCase: LeaveTeamUseCase;
|
|
let teamRepository: { findById: Mock };
|
|
let membershipRepository: {
|
|
getMembership: Mock;
|
|
removeMembership: Mock;
|
|
};
|
|
let logger: Logger;
|
|
beforeEach(() => {
|
|
teamRepository = {
|
|
findById: vi.fn(),
|
|
};
|
|
membershipRepository = {
|
|
getMembership: vi.fn(),
|
|
removeMembership: vi.fn(),
|
|
};
|
|
logger = {
|
|
debug: vi.fn(),
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
} as unknown as Logger;
|
|
useCase = new LeaveTeamUseCase(teamRepository as unknown as TeamRepository,
|
|
membershipRepository as unknown as TeamMembershipRepository,
|
|
logger);
|
|
});
|
|
|
|
it('should leave team successfully', async () => {
|
|
const input: LeaveTeamInput = { teamId: 'team-1', driverId: 'driver-1' };
|
|
|
|
teamRepository.findById.mockResolvedValue({ id: 'team-1' });
|
|
const membership = {
|
|
teamId: 'team-1',
|
|
driverId: 'driver-1',
|
|
role: 'driver',
|
|
status: 'active',
|
|
joinedAt: new Date(),
|
|
};
|
|
membershipRepository.getMembership.mockResolvedValue(membership);
|
|
membershipRepository.removeMembership.mockResolvedValue(undefined);
|
|
|
|
const result = await useCase.execute(input);
|
|
|
|
expect(result.isOk()).toBe(true);
|
|
const presented = result.unwrap();
|
|
|
|
expect(presented.team.id).toBe('team-1');
|
|
expect(presented.previousMembership).toEqual(membership);
|
|
});
|
|
|
|
it('should return error when team is not found', async () => {
|
|
const input: LeaveTeamInput = { teamId: 'team-1', driverId: 'driver-1' };
|
|
|
|
teamRepository.findById.mockResolvedValue(null);
|
|
|
|
const result = await useCase.execute(input);
|
|
|
|
expect(result.isErr()).toBe(true);
|
|
const err = result.unwrapErr() as ApplicationErrorCode<
|
|
LeaveTeamErrorCode,
|
|
{ message: string }
|
|
>;
|
|
expect(err.code).toBe('TEAM_NOT_FOUND');
|
|
expect(err.details.message).toBe('Team team-1 not found');
|
|
});
|
|
|
|
it('should return error when not a member', async () => {
|
|
const input: LeaveTeamInput = { teamId: 'team-1', driverId: 'driver-1' };
|
|
|
|
teamRepository.findById.mockResolvedValue({ id: 'team-1' });
|
|
membershipRepository.getMembership.mockResolvedValue(null);
|
|
|
|
const result = await useCase.execute(input);
|
|
|
|
expect(result.isErr()).toBe(true);
|
|
const err = result.unwrapErr() as ApplicationErrorCode<
|
|
LeaveTeamErrorCode,
|
|
{ message: string }
|
|
>;
|
|
expect(err.code).toBe('NOT_MEMBER');
|
|
expect(err.details.message).toBe('Not a member of this team');
|
|
});
|
|
|
|
it('should return error when owner tries to leave', async () => {
|
|
const input: LeaveTeamInput = { teamId: 'team-1', driverId: 'driver-1' };
|
|
|
|
teamRepository.findById.mockResolvedValue({ id: 'team-1' });
|
|
membershipRepository.getMembership.mockResolvedValue({
|
|
teamId: 'team-1',
|
|
driverId: 'driver-1',
|
|
role: 'owner',
|
|
status: 'active',
|
|
joinedAt: new Date(),
|
|
});
|
|
|
|
const result = await useCase.execute(input);
|
|
|
|
expect(result.isErr()).toBe(true);
|
|
const err = result.unwrapErr() as ApplicationErrorCode<
|
|
LeaveTeamErrorCode,
|
|
{ message: string }
|
|
>;
|
|
expect(err.code).toBe('OWNER_CANNOT_LEAVE');
|
|
expect(err.details.message).toBe(
|
|
'Team owner cannot leave. Transfer ownership or disband team first.',
|
|
);
|
|
});
|
|
|
|
it('should return error on repository failure', async () => {
|
|
const input: LeaveTeamInput = { teamId: 'team-1', driverId: 'driver-1' };
|
|
const error = new Error('Repository error');
|
|
|
|
teamRepository.findById.mockRejectedValue(error);
|
|
|
|
const result = await useCase.execute(input);
|
|
|
|
expect(result.isErr()).toBe(true);
|
|
const err = result.unwrapErr() as ApplicationErrorCode<
|
|
LeaveTeamErrorCode,
|
|
{ message: string }
|
|
>;
|
|
expect(err.code).toBe('REPOSITORY_ERROR');
|
|
expect(err.details.message).toBe('Repository error');
|
|
});
|
|
}); |