44
55import { summaryCommand , SummaryCommandOptions } from './logs-summary' ;
66import { logger } from '../logger' ;
7- import { LogSource } from '../types' ;
8- import { createLogCommandTestHarness } from './test-helpers.test-utils' ;
7+ import { createLogCommandTests , createLogCommandTestHarness } from './test-helpers.test-utils' ;
98
109// Mock dependencies
1110jest . mock ( '../logs/log-discovery' ) ;
@@ -20,44 +19,18 @@ jest.mock('../logger', () => ({
2019 } ,
2120} ) ) ;
2221
23- describe ( 'logs-summary command' , ( ) => {
24- const harness = createLogCommandTestHarness ( ) ;
25-
26- it ( 'should discover and use most recent log source' , async ( ) => {
27- const mockSource : LogSource = {
28- type : 'preserved' ,
29- path : '/tmp/squid-logs-123' ,
30- timestamp : Date . now ( ) ,
31- dateStr : new Date ( ) . toLocaleString ( ) ,
32- } ;
33-
34- harness . mockedDiscovery . discoverLogSources . mockResolvedValue ( [ mockSource ] ) ;
35- harness . mockedDiscovery . selectMostRecent . mockReturnValue ( mockSource ) ;
36- harness . mockedAggregator . loadAndAggregate . mockResolvedValue ( {
37- totalRequests : 10 ,
38- allowedRequests : 8 ,
39- deniedRequests : 2 ,
40- uniqueDomains : 3 ,
41- byDomain : new Map ( ) ,
42- timeRange : { start : 1000 , end : 2000 } ,
43- } ) ;
44- harness . mockedFormatter . formatStats . mockReturnValue ( 'markdown summary' ) ;
22+ createLogCommandTests < SummaryCommandOptions > (
23+ 'summary' ,
24+ summaryCommand ,
25+ 'markdown' ,
26+ ( overrides ?) => ( { format : 'markdown' , ...overrides } as SummaryCommandOptions ) ,
27+ ) ;
4528
46- const options : SummaryCommandOptions = {
47- format : 'markdown' ,
48- } ;
49-
50- await summaryCommand ( options ) ;
51-
52- expect ( harness . mockedDiscovery . discoverLogSources ) . toHaveBeenCalled ( ) ;
53- expect ( harness . mockedDiscovery . selectMostRecent ) . toHaveBeenCalled ( ) ;
54- expect ( harness . mockedAggregator . loadAndAggregate ) . toHaveBeenCalledWith ( mockSource ) ;
55- expect ( harness . mockedFormatter . formatStats ) . toHaveBeenCalled ( ) ;
56- expect ( harness . mockConsoleLog ) . toHaveBeenCalledWith ( 'markdown summary' ) ;
57- } ) ;
29+ describe ( 'logs-summary command - logging behavior' , ( ) => {
30+ const harness = createLogCommandTestHarness ( ) ;
5831
5932 it ( 'should default to markdown format' , async ( ) => {
60- const mockSource : LogSource = { type : 'running' , containerName : 'awf-squid' } ;
33+ const mockSource = { type : 'running' as const , containerName : 'awf-squid' } ;
6134
6235 harness . mockedDiscovery . discoverLogSources . mockResolvedValue ( [ mockSource ] ) ;
6336 harness . mockedDiscovery . selectMostRecent . mockReturnValue ( mockSource ) ;
@@ -77,123 +50,13 @@ describe('logs-summary command', () => {
7750 expect ( harness . mockedFormatter . formatStats ) . toHaveBeenCalledWith (
7851 expect . anything ( ) ,
7952 'markdown' ,
80- expect . any ( Boolean )
53+ expect . any ( Boolean ) ,
8154 ) ;
8255 } ) ;
8356
84- it ( 'should use specified source when provided' , async ( ) => {
85- const mockSource : LogSource = {
86- type : 'preserved' ,
87- path : '/custom/path' ,
88- } ;
89-
90- harness . mockedDiscovery . discoverLogSources . mockResolvedValue ( [ ] ) ;
91- harness . mockedDiscovery . validateSource . mockResolvedValue ( mockSource ) ;
92- harness . mockedAggregator . loadAndAggregate . mockResolvedValue ( {
93- totalRequests : 5 ,
94- allowedRequests : 5 ,
95- deniedRequests : 0 ,
96- uniqueDomains : 2 ,
97- byDomain : new Map ( ) ,
98- timeRange : null ,
99- } ) ;
100- harness . mockedFormatter . formatStats . mockReturnValue ( 'formatted' ) ;
101-
102- const options : SummaryCommandOptions = {
103- format : 'markdown' ,
104- source : '/custom/path' ,
105- } ;
106-
107- await summaryCommand ( options ) ;
108-
109- expect ( harness . mockedDiscovery . validateSource ) . toHaveBeenCalledWith ( '/custom/path' ) ;
110- expect ( harness . mockedAggregator . loadAndAggregate ) . toHaveBeenCalledWith ( mockSource ) ;
111- } ) ;
112-
113- it ( 'should exit with error if no sources found' , async ( ) => {
114- harness . mockedDiscovery . discoverLogSources . mockResolvedValue ( [ ] ) ;
115-
116- const options : SummaryCommandOptions = {
117- format : 'markdown' ,
118- } ;
119-
120- await expect ( summaryCommand ( options ) ) . rejects . toThrow ( 'process.exit called' ) ;
121- expect ( harness . mockExit ) . toHaveBeenCalledWith ( 1 ) ;
122- } ) ;
123-
124- it ( 'should exit with error if specified source is invalid' , async ( ) => {
125- harness . mockedDiscovery . discoverLogSources . mockResolvedValue ( [ ] ) ;
126- harness . mockedDiscovery . validateSource . mockRejectedValue ( new Error ( 'Source not found' ) ) ;
127-
128- const options : SummaryCommandOptions = {
129- format : 'markdown' ,
130- source : '/invalid/path' ,
131- } ;
132-
133- await expect ( summaryCommand ( options ) ) . rejects . toThrow ( 'process.exit called' ) ;
134- expect ( harness . mockExit ) . toHaveBeenCalledWith ( 1 ) ;
135- } ) ;
136-
137- it ( 'should support all output formats' , async ( ) => {
138- const mockSource : LogSource = { type : 'running' , containerName : 'awf-squid' } ;
139-
140- harness . mockedDiscovery . discoverLogSources . mockResolvedValue ( [ mockSource ] ) ;
141- harness . mockedDiscovery . selectMostRecent . mockReturnValue ( mockSource ) ;
142- harness . mockedAggregator . loadAndAggregate . mockResolvedValue ( {
143- totalRequests : 0 ,
144- allowedRequests : 0 ,
145- deniedRequests : 0 ,
146- uniqueDomains : 0 ,
147- byDomain : new Map ( ) ,
148- timeRange : null ,
149- } ) ;
150- harness . mockedFormatter . formatStats . mockReturnValue ( 'output' ) ;
151-
152- // Test JSON format
153- await summaryCommand ( { format : 'json' } ) ;
154- expect ( harness . mockedFormatter . formatStats ) . toHaveBeenCalledWith (
155- expect . anything ( ) ,
156- 'json' ,
157- expect . any ( Boolean )
158- ) ;
159-
160- // Test markdown format
161- harness . mockedFormatter . formatStats . mockClear ( ) ;
162- await summaryCommand ( { format : 'markdown' } ) ;
163- expect ( harness . mockedFormatter . formatStats ) . toHaveBeenCalledWith (
164- expect . anything ( ) ,
165- 'markdown' ,
166- expect . any ( Boolean )
167- ) ;
168-
169- // Test pretty format
170- harness . mockedFormatter . formatStats . mockClear ( ) ;
171- await summaryCommand ( { format : 'pretty' } ) ;
172- expect ( harness . mockedFormatter . formatStats ) . toHaveBeenCalledWith (
173- expect . anything ( ) ,
174- 'pretty' ,
175- expect . any ( Boolean )
176- ) ;
177- } ) ;
178-
179- it ( 'should handle aggregation errors gracefully' , async ( ) => {
180- const mockSource : LogSource = { type : 'running' , containerName : 'awf-squid' } ;
181-
182- harness . mockedDiscovery . discoverLogSources . mockResolvedValue ( [ mockSource ] ) ;
183- harness . mockedDiscovery . selectMostRecent . mockReturnValue ( mockSource ) ;
184- harness . mockedAggregator . loadAndAggregate . mockRejectedValue ( new Error ( 'Failed to load' ) ) ;
185-
186- const options : SummaryCommandOptions = {
187- format : 'markdown' ,
188- } ;
189-
190- await expect ( summaryCommand ( options ) ) . rejects . toThrow ( 'process.exit called' ) ;
191- expect ( harness . mockExit ) . toHaveBeenCalledWith ( 1 ) ;
192- } ) ;
193-
19457 it ( 'should emit source-selection info logs only for pretty format, suppress them for markdown and json' , async ( ) => {
195- const mockSource : LogSource = {
196- type : 'preserved' ,
58+ const mockSource = {
59+ type : 'preserved' as const ,
19760 path : '/tmp/squid-logs-123' ,
19861 dateStr : 'Mon Jan 01 2024' ,
19962 } ;
0 commit comments