import { buildTestQueryClient } from '../../__utils__/query_client' import type { ApiClient } from '../../hooks/use_api_client' import { availableFeatures, featuresQueryOptions } from '../../hooks/use_features' const features = { data: [{ type: 'Feature', id: '1', name: 'QA_MOBILE_search', enabled: true }], links: {}, meta: { count: 1, totalCount: 1 }, } const buildClient = (get: jest.Mock) => ({ chat: { get } }) as unknown as ApiClient const fetchTwice = async (get: jest.Mock, secondsBetween: number) => { const queryClient = buildTestQueryClient() const options = featuresQueryOptions(buildClient(get)) await queryClient.fetchQuery(options) jest.advanceTimersByTime(secondsBetween * 1000) await queryClient.fetchQuery(options) } describe('availableFeatures', () => { it('never reads a web-only flag', () => { Object.values(availableFeatures).forEach(name => { expect(name).not.toMatch(/_WEB_/) }) }) }) describe('featuresQueryOptions', () => { beforeEach(() => { jest.useFakeTimers() }) afterEach(() => { jest.useRealTimers() }) it('keeps successful flags fresh for five minutes', async () => { const get = jest.fn().mockResolvedValue(features) await fetchTwice(get, 4 * 60) expect(get).toHaveBeenCalledTimes(1) }) it('refetches right away after a failed fetch', async () => { const get = jest.fn().mockRejectedValue({ status: 503 }) await fetchTwice(get, 1) expect(get).toHaveBeenCalledTimes(2) }) it('backs off for a minute after a 429', async () => { const get = jest.fn().mockRejectedValue({ status: 429 }) const queryClient = buildTestQueryClient() const options = featuresQueryOptions(buildClient(get)) await queryClient.fetchQuery(options) jest.advanceTimersByTime(30 * 1000) await queryClient.fetchQuery(options) expect(get).toHaveBeenCalledTimes(1) jest.advanceTimersByTime(31 * 1000) await queryClient.fetchQuery(options) expect(get).toHaveBeenCalledTimes(2) }) })