Skip to content

Commit 3ba5f47

Browse files
committed
fix: change test files locations chnages
1 parent 3300209 commit 3ba5f47

3 files changed

Lines changed: 263 additions & 5 deletions

File tree

jest.config.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
module.exports = {
22
preset: 'ts-jest',
33
testEnvironment: 'node',
4-
roots: ['<rootDir>/src'],
5-
testMatch: [
6-
'**/*.spec.ts', // Look for spec files anywhere in src
7-
'<rootDir>/test/**/*.spec.ts' // Keep existing test directory pattern
8-
],
4+
roots: ['<rootDir>/src', '<rootDir>/test'],
5+
testMatch: ['<rootDir>/test/**/*.spec.ts'],
96
moduleFileExtensions: ['ts', 'js', 'json'],
107
transform: {
118
'^.+\\.ts$': ['ts-jest', {

test/logger/log.controller.spec.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { LogController } from './log.controller';
3+
import { LoggerServiceDb } from '../../../logger/services/logger.service.db';
4+
import { NotFoundException } from '@nestjs/common';
5+
import { Logger } from 'src/logger/infrastructure/persistence/mongoose/logger.schema';
6+
import { PaginatedLogs } from '../../../logger/domain/interfaces/log-model.interface';
7+
8+
describe('LogController', () => {
9+
let controller: LogController;
10+
let logService: LoggerServiceDb;
11+
12+
const mockLog = {
13+
_id: '1',
14+
level: 'info',
15+
message: 'Test log',
16+
context: 'NotificationController',
17+
timestamp: new Date(),
18+
};
19+
20+
const mockStats = {
21+
total: 10,
22+
info: 5,
23+
warn: 3,
24+
error: 2,
25+
};
26+
27+
beforeEach(async () => {
28+
const module: TestingModule = await Test.createTestingModule({
29+
controllers: [LogController],
30+
providers: [
31+
{
32+
provide: LoggerServiceDb,
33+
useValue: {
34+
getLogsByFilter: jest.fn().mockResolvedValue({
35+
logs: [mockLog],
36+
total: 1,
37+
}),
38+
getLogById: jest.fn().mockResolvedValue(mockLog),
39+
deleteLogById: jest.fn().mockResolvedValue(undefined),
40+
deleteLogsByFilter: jest.fn().mockResolvedValue(1),
41+
getLogStats: jest.fn().mockResolvedValue(mockStats),
42+
},
43+
},
44+
],
45+
}).compile();
46+
47+
controller = module.get<LogController>(LogController);
48+
logService = module.get<LoggerServiceDb>(LoggerServiceDb);
49+
});
50+
51+
describe('getLogs', () => {
52+
it('should return logs with default pagination', async () => {
53+
const mockResult: PaginatedLogs = {
54+
logs: [mockLog as unknown as Logger],
55+
total: 1,
56+
};
57+
58+
const spy = jest
59+
.spyOn(logService, 'getLogsByFilter')
60+
.mockResolvedValue(mockResult);
61+
62+
const result = await controller.getLogs('info', 'LogController', 1, 10);
63+
64+
expect(spy).toHaveBeenCalledWith('info', 'LogController', 1, 10);
65+
expect(result).toEqual({
66+
data: [mockLog],
67+
total: 1,
68+
page: 1,
69+
totalPages: 1,
70+
});
71+
});
72+
});
73+
74+
describe('getLogById', () => {
75+
it('should return a log by ID', async () => {
76+
const result = await controller.getLogById('1');
77+
expect(result).toEqual({ data: mockLog });
78+
});
79+
80+
it('should throw NotFoundException if log not found', async () => {
81+
jest
82+
.spyOn(logService, 'getLogById')
83+
.mockResolvedValue(null as unknown as Logger);
84+
85+
await expect(controller.getLogById('999')).rejects.toThrow(
86+
NotFoundException,
87+
);
88+
await expect(controller.getLogById('999')).rejects.toThrow(
89+
'Log with ID 999 not found',
90+
);
91+
});
92+
});
93+
94+
describe('deleteLogById', () => {
95+
it('should delete a log by ID', async () => {
96+
await controller.deleteLogById('1');
97+
//expect(logService.deleteLogById).toHaveBeenCalledWith('1');
98+
});
99+
100+
it('should throw NotFoundException if log not found', async () => {
101+
jest
102+
.spyOn(logService, 'getLogById')
103+
.mockResolvedValue(null as unknown as Logger);
104+
105+
await expect(controller.deleteLogById('999')).rejects.toThrow(
106+
NotFoundException,
107+
);
108+
});
109+
});
110+
111+
describe('getLogStats', () => {
112+
it('should return log statistics', async () => {
113+
const result = await controller.getLogStats('info', 'TestContext');
114+
expect(result).toEqual({ data: mockStats });
115+
});
116+
117+
it('should return stats without filters', async () => {
118+
const result = await controller.getLogStats(undefined, undefined);
119+
expect(result).toEqual({ data: mockStats });
120+
});
121+
});
122+
});
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { NotificationController } from '../../src/notification/presentation/controllers/notification.controller';
3+
import { NotificationFactory } from '../../src/notification/application/factories/notification.factory';
4+
import { INotificationRepository } from '../../src/notification/domain/interfaces/notification-repository.interface';
5+
import { LoggerServiceFile } from '../../src/logger/services/logger.service.file';
6+
import { LoggerServiceDb } from '../../src/logger/services/logger.service.db';
7+
import { SendNotificationDto } from '../../src/notification/presentation/dtos/send-notification.dto';
8+
import { Notification } from '../../src/notification/domain/entities/notification.entity';
9+
import {
10+
NotificationChannel,
11+
NotificationType,
12+
} from '../../src/config/notification.config';
13+
14+
describe('NotificationController', () => {
15+
let controller: NotificationController;
16+
let factory: NotificationFactory;
17+
let repository: INotificationRepository;
18+
19+
const mockNotification = new Notification(
20+
'test@example.com',
21+
'Test Subject',
22+
'Test Body',
23+
NotificationChannel.EMAIL,
24+
NotificationType.ADMISSION_ID,
25+
new Date(),
26+
);
27+
28+
const mockSendDto: SendNotificationDto = {
29+
recipient: 'test@example.com',
30+
subject: 'Test Subject',
31+
body: 'Test Body',
32+
mediaType: NotificationChannel.EMAIL,
33+
notificationType: NotificationType.ADMISSION_ID,
34+
createdAt: new Date(),
35+
};
36+
37+
const mockStrategy = {
38+
send: jest.fn().mockResolvedValue('EMAIL'),
39+
};
40+
41+
beforeEach(async () => {
42+
const module: TestingModule = await Test.createTestingModule({
43+
controllers: [NotificationController],
44+
providers: [
45+
{
46+
provide: NotificationFactory,
47+
useValue: {
48+
createStrategy: jest.fn().mockReturnValue(mockStrategy),
49+
},
50+
},
51+
{
52+
provide: 'INotificationRepository',
53+
useValue: {
54+
save: jest.fn().mockResolvedValue(mockNotification),
55+
findAll: jest.fn().mockResolvedValue([mockNotification]),
56+
count: jest.fn().mockResolvedValue(1),
57+
},
58+
},
59+
{
60+
provide: LoggerServiceFile,
61+
useValue: {
62+
log: jest.fn(),
63+
error: jest.fn(),
64+
},
65+
},
66+
{
67+
provide: LoggerServiceDb,
68+
useValue: {
69+
log: jest.fn(),
70+
error: jest.fn().mockResolvedValue(undefined),
71+
},
72+
},
73+
],
74+
}).compile();
75+
76+
controller = module.get<NotificationController>(NotificationController);
77+
factory = module.get<NotificationFactory>(NotificationFactory);
78+
repository = module.get<INotificationRepository>('INotificationRepository');
79+
80+
// Use spies to avoid unbound method errors
81+
jest.spyOn(factory, 'createStrategy');
82+
jest.spyOn(repository, 'save');
83+
jest.spyOn(mockStrategy, 'send');
84+
});
85+
86+
describe('send', () => {
87+
it('should send notification and log successfully', async () => {
88+
await controller.send(mockSendDto);
89+
90+
// eslint-disable-next-line @typescript-eslint/unbound-method
91+
expect(factory.createStrategy).toHaveBeenCalledWith(
92+
mockSendDto.mediaType,
93+
);
94+
// eslint-disable-next-line @typescript-eslint/unbound-method
95+
expect(repository.save).toHaveBeenCalledWith(expect.any(Notification));
96+
expect(mockStrategy.send).toHaveBeenCalledWith(expect.any(Notification));
97+
});
98+
99+
it('should throw error if strategy send fails', async () => {
100+
jest.spyOn(factory, 'createStrategy').mockReturnValue({
101+
send: jest.fn().mockRejectedValue(new Error('Send failed')),
102+
});
103+
104+
await expect(controller.send(mockSendDto)).rejects.toThrow('Send failed');
105+
});
106+
});
107+
108+
describe('getNotificationHistory', () => {
109+
it('should return notification history with default pagination', async () => {
110+
jest.spyOn(repository, 'findAll');
111+
const result = await controller.getNotificationHistory(1, 10);
112+
113+
// eslint-disable-next-line @typescript-eslint/unbound-method
114+
expect(repository.findAll).toHaveBeenCalledWith(0, 10);
115+
expect(result).toEqual({
116+
data: [mockNotification],
117+
total: 1,
118+
page: 1,
119+
totalPages: 1,
120+
});
121+
});
122+
123+
it('should handle custom pagination', async () => {
124+
jest
125+
.spyOn(repository, 'findAll')
126+
.mockResolvedValue([mockNotification, mockNotification]);
127+
const result = await controller.getNotificationHistory(2, 5);
128+
129+
// eslint-disable-next-line @typescript-eslint/unbound-method
130+
expect(repository.findAll).toHaveBeenCalledWith(5, 5);
131+
expect(result).toEqual({
132+
data: [mockNotification, mockNotification],
133+
total: 2,
134+
page: 2,
135+
totalPages: 1,
136+
});
137+
});
138+
});
139+
});

0 commit comments

Comments
 (0)