Skip to content

Commit 89da96c

Browse files
committed
feat: Add unit tests for various command classes to improve test coverage
1 parent a2dab49 commit 89da96c

File tree

7 files changed

+956
-0
lines changed

7 files changed

+956
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* eslint-disable no-undefined */
2+
import { Command } from 'commander';
3+
4+
import { container } from '../../core/system/container';
5+
import { SERVICE_KEYS } from '../../types/core';
6+
import { ILogger } from '../../types/observability';
7+
import { CommandName, IReferenceAuditUseCase } from '../../types';
8+
9+
import { RefAuditCommand } from './ref-audit.command';
10+
11+
jest.mock('../../core/system/container');
12+
jest.mock('commander');
13+
14+
describe('RefAuditCommand', () => {
15+
let mockLogger: jest.Mocked<ILogger>;
16+
let mockService: jest.Mocked<IReferenceAuditUseCase>;
17+
let mockParentCommand: jest.Mocked<Command>;
18+
19+
beforeEach(() => {
20+
mockLogger = {
21+
info: jest.fn(),
22+
} as unknown as jest.Mocked<ILogger>;
23+
24+
mockService = {
25+
execute: jest.fn().mockResolvedValue(undefined),
26+
} as jest.Mocked<IReferenceAuditUseCase>;
27+
28+
mockParentCommand = {
29+
command: jest.fn().mockReturnThis(),
30+
description: jest.fn().mockReturnThis(),
31+
action: jest.fn().mockReturnThis(),
32+
} as unknown as jest.Mocked<Command>;
33+
34+
(container.resolve as jest.Mock).mockReturnValue(mockService);
35+
});
36+
37+
afterEach(() => {
38+
jest.clearAllMocks();
39+
});
40+
41+
it('should have correct name and description', () => {
42+
const cmd = new RefAuditCommand(mockLogger);
43+
expect(cmd.name).toBe(CommandName.AUDIT);
44+
expect(cmd.description).toBe('Audit references across repo & tasks');
45+
});
46+
47+
it('should execute the command successfully', async () => {
48+
const cmd = new RefAuditCommand(mockLogger);
49+
await cmd.execute();
50+
51+
expect(mockLogger.info).toHaveBeenCalledWith('Executing ref audit command');
52+
expect(container.resolve).toHaveBeenCalledWith(SERVICE_KEYS.REFERENCE_AUDIT);
53+
expect(mockService.execute).toHaveBeenCalled();
54+
expect(mockLogger.info).toHaveBeenCalledWith('Ref audit command executed');
55+
});
56+
57+
it('should configure the command on parent', () => {
58+
RefAuditCommand.configure(mockParentCommand, mockLogger);
59+
60+
expect(mockParentCommand.command).toHaveBeenCalledWith(CommandName.AUDIT);
61+
expect(mockParentCommand.description).toHaveBeenCalledWith(
62+
'Audit references across repo & tasks',
63+
);
64+
expect(mockParentCommand.action).toHaveBeenCalledWith(expect.any(Function));
65+
});
66+
67+
it('should handle service execution error', async () => {
68+
const error = new Error('Service error');
69+
mockService.execute.mockRejectedValue(error);
70+
71+
const cmd = new RefAuditCommand(mockLogger);
72+
73+
await expect(cmd.execute()).rejects.toThrow('Service error');
74+
expect(mockLogger.info).toHaveBeenCalledWith('Executing ref audit command');
75+
expect(mockLogger.info).not.toHaveBeenCalledWith('Ref audit command executed');
76+
});
77+
});
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/* eslint-disable no-undefined */
2+
import { Command } from 'commander';
3+
4+
import { container } from '../../core/system/container';
5+
import { SERVICE_KEYS } from '../../types/core';
6+
import { ILogger } from '../../types/observability';
7+
import { CommandName, IUIdSupersedeUseCase } from '../../types';
8+
9+
import { SupersedeCommand } from './supersede.command';
10+
11+
jest.mock('../../core/system/container');
12+
jest.mock('commander');
13+
14+
describe('SupersedeCommand', () => {
15+
let mockLogger: jest.Mocked<ILogger>;
16+
let mockService: jest.Mocked<IUIdSupersedeUseCase>;
17+
let command: SupersedeCommand;
18+
19+
beforeEach(() => {
20+
mockLogger = {
21+
info: jest.fn(),
22+
error: jest.fn(),
23+
warn: jest.fn(),
24+
debug: jest.fn(),
25+
} as unknown as jest.Mocked<ILogger>;
26+
27+
mockService = {
28+
execute: jest.fn().mockResolvedValue(undefined),
29+
} as jest.Mocked<IUIdSupersedeUseCase>;
30+
31+
(container.resolve as jest.Mock).mockReturnValue(mockService);
32+
33+
command = new SupersedeCommand(mockLogger);
34+
});
35+
36+
afterEach(() => {
37+
jest.clearAllMocks();
38+
});
39+
40+
describe('execute', () => {
41+
it('should execute supersede and log correctly', async () => {
42+
const oldUid = 'OLD123';
43+
const newUid = 'NEW456';
44+
45+
await command.execute({ oldUid, newUid });
46+
47+
expect(mockLogger.info).toHaveBeenCalledWith('Executing supersede command', {
48+
newUid,
49+
oldUid,
50+
});
51+
expect(container.resolve).toHaveBeenCalledWith(SERVICE_KEYS.UID_SUPERSEDE);
52+
expect(mockService.execute).toHaveBeenCalledWith(oldUid, newUid);
53+
expect(mockLogger.info).toHaveBeenCalledWith(
54+
`Supersede command executed: ${oldUid} -> ${newUid}`,
55+
{ newUid, oldUid },
56+
);
57+
});
58+
59+
it('should handle service execution error', async () => {
60+
const error = new Error('Service error');
61+
mockService.execute.mockRejectedValue(error);
62+
63+
await expect(command.execute({ oldUid: 'OLD123', newUid: 'NEW456' })).rejects.toThrow(
64+
'Service error',
65+
);
66+
67+
expect(mockLogger.info).toHaveBeenCalledWith('Executing supersede command', {
68+
newUid: 'NEW456',
69+
oldUid: 'OLD123',
70+
});
71+
expect(mockService.execute).toHaveBeenCalledWith('OLD123', 'NEW456');
72+
// Note: In real scenario, error logging might be handled by BaseCommand or elsewhere
73+
});
74+
});
75+
76+
describe('configure', () => {
77+
it('should configure the command correctly', () => {
78+
const mockParent = new Command();
79+
const mockCommand = {
80+
command: jest.fn().mockReturnThis(),
81+
argument: jest.fn().mockReturnThis(),
82+
description: jest.fn().mockReturnThis(),
83+
action: jest.fn().mockReturnThis(),
84+
};
85+
mockParent.command = jest.fn().mockReturnValue(mockCommand);
86+
87+
SupersedeCommand.configure(mockParent, mockLogger);
88+
89+
expect(mockParent.command).toHaveBeenCalledWith(CommandName.SUPERSEDE);
90+
expect(mockCommand.argument).toHaveBeenCalledWith('<oldUid>', 'Old UID');
91+
expect(mockCommand.argument).toHaveBeenCalledWith('<newUid>', 'New UID');
92+
expect(mockCommand.description).toHaveBeenCalledWith('Supersede an old UID with a new one');
93+
expect(mockCommand.action).toHaveBeenCalledWith(expect.any(Function));
94+
});
95+
});
96+
97+
describe('properties', () => {
98+
it('should have correct name and description', () => {
99+
expect(command.name).toBe(CommandName.SUPERSEDE);
100+
expect(command.description).toBe('Supersede an old UID with a new one');
101+
});
102+
});
103+
});

0 commit comments

Comments
 (0)