mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-15 06:35:20 -07:00
The TypeScript helper refactor exposed a separate production risk: builds can fail when the sitemap-endpoints API returns a transient 5xx during Pagefind index generation. Move that fetch into a small helper with retry logic and add a focused prebuild test so this failure mode is caught without waiting on a full deploy. Constraint: Must keep Pagefind index generation behavior the same when the endpoint is healthy Rejected: Ignore the failure as external-only | transient 5xx responses can still block deploys and CI repeatedly Confidence: high Scope-risk: narrow Reversibility: clean Directive: When external build inputs can fail transiently, add a small retryable helper plus a direct test before relying on full deploy verification Tested: pnpm exec vitest run test/prebuild/load-sitemap-endpoints.test.ts; pnpm run typecheck; pnpm run test-prebuild Not-tested: Full production redeploy completion before push
94 lines
2.2 KiB
TypeScript
94 lines
2.2 KiB
TypeScript
import {
|
|
beforeEach,
|
|
describe,
|
|
expect,
|
|
it,
|
|
vi
|
|
} from 'vitest'
|
|
|
|
import axios from 'axios'
|
|
|
|
import {
|
|
fetchJsonWithRetries,
|
|
shouldRetryError
|
|
} from '~/helpers/pagefind/load-sitemap-endpoints'
|
|
|
|
vi.mock( 'axios', () => {
|
|
return {
|
|
default: {
|
|
get: vi.fn()
|
|
}
|
|
}
|
|
} )
|
|
|
|
describe( 'load sitemap endpoints helper', () => {
|
|
beforeEach( () => {
|
|
vi.mocked( axios.get ).mockReset()
|
|
} )
|
|
|
|
it( 'retries transient 5xx errors and eventually resolves', async () => {
|
|
const axiosGet = vi.mocked( axios.get )
|
|
|
|
axiosGet
|
|
.mockRejectedValueOnce({
|
|
response: {
|
|
status: 502
|
|
}
|
|
})
|
|
.mockResolvedValueOnce({
|
|
data: {
|
|
ok: true
|
|
}
|
|
} )
|
|
|
|
const data = await fetchJsonWithRetries( 'https://api.doesitarm.com/sitemap-endpoints.json', {
|
|
attempts: 2,
|
|
delayMs: 0
|
|
} )
|
|
|
|
expect( data ).toEqual({
|
|
ok: true
|
|
} )
|
|
expect( axiosGet ).toHaveBeenCalledTimes( 2 )
|
|
} )
|
|
|
|
it( 'does not retry non-5xx errors', async () => {
|
|
const axiosGet = vi.mocked( axios.get )
|
|
|
|
axiosGet.mockRejectedValueOnce({
|
|
response: {
|
|
status: 404
|
|
}
|
|
})
|
|
|
|
await expect( fetchJsonWithRetries( 'https://api.doesitarm.com/sitemap-endpoints.json', {
|
|
attempts: 3,
|
|
delayMs: 0
|
|
} ) ).rejects.toEqual({
|
|
response: {
|
|
status: 404
|
|
}
|
|
})
|
|
|
|
expect( axiosGet ).toHaveBeenCalledTimes( 1 )
|
|
} )
|
|
|
|
it( 'classifies retryable server errors', () => {
|
|
expect( shouldRetryError( {
|
|
response: {
|
|
status: 502
|
|
}
|
|
} ) ).toBe( true )
|
|
expect( shouldRetryError( {
|
|
response: {
|
|
status: 503
|
|
}
|
|
} ) ).toBe( true )
|
|
expect( shouldRetryError( {
|
|
response: {
|
|
status: 404
|
|
}
|
|
} ) ).toBe( false )
|
|
expect( shouldRetryError( new Error( 'network' ) ) ).toBe( false )
|
|
} )
|
|
} )
|