freshyo/apps/user-ui/tests/home.test.tsx
2026-09-17 23:13:32 +05:30

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')
})