import { DyFM_EnvironmentFlag, DyFM_Error } from '@futdevpro/fsm-dynamo'; import { DyNTS_ClientSafeError_Util } from './client-safe-error.util'; import { DyNTS_global_settings } from './global-settings.const'; // A kliens-safe error-strip SSOT tesztjei (BFR-FDPAUTHSERVICE-002) — a 3 strip-szabály + // a nem-DyFM fail-safe ág. A DyFM_Error mező-neveit a valós instansán verifikáljuk (no-guessing). describe('| DyNTS_ClientSafeError_Util', (): void => { /** Egy teljes-mezős DyFM_Error a strip-tesztekhez (a leak-vektor mezőkkel feltöltve). */ function buildRichError(): DyFM_Error { const error: DyFM_Error = new DyFM_Error({ message: 'internal reason', userMessage: 'user facing message', errorCode: 'DyNTS-TEST-CSE0', error: new Error('inner cause'), additionalContent: { userId: 'u1' }, confidentialContent: { secret: 's3cr3t' }, }); return error; } afterEach((): void => { // a prod-teszt env-átállítását visszaállítjuk (a global-settings megosztott singleton) DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.local; }); it('| MINDIG strip-eli a leak-vektor mezőket (nem-prod env-ben is)', (): void => { DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.local; const error: DyFM_Error = buildRichError(); const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(error) as Record; expect(safe['__localStack']).toBeUndefined(); expect(safe['stack']).toBeUndefined(); expect(safe['___systemVersion']).toBeUndefined(); expect(safe['___issuer']).toBeUndefined(); expect(safe['___issuerSystem']).toBeUndefined(); expect(safe['___issuerService']).toBeUndefined(); expect(safe['confidentialContent']).toBeUndefined(); expect(safe['error']).toBeUndefined(); expect(safe['errors']).toBeUndefined(); }); it('| MEGTARTJA a kliens-fogyasztott mező-alakot (_message, _errorCodes, __userMessage)', (): void => { DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.local; const error: DyFM_Error = buildRichError(); const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(error) as Record; // QA2-005: a `_message` ALAKJA marad, de a TARTALMA a user-safe `__userMessage` — // a technikai 'internal reason' (belső URL / nyers DB-hiba osztály) nem megy ki expect(safe['_message']).toBe('user facing message'); expect(safe['__userMessage']).toBe('user facing message'); expect(Array.isArray(safe['_errorCodes'])).toBeTrue(); expect((safe['_errorCodes'] as string[]).join(',')).toContain('DyNTS-TEST-CSE0'); }); it('| QA2-005: a technikai _message / _messages NEM szivárog ki (test-env-ben sem)', (): void => { DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.test; const error: DyFM_Error = new DyFM_Error({ message: 'API call "registerAccount" failed on the other end!\nurl: http://auth-service:39005/api/account/register' + '\nerror response found: E11000 duplicate key error collection', userMessage: 'Registration failed!', errorCode: 'DyNTS-TEST-CSE1', }); const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(error) as Record; const serialized: string = JSON.stringify(safe); expect(safe['_message']).toBe('Registration failed!'); expect(safe['_messages']).toBeUndefined(); expect(serialized).not.toContain('auth-service:39005'); expect(serialized).not.toContain('E11000'); }); it('| QA2-005: __userMessage nélkül a _message generikus szövegre cserélődik (nem a technikai)', (): void => { DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.test; const error: DyFM_Error = new DyFM_Error({ message: 'raw internal detail: http://auth-service:39005/api', errorCode: 'DyNTS-TEST-CSE2', }); // a konstruktor default-userMessage viselkedésétől függetlenül: a technikai szöveg nem mehet ki (error as unknown as Record)['__userMessage'] = undefined; const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(error) as Record; expect(typeof safe['_message']).toBe('string'); expect(safe['_message'] as string).not.toContain('auth-service:39005'); expect((safe['_message'] as string).length).toBeGreaterThan(0); }); it('| QA2-005: az additionalContent.requestDebug env-FÜGGETLENÜL strip-elve, a többi mező marad (non-prod)', (): void => { DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.test; const error: DyFM_Error = new DyFM_Error({ message: 'internal reason', userMessage: 'user facing message', errorCode: 'DyNTS-TEST-CSE3', additionalContent: { userId: 'u1', requestDebug: { headerKeys: ['authorization', 'cookie'], remoteAddress: '172.18.0.5' }, }, }); const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(error) as Record; const additionalContent: Record = safe['additionalContent'] as Record; expect(additionalContent).toBeDefined(); expect(additionalContent['userId']).toBe('u1'); expect(additionalContent['requestDebug']).toBeUndefined(); }); it('| nem-prod env: az additionalContent (diagnosztikai snapshot) MARAD', (): void => { DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.local; const error: DyFM_Error = buildRichError(); const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(error) as Record; expect(safe['additionalContent']).toEqual({ userId: 'u1' }); }); it('| prod env: az additionalContent IS strip-elve', (): void => { DyNTS_global_settings.env_settings.environment = DyFM_EnvironmentFlag.prod; const error: DyFM_Error = buildRichError(); const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(error) as Record; expect(safe['additionalContent']).toBeUndefined(); // a mindig-strip lista prod-ban is érvényes expect(safe['__localStack']).toBeUndefined(); expect(safe['stack']).toBeUndefined(); }); it('| nem-DyFM object-error: fail-safe minimál { message } shape (axios-config nem szivárog)', (): void => { const axiosLike: { message: string; config: { headers: { authorization: string } } } = { message: 'Request failed with status code 401', config: { headers: { authorization: 'Bearer LEAK' } }, }; const safe: Record = DyNTS_ClientSafeError_Util.toClientSafe(axiosLike) as Record; expect(safe['message']).toBe('Request failed with status code 401'); expect(safe['config']).toBeUndefined(); }); it('| nem-object error (string/undefined): változatlanul átmegy', (): void => { expect(DyNTS_ClientSafeError_Util.toClientSafe('plain string')).toBe('plain string'); expect(DyNTS_ClientSafeError_Util.toClientSafe(undefined)).toBeUndefined(); }); });