admin/lib/observability/expectedProductError.test.ts
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

44 lines
1.8 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { isExpectedProductError, shouldDropExpectedProductSentryEvent } from '@/lib/observability/expectedProductError'
import { getProductApiErrorMessage } from '@/services/apiErrorLocalization'
describe('expected product Sentry filter', () => {
it('drops a ServiceError-shaped MESSAGING_BLOCKED exception', () => {
const error = Object.assign(new Error(getProductApiErrorMessage('MESSAGING_BLOCKED')), {
apiCode: 'MESSAGING_BLOCKED',
statusCode: 403,
})
expect(isExpectedProductError(error)).toBe(true)
expect(shouldDropExpectedProductSentryEvent({ exception: { values: [{ value: error.message }] } }, error)).toBe(true)
})
it('drops an unhandled rejection that only carries the localized message', () => {
expect(
shouldDropExpectedProductSentryEvent({
exception: { values: [{ value: 'ارسال پیام بین این کاربران امکان‌پذیر نیست.' }] },
})
).toBe(true)
})
it('drops soft session-expiry rejections from axios handleSessionExpired', () => {
expect(
shouldDropExpectedProductSentryEvent({
exception: { values: [{ value: 'نشست منقضی شده است' }] },
})
).toBe(true)
})
it('keeps real application crashes and infrastructure failures', () => {
expect(isExpectedProductError(new TypeError('Cannot read properties of undefined'))).toBe(false)
expect(
shouldDropExpectedProductSentryEvent({
exception: { values: [{ value: 'PrismaClientKnownRequestError: column does not exist' }] },
})
).toBe(false)
expect(isExpectedProductError(Object.assign(new Error('SMS provider failed'), { apiCode: 'SERVICE_UNAVAILABLE' }))).toBe(false)
expect(shouldDropExpectedProductSentryEvent({ message: 'api_failure' })).toBe(false)
})
})