125 lines
3.6 KiB
TypeScript
125 lines
3.6 KiB
TypeScript
/**
|
|
* Integration tests for app/(drawer)/(tabs)/home/index.tsx
|
|
*
|
|
* API responses are mocked at the network layer:
|
|
* - common.essentialConsts -> tests/__fixtures__/essentialConsts.json
|
|
* - assets CDN -> tests/mocks/mock-*-response.json
|
|
*
|
|
* Runner: `bun run test` (or `bun run test:watch`) from apps/user-ui.
|
|
*/
|
|
|
|
import React from 'react'
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
import {
|
|
fireEvent,
|
|
render,
|
|
screen,
|
|
waitFor,
|
|
within,
|
|
} from '@testing-library/react-native'
|
|
import { RefreshProvider } from 'common-ui'
|
|
|
|
import Dashboard from '@/app/(drawer)/(tabs)/home/index'
|
|
import { trpc, trpcClient } from '@/src/trpc-client'
|
|
import productsResponse from './mocks/mock-products-response.json'
|
|
import { PRODUCTS_URL, setupApiMocks } from './mocks/api'
|
|
|
|
// The tag grid renders at most this many items before its "Show More" button
|
|
// expands it (see the products.slice(0, 6) in TagScene).
|
|
const TAG_GRID_PREVIEW = 6
|
|
|
|
const knownProductIds = new Set(productsResponse.products.map((p) => p.id))
|
|
const tags = productsResponse.tags
|
|
|
|
/** Products a tag points at that actually exist in the products cache. */
|
|
const productIdsForTag = (tag: (typeof tags)[number]) =>
|
|
tag.productIds.filter((id) => knownProductIds.has(id))
|
|
|
|
function renderHome() {
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: { queries: { retry: false, gcTime: 0 } },
|
|
})
|
|
|
|
return render(
|
|
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
|
<QueryClientProvider client={queryClient}>
|
|
<RefreshProvider queryClient={queryClient}>
|
|
<Dashboard />
|
|
</RefreshProvider>
|
|
</QueryClientProvider>
|
|
</trpc.Provider>
|
|
)
|
|
}
|
|
|
|
describe('Home page', () => {
|
|
let api: ReturnType<typeof setupApiMocks>
|
|
|
|
beforeEach(() => {
|
|
api = setupApiMocks()
|
|
})
|
|
|
|
it('requests the products cache url derived from common.essentialConsts', async () => {
|
|
renderHome()
|
|
|
|
await waitFor(() => {
|
|
expect(
|
|
api.fetchMock.mock.calls.some(([url]) =>
|
|
String(url).includes('common.essentialConsts')
|
|
)
|
|
).toBe(true)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(api.axiosGet).toHaveBeenCalledWith(PRODUCTS_URL)
|
|
})
|
|
})
|
|
|
|
it('shows a tab for every tag', async () => {
|
|
renderHome()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId(`tag-tab-${tags[0].id}`)).toBeTruthy()
|
|
})
|
|
|
|
for (const tag of tags) {
|
|
const tab = screen.getByTestId(`tag-tab-${tag.id}`)
|
|
expect(within(tab).getByText(tag.tagName)).toBeVisible()
|
|
}
|
|
})
|
|
|
|
it('shows every product of every tag, expanding each grid once', async () => {
|
|
renderHome()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId(`tag-grid-${tags[0].id}`)).toBeTruthy()
|
|
})
|
|
|
|
for (const tag of tags) {
|
|
fireEvent.press(screen.getByTestId(`tag-tab-${tag.id}`))
|
|
|
|
const expected = productIdsForTag(tag)
|
|
expect(expected.length).toBeGreaterThan(0)
|
|
|
|
for (const id of expected.slice(0, TAG_GRID_PREVIEW)) {
|
|
expect(screen.getByTestId(`tag-product-${id}`)).toBeVisible()
|
|
}
|
|
|
|
if (expected.length <= TAG_GRID_PREVIEW) continue
|
|
|
|
// Items past the preview are withheld until the grid is expanded.
|
|
expect(
|
|
screen.queryByTestId(`tag-product-${expected[TAG_GRID_PREVIEW]}`)
|
|
).toBeNull()
|
|
|
|
fireEvent.press(screen.getByTestId(`tag-show-more-${tag.id}`))
|
|
|
|
for (const id of expected) {
|
|
expect(screen.getByTestId(`tag-product-${id}`)).toBeVisible()
|
|
}
|
|
}
|
|
})
|
|
|
|
it.todo('shows every product returned by the products cache')
|
|
it.todo('shows the store list')
|
|
it.todo('shows the upcoming delivery slots')
|
|
})
|