@toptal/davinci-cloudflare-requests-handler
Version:
Toptal Cloudflare requests handler
170 lines (142 loc) • 5.16 kB
text/typescript
import { setItem, getItem } from './utils/local-storage'
import * as pageReloadUtils from './utils/page-reload'
import * as reportSentryUtils from './utils/report-sentry'
import cloudflareFetchHander from './cloudflare-fetch-handler'
import {
DAVINCI_CLOUDFLARE_NUMBER_OF_RETRIES_KEY,
DAVINCI_CLOUDFLARE_LAST_RETRY_DATE_KEY,
MILLISECONDS_TO_NEXT_RETRY,
MULTIPLE_RETRIES_ERROR_MESSAGE,
} from './constants'
jest.mock('./utils/local-storage')
describe('cloudflareFetchHander', () => {
let pageReloadSpy: jest.SpyInstance<void, []>
const getLocalStorageItemSpy = getItem as jest.Mock<
ReturnType<typeof getItem>
>
const setLocalStorageItemSpy = setItem as jest.Mock<
ReturnType<typeof setItem>
>
let reportToSentrySpy: jest.SpyInstance<void, [message: string]>
beforeEach(() => {
pageReloadSpy = jest
.spyOn(pageReloadUtils, 'pageReload')
.mockImplementation(jest.fn())
getLocalStorageItemSpy.mockReturnValue(null)
setLocalStorageItemSpy.mockReturnValue(undefined)
reportToSentrySpy = jest
.spyOn(reportSentryUtils, 'reportToSentry')
.mockImplementation(jest.fn())
})
afterEach(() => {
jest.restoreAllMocks()
getLocalStorageItemSpy.mockReset()
setLocalStorageItemSpy.mockReset()
})
it('does nothing if status is 200 OK', () => {
const okResponse = {
status: 200,
}
// Act
cloudflareFetchHander(okResponse as Response)
expect(pageReloadSpy).not.toHaveBeenCalled()
expect(getLocalStorageItemSpy).not.toHaveBeenCalled()
expect(setLocalStorageItemSpy).not.toHaveBeenCalled()
})
it('reloads the page if status 429 Too Many Requests and it is a first request', () => {
const tooManyRequestsResponse = {
status: 429,
}
const numberOfRetries = null
const expectedUpdatedNumberOfRetries = '1'
getLocalStorageItemSpy.mockReturnValueOnce(numberOfRetries)
// Act
cloudflareFetchHander(tooManyRequestsResponse as Response)
expect(setLocalStorageItemSpy).toHaveBeenNthCalledWith(
1,
DAVINCI_CLOUDFLARE_LAST_RETRY_DATE_KEY,
expect.any(String)
)
expect(setLocalStorageItemSpy).toHaveBeenNthCalledWith(
2,
DAVINCI_CLOUDFLARE_NUMBER_OF_RETRIES_KEY,
expectedUpdatedNumberOfRetries
)
expect(pageReloadSpy).toHaveBeenCalled()
})
it('reloads the page if status 429 and number of retries is not max', () => {
const tooManyRequestsResponse = {
status: 429,
}
const numberOfRetries = '2'
const expectedUpdatedNumberOfRetries = '3'
getLocalStorageItemSpy.mockReturnValueOnce(numberOfRetries)
// Act
cloudflareFetchHander(tooManyRequestsResponse as Response)
expect(setLocalStorageItemSpy).toHaveBeenNthCalledWith(
1,
DAVINCI_CLOUDFLARE_LAST_RETRY_DATE_KEY,
expect.any(String)
)
expect(setLocalStorageItemSpy).toHaveBeenNthCalledWith(
2,
DAVINCI_CLOUDFLARE_NUMBER_OF_RETRIES_KEY,
expectedUpdatedNumberOfRetries
)
expect(pageReloadSpy).toHaveBeenCalled()
})
it('stops reloading the page after 3rd retry if last retry was not long ago', () => {
const tooManyRequestsResponse = {
status: 429,
}
const numberOfRetries = '3'
const notLongAgoLastRetryDate = Date.now()
getLocalStorageItemSpy.mockReturnValueOnce(numberOfRetries)
getLocalStorageItemSpy.mockReturnValueOnce(String(notLongAgoLastRetryDate))
// Act
cloudflareFetchHander(tooManyRequestsResponse as Response)
expect(pageReloadSpy).not.toHaveBeenCalled()
expect(setLocalStorageItemSpy).not.toHaveBeenCalled()
})
it('reloads the page after 3rd retry if last retry was long ago', () => {
const tooManyRequestsResponse = {
status: 429,
}
const numberOfRetries = '3'
const expectedUpdatedNumberOfRetries = '0'
const longAgoLastRetryDate =
new Date().getTime() - 2 * MILLISECONDS_TO_NEXT_RETRY
getLocalStorageItemSpy.mockReturnValueOnce(numberOfRetries)
getLocalStorageItemSpy.mockReturnValueOnce(String(longAgoLastRetryDate))
// Act
cloudflareFetchHander(tooManyRequestsResponse as Response)
expect(setLocalStorageItemSpy).toHaveBeenNthCalledWith(
1,
DAVINCI_CLOUDFLARE_LAST_RETRY_DATE_KEY,
expect.any(String)
)
expect(setLocalStorageItemSpy).toHaveBeenNthCalledWith(
2,
DAVINCI_CLOUDFLARE_NUMBER_OF_RETRIES_KEY,
expectedUpdatedNumberOfRetries
)
expect(pageReloadSpy).toHaveBeenCalled()
expect(reportToSentrySpy).not.toHaveBeenCalled()
})
it('reports to Sentry if multiple retries happen n short amount of time', () => {
const tooManyRequestsResponse = {
status: 429,
}
const numberOfRetries = '1'
const shortAmountOfTimeAfterLastRetryDate = new Date().getTime() - 1
getLocalStorageItemSpy.mockReturnValueOnce(numberOfRetries)
getLocalStorageItemSpy.mockReturnValueOnce(
String(shortAmountOfTimeAfterLastRetryDate)
)
// Act
cloudflareFetchHander(tooManyRequestsResponse as Response)
expect(reportToSentrySpy).toHaveBeenCalledWith(
MULTIPLE_RETRIES_ERROR_MESSAGE
)
})
})