576 lines
24 KiB
TypeScript
576 lines
24 KiB
TypeScript
/**
|
|
* Integration Test: Team Membership Use Case Orchestration
|
|
*
|
|
* Tests the orchestration logic of team membership-related Use Cases:
|
|
* - JoinTeamUseCase: Allows driver to request to join a team
|
|
* - CancelJoinRequestUseCase: Allows driver to cancel join request
|
|
* - ApproveJoinRequestUseCase: Admin approves join request
|
|
* - RejectJoinRequestUseCase: Admin rejects join request
|
|
* - Validates that Use Cases correctly interact with their Ports (Repositories, Event Publishers)
|
|
* - Uses In-Memory adapters for fast, deterministic testing
|
|
*
|
|
* Focus: Business logic orchestration, NOT UI rendering
|
|
*/
|
|
|
|
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
|
|
import { InMemoryTeamRepository } from '../../../adapters/teams/persistence/inmemory/InMemoryTeamRepository';
|
|
import { InMemoryDriverRepository } from '../../../adapters/drivers/persistence/inmemory/InMemoryDriverRepository';
|
|
import { InMemoryEventPublisher } from '../../../adapters/events/InMemoryEventPublisher';
|
|
import { JoinTeamUseCase } from '../../../core/teams/use-cases/JoinTeamUseCase';
|
|
import { CancelJoinRequestUseCase } from '../../../core/teams/use-cases/CancelJoinRequestUseCase';
|
|
import { ApproveJoinRequestUseCase } from '../../../core/teams/use-cases/ApproveJoinRequestUseCase';
|
|
import { RejectJoinRequestUseCase } from '../../../core/teams/use-cases/RejectJoinRequestUseCase';
|
|
import { JoinTeamCommand } from '../../../core/teams/ports/JoinTeamCommand';
|
|
import { CancelJoinRequestCommand } from '../../../core/teams/ports/CancelJoinRequestCommand';
|
|
import { ApproveJoinRequestCommand } from '../../../core/teams/ports/ApproveJoinRequestCommand';
|
|
import { RejectJoinRequestCommand } from '../../../core/teams/ports/RejectJoinRequestCommand';
|
|
|
|
describe('Team Membership Use Case Orchestration', () => {
|
|
let teamRepository: InMemoryTeamRepository;
|
|
let driverRepository: InMemoryDriverRepository;
|
|
let eventPublisher: InMemoryEventPublisher;
|
|
let joinTeamUseCase: JoinTeamUseCase;
|
|
let cancelJoinRequestUseCase: CancelJoinRequestUseCase;
|
|
let approveJoinRequestUseCase: ApproveJoinRequestUseCase;
|
|
let rejectJoinRequestUseCase: RejectJoinRequestUseCase;
|
|
|
|
beforeAll(() => {
|
|
// TODO: Initialize In-Memory repositories and event publisher
|
|
// teamRepository = new InMemoryTeamRepository();
|
|
// driverRepository = new InMemoryDriverRepository();
|
|
// eventPublisher = new InMemoryEventPublisher();
|
|
// joinTeamUseCase = new JoinTeamUseCase({
|
|
// teamRepository,
|
|
// driverRepository,
|
|
// eventPublisher,
|
|
// });
|
|
// cancelJoinRequestUseCase = new CancelJoinRequestUseCase({
|
|
// teamRepository,
|
|
// driverRepository,
|
|
// eventPublisher,
|
|
// });
|
|
// approveJoinRequestUseCase = new ApproveJoinRequestUseCase({
|
|
// teamRepository,
|
|
// driverRepository,
|
|
// eventPublisher,
|
|
// });
|
|
// rejectJoinRequestUseCase = new RejectJoinRequestUseCase({
|
|
// teamRepository,
|
|
// driverRepository,
|
|
// eventPublisher,
|
|
// });
|
|
});
|
|
|
|
beforeEach(() => {
|
|
// TODO: Clear all In-Memory repositories before each test
|
|
// teamRepository.clear();
|
|
// driverRepository.clear();
|
|
// eventPublisher.clear();
|
|
});
|
|
|
|
describe('JoinTeamUseCase - Success Path', () => {
|
|
it('should create a join request for a team', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Driver requests to join team
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The team has available roster slots
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: A join request should be created
|
|
// And: The request should be in pending status
|
|
// And: EventPublisher should emit TeamJoinRequestCreatedEvent
|
|
});
|
|
|
|
it('should create a join request with message', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Driver requests to join team with message
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// When: JoinTeamUseCase.execute() is called with message
|
|
// Then: A join request should be created with the message
|
|
// And: EventPublisher should emit TeamJoinRequestCreatedEvent
|
|
});
|
|
|
|
it('should create a join request when team is not full', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Team has available slots
|
|
// Given: A driver exists
|
|
// And: A team exists with available roster slots
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: A join request should be created
|
|
// And: EventPublisher should emit TeamJoinRequestCreatedEvent
|
|
});
|
|
});
|
|
|
|
describe('JoinTeamUseCase - Validation', () => {
|
|
it('should reject join request when team is full', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Team is full
|
|
// Given: A driver exists
|
|
// And: A team exists and is full
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: Should throw TeamFullError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject join request when driver is already a member', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Driver already member
|
|
// Given: A driver exists
|
|
// And: The driver is already a member of the team
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: Should throw DriverAlreadyMemberError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject join request when driver already has pending request', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Driver has pending request
|
|
// Given: A driver exists
|
|
// And: The driver already has a pending join request for the team
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: Should throw JoinRequestAlreadyExistsError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject join request with invalid message length', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Invalid message length
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// When: JoinTeamUseCase.execute() is called with message exceeding limit
|
|
// Then: Should throw ValidationError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('JoinTeamUseCase - Error Handling', () => {
|
|
it('should throw error when driver does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent driver
|
|
// Given: No driver exists with the given ID
|
|
// When: JoinTeamUseCase.execute() is called with non-existent driver ID
|
|
// Then: Should throw DriverNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should throw error when team does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent team
|
|
// Given: A driver exists
|
|
// And: No team exists with the given ID
|
|
// When: JoinTeamUseCase.execute() is called with non-existent team ID
|
|
// Then: Should throw TeamNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should handle repository errors gracefully', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Repository throws error
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: TeamRepository throws an error during save
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: Should propagate the error appropriately
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('CancelJoinRequestUseCase - Success Path', () => {
|
|
it('should cancel a pending join request', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Driver cancels join request
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The driver has a pending join request for the team
|
|
// When: CancelJoinRequestUseCase.execute() is called
|
|
// Then: The join request should be cancelled
|
|
// And: EventPublisher should emit TeamJoinRequestCancelledEvent
|
|
});
|
|
|
|
it('should cancel a join request with reason', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Driver cancels join request with reason
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The driver has a pending join request for the team
|
|
// When: CancelJoinRequestUseCase.execute() is called with reason
|
|
// Then: The join request should be cancelled with the reason
|
|
// And: EventPublisher should emit TeamJoinRequestCancelledEvent
|
|
});
|
|
});
|
|
|
|
describe('CancelJoinRequestUseCase - Validation', () => {
|
|
it('should reject cancellation when request does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent join request
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The driver does not have a join request for the team
|
|
// When: CancelJoinRequestUseCase.execute() is called
|
|
// Then: Should throw JoinRequestNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject cancellation when request is not pending', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Request already processed
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The driver has an approved join request for the team
|
|
// When: CancelJoinRequestUseCase.execute() is called
|
|
// Then: Should throw JoinRequestNotPendingError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject cancellation with invalid reason length', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Invalid reason length
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The driver has a pending join request for the team
|
|
// When: CancelJoinRequestUseCase.execute() is called with reason exceeding limit
|
|
// Then: Should throw ValidationError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('CancelJoinRequestUseCase - Error Handling', () => {
|
|
it('should throw error when driver does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent driver
|
|
// Given: No driver exists with the given ID
|
|
// When: CancelJoinRequestUseCase.execute() is called with non-existent driver ID
|
|
// Then: Should throw DriverNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should throw error when team does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent team
|
|
// Given: A driver exists
|
|
// And: No team exists with the given ID
|
|
// When: CancelJoinRequestUseCase.execute() is called with non-existent team ID
|
|
// Then: Should throw TeamNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should handle repository errors gracefully', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Repository throws error
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: TeamRepository throws an error during update
|
|
// When: CancelJoinRequestUseCase.execute() is called
|
|
// Then: Should propagate the error appropriately
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('ApproveJoinRequestUseCase - Success Path', () => {
|
|
it('should approve a pending join request', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Admin approves join request
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request for the team
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: The join request should be approved
|
|
// And: The driver should be added to the team roster
|
|
// And: EventPublisher should emit TeamJoinRequestApprovedEvent
|
|
// And: EventPublisher should emit TeamMemberAddedEvent
|
|
});
|
|
|
|
it('should approve join request with approval note', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Admin approves with note
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request for the team
|
|
// When: ApproveJoinRequestUseCase.execute() is called with approval note
|
|
// Then: The join request should be approved with the note
|
|
// And: EventPublisher should emit TeamJoinRequestApprovedEvent
|
|
});
|
|
|
|
it('should approve join request when team has available slots', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Team has available slots
|
|
// Given: A team captain exists
|
|
// And: A team exists with available roster slots
|
|
// And: A driver has a pending join request for the team
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: The join request should be approved
|
|
// And: EventPublisher should emit TeamJoinRequestApprovedEvent
|
|
});
|
|
});
|
|
|
|
describe('ApproveJoinRequestUseCase - Validation', () => {
|
|
it('should reject approval when team is full', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Team is full
|
|
// Given: A team captain exists
|
|
// And: A team exists and is full
|
|
// And: A driver has a pending join request for the team
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: Should throw TeamFullError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject approval when request does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent join request
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: No driver has a join request for the team
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: Should throw JoinRequestNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject approval when request is not pending', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Request already processed
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has an approved join request for the team
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: Should throw JoinRequestNotPendingError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject approval with invalid approval note length', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Invalid approval note length
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request for the team
|
|
// When: ApproveJoinRequestUseCase.execute() is called with approval note exceeding limit
|
|
// Then: Should throw ValidationError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('ApproveJoinRequestUseCase - Error Handling', () => {
|
|
it('should throw error when team captain does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent team captain
|
|
// Given: No team captain exists with the given ID
|
|
// When: ApproveJoinRequestUseCase.execute() is called with non-existent captain ID
|
|
// Then: Should throw DriverNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should throw error when team does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent team
|
|
// Given: A team captain exists
|
|
// And: No team exists with the given ID
|
|
// When: ApproveJoinRequestUseCase.execute() is called with non-existent team ID
|
|
// Then: Should throw TeamNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should handle repository errors gracefully', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Repository throws error
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: TeamRepository throws an error during update
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: Should propagate the error appropriately
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('RejectJoinRequestUseCase - Success Path', () => {
|
|
it('should reject a pending join request', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Admin rejects join request
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request for the team
|
|
// When: RejectJoinRequestUseCase.execute() is called
|
|
// Then: The join request should be rejected
|
|
// And: EventPublisher should emit TeamJoinRequestRejectedEvent
|
|
});
|
|
|
|
it('should reject join request with rejection reason', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Admin rejects with reason
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request for the team
|
|
// When: RejectJoinRequestUseCase.execute() is called with rejection reason
|
|
// Then: The join request should be rejected with the reason
|
|
// And: EventPublisher should emit TeamJoinRequestRejectedEvent
|
|
});
|
|
});
|
|
|
|
describe('RejectJoinRequestUseCase - Validation', () => {
|
|
it('should reject rejection when request does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent join request
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: No driver has a join request for the team
|
|
// When: RejectJoinRequestUseCase.execute() is called
|
|
// Then: Should throw JoinRequestNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject rejection when request is not pending', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Request already processed
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has an approved join request for the team
|
|
// When: RejectJoinRequestUseCase.execute() is called
|
|
// Then: Should throw JoinRequestNotPendingError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should reject rejection with invalid reason length', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Invalid reason length
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request for the team
|
|
// When: RejectJoinRequestUseCase.execute() is called with reason exceeding limit
|
|
// Then: Should throw ValidationError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('RejectJoinRequestUseCase - Error Handling', () => {
|
|
it('should throw error when team captain does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent team captain
|
|
// Given: No team captain exists with the given ID
|
|
// When: RejectJoinRequestUseCase.execute() is called with non-existent captain ID
|
|
// Then: Should throw DriverNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should throw error when team does not exist', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Non-existent team
|
|
// Given: A team captain exists
|
|
// And: No team exists with the given ID
|
|
// When: RejectJoinRequestUseCase.execute() is called with non-existent team ID
|
|
// Then: Should throw TeamNotFoundError
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
|
|
it('should handle repository errors gracefully', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Repository throws error
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: TeamRepository throws an error during update
|
|
// When: RejectJoinRequestUseCase.execute() is called
|
|
// Then: Should propagate the error appropriately
|
|
// And: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
|
|
describe('Team Membership Data Orchestration', () => {
|
|
it('should correctly track join request status', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Join request status tracking
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: The join request should be in pending status
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: The join request should be in approved status
|
|
// And: The driver should be added to the team roster
|
|
});
|
|
|
|
it('should correctly handle team roster size limits', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Roster size limit enforcement
|
|
// Given: A team exists with roster size limit of 5
|
|
// And: The team has 4 members
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: A join request should be created
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: The join request should be approved
|
|
// And: The team should now have 5 members
|
|
});
|
|
|
|
it('should correctly handle multiple join requests', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Multiple join requests
|
|
// Given: A team exists with available slots
|
|
// And: Multiple drivers have pending join requests
|
|
// When: ApproveJoinRequestUseCase.execute() is called for each request
|
|
// Then: Each request should be approved
|
|
// And: Each driver should be added to the team roster
|
|
});
|
|
|
|
it('should correctly handle join request cancellation', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Join request cancellation
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The driver has a pending join request
|
|
// When: CancelJoinRequestUseCase.execute() is called
|
|
// Then: The join request should be cancelled
|
|
// And: The driver should not be added to the team roster
|
|
});
|
|
});
|
|
|
|
describe('Team Membership Event Orchestration', () => {
|
|
it('should emit TeamJoinRequestCreatedEvent with correct payload', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Event emission on join request creation
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// When: JoinTeamUseCase.execute() is called
|
|
// Then: EventPublisher should emit TeamJoinRequestCreatedEvent
|
|
// And: The event should contain request ID, team ID, and driver ID
|
|
});
|
|
|
|
it('should emit TeamJoinRequestCancelledEvent with correct payload', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Event emission on join request cancellation
|
|
// Given: A driver exists
|
|
// And: A team exists
|
|
// And: The driver has a pending join request
|
|
// When: CancelJoinRequestUseCase.execute() is called
|
|
// Then: EventPublisher should emit TeamJoinRequestCancelledEvent
|
|
// And: The event should contain request ID, team ID, and driver ID
|
|
});
|
|
|
|
it('should emit TeamJoinRequestApprovedEvent with correct payload', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Event emission on join request approval
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request
|
|
// When: ApproveJoinRequestUseCase.execute() is called
|
|
// Then: EventPublisher should emit TeamJoinRequestApprovedEvent
|
|
// And: The event should contain request ID, team ID, and driver ID
|
|
});
|
|
|
|
it('should emit TeamJoinRequestRejectedEvent with correct payload', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: Event emission on join request rejection
|
|
// Given: A team captain exists
|
|
// And: A team exists
|
|
// And: A driver has a pending join request
|
|
// When: RejectJoinRequestUseCase.execute() is called
|
|
// Then: EventPublisher should emit TeamJoinRequestRejectedEvent
|
|
// And: The event should contain request ID, team ID, and driver ID
|
|
});
|
|
|
|
it('should not emit events on validation failure', async () => {
|
|
// TODO: Implement test
|
|
// Scenario: No events on validation failure
|
|
// Given: Invalid parameters
|
|
// When: Any use case is called with invalid data
|
|
// Then: EventPublisher should NOT emit any events
|
|
});
|
|
});
|
|
});
|