Skip to content

Commit

Permalink
Adapt to new GQL error handling: no 500s
Browse files Browse the repository at this point in the history
  • Loading branch information
myieye committed Nov 11, 2024
1 parent 830b918 commit c6a1646
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 12 deletions.
4 changes: 2 additions & 2 deletions frontend/tests/errorHandling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ test('client-side gql 500 does not break the application', async ({ page }) => {
const responsePromise = page.waitForResponse('/api/graphql');
await page.getByText('GQL 500').click();
await responsePromise.catch(() => { });// Ignore the error
await expect(page.locator(':text-matches("Unexpected response:.*(500)", "g")').first()).toBeVisible();
await expect(page.locator(':text-matches("Unexpected Execution Error", "g")').first()).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
await page.locator('#home').click();
await new UserDashboardPage(page).waitFor();
Expand All @@ -75,7 +75,7 @@ test('client-side gql 500 does not break the application', async ({ page }) => {
test('server-side gql 500 does not kill the server', async ({ page }) => {
await loginAs(page.request, 'admin', testEnv.defaultPassword);
await new SandboxPage(page).goto({ urlEnd: '?ssr-gql-500', expectErrorResponse: true });
await expect(page.locator(':text-matches("Unexpected response:.*(500)", "g")').first()).toBeVisible();
await expect(page.locator(':text-matches("Unexpected Execution Error", "g")').first()).toBeVisible();
// we've verified that a 500 occured, now we verify that the server is still alive
await new AdminDashboardPage(page).goto();
test.fail(); // Everything up to here passed, but we expect a soft 500 response assertion to ultimately fail the test
Expand Down
8 changes: 6 additions & 2 deletions frontend/tests/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { test as base, expect, type BrowserContext, type BrowserContextOptions }
import * as testEnv from './envVars';
import { type UUID, randomUUID } from 'crypto';
import { deleteUser, loginAs, registerUser } from './utils/authHelpers';
import { executeGql } from './utils/gqlHelpers';
import { executeGql, type GqlResult } from './utils/gqlHelpers';
import { mkdtemp, rm } from 'fs/promises';
import { join } from 'path';
import { tmpdir } from 'os';
Expand Down Expand Up @@ -32,7 +32,7 @@ type Fixtures = {
}

function addUnexpectedResponseListener(context: BrowserContext): void {
context.addListener('response', response => {
context.addListener('response', async (response) => {
const traceparent = response.request().headers()['traceparent'];
const status = response.status();
const url = response.request().url();
Expand All @@ -41,6 +41,10 @@ function addUnexpectedResponseListener(context: BrowserContext): void {
if (response.request().isNavigationRequest()) {
expect.soft(response.status(), unexpectedResponseMessage).toBeLessThan(400);
}
if (url.endsWith('/api/graphql') && response.ok()) { // response.ok() filters out redirects, which don't have a response body
const result = await response.json() as GqlResult;
expect.soft(result.errors?.[0]?.message).not.toBe('Unexpected Execution Error');
}
});
}

Expand Down
19 changes: 11 additions & 8 deletions frontend/tests/utils/gqlHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { expect, type APIRequestContext, type Page } from '@playwright/test';
import { serverBaseUrl } from '../envVars';
import {expect, type APIRequestContext, type Page} from '@playwright/test';
import {serverBaseUrl} from '../envVars';

export function validateGqlErrors(json: {errors: unknown, data: unknown}, expectError = false): void {
type GqlError = {message: string};
export type GqlResult = { errors?: GqlError[], data?: { errors?: GqlError[] }[] };

export function validateGqlErrors(json: GqlResult, expectError = false): void {
if (!expectError) {
expect(json.errors).toBeFalsy();
expect(json.data).toBeDefined();
Object.values(json.data as {errors: unknown}[]).forEach(value => expect(value.errors).toBeFalsy());
Object.values(json.data!).forEach(value => expect(value.errors).toBeFalsy());
}
}

export async function executeGql<T>(api: APIRequestContext, gql: string, expectError = false): Promise<T> {
const response = await api.post(`${serverBaseUrl}/api/graphql`, {data: {query: gql}});
await expect(response, `code was ${response.status()} (${response.statusText()})`).toBeOK();
const json: unknown = await response.json();
const json = await response.json() as GqlResult;
expect(json, `for query ${gql}`).not.toBeNull();
validateGqlErrors(json as {errors: unknown, data: unknown}, expectError);
validateGqlErrors(json, expectError);
return json as T;
}

Expand All @@ -23,8 +26,8 @@ export async function waitForGqlResponse<T>(page: Page, action: () => Promise<vo
await action();
const response = await gqlPromise;
expect(response.ok(), `code was ${response.status()} (${response.statusText()})`).toBeTruthy();
const json: unknown = await response.json();
const json = await response.json() as GqlResult;
expect(json, `for query ${response.request().postData()}`).not.toBeNull();
validateGqlErrors(json as { errors: unknown, data: unknown });
validateGqlErrors(json);
return json as T;
}

0 comments on commit c6a1646

Please sign in to comment.