Skip to content

Commit

Permalink
APQ: Follow Apollo's implementation more & integration tests for Apol…
Browse files Browse the repository at this point in the history
…lo Client (dotansimha#2985)

* Integration tests for APQ plugin and Apollo Client

* Skip v15

* Go

* Go

* Lint

* Follow Apollo's implementation

* Fix tests

* chore(dependencies): updated changesets for modified dependencies

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
ardatan and github-actions[bot] authored Sep 5, 2023
1 parent 968eb01 commit 75ee852
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-yoga/plugin-prometheus': patch
---
dependencies updates:
- Updated dependency [`@envelop/[email protected]`
↗︎](https://www.npmjs.com/package/@envelop/prometheus/v/8.0.1) (from `8.0.0`, in `dependencies`)
5 changes: 5 additions & 0 deletions .changeset/olive-hairs-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-yoga/plugin-apq': patch
---

Add `extensions.code` to match Apollo's APQ implementation
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if (process.env.LEAKS_TEST === 'true') {
'!**/urql-exchange.spec.ts',
'!**/apollo-link.spec.ts',
'!**/uwebsockets.test.ts',
'!**/apollo-client.test.ts',
);
}

Expand Down
91 changes: 91 additions & 0 deletions packages/plugins/apq/__integration-tests__/apollo-client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* eslint-disable import/no-extraneous-dependencies */
import crypto from 'node:crypto';
import { parse, version } from 'graphql';
import { createSchema, createYoga } from 'graphql-yoga';
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries';
import { useAPQ } from '@graphql-yoga/plugin-apq';

function sha256(input: string) {
return crypto.createHash('sha256').update(input).digest('hex');
}

describe('Automatic Persisted Queries', () => {
if (version.startsWith('15')) {
// eslint-disable-next-line @typescript-eslint/no-empty-function
it('noop', () => {});
return;
}
const server = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
foo: String
}
`,
resolvers: {
Query: {
foo() {
return 'bar';
},
},
},
}),
plugins: [useAPQ()],
});

const fetchSpy = jest.fn(async (info: RequestInfo | URL, init: RequestInit) =>
server.fetch(info as URL, init),
);

const linkChain = createPersistedQueryLink({ sha256 }).concat(
new HttpLink({ uri: 'http://localhost:4000/graphql', fetch: fetchSpy }),
);

const client = new ApolloClient({
cache: new InMemoryCache(),
link: linkChain,
});

it('works', async () => {
const query = '{\n foo\n}';
const { data } = await client.query({ query: parse(query) });

expect(data).toEqual({ foo: 'bar' });

expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(fetchSpy.mock.calls[0][1]).toMatchObject({
body: JSON.stringify({
variables: {},
extensions: {
persistedQuery: {
version: 1,
sha256Hash: sha256(query),
},
},
}),
headers: {
'content-type': 'application/json',
accept: '*/*',
},
method: 'POST',
});
expect(fetchSpy.mock.calls[1][1]).toMatchObject({
body: JSON.stringify({
variables: {},
extensions: {
persistedQuery: {
version: 1,
sha256Hash: sha256(query),
},
},
query,
}),
headers: {
'content-type': 'application/json',
accept: '*/*',
},
method: 'POST',
});
});
});
4 changes: 3 additions & 1 deletion packages/plugins/apq/__tests__/apq.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ describe('Automatic Persisted Queries', () => {

expect(response.ok).toBe(false);
expect(await response.json()).toEqual({
errors: [{ message: 'PersistedQueryMismatch' }],
errors: [
{ message: 'PersistedQueryMismatch', extensions: { code: 'PERSISTED_QUERY_MISMATCH' } },
],
});
});
});
2 changes: 2 additions & 0 deletions packages/plugins/apq/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
"graphql-yoga": "^4.0.4"
},
"devDependencies": {
"@apollo/client": "3.8.2",
"crypto-hash": "2.0.1",
"graphql-yoga": "4.0.4"
},
"publishConfig": {
Expand Down
2 changes: 2 additions & 0 deletions packages/plugins/apq/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export function useAPQ(options: APQOptions = {}): Plugin {
http: {
status: 404,
},
code: 'PERSISTED_QUERY_NOT_FOUND',
},
});
}
Expand All @@ -103,6 +104,7 @@ export function useAPQ(options: APQOptions = {}): Plugin {
http: {
status: 400,
},
code: 'PERSISTED_QUERY_MISMATCH',
},
});
}
Expand Down
68 changes: 67 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 75ee852

Please sign in to comment.