template-saas-backend-v2/src/modules/sales/__tests__/dashboard.controller.spec.ts
Adrian Flores Cortes 23bd170769 test(P2): Recreate 4 controller test files
- products.controller.spec.ts (16 tests) - Portfolio module
- activities.controller.spec.ts (8 tests) - Sales module
- leads.controller.spec.ts (9 tests) - Sales module
- dashboard.controller.spec.ts (6 tests) - Sales module

Total: 39 new tests for previously deleted test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:26:10 -06:00

192 lines
6.6 KiB
TypeScript

import { Test, TestingModule } from '@nestjs/testing';
import { SalesDashboardController } from '../controllers/dashboard.controller';
import { SalesDashboardService } from '../services';
import { LeadStatus, LeadSource, OpportunityStage } from '../entities';
import {
SalesDashboardDto,
LeadsByStatusDto,
LeadsBySourceDto,
OpportunitiesByStageDto,
ConversionFunnelDto,
SalesPerformanceDto,
} from '../dto';
describe('SalesDashboardController', () => {
let controller: SalesDashboardController;
let dashboardService: jest.Mocked<SalesDashboardService>;
const mockTenantId = '550e8400-e29b-41d4-a716-446655440001';
const mockUserId = '550e8400-e29b-41d4-a716-446655440002';
const mockRequestUser = {
id: mockUserId,
email: 'test@example.com',
tenant_id: mockTenantId,
role: 'admin',
};
const mockSummary: SalesDashboardDto = {
totalLeads: 150,
totalOpportunities: 45,
totalPipelineValue: 1250000,
wonDeals: 12,
conversionRate: 26.7,
averageDealSize: 104166.67,
activitiesThisWeek: 35,
currency: 'USD',
};
const mockLeadsByStatus: LeadsByStatusDto[] = [
{ status: LeadStatus.NEW, count: 50, percentage: 33.3 },
{ status: LeadStatus.CONTACTED, count: 40, percentage: 26.7 },
{ status: LeadStatus.QUALIFIED, count: 35, percentage: 23.3 },
{ status: LeadStatus.CONVERTED, count: 25, percentage: 16.7 },
];
const mockLeadsBySource: LeadsBySourceDto[] = [
{ source: LeadSource.WEBSITE, count: 60, percentage: 40.0 },
{ source: LeadSource.REFERRAL, count: 45, percentage: 30.0 },
{ source: LeadSource.EVENT, count: 25, percentage: 16.7 },
{ source: LeadSource.COLD_CALL, count: 20, percentage: 13.3 },
];
const mockOpportunitiesByStage: OpportunitiesByStageDto[] = [
{ stage: OpportunityStage.QUALIFICATION, count: 15, totalAmount: 375000, percentage: 33.3 },
{ stage: OpportunityStage.PROPOSAL, count: 12, totalAmount: 480000, percentage: 26.7 },
{ stage: OpportunityStage.NEGOTIATION, count: 10, totalAmount: 350000, percentage: 22.2 },
{ stage: OpportunityStage.CLOSED_WON, count: 8, totalAmount: 320000, percentage: 17.8 },
];
const mockConversionFunnel: ConversionFunnelDto[] = [
{ stage: 'leads', count: 150, percentage: 100, conversionFromPrevious: 100 },
{ stage: 'qualified', count: 75, percentage: 50, conversionFromPrevious: 50 },
{ stage: 'opportunities', count: 45, percentage: 30, conversionFromPrevious: 60 },
{ stage: 'proposals', count: 30, percentage: 20, conversionFromPrevious: 66.7 },
{ stage: 'won', count: 12, percentage: 8, conversionFromPrevious: 40 },
];
const mockSalesPerformance: SalesPerformanceDto[] = [
{
userId: 'user-001',
userName: 'John Doe',
leadsAssigned: 45,
opportunitiesWon: 5,
totalRevenue: 125000,
conversionRate: 11.1,
activitiesCompleted: 120,
},
{
userId: 'user-002',
userName: 'Jane Smith',
leadsAssigned: 52,
opportunitiesWon: 7,
totalRevenue: 175000,
conversionRate: 13.5,
activitiesCompleted: 145,
},
];
beforeEach(async () => {
const mockDashboardService = {
getDashboardSummary: jest.fn(),
getLeadsByStatus: jest.fn(),
getLeadsBySource: jest.fn(),
getOpportunitiesByStage: jest.fn(),
getConversionFunnel: jest.fn(),
getSalesPerformance: jest.fn(),
};
const module: TestingModule = await Test.createTestingModule({
controllers: [SalesDashboardController],
providers: [
{
provide: SalesDashboardService,
useValue: mockDashboardService,
},
],
}).compile();
controller = module.get<SalesDashboardController>(SalesDashboardController);
dashboardService = module.get(SalesDashboardService);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('getSummary', () => {
it('should return dashboard summary', async () => {
dashboardService.getDashboardSummary.mockResolvedValue(mockSummary);
const result = await controller.getSummary(mockRequestUser);
expect(dashboardService.getDashboardSummary).toHaveBeenCalledWith(mockTenantId);
expect(result).toEqual(mockSummary);
expect(result.totalLeads).toBe(150);
expect(result.conversionRate).toBe(26.7);
});
});
describe('getLeadsByStatus', () => {
it('should return leads grouped by status', async () => {
dashboardService.getLeadsByStatus.mockResolvedValue(mockLeadsByStatus);
const result = await controller.getLeadsByStatus(mockRequestUser);
expect(dashboardService.getLeadsByStatus).toHaveBeenCalledWith(mockTenantId);
expect(result).toEqual(mockLeadsByStatus);
expect(result.length).toBe(4);
});
});
describe('getLeadsBySource', () => {
it('should return leads grouped by source', async () => {
dashboardService.getLeadsBySource.mockResolvedValue(mockLeadsBySource);
const result = await controller.getLeadsBySource(mockRequestUser);
expect(dashboardService.getLeadsBySource).toHaveBeenCalledWith(mockTenantId);
expect(result).toEqual(mockLeadsBySource);
expect(result.length).toBe(4);
});
});
describe('getOpportunitiesByStage', () => {
it('should return opportunities grouped by stage', async () => {
dashboardService.getOpportunitiesByStage.mockResolvedValue(mockOpportunitiesByStage);
const result = await controller.getOpportunitiesByStage(mockRequestUser);
expect(dashboardService.getOpportunitiesByStage).toHaveBeenCalledWith(mockTenantId);
expect(result).toEqual(mockOpportunitiesByStage);
expect(result.length).toBe(4);
});
});
describe('getConversionFunnel', () => {
it('should return conversion funnel data', async () => {
dashboardService.getConversionFunnel.mockResolvedValue(mockConversionFunnel);
const result = await controller.getConversionFunnel(mockRequestUser);
expect(dashboardService.getConversionFunnel).toHaveBeenCalledWith(mockTenantId);
expect(result).toEqual(mockConversionFunnel);
expect(result.length).toBe(5);
expect(result[0].stage).toBe('leads');
});
});
describe('getSalesPerformance', () => {
it('should return sales performance data', async () => {
dashboardService.getSalesPerformance.mockResolvedValue(mockSalesPerformance);
const result = await controller.getSalesPerformance(mockRequestUser);
expect(dashboardService.getSalesPerformance).toHaveBeenCalledWith(mockTenantId);
expect(result).toEqual(mockSalesPerformance);
expect(result.length).toBe(2);
expect(result[0].totalRevenue).toBe(125000);
});
});
});