Skip to content

Commit 5788a7c

Browse files
committed
feat(tests): add comprehensive unit tests for encryption module and its functionalities
1 parent 897f048 commit 5788a7c

File tree

2 files changed

+784
-0
lines changed

2 files changed

+784
-0
lines changed
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2+
import { displayStartupBanner } from '../../../src/utils/banner';
3+
4+
// Helper function to strip ANSI color codes from strings
5+
const stripAnsiCodes = (str: string): string => {
6+
return str.replace(/\x1b\[[0-9;]*m/g, '');
7+
};
8+
9+
describe('banner.ts', () => {
10+
let consoleLogSpy: ReturnType<typeof vi.spyOn>;
11+
let originalEnv: NodeJS.ProcessEnv;
12+
13+
beforeEach(() => {
14+
// Spy on console.log to capture output
15+
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
16+
17+
// Store original environment variables
18+
originalEnv = { ...process.env };
19+
20+
// Clear console log spy calls from previous tests
21+
consoleLogSpy.mockClear();
22+
});
23+
24+
afterEach(() => {
25+
// Restore console.log
26+
consoleLogSpy.mockRestore();
27+
28+
// Restore original environment variables
29+
process.env = originalEnv;
30+
});
31+
32+
describe('displayStartupBanner', () => {
33+
it('should call console.log with banner content', () => {
34+
const testPort = 3000;
35+
36+
displayStartupBanner(testPort);
37+
38+
expect(consoleLogSpy).toHaveBeenCalledTimes(1);
39+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
40+
expect(typeof bannerOutput).toBe('string');
41+
expect(bannerOutput.length).toBeGreaterThan(0);
42+
});
43+
44+
it('should include the port number in the banner', () => {
45+
const testPort = 4000;
46+
47+
displayStartupBanner(testPort);
48+
49+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
50+
expect(bannerOutput).toContain('4000');
51+
expect(bannerOutput).toContain('Running on port');
52+
});
53+
54+
it('should include DEPLOYSTACK ASCII art', () => {
55+
const testPort = 3000;
56+
57+
displayStartupBanner(testPort);
58+
59+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
60+
// Check for parts of the ASCII art
61+
expect(bannerOutput).toContain('██████╗ ███████╗██████╗ ██╗ ██████╗ ██╗ ██╗███████╗████████╗ █████╗ ██████╗██╗ ██╗');
62+
expect(bannerOutput).toContain('DeployStack CI/CD Backend');
63+
});
64+
65+
it('should include ANSI color codes', () => {
66+
const testPort = 3000;
67+
68+
displayStartupBanner(testPort);
69+
70+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
71+
// Check for ANSI color codes
72+
expect(bannerOutput).toContain('\x1b[38;5;51m'); // Cyan color
73+
expect(bannerOutput).toContain('\x1b[38;5;93m'); // Purple color
74+
expect(bannerOutput).toContain('\x1b[38;5;82m'); // Green color
75+
expect(bannerOutput).toContain('\x1b[38;5;196m'); // Red color
76+
expect(bannerOutput).toContain('\x1b[0m'); // Reset color
77+
});
78+
79+
it('should use DEPLOYSTACK_BACKEND_VERSION when available', () => {
80+
process.env.DEPLOYSTACK_BACKEND_VERSION = '1.2.3';
81+
const testPort = 3000;
82+
83+
displayStartupBanner(testPort);
84+
85+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
86+
expect(bannerOutput).toContain('v1.2.3');
87+
expect(bannerOutput).toContain('DeployStack CI/CD Backend');
88+
});
89+
90+
it('should fallback to npm_package_version when DEPLOYSTACK_BACKEND_VERSION is not set', () => {
91+
delete process.env.DEPLOYSTACK_BACKEND_VERSION;
92+
process.env.npm_package_version = '2.1.0';
93+
const testPort = 3000;
94+
95+
displayStartupBanner(testPort);
96+
97+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
98+
expect(bannerOutput).toContain('v2.1.0');
99+
});
100+
101+
it('should use default version when no version environment variables are set', () => {
102+
delete process.env.DEPLOYSTACK_BACKEND_VERSION;
103+
delete process.env.npm_package_version;
104+
const testPort = 3000;
105+
106+
displayStartupBanner(testPort);
107+
108+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
109+
expect(bannerOutput).toContain('v0.1.0');
110+
});
111+
112+
it('should display current NODE_ENV', () => {
113+
const originalNodeEnv = process.env.NODE_ENV;
114+
process.env.NODE_ENV = 'production';
115+
const testPort = 3000;
116+
117+
displayStartupBanner(testPort);
118+
119+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
120+
const cleanOutput = stripAnsiCodes(bannerOutput);
121+
expect(cleanOutput).toContain('Environment: production');
122+
123+
// Restore original NODE_ENV
124+
process.env.NODE_ENV = originalNodeEnv;
125+
});
126+
127+
it('should display development as default environment when NODE_ENV is not set', () => {
128+
const originalNodeEnv = process.env.NODE_ENV;
129+
delete process.env.NODE_ENV;
130+
const testPort = 3000;
131+
132+
displayStartupBanner(testPort);
133+
134+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
135+
const cleanOutput = stripAnsiCodes(bannerOutput);
136+
expect(cleanOutput).toContain('Environment: development');
137+
138+
// Restore original NODE_ENV
139+
if (originalNodeEnv !== undefined) {
140+
process.env.NODE_ENV = originalNodeEnv;
141+
}
142+
});
143+
144+
it('should handle different port numbers correctly', () => {
145+
const testCases = [80, 443, 3000, 8080, 65535];
146+
147+
testCases.forEach((port) => {
148+
consoleLogSpy.mockClear();
149+
displayStartupBanner(port);
150+
151+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
152+
const cleanOutput = stripAnsiCodes(bannerOutput);
153+
expect(cleanOutput).toContain(`Running on port ${port}`);
154+
});
155+
});
156+
157+
it('should include all required banner sections', () => {
158+
const testPort = 3000;
159+
160+
displayStartupBanner(testPort);
161+
162+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
163+
164+
// Check for banner structure elements
165+
expect(bannerOutput).toContain('╔═══'); // Top border
166+
expect(bannerOutput).toContain('╚═══'); // Bottom border
167+
expect(bannerOutput).toContain('║'); // Side borders
168+
expect(bannerOutput).toContain('DeployStack CI/CD Backend');
169+
expect(bannerOutput).toContain('Running on port');
170+
expect(bannerOutput).toContain('Environment:');
171+
});
172+
173+
it('should handle edge case with port 0', () => {
174+
const testPort = 0;
175+
176+
displayStartupBanner(testPort);
177+
178+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
179+
const cleanOutput = stripAnsiCodes(bannerOutput);
180+
expect(cleanOutput).toContain('Running on port 0');
181+
});
182+
183+
it('should handle very large port numbers', () => {
184+
const testPort = 65535;
185+
186+
displayStartupBanner(testPort);
187+
188+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
189+
const cleanOutput = stripAnsiCodes(bannerOutput);
190+
expect(cleanOutput).toContain('Running on port 65535');
191+
});
192+
193+
it('should maintain consistent banner format across different environments', () => {
194+
const environments = ['development', 'production', 'test', 'staging'];
195+
const testPort = 3000;
196+
const originalNodeEnv = process.env.NODE_ENV;
197+
198+
environments.forEach((env) => {
199+
consoleLogSpy.mockClear();
200+
process.env.NODE_ENV = env;
201+
202+
displayStartupBanner(testPort);
203+
204+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
205+
const cleanOutput = stripAnsiCodes(bannerOutput);
206+
expect(cleanOutput).toContain(`Environment: ${env}`);
207+
expect(bannerOutput).toContain('╔═══'); // Ensure banner structure is consistent
208+
expect(bannerOutput).toContain('╚═══');
209+
});
210+
211+
// Restore original NODE_ENV
212+
if (originalNodeEnv !== undefined) {
213+
process.env.NODE_ENV = originalNodeEnv;
214+
}
215+
});
216+
217+
it('should handle empty string environment variables gracefully', () => {
218+
const originalNodeEnv = process.env.NODE_ENV;
219+
const originalBackendVersion = process.env.DEPLOYSTACK_BACKEND_VERSION;
220+
const originalNpmVersion = process.env.npm_package_version;
221+
222+
process.env.DEPLOYSTACK_BACKEND_VERSION = '';
223+
process.env.npm_package_version = '';
224+
process.env.NODE_ENV = '';
225+
const testPort = 3000;
226+
227+
displayStartupBanner(testPort);
228+
229+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
230+
const cleanOutput = stripAnsiCodes(bannerOutput);
231+
expect(cleanOutput).toContain('v0.1.0'); // Should fallback to default
232+
expect(cleanOutput).toContain('Environment: development'); // Should fallback to default
233+
234+
// Restore original environment variables
235+
if (originalNodeEnv !== undefined) {
236+
process.env.NODE_ENV = originalNodeEnv;
237+
}
238+
if (originalBackendVersion !== undefined) {
239+
process.env.DEPLOYSTACK_BACKEND_VERSION = originalBackendVersion;
240+
}
241+
if (originalNpmVersion !== undefined) {
242+
process.env.npm_package_version = originalNpmVersion;
243+
}
244+
});
245+
246+
it('should prioritize DEPLOYSTACK_BACKEND_VERSION over npm_package_version', () => {
247+
process.env.DEPLOYSTACK_BACKEND_VERSION = '5.0.0';
248+
process.env.npm_package_version = '4.0.0';
249+
const testPort = 3000;
250+
251+
displayStartupBanner(testPort);
252+
253+
const bannerOutput = consoleLogSpy.mock.calls[0][0] as string;
254+
expect(bannerOutput).toContain('v5.0.0');
255+
expect(bannerOutput).not.toContain('v4.0.0');
256+
});
257+
});
258+
});

0 commit comments

Comments
 (0)