Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Jan 3, 2024
1 parent 718cecc commit fe8c704
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
12 changes: 10 additions & 2 deletions integration-test/src/app/cc/ApolloWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@ setVerbosity("debug");
loadDevMessages();
loadErrorMessages();

export function ApolloWrapper({ children }: React.PropsWithChildren<{}>) {
export function ApolloWrapper({
children,
nonce,
}: React.PropsWithChildren<{ nonce?: string }>) {
return (
<ApolloNextAppProvider makeClient={makeClient}>
<ApolloNextAppProvider
makeClient={makeClient}
extraScriptProps={{
nonce,
}}
>
{children}
</ApolloNextAppProvider>
);
Expand Down
27 changes: 27 additions & 0 deletions integration-test/src/app/cc/dynamic/dynamic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,31 @@ test.describe("CC dynamic", () => {
await expect(page.getByText("Soft Warm Apollo Beanie")).toBeVisible();
});
});
test.describe("useSuspenseQuery with a nonce", () => {
test("invalid: logs an error", async ({ page, blockRequest }) => {
await page.goto(
"http://localhost:3000/cc/dynamic/useSuspenseQuery?nonce=invalid",
{
waitUntil: "commit",
}
);

const messagePromise = page.waitForEvent("console");
const message = await messagePromise;
expect(message.text()).toMatch(
/^Refused to execute inline script because it violates the following Content Security Policy/
);
});
test("valid: does not log an error", async ({ page, blockRequest }) => {
await page.goto(
"http://localhost:3000/cc/dynamic/useSuspenseQuery?nonce=8IBTHwOdqNKAWeKl7plt8g==",
{
waitUntil: "commit",
}
);

const messagePromise = page.waitForEvent("console");
expect(messagePromise).rejects.toThrow(/waiting for event \"console\"/);
});
});
});
4 changes: 3 additions & 1 deletion integration-test/src/app/cc/dynamic/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { headers } from "next/headers";
import { ApolloWrapper } from "../ApolloWrapper";

export default function Layout({ children }: React.PropsWithChildren) {
// force this into definitely rendering on the server, and dynamically
console.log(headers().toString().substring(0, 0));
return children;
const nonce = headers().get("x-nonce-param") ?? undefined;
return <ApolloWrapper nonce={nonce}>{children}</ApolloWrapper>;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApolloWrapper } from "./ApolloWrapper";
import { ApolloWrapper } from "../ApolloWrapper";

export default async function Layout({
children,
Expand Down
33 changes: 33 additions & 0 deletions integration-test/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { NextRequest, NextResponse } from "next/server";

export function middleware(request: NextRequest) {
const nonce = request.nextUrl.searchParams.get("nonce");
if (nonce) {
// we set a fixed nonce here so we can test correct and incorrect nonce values
const validNonce = "8IBTHwOdqNKAWeKl7plt8g==";
// 'unsafe-eval' for `react-refresh`
const contentSecurityPolicyHeaderValue = `default-src 'self'; script-src 'nonce-${validNonce}' 'strict-dynamic' 'unsafe-eval';`;

const requestHeaders = new Headers(request.headers);
// valid nonce for next
requestHeaders.set("x-nonce", validNonce);
// potentially invalid nonce for `ApolloNextAppProvider`
requestHeaders.set("x-nonce-param", nonce);
requestHeaders.set(
"Content-Security-Policy",
contentSecurityPolicyHeaderValue
);

const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});
response.headers.set(
"Content-Security-Policy",
contentSecurityPolicyHeaderValue
);

return response;
}
}

0 comments on commit fe8c704

Please sign in to comment.