Skip to content

Commit

Permalink
test: invalid ref retry
Browse files Browse the repository at this point in the history
  • Loading branch information
angeloashmore committed Oct 30, 2024
1 parent fc131d1 commit d10ebe6
Show file tree
Hide file tree
Showing 18 changed files with 161 additions and 70 deletions.
148 changes: 79 additions & 69 deletions test/__testutils__/testInvalidRefRetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { expect, it, vi } from "vitest"
import { rest } from "msw"

import { createTestClient } from "./createClient"
import { getMasterRef } from "./getMasterRef"
import { mockPrismicRestAPIV2 } from "./mockPrismicRestAPIV2"

import * as prismic from "../../src"
import type * as prismic from "../../src"

type TestInvalidRefRetryArgs = {
run: (
Expand All @@ -15,74 +14,85 @@ type TestInvalidRefRetryArgs = {
) => Promise<unknown>
}

export const testInvalidRefRetry = (
description: string,
args: TestInvalidRefRetryArgs,
): void => {
it.concurrent(description, async (ctx) => {
const client = createTestClient({ ctx })

const triedRefs: string[] = []

const repositoryResponse = ctx.mock.api.repository()
repositoryResponse.refs = [ctx.mock.api.ref({ isMasterRef: true })]

const latestRef = ctx.mock.api.ref().ref

mockPrismicRestAPIV2({ ctx, repositoryResponse })

const queryEndpoint = new URL(
"documents/search",
`${client.documentAPIEndpoint}/`,
).toString()

ctx.server.use(
rest.get(queryEndpoint, (req, res, ctx) => {
const ref = req.url.searchParams.get("ref")
if (ref) {
triedRefs.push(ref)
}

if (triedRefs.length <= 1) {
return res(
ctx.status(404),
export const testInvalidRefRetry = (args: TestInvalidRefRetryArgs): void => {
it.concurrent(
"retries with the master ref when an invalid ref is used",
async (ctx) => {
const client = createTestClient({ ctx })
const badRef = ctx.mock.api.ref().ref
const masterRef = ctx.mock.api.ref().ref
const queryResponse = ctx.mock.api.query({
documents: [ctx.mock.value.document()],
})

const triedRefs: (string | null)[] = []

mockPrismicRestAPIV2({ ctx, queryResponse })
const endpoint = new URL(
"documents/search",
`${client.documentAPIEndpoint}/`,
).toString()
ctx.server.use(
rest.get(endpoint, (req) => {
triedRefs.push(req.url.searchParams.get("ref"))
}),
rest.get(endpoint, (_req, res, ctx) =>
res.once(
ctx.json({
type: "api_notfound_error",
message: `Ref not found. Ensure you have the correct ref and try again. Master ref is: ${latestRef}`,
message: `Master ref is: ${masterRef}`,
}),
)
}
}),
)

const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0)

await args.run(client)

expect(triedRefs).toStrictEqual([
getMasterRef(repositoryResponse),
latestRef,
])

// Check that refs are not retried more than once.
ctx.server.use(
rest.get(queryEndpoint, (_req, res, ctx) => {
return res(
ctx.status(404),
ctx.json({
type: "api_notfound_error",
message: `Ref not found. Ensure you have the correct ref and try again. Master ref is: ${triedRefs[0]}`,
}),
)
}),
)

await expect(async () => {
await args.run(client)
}).rejects.toThrow(prismic.RefNotFoundError)

consoleWarnSpy.mockRestore()
})
ctx.status(404),
),
),
)

const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0)
await args.run(client, { ref: badRef })
consoleWarnSpy.mockRestore()

expect(triedRefs).toStrictEqual([badRef, masterRef])
},
)

it.concurrent(
"retries with the master ref when an expired ref is used",
async (ctx) => {
const client = createTestClient({ ctx })
const badRef = ctx.mock.api.ref().ref
const masterRef = ctx.mock.api.ref().ref
const queryResponse = ctx.mock.api.query({
documents: [ctx.mock.value.document()],
})

const triedRefs: (string | null)[] = []

mockPrismicRestAPIV2({ ctx, queryResponse })
const endpoint = new URL(
"documents/search",
`${client.documentAPIEndpoint}/`,
).toString()
ctx.server.use(
rest.get(endpoint, (req) => {
triedRefs.push(req.url.searchParams.get("ref"))
}),
rest.get(endpoint, (_req, res, ctx) =>
res.once(
ctx.json({ message: `Master ref is: ${masterRef}` }),
ctx.status(410),
),
),
)

const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0)
await args.run(client, { ref: badRef })
consoleWarnSpy.mockRestore()

expect(triedRefs).toStrictEqual([badRef, masterRef])
},
)
}
2 changes: 1 addition & 1 deletion test/client-get.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ it("uses cached repository metadata within the client's repository cache TTL", a
)
})

testInvalidRefRetry("retries on expired refs", {
testInvalidRefRetry({
run: (client, params) => client.get(params),
})

Expand Down
5 changes: 5 additions & 0 deletions test/client-getAllByEveryTag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetAllMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetAllMethod("returns all documents by every tag from paginated response", {
run: (client) => client.getAllByEveryTag(["foo", "bar"]),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getAllByEveryTag(["foo", "bar"], params),
})

testInvalidRefRetry({
run: (client, params) => client.getAllByEveryTag(["foo", "bar"], params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getAllByEveryTag(["foo", "bar"], params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getAllByIDs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetAllMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetAllMethod("returns all documents by IDs from paginated response", {
run: (client) => client.getAllByIDs(["id1", "id2"]),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getAllByIDs(["id1", "id2"], params),
})

testInvalidRefRetry({
run: (client, params) => client.getAllByIDs(["id1", "id2"], params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getAllByIDs(["id1", "id2"], params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getAllBySomeTags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetAllMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetAllMethod("returns all documents by some tags from paginated response", {
run: (client) => client.getAllBySomeTags(["foo", "bar"]),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getAllBySomeTags(["foo", "bar"], params),
})

testInvalidRefRetry({
run: (client, params) => client.getAllBySomeTags(["foo", "bar"], params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getAllBySomeTags(["foo", "bar"], params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getAllByTag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetAllMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetAllMethod("returns all documents by tag from paginated response", {
run: (client) => client.getAllByTag("tag"),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getAllByTag("tag", params),
})

testInvalidRefRetry({
run: (client, params) => client.getAllByTag("tag", params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getAllByTag("tag", params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getAllByType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetAllMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetAllMethod("returns all documents by type from paginated response", {
run: (client) => client.getAllByType("type"),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getAllByType("type", params),
})

testInvalidRefRetry({
run: (client, params) => client.getAllByType("type", params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getAllByType("type", params),
})
Expand Down
6 changes: 6 additions & 0 deletions test/client-getAllByUIDs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetAllMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetAllMethod("returns all documents by UIDs from paginated response", {
run: (client) => client.getAllByUIDs("type", ["uid1", "uid2"]),
Expand Down Expand Up @@ -36,6 +37,11 @@ testFetchOptions("supports fetch options", {
client.getAllByUIDs("type", ["uid1", "uid2"], params),
})

testInvalidRefRetry({
run: (client, params) =>
client.getAllByUIDs("type", ["uid1", "uid2"], params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) =>
client.getAllByUIDs("type", ["uid1", "uid2"], params),
Expand Down
5 changes: 5 additions & 0 deletions test/client-getByEveryTag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetMethod("queries for documents by tag", {
run: (client) => client.getByEveryTag(["foo", "bar"]),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getByEveryTag(["foo", "bar"], params),
})

testInvalidRefRetry({
run: (client, params) => client.getByEveryTag(["foo", "bar"], params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getByEveryTag(["foo", "bar"], params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getByID.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetFirstMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetFirstMethod("queries for document by ID", {
run: (client) => client.getByID("id"),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getByID("id", params),
})

testInvalidRefRetry({
run: (client, params) => client.getByID("id", params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getByID("id", params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getByIDs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetMethod("queries for documents by IDs", {
run: (client) => client.getByIDs(["id1", "id2"]),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getByIDs(["id1", "id2"], params),
})

testInvalidRefRetry({
run: (client, params) => client.getByIDs(["id1", "id2"], params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getByIDs(["id1", "id2"], params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getBySomeTags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetMethod("queries for documents by some tags", {
run: (client) => client.getBySomeTags(["foo", "bar"]),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getBySomeTags(["foo", "bar"], params),
})

testInvalidRefRetry({
run: (client, params) => client.getBySomeTags(["foo", "bar"], params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getBySomeTags(["foo", "bar"], params),
})
Expand Down
5 changes: 5 additions & 0 deletions test/client-getByTag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testAbortableMethod } from "./__testutils__/testAbortableMethod"
import { testGetMethod } from "./__testutils__/testAnyGetMethod"
import { testConcurrentMethod } from "./__testutils__/testConcurrentMethod"
import { testFetchOptions } from "./__testutils__/testFetchOptions"
import { testInvalidRefRetry } from "./__testutils__/testInvalidRefRetry"

testGetMethod("queries for documents by tag", {
run: (client) => client.getByTag("tag"),
Expand Down Expand Up @@ -29,6 +30,10 @@ testFetchOptions("supports fetch options", {
run: (client, params) => client.getByTag("tag", params),
})

testInvalidRefRetry({
run: (client, params) => client.getByTag("tag", params),
})

testAbortableMethod("is abortable with an AbortController", {
run: (client, params) => client.getByTag("tag", params),
})
Expand Down
Loading

0 comments on commit d10ebe6

Please sign in to comment.