Skip to content

Commit

Permalink
Make query tests more resilient to changes in implementation details
Browse files Browse the repository at this point in the history
  • Loading branch information
victorhmp committed Mar 30, 2022
1 parent 8d82a6d commit 304c173
Showing 1 changed file with 158 additions and 11 deletions.
169 changes: 158 additions & 11 deletions packages/api/test/queries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,38 @@ import { execute, parse } from 'graphql'

import type { Options } from '../src'
import { getSchema, getContextFactory } from '../src'
import { AllCollectionsQueryFirst5 } from '../mocks/AllCollectionsQuery'
import { AllProductsQueryFirst5 } from '../mocks/AllProductsQuery'
import { CollectionDesksQuery } from '../mocks/CollectionQuery'
import { ProductByIdQuery } from '../mocks/ProductQuery'
import { SearchQueryFirst5Products } from '../mocks/SearchQuery'
import {
AllProductsQueryFirst5,
productSearchPage1Count5Fetch,
checkoutSimulationFetch as allProductsCheckoutSimulationFetch,
} from '../mocks/AllProductsQuery'
import {
CollectionDesksQuery,
pageTypeDesksFetch,
pageTypeOfficeDesksFetch,
pageTypeOfficeFetch,
} from '../mocks/CollectionQuery'
import {
checkoutSimulationFetch,
ProductByIdQuery,
productSearchFetch,
} from '../mocks/ProductQuery'
import {
AllCollectionsQueryFirst5,
catalogBrandListFetch,
catalogCategory3Fetch,
catalogPageTypeAcer,
catalogPageTypeAdidas,
catalogPageTypeBrand,
catalogPageTypeIRobot,
catalogPageTypeSkechers,
} from '../mocks/AllCollectionsQuery'
import {
SearchQueryFirst5Products,
productSearchCategory1Fetch,
attributeSearchCategory1Fetch,
checkoutSimulationFetch as searchCheckoutSimulationFetch,
} from '../mocks/SearchQuery'

let schema: GraphQLSchema
let context: Record<string, any>
Expand All @@ -20,6 +47,28 @@ const apiOptions = {
hideUnavailableItems: false,
} as Options

const mockedFetch = jest.fn()

function pickFetchAPICallResult(
info: RequestInfo,
_: RequestInit | undefined,
expectedFetchAPICalls: Array<Record<'info' | 'init' | 'result', unknown>>
) {
for (const call of expectedFetchAPICalls) {
if (info === call.info) {
return call.result
}
}

throw new Error(
`fetchAPI was called with an unexpected 'info' argument.\ninfo: ${info}`
)
}

jest.mock('../src/platforms/vtex/clients/fetch.ts', () => ({
fetchAPI: (info: RequestInfo, init?: RequestInit) => mockedFetch(info, init),
}))

beforeAll(async () => {
schema = await getSchema(apiOptions)

Expand All @@ -28,52 +77,150 @@ beforeAll(async () => {
context = contextFactory({})
})

// Always clear the mocked fetch before each test so we can count and validate
// the calls performed by each query independently.
beforeEach(() => mockedFetch.mockClear())

test('`collection` query', async () => {
const fetchAPICalls = [
pageTypeDesksFetch,
pageTypeOfficeFetch,
pageTypeOfficeDesksFetch,
]

mockedFetch.mockImplementation((info, init) =>
pickFetchAPICallResult(info, init, fetchAPICalls)
)

const response = await execute(
schema,
parse(CollectionDesksQuery),
null,
context
)

expect(mockedFetch).toHaveBeenCalledTimes(3)

fetchAPICalls.forEach((fetchAPICall) => {
expect(mockedFetch).toHaveBeenCalledWith(
fetchAPICall.info,
fetchAPICall.init
)
})

expect(response).toMatchSnapshot()
})

test('`product` query', async () => {
const fetchAPICalls = [productSearchFetch, checkoutSimulationFetch]

mockedFetch.mockImplementation((info, init) =>
pickFetchAPICallResult(info, init, fetchAPICalls)
)

const response = await execute(schema, parse(ProductByIdQuery), null, context)

expect(mockedFetch).toHaveBeenCalledTimes(2)

fetchAPICalls.forEach((fetchAPICall) => {
expect(mockedFetch).toHaveBeenCalledWith(
fetchAPICall.info,
fetchAPICall.init
)
})

expect(response).toMatchSnapshot()
})

test('`search` query', async () => {
test('`allCollections` query', async () => {
const fetchAPICalls = [
catalogBrandListFetch,
catalogCategory3Fetch,
catalogPageTypeSkechers,
catalogPageTypeAdidas,
catalogPageTypeAcer,
catalogPageTypeIRobot,
catalogPageTypeBrand,
]

mockedFetch.mockImplementation((info, init) =>
pickFetchAPICallResult(info, init, fetchAPICalls)
)

const response = await execute(
schema,
parse(SearchQueryFirst5Products),
parse(AllCollectionsQueryFirst5),
null,
context
)

expect(mockedFetch).toHaveBeenCalledTimes(7)

fetchAPICalls.forEach((fetchAPICall) => {
expect(mockedFetch).toHaveBeenCalledWith(
fetchAPICall.info,
fetchAPICall.init
)
})

expect(response).toMatchSnapshot()
})

test('`allCollections` query', async () => {
test('`allProducts` query', async () => {
const fetchAPICalls = [
productSearchPage1Count5Fetch,
allProductsCheckoutSimulationFetch,
]

mockedFetch.mockImplementation((info, init) =>
pickFetchAPICallResult(info, init, fetchAPICalls)
)

const response = await execute(
schema,
parse(AllCollectionsQueryFirst5),
parse(AllProductsQueryFirst5),
null,
context
)

expect(mockedFetch).toHaveBeenCalledTimes(2)

fetchAPICalls.forEach((fetchAPICall) => {
expect(mockedFetch).toHaveBeenCalledWith(
fetchAPICall.info,
fetchAPICall.init
)
})

expect(response).toMatchSnapshot()
})

test('`allProducts` query', async () => {
test('`search` query', async () => {
const fetchAPICalls = [
productSearchCategory1Fetch,
attributeSearchCategory1Fetch,
searchCheckoutSimulationFetch,
]

mockedFetch.mockImplementation((info, init) =>
pickFetchAPICallResult(info, init, fetchAPICalls)
)

const response = await execute(
schema,
parse(AllProductsQueryFirst5),
parse(SearchQueryFirst5Products),
null,
context
)

expect(mockedFetch).toHaveBeenCalledTimes(3)

fetchAPICalls.forEach((fetchAPICall) => {
expect(mockedFetch).toHaveBeenCalledWith(
fetchAPICall.info,
fetchAPICall.init
)
})

expect(response).toMatchSnapshot()
})

0 comments on commit 304c173

Please sign in to comment.