forked from CredenceOrg/Credence-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog.test.ts
More file actions
77 lines (60 loc) · 2.37 KB
/
Copy pathlog.test.ts
File metadata and controls
77 lines (60 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { afterEach, describe, expect, it, vi } from 'vitest'
import { logDebug, logError, logInfo, logWarn } from './log'
afterEach(() => {
vi.restoreAllMocks()
})
const captureInfo = () => {
const lines: string[] = []
vi.spyOn(console, 'info').mockImplementation((line: string) => {
lines.push(line)
})
return lines
}
describe('structured logger', () => {
it('emits a single key=value line for an info event', () => {
const lines = captureInfo()
logInfo('boot_ready', { scope: 'test', ok: true })
expect(lines.length).toBe(1)
const line = lines[0] ?? ''
expect(line).toMatch(/^ts=\d{4}-\d{2}-\d{2}T/)
expect(line).toMatch(/level=info/)
expect(line).toMatch(/event=boot_ready/)
expect(line).toMatch(/scope=test/)
expect(line).toMatch(/ok=true/)
})
it('routes warn and error to the correct sinks', () => {
const info = vi.spyOn(console, 'info').mockImplementation(() => {})
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
const err = vi.spyOn(console, 'error').mockImplementation(() => {})
logWarn('cache_stale', { scope: 'test' })
logError('fatal', { code: 7 })
expect(info).not.toHaveBeenCalled()
expect(warn).toHaveBeenCalledTimes(1)
expect(err).toHaveBeenCalledTimes(1)
expect(warn.mock.calls[0]?.[0]).toMatch(/event=cache_stale/)
expect(err.mock.calls[0]?.[0]).toMatch(/event=fatal code=7/)
})
it('routes debug to console.debug', () => {
const debug = vi.spyOn(console, 'debug').mockImplementation(() => {})
logDebug('route_prefetch', { path: '/dashboard' })
expect(debug).toHaveBeenCalledTimes(1)
expect(debug.mock.calls[0]?.[0]).toMatch(/event=route_prefetch path=\/dashboard/)
})
it('drops fields whose key looks like a secret', () => {
const lines = captureInfo()
logInfo('attempt', { token: 'ghp_abc', scope: 'test', authorization: 'Bearer x' })
expect(lines.length).toBe(1)
const line = lines[0] ?? ''
expect(line).not.toMatch(/ghp_abc/)
expect(line).not.toMatch(/Bearer x/)
expect(line).toMatch(/scope=test/)
})
it('renders empty or null fields as a dash', () => {
const lines = captureInfo()
logInfo('attempt', { empty: '', missing: null as unknown as string, ok: true })
const line = lines[0] ?? ''
expect(line).toMatch(/empty=-/)
expect(line).toMatch(/missing=-/)
expect(line).toMatch(/ok=true/)
})
})