Skip to content

Commit 6030bd4

Browse files
committed
chore: test coverage
1 parent 4ee79be commit 6030bd4

2 files changed

Lines changed: 257 additions & 2 deletions

File tree

src/services/printScanResult.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function printScanResult(
4343
let exitWithError = false;
4444

4545
// Determine if output should be in JSON format
46-
const isJson = opts.json ?? false;
46+
const isJson = opts.json;
4747

4848
printHeader(comparedAgainst);
4949

test/unit/services/printScanResult.test.ts

Lines changed: 256 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ vi.mock('../../../src/ui/scan/printMissing.js', () => ({
1616
printMissing: vi.fn(),
1717
}));
1818

19+
vi.mock('../../../src/ui/scan/printUnused.js', () => ({
20+
printUnused: vi.fn(),
21+
}));
22+
1923
vi.mock('../../../src/ui/shared/printDuplicates.js', () => ({
2024
printDuplicates: vi.fn(),
2125
}));
@@ -60,6 +64,10 @@ vi.mock('../../../src/ui/scan/printExpireWarnings.js', () => ({
6064
printExpireWarnings: vi.fn(),
6165
}));
6266

67+
vi.mock('../../../src/ui/scan/printInconsistentNamingWarning.js', () => ({
68+
printInconsistentNamingWarning: vi.fn(),
69+
}));
70+
6371
vi.mock('../../../src/core/scan/computeHealthScore.js', () => ({
6472
computeHealthScore: vi.fn(() => 100),
6573
}));
@@ -72,13 +80,25 @@ vi.mock('../../../src/ui/shared/printGitignore.js', () => ({
7280
printGitignoreWarning: vi.fn(),
7381
}));
7482

75-
vi.mock('../../../src/git.js', () => ({
83+
vi.mock('../../../src/services/git.js', () => ({
7684
checkGitignoreStatus: vi.fn(() => null),
7785
}));
7886

7987
import { printScanResult } from '../../../src/services/printScanResult.js';
8088
import { printMissing } from '../../../src/ui/scan/printMissing.js';
8189
import { printAutoFix } from '../../../src/ui/shared/printAutoFix.js';
90+
import { checkGitignoreStatus } from '../../../src/services/git.js';
91+
import { printGitignoreWarning } from '../../../src/ui/shared/printGitignore.js';
92+
import { printStats } from '../../../src/ui/scan/printStats.js';
93+
import { printDuplicates } from '../../../src/ui/shared/printDuplicates.js';
94+
import { printUnused } from '../../../src/ui/scan/printUnused.js';
95+
import { printFrameworkWarnings } from '../../../src/ui/scan/printFrameworkWarnings.js';
96+
import { printUppercaseWarning } from '../../../src/ui/scan/printUppercaseWarning.js';
97+
import { printInconsistentNamingWarning } from '../../../src/ui/scan/printInconsistentNamingWarning.js';
98+
import { printExampleWarnings } from '../../../src/ui/scan/printExampleWarnings.js';
99+
import { printSecrets } from '../../../src/ui/scan/printSecrets.js';
100+
import { printExpireWarnings } from '../../../src/ui/scan/printExpireWarnings.js';
101+
import { printConsolelogWarning } from '../../../src/ui/scan/printConsolelogWarning.js';
82102

83103
describe('printScanResult', () => {
84104
const baseScanResult: ScanResult = {
@@ -110,6 +130,7 @@ describe('printScanResult', () => {
110130
beforeEach(() => {
111131
vi.clearAllMocks();
112132
vi.mocked(printMissing).mockReturnValue(false);
133+
vi.mocked(checkGitignoreStatus).mockReturnValue(null);
113134
});
114135

115136
it('returns exitWithError true when missing variables exist', () => {
@@ -162,4 +183,238 @@ describe('printScanResult', () => {
162183

163184
expect(result.exitWithError).toBe(false);
164185
});
186+
187+
it('prints gitignore warning when env file is not ignored', () => {
188+
vi.mocked(checkGitignoreStatus).mockReturnValue({
189+
reason: 'not-ignored',
190+
} as any);
191+
192+
printScanResult(baseScanResult, baseOpts, '.env');
193+
194+
expect(printGitignoreWarning).toHaveBeenCalledWith(
195+
expect.objectContaining({ reason: 'not-ignored', strict: false }),
196+
);
197+
});
198+
199+
it('returns exitWithError true in strict mode when gitignore issue exists', () => {
200+
vi.mocked(checkGitignoreStatus).mockReturnValue({
201+
reason: 'not-ignored',
202+
} as any);
203+
204+
const result = printScanResult(
205+
baseScanResult,
206+
{ ...baseOpts, strict: true },
207+
'.env',
208+
);
209+
210+
expect(result.exitWithError).toBe(true);
211+
});
212+
213+
it('prints framework warnings when present', () => {
214+
printScanResult(
215+
{
216+
...baseScanResult,
217+
frameworkWarnings: [{ type: 'nextjs', message: 'warn' } as any],
218+
},
219+
baseOpts,
220+
'.env',
221+
);
222+
223+
expect(printFrameworkWarnings).toHaveBeenCalled();
224+
});
225+
226+
it('prints uppercase warnings when present', () => {
227+
printScanResult(
228+
{
229+
...baseScanResult,
230+
uppercaseWarnings: [{ key: 'Api_Key', expected: 'API_KEY' } as any],
231+
},
232+
baseOpts,
233+
'.env',
234+
);
235+
236+
expect(printUppercaseWarning).toHaveBeenCalled();
237+
});
238+
239+
it('prints inconsistent naming warnings when present', () => {
240+
printScanResult(
241+
{
242+
...baseScanResult,
243+
inconsistentNamingWarnings: [{ key: 'MY-KEY' } as any],
244+
},
245+
baseOpts,
246+
'.env',
247+
);
248+
249+
expect(printInconsistentNamingWarning).toHaveBeenCalled();
250+
});
251+
252+
it('prints example warnings when present', () => {
253+
printScanResult(
254+
{
255+
...baseScanResult,
256+
exampleWarnings: [{ severity: 'low' } as any],
257+
},
258+
baseOpts,
259+
'.env',
260+
);
261+
262+
expect(printExampleWarnings).toHaveBeenCalled();
263+
});
264+
265+
it('prints secrets when secrets flag is enabled', () => {
266+
printScanResult(
267+
{
268+
...baseScanResult,
269+
secrets: [{ severity: 'low' } as any],
270+
},
271+
{ ...baseOpts, secrets: true },
272+
'.env',
273+
);
274+
275+
expect(printSecrets).toHaveBeenCalled();
276+
});
277+
278+
it('prints expiration warnings when present', () => {
279+
printScanResult(
280+
{
281+
...baseScanResult,
282+
expireWarnings: [{ key: 'TOKEN', daysLeft: 5 } as any],
283+
},
284+
baseOpts,
285+
'.env',
286+
);
287+
288+
expect(printExpireWarnings).toHaveBeenCalled();
289+
});
290+
291+
it('returns exitWithError true when high severity example warning exists', () => {
292+
const result = printScanResult(
293+
{
294+
...baseScanResult,
295+
exampleWarnings: [{ severity: 'high' } as any],
296+
},
297+
baseOpts,
298+
'.env',
299+
);
300+
301+
expect(result.exitWithError).toBe(true);
302+
});
303+
304+
it('checks gitignore status with cwd and default env file', () => {
305+
printScanResult(baseScanResult, baseOpts, '.env');
306+
307+
expect(checkGitignoreStatus).toHaveBeenCalledWith({
308+
cwd: '/root',
309+
envFile: '.env',
310+
});
311+
});
312+
313+
it('does not print stats when showStats is false', () => {
314+
printScanResult(baseScanResult, { ...baseOpts, showStats: false }, '.env');
315+
316+
expect(printStats).not.toHaveBeenCalled();
317+
});
318+
319+
it('uses default env file in duplicates when comparedAgainst is empty', () => {
320+
printScanResult(
321+
{
322+
...baseScanResult,
323+
duplicates: undefined as any,
324+
},
325+
baseOpts,
326+
'',
327+
);
328+
329+
expect(printDuplicates).toHaveBeenCalledWith(
330+
'.env',
331+
'example file',
332+
[],
333+
[],
334+
false,
335+
false,
336+
undefined,
337+
);
338+
});
339+
340+
it('does not print console log warning when logged is undefined', () => {
341+
printScanResult(
342+
{
343+
...baseScanResult,
344+
logged: undefined as any,
345+
},
346+
baseOpts,
347+
'.env',
348+
);
349+
350+
expect(printConsolelogWarning).not.toHaveBeenCalled();
351+
});
352+
353+
it('keeps exitWithError false when secrets is undefined and no strict violations', () => {
354+
const result = printScanResult(
355+
{
356+
...baseScanResult,
357+
secrets: undefined as any,
358+
},
359+
baseOpts,
360+
'.env',
361+
);
362+
363+
expect(result.exitWithError).toBe(false);
364+
});
365+
366+
it('evaluates full strict violation chain and stays false when all checks are clean', () => {
367+
const result = printScanResult(
368+
baseScanResult,
369+
{ ...baseOpts, strict: true },
370+
'.env',
371+
);
372+
373+
expect(result.exitWithError).toBe(false);
374+
});
375+
376+
it('does not call printAutoFix when fix is true but no fixContext is provided', () => {
377+
printScanResult(baseScanResult, { ...baseOpts, fix: true }, '.env');
378+
379+
expect(printAutoFix).not.toHaveBeenCalled();
380+
});
381+
382+
it('does not print unused variables when showUnused is false', () => {
383+
printScanResult(
384+
{
385+
...baseScanResult,
386+
unused: ['SOME_VAR'],
387+
},
388+
{ ...baseOpts, showUnused: false },
389+
'.env',
390+
);
391+
392+
expect(printUnused).not.toHaveBeenCalled();
393+
});
394+
395+
it('does not call printAutoFix when fix is false even if fixContext exists', () => {
396+
printScanResult(baseScanResult, { ...baseOpts, fix: false }, '.env', {
397+
fixApplied: true,
398+
removedDuplicates: [],
399+
addedEnv: [],
400+
gitignoreUpdated: false,
401+
});
402+
403+
expect(printAutoFix).not.toHaveBeenCalled();
404+
});
405+
406+
it('calls printAutoFix with default env file when comparedAgainst is empty', () => {
407+
printScanResult(baseScanResult, { ...baseOpts, fix: true }, '', {
408+
fixApplied: true,
409+
removedDuplicates: [],
410+
addedEnv: [],
411+
gitignoreUpdated: false,
412+
});
413+
414+
expect(printAutoFix).toHaveBeenCalledWith(
415+
expect.objectContaining({ fixApplied: true }),
416+
'.env',
417+
false,
418+
);
419+
});
165420
});

0 commit comments

Comments
 (0)