diff --git a/src/logs/log-aggregator.test.ts b/src/logs/log-aggregator.test.ts index 1c5687403..5ead11d5d 100644 --- a/src/logs/log-aggregator.test.ts +++ b/src/logs/log-aggregator.test.ts @@ -25,6 +25,37 @@ describe('log-aggregator', () => { }); describe('aggregateLogs', () => { + /** Returns a pair of valid CONNECT tunnel entries used across filtering tests. */ + function validTunnelEntries(): ParsedLogEntry[] { + return [ + createLogEntry({ domain: 'github.com', url: 'github.com:443', isAllowed: true }), + createLogEntry({ domain: 'npmjs.org', url: 'npmjs.org:443', isAllowed: true }), + ]; + } + + /** Returns a benign operational transaction-end-before-headers entry. */ + function transactionEndEntry(overrides: Partial = {}): ParsedLogEntry { + return createLogEntry({ + domain: '-', + url: 'error:transaction-end-before-headers', + decision: 'NONE_NONE:HIER_NONE', + statusCode: 0, + isAllowed: false, + ...overrides, + }); + } + + /** Asserts that stats reflect only the two valid tunnel entries (github.com + npmjs.org). */ + function expectOnlyValidTunnelStats(stats: ReturnType): void { + expect(stats.totalRequests).toBe(2); // Only actual requests, not benign operational entries + expect(stats.allowedRequests).toBe(2); + expect(stats.deniedRequests).toBe(0); + expect(stats.uniqueDomains).toBe(2); + expect(stats.byDomain.has('github.com')).toBe(true); + expect(stats.byDomain.has('npmjs.org')).toBe(true); + expect(stats.byDomain.has('-')).toBe(false); // Filtered entry not in domain stats + } + it('should return empty stats for empty array', () => { const stats = aggregateLogs([]); @@ -104,74 +135,30 @@ describe('log-aggregator', () => { }); it('should filter out transaction-end-before-headers entries', () => { + const [first, second] = validTunnelEntries(); const entries: ParsedLogEntry[] = [ - createLogEntry({ - domain: 'github.com', - url: 'github.com:443', - isAllowed: true - }), - createLogEntry({ - domain: '-', - url: 'error:transaction-end-before-headers', - decision: 'NONE_NONE:HIER_NONE', - statusCode: 0, - isAllowed: false - }), - createLogEntry({ - domain: 'npmjs.org', - url: 'npmjs.org:443', - isAllowed: true - }), + first, + transactionEndEntry(), + second, ]; const stats = aggregateLogs(entries); - // Should only count the two valid entries - expect(stats.totalRequests).toBe(2); // Only actual requests, not benign operational entries - expect(stats.allowedRequests).toBe(2); - expect(stats.deniedRequests).toBe(0); - expect(stats.uniqueDomains).toBe(2); - expect(stats.byDomain.has('github.com')).toBe(true); - expect(stats.byDomain.has('npmjs.org')).toBe(true); - expect(stats.byDomain.has('-')).toBe(false); // Filtered entry not in domain stats + expectOnlyValidTunnelStats(stats); }); it('should handle multiple transaction-end-before-headers entries', () => { + const [first, second] = validTunnelEntries(); const entries: ParsedLogEntry[] = [ - createLogEntry({ - domain: 'github.com', - url: 'github.com:443', - isAllowed: true - }), - createLogEntry({ - domain: '-', - url: 'error:transaction-end-before-headers', - clientIp: '::1', // healthcheck from localhost - decision: 'NONE_NONE:HIER_NONE', - statusCode: 0, - isAllowed: false - }), - createLogEntry({ - domain: '-', - url: 'error:transaction-end-before-headers', - clientIp: '172.30.0.20', // shutdown-time connection closure - decision: 'NONE_NONE:HIER_NONE', - statusCode: 0, - isAllowed: false - }), - createLogEntry({ - domain: 'npmjs.org', - url: 'npmjs.org:443', - isAllowed: true - }), + first, + transactionEndEntry({ clientIp: '::1' }), // healthcheck from localhost + second, + transactionEndEntry({ clientIp: '172.30.0.20' }), // shutdown-time connection closure ]; const stats = aggregateLogs(entries); - expect(stats.totalRequests).toBe(2); // Only actual requests - expect(stats.allowedRequests).toBe(2); - expect(stats.deniedRequests).toBe(0); - expect(stats.uniqueDomains).toBe(2); + expectOnlyValidTunnelStats(stats); }); it('should still count time range from all entries including filtered ones', () => {