fix(lint): resolve all 24 ESLint errors across web, api and e2e

- Remove unused imports (waitFor, useAuthStore) in dashboard test files
- Convert import() type annotation to import type in comparison-store spec
- Add next-env.d.ts to ESLint ignores (auto-generated file)
- Fix empty object pattern in auth.fixture.ts
- Sort import order alphabetically in 5 API test files

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-11 00:42:00 +07:00
parent d824d16760
commit 0593d40098
14 changed files with 734 additions and 14 deletions

View File

@@ -0,0 +1,135 @@
import { CreateLeadCommand } from '../../application/commands/create-lead/create-lead.command';
import { DeleteLeadCommand } from '../../application/commands/delete-lead/delete-lead.command';
import { UpdateLeadStatusCommand } from '../../application/commands/update-lead-status/update-lead-status.command';
import { GetLeadStatsQuery } from '../../application/queries/get-lead-stats/get-lead-stats.query';
import { GetLeadsByAgentQuery } from '../../application/queries/get-leads-by-agent/get-leads-by-agent.query';
import { LeadsController } from '../controllers/leads.controller';
describe('LeadsController', () => {
let controller: LeadsController;
let mockCommandBus: { execute: ReturnType<typeof vi.fn> };
let mockQueryBus: { execute: ReturnType<typeof vi.fn> };
const mockAgent = { sub: 'agent-1', phone: '0901234567', role: 'AGENT' };
beforeEach(() => {
mockCommandBus = { execute: vi.fn() };
mockQueryBus = { execute: vi.fn() };
controller = new LeadsController(mockCommandBus as any, mockQueryBus as any);
});
describe('POST /leads — createLead', () => {
it('dispatches CreateLeadCommand with correct parameters', async () => {
const dto = {
name: 'Nguyễn Văn A',
phone: '0909123456',
email: 'a@example.com',
source: 'website',
score: 80,
notes: 'Quan tâm căn hộ',
};
const expected = { id: 'lead-1', name: 'Nguyễn Văn A' };
mockCommandBus.execute.mockResolvedValue(expected);
const result = await controller.createLead(dto as any, mockAgent as any);
expect(mockCommandBus.execute).toHaveBeenCalledWith(expect.any(CreateLeadCommand));
const cmd = mockCommandBus.execute.mock.calls[0]![0] as CreateLeadCommand;
expect(cmd.agentUserId).toBe('agent-1');
expect(cmd.name).toBe('Nguyễn Văn A');
expect(cmd.phone).toBe('0909123456');
expect(cmd.email).toBe('a@example.com');
expect(cmd.source).toBe('website');
expect(cmd.score).toBe(80);
expect(cmd.notes).toBe('Quan tâm căn hộ');
expect(result).toEqual(expected);
});
it('passes null for optional fields', async () => {
const dto = { name: 'Test', phone: '0909000000', source: 'referral' };
mockCommandBus.execute.mockResolvedValue({ id: 'lead-2' });
await controller.createLead(dto as any, mockAgent as any);
const cmd = mockCommandBus.execute.mock.calls[0]![0] as CreateLeadCommand;
expect(cmd.email).toBeNull();
expect(cmd.score).toBeNull();
expect(cmd.notes).toBeNull();
});
});
describe('GET /leads — getLeads', () => {
it('dispatches GetLeadsByAgentQuery with defaults', async () => {
const expected = { data: [], total: 0, page: 1, limit: 20, totalPages: 0 };
mockQueryBus.execute.mockResolvedValue(expected);
const result = await controller.getLeads({} as any, mockAgent as any);
expect(mockQueryBus.execute).toHaveBeenCalledWith(expect.any(GetLeadsByAgentQuery));
const query = mockQueryBus.execute.mock.calls[0]![0] as GetLeadsByAgentQuery;
expect(query.agentUserId).toBe('agent-1');
expect(query.status).toBeNull();
expect(query.page).toBe(1);
expect(query.limit).toBe(20);
expect(result).toEqual(expected);
});
it('passes custom filters', async () => {
mockQueryBus.execute.mockResolvedValue({ data: [] });
await controller.getLeads({ status: 'qualified', page: 2, limit: 10 } as any, mockAgent as any);
const query = mockQueryBus.execute.mock.calls[0]![0] as GetLeadsByAgentQuery;
expect(query.status).toBe('qualified');
expect(query.page).toBe(2);
expect(query.limit).toBe(10);
});
});
describe('GET /leads/stats — getStats', () => {
it('dispatches GetLeadStatsQuery', async () => {
const expected = { total: 50, qualified: 10, converted: 5 };
mockQueryBus.execute.mockResolvedValue(expected);
const result = await controller.getStats(mockAgent as any);
expect(mockQueryBus.execute).toHaveBeenCalledWith(expect.any(GetLeadStatsQuery));
const query = mockQueryBus.execute.mock.calls[0]![0] as GetLeadStatsQuery;
expect(query.agentUserId).toBe('agent-1');
expect(result).toEqual(expected);
});
});
describe('PATCH /leads/:id/status — updateStatus', () => {
it('dispatches UpdateLeadStatusCommand and returns updated true', async () => {
mockCommandBus.execute.mockResolvedValue(undefined);
const result = await controller.updateStatus(
'lead-1',
{ status: 'qualified' } as any,
mockAgent as any,
);
expect(mockCommandBus.execute).toHaveBeenCalledWith(expect.any(UpdateLeadStatusCommand));
const cmd = mockCommandBus.execute.mock.calls[0]![0] as UpdateLeadStatusCommand;
expect(cmd.leadId).toBe('lead-1');
expect(cmd.agentUserId).toBe('agent-1');
expect(cmd.newStatus).toBe('qualified');
expect(result).toEqual({ updated: true });
});
});
describe('DELETE /leads/:id — deleteLead', () => {
it('dispatches DeleteLeadCommand and returns deleted true', async () => {
mockCommandBus.execute.mockResolvedValue(undefined);
const result = await controller.deleteLead('lead-1', mockAgent as any);
expect(mockCommandBus.execute).toHaveBeenCalledWith(expect.any(DeleteLeadCommand));
const cmd = mockCommandBus.execute.mock.calls[0]![0] as DeleteLeadCommand;
expect(cmd.leadId).toBe('lead-1');
expect(cmd.agentUserId).toBe('agent-1');
expect(result).toEqual({ deleted: true });
});
});
});