Skip to content

Commit 1962f57

Browse files
committed
fix(testing): fixing the tests and proper async handling
1 parent b64a23a commit 1962f57

File tree

6 files changed

+11388
-8075
lines changed

6 files changed

+11388
-8075
lines changed

server/src/audit/audit.service.spec.ts

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ describe('AuditService', () => {
1515
process.env.KUBERO_AUDIT = 'true';
1616
process.env.KUBERO_AUDIT_LIMIT = '10';
1717
AuditService.prototype.init = jest.fn();
18-
service = new AuditService(mockPrisma);
18+
service = new AuditService();
1919
service['enabled'] = true;
20+
service['prisma'] = mockPrisma;
2021
});
2122

2223
afterEach(() => {
@@ -29,7 +30,7 @@ describe('AuditService', () => {
2930

3031
it('should not enable audit if KUBERO_AUDIT is not true', () => {
3132
process.env.KUBERO_AUDIT = 'false';
32-
const s = new AuditService(mockPrisma);
33+
const s = new AuditService();
3334
expect(s.getAuditEnabled()).toBe(false);
3435
});
3536
/*
@@ -52,10 +53,10 @@ describe('AuditService', () => {
5253
});
5354
*/
5455

55-
it('init should do nothing if not enabled', async () => {
56+
it('init should do nothing if not enabled', () => {
5657
const logSpy = jest.spyOn(service, 'log');
5758
service['enabled'] = false;
58-
await service.init();
59+
service.init();
5960
expect(logSpy).not.toHaveBeenCalled();
6061
});
6162

@@ -75,12 +76,14 @@ describe('AuditService', () => {
7576
value: {},
7677
writable: true,
7778
});
78-
mockPrisma.audit.create = jest.fn().mockResolvedValue({});
79+
// create a local spy and assign it to the mock to avoid referencing an unbound method
80+
const createSpy = jest.fn().mockResolvedValue({});
81+
mockPrisma.audit.create = createSpy;
7982
mockPrisma.audit.count = jest.fn().mockResolvedValue(0);
8083
mockPrisma.audit.findMany = jest.fn().mockResolvedValue([]);
8184
mockPrisma.audit.deleteMany = jest.fn().mockResolvedValue({});
8285
await service.log(entry);
83-
expect(mockPrisma.audit.create).toHaveBeenCalledWith({
86+
expect(createSpy).toHaveBeenCalledWith({
8487
data: expect.objectContaining({
8588
user: 'test',
8689
severity: 'normal',
@@ -121,15 +124,23 @@ describe('AuditService', () => {
121124
});
122125

123126
it('should reset audit log', async () => {
124-
mockPrisma.audit.deleteMany = jest.fn().mockResolvedValue({});
127+
// ensure audit object exists and assign a local spy to avoid referencing an unbound method
128+
Object.defineProperty(mockPrisma, 'audit', {
129+
value: {},
130+
writable: true,
131+
});
132+
const deleteSpy = jest.fn().mockResolvedValue({});
133+
mockPrisma.audit.deleteMany = deleteSpy;
125134
const logSpy = jest.spyOn(service['logger'], 'log');
126135
await service.reset();
127-
expect(mockPrisma.audit.deleteMany).toHaveBeenCalled();
136+
expect(deleteSpy).toHaveBeenCalled();
128137
expect(logSpy).toHaveBeenCalledWith('Audit log reset.');
129138
});
130139

131140
it('should return 0 for count if not enabled', async () => {
132141
service['enabled'] = false;
142+
mockPrisma.audit.count = jest.fn().mockResolvedValue(0);
143+
133144
const count = await service.count();
134145
expect(count).toBe(0);
135146
});
@@ -144,7 +155,10 @@ describe('AuditService', () => {
144155

145156
it('should not log if not enabled', async () => {
146157
service['enabled'] = false;
147-
const createSpy = jest.spyOn(mockPrisma.audit, 'create');
158+
159+
const createSpy = jest.fn().mockResolvedValue({});
160+
mockPrisma.audit.create = createSpy;
161+
148162
await service.log({
149163
user: 'test',
150164
severity: 'normal',
@@ -173,10 +187,12 @@ describe('AuditService', () => {
173187
message: 'foo',
174188
},
175189
];
176-
mockPrisma.audit.findMany = jest.fn().mockResolvedValue(rows);
190+
// create local spy and assign to mock to avoid referencing an unbound method
191+
const findManySpy = jest.fn().mockResolvedValue(rows);
192+
mockPrisma.audit.findMany = findManySpy;
177193

178194
const result = await service.getFiltered(10, 'foo');
179-
expect(mockPrisma.audit.findMany).toHaveBeenCalledWith({
195+
expect(findManySpy).toHaveBeenCalledWith({
180196
where: { message: { contains: 'foo' } },
181197
orderBy: { timestamp: 'desc' },
182198
take: 10,
@@ -209,10 +225,14 @@ describe('AuditService', () => {
209225
message: 'foo',
210226
},
211227
];
212-
mockPrisma.audit.findMany = jest.fn().mockResolvedValue(rows);
228+
// create local spy and assign to mock to avoid referencing an unbound method
229+
const findManySpy2 = jest.fn().mockResolvedValue(rows);
230+
231+
mockPrisma.audit.findMany = findManySpy2;
232+
mockPrisma.audit.count = jest.fn().mockResolvedValue(rows.length);
213233

214234
const result = await service.getAppEntries('pipe', 'dev', 'app', 5);
215-
expect(mockPrisma.audit.findMany).toHaveBeenCalledWith({
235+
expect(findManySpy2).toHaveBeenCalledWith({
216236
where: { pipeline: 'pipe', phase: 'dev', app: 'app' },
217237
orderBy: { timestamp: 'desc' },
218238
take: 5,

server/src/audit/audit.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class AuditService {
88
private logmaxbackups: number = 1000;
99
private enabled: boolean = true;
1010
private readonly logger = new Logger(AuditService.name);
11-
private readonly prisma = new PrismaClient();
11+
private prisma = new PrismaClient();
1212

1313
constructor() {
1414
this.logmaxbackups = process.env.KUBERO_AUDIT_LIMIT

server/src/config/config.service.spec.ts

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ describe('ConfigService', () => {
173173
expect(result.host).toBe('registry');
174174
});
175175

176-
it('should get banner', async () => {
177-
const result = await service.getBanner();
176+
it('should get banner', () => {
177+
const result = service.getBanner();
178178
expect(result).toHaveProperty('show');
179179
});
180180

@@ -199,9 +199,9 @@ describe('ConfigService', () => {
199199
expect(result.status).toBe('error');
200200
});
201201

202-
it('should update running config if setup enabled', () => {
202+
it('should update running config if setup enabled', async () => {
203203
process.env.KUBERO_SETUP = 'enabled';
204-
const result = service.updateRunningConfig(
204+
const result = await service.updateRunningConfig(
205205
'kube',
206206
'ctx',
207207
'ns',
@@ -213,9 +213,9 @@ describe('ConfigService', () => {
213213
expect(kubectl.createNamespace).toHaveBeenCalled();
214214
});
215215

216-
it('should return error if setup is disabled in updateRunningConfig', () => {
216+
it('should return error if setup is disabled in updateRunningConfig', async () => {
217217
process.env.KUBERO_SETUP = 'disabled';
218-
const result = service.updateRunningConfig(
218+
const result = await service.updateRunningConfig(
219219
'kube',
220220
'ctx',
221221
'ns',
@@ -298,8 +298,8 @@ describe('ConfigService', () => {
298298
});
299299
*/
300300

301-
it('should get cluster issuer', async () => {
302-
const result = await service.getClusterIssuer();
301+
it('should get cluster issuer', () => {
302+
const result = service.getClusterIssuer();
303303
expect(result.clusterissuer).toBe('letsencrypt-prod');
304304
});
305305

@@ -439,7 +439,9 @@ describe('ConfigService', () => {
439439
});
440440

441441
it('should handle database errors', async () => {
442-
mockPrismaClient.runpack.findMany.mockRejectedValue(new Error('Database error'));
442+
mockPrismaClient.runpack.findMany.mockRejectedValue(
443+
new Error('Database error'),
444+
);
443445

444446
await expect(service.getRunpacks()).rejects.toThrow('Database error');
445447
});
@@ -490,7 +492,9 @@ describe('ConfigService', () => {
490492
});
491493

492494
it('should handle database errors', async () => {
493-
mockPrismaClient.podSize.findMany.mockRejectedValue(new Error('Database error'));
495+
mockPrismaClient.podSize.findMany.mockRejectedValue(
496+
new Error('Database error'),
497+
);
494498

495499
await expect(service.getPodSizes()).rejects.toThrow('Database error');
496500
});
@@ -622,7 +626,7 @@ describe('ConfigService', () => {
622626
expect(result.description).toBe('Large pod size');
623627
expect(result.resources.requests?.memory).toBe('512Mi');
624628
expect(result.resources.limits?.memory).toBe('1Gi');
625-
629+
626630
expect(mockPrismaClient.podSize.create).toHaveBeenCalledWith({
627631
data: {
628632
name: 'large',
@@ -676,9 +680,13 @@ describe('ConfigService', () => {
676680
resources: {},
677681
});
678682

679-
mockPrismaClient.podSize.create.mockRejectedValue(new Error('Database error'));
683+
mockPrismaClient.podSize.create.mockRejectedValue(
684+
new Error('Database error'),
685+
);
680686

681-
await expect(service.addPodSize(mockPodSize)).rejects.toThrow('Database error');
687+
await expect(service.addPodSize(mockPodSize)).rejects.toThrow(
688+
'Database error',
689+
);
682690
});
683691
});
684692

@@ -719,7 +727,7 @@ describe('ConfigService', () => {
719727
expect(result.description).toBe('Updated large pod size');
720728
expect(result.resources.requests?.memory).toBe('1Gi');
721729
expect(result.resources.limits?.memory).toBe('2Gi');
722-
730+
723731
expect(mockPrismaClient.podSize.update).toHaveBeenCalledWith({
724732
where: { id: podSizeId },
725733
data: {
@@ -740,9 +748,13 @@ describe('ConfigService', () => {
740748
resources: {},
741749
});
742750

743-
mockPrismaClient.podSize.update.mockRejectedValue(new Error('Database error'));
751+
mockPrismaClient.podSize.update.mockRejectedValue(
752+
new Error('Database error'),
753+
);
744754

745-
await expect(service.updatePodSize('test-id', mockPodSize)).rejects.toThrow('Database error');
755+
await expect(
756+
service.updatePodSize('test-id', mockPodSize),
757+
).rejects.toThrow('Database error');
746758
});
747759
});
748760

@@ -774,7 +786,7 @@ describe('ConfigService', () => {
774786
mockPrismaClient.podSize.findUnique.mockResolvedValue(null);
775787

776788
await expect(service.deletePodSize(podSizeId)).rejects.toThrow(
777-
`PodSize with id ${podSizeId} not found`
789+
`PodSize with id ${podSizeId} not found`,
778790
);
779791

780792
expect(mockPrismaClient.podSize.delete).not.toHaveBeenCalled();
@@ -785,9 +797,13 @@ describe('ConfigService', () => {
785797
const mockPodSize = { id: podSizeId, name: 'test' };
786798

787799
mockPrismaClient.podSize.findUnique.mockResolvedValue(mockPodSize);
788-
mockPrismaClient.podSize.delete.mockRejectedValue(new Error('Database error'));
800+
mockPrismaClient.podSize.delete.mockRejectedValue(
801+
new Error('Database error'),
802+
);
789803

790-
await expect(service.deletePodSize(podSizeId)).rejects.toThrow('Database error');
804+
await expect(service.deletePodSize(podSizeId)).rejects.toThrow(
805+
'Database error',
806+
);
791807
});
792808
});
793809

@@ -819,7 +835,7 @@ describe('ConfigService', () => {
819835
runpackId,
820836
runpackName: 'nodejs-to-delete',
821837
},
822-
})
838+
}),
823839
);
824840
});
825841

@@ -829,7 +845,7 @@ describe('ConfigService', () => {
829845
mockPrismaClient.runpack.findUnique.mockResolvedValue(null);
830846

831847
await expect(service.deleteRunpack(runpackId)).rejects.toThrow(
832-
`Runpack with id ${runpackId} not found`
848+
`Runpack with id ${runpackId} not found`,
833849
);
834850

835851
expect(mockPrismaClient.runpack.delete).not.toHaveBeenCalled();
@@ -841,9 +857,13 @@ describe('ConfigService', () => {
841857
const mockRunpack = { id: runpackId, name: 'test-runpack' };
842858

843859
mockPrismaClient.runpack.findUnique.mockResolvedValue(mockRunpack);
844-
mockPrismaClient.runpack.delete.mockRejectedValue(new Error('Database error'));
860+
mockPrismaClient.runpack.delete.mockRejectedValue(
861+
new Error('Database error'),
862+
);
845863

846-
await expect(service.deleteRunpack(runpackId)).rejects.toThrow('Database error');
864+
await expect(service.deleteRunpack(runpackId)).rejects.toThrow(
865+
'Database error',
866+
);
847867
});
848868
});
849869
});

server/src/kubernetes/kubernetes.service.spec.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,21 +217,21 @@ describe('KubernetesService', () => {
217217
items: [
218218
{
219219
metadata: { name: 'pod1' },
220-
status: { startTime: new Date(Date.now() - 60000) } // 1 minute ago
220+
status: { startTime: new Date(Date.now() - 60000) }, // 1 minute ago
221221
},
222222
{
223223
metadata: { name: 'pod2' },
224-
status: { startTime: new Date(Date.now() - 3600000) } // 1 hour ago
224+
status: { startTime: new Date(Date.now() - 3600000) }, // 1 hour ago
225225
},
226226
{
227227
metadata: { name: 'pod3' },
228-
status: {} // no startTime
228+
status: {}, // no startTime
229229
},
230230
{
231-
metadata: {} // no name
232-
}
233-
]
234-
}
231+
metadata: {}, // no name
232+
},
233+
],
234+
},
235235
};
236236

237237
// Access the mocked coreV1Api through the service
@@ -240,7 +240,9 @@ describe('KubernetesService', () => {
240240

241241
const result = await service.getPodUptimes('test-namespace');
242242

243-
expect(coreV1ApiMock.listNamespacedPod).toHaveBeenCalledWith('test-namespace');
243+
expect(coreV1ApiMock.listNamespacedPod).toHaveBeenCalledWith(
244+
'test-namespace',
245+
);
244246
expect(result).toBeDefined();
245247
expect(result['pod1']).toBeDefined();
246248
expect(result['pod1'].ms).toBeGreaterThan(50000); // roughly 1 minute in ms
@@ -264,7 +266,7 @@ describe('KubernetesService', () => {
264266

265267
it('should return -1 when startTime is not provided', () => {
266268
const pod = {
267-
status: {}
269+
status: {},
268270
};
269271

270272
const uptime = (service as any).getPodUptimeMS(pod);

0 commit comments

Comments
 (0)