import assert from 'node:assert/strict' import test from 'node:test' import type { AxiosResponse } from 'axios' import { createResponseDiagnostic, createSafeApiErrorReport, createValidationDiagnostic, } from '../src/api/diagnostics' import { RequestError } from '../src/api/errors' function sensitiveResponse(): AxiosResponse { return { config: { baseURL: 'https://api.example.com/', data: JSON.stringify({ phone: '13800000000' }), headers: { sessionId: 'secret-session', userId: 'secret-user', }, method: 'post', url: '/am/example', }, data: { token: 'secret-token' }, headers: { authorization: 'secret-authorization' }, status: 200, statusText: 'OK', } } test('API diagnostics only retain non-sensitive request shape', () => { const diagnostic = createResponseDiagnostic(sensitiveResponse()) assert.deepEqual(diagnostic, { httpStatus: 200, method: 'POST', path: '/am/example', type: 'Response', }) const serialized = JSON.stringify(diagnostic) assert.doesNotMatch(serialized, /secret|phone|token|authorization|example\.com/) }) test('validation diagnostics retain issue paths without response data', () => { const diagnostic = createValidationDiagnostic(sensitiveResponse(), [ { code: 'invalid_type', expected: 'string', message: 'Invalid input: expected string, received number', path: ['data', 'userId'], }, ]) assert.equal(diagnostic.issues?.[0]?.path, 'data.userId') const serialized = JSON.stringify(diagnostic) assert.doesNotMatch(serialized, /secret|13800000000|authorization|example\.com/) }) test('global API error reports never expose RequestError causes', () => { const response = sensitiveResponse() const cause = { issues: [ { code: 'invalid_type', expected: 'string', message: 'Invalid input: expected string, received number', path: ['data', 'userId'], }, ], response, } const report = createSafeApiErrorReport( new RequestError('server message may contain private data', 'ValidationError', cause), ) assert.equal(report.requestType, 'ValidationError') assert.equal(report.diagnostic?.type, 'ValidationError') const serialized = JSON.stringify(report) assert.doesNotMatch( serialized, /private|secret|13800000000|authorization|example\.com|server message/, ) })