Skip to content

Commit cd4bc26

Browse files
committed
Added tests for isAuthenticated and getDecodedToken ✅
1 parent 126cff7 commit cd4bc26

File tree

7 files changed

+198
-35
lines changed

7 files changed

+198
-35
lines changed

tests/__snapshots__/hasRole.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Array [
4444

4545
exports[`Testing hasRole directive without handler overriding should prevent accessing a query without the necessary roles 1`] = `
4646
Array [
47-
[GraphQLError: Insufficient roles. Missing one of these: USER, ADMIN, SUPER_ADMIN],
47+
[GraphQLError: Insufficient roles. Missing one of these: USER],
4848
]
4949
`;
5050

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Testing isAuthenticated directive with handler overriding should override the isAuthenticated default handler correctly and throw an error 1`] = `
4+
Array [
5+
[GraphQLError: Authorization header: Bearer TOKEN],
6+
]
7+
`;
8+
9+
exports[`Testing isAuthenticated directive without handler overriding should allow accessing a mutation authenticated 1`] = `
10+
Object {
11+
"protectedMutation": "@MUTATION Input: foo Protected Input: undefined",
12+
}
13+
`;
14+
15+
exports[`Testing isAuthenticated directive without handler overriding should allow accessing a mutation's input authenticated 1`] = `
16+
Object {
17+
"protectedMutation": "@MUTATION Input: foo Protected Input: bar",
18+
}
19+
`;
20+
21+
exports[`Testing isAuthenticated directive without handler overriding should allow accessing a query's input authenticated 1`] = `
22+
Object {
23+
"protectedQuery": "@QUERY Input: foo Protected Input: undefined",
24+
}
25+
`;

tests/getDecodedToken.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// import jwt from "jsonwebtoken";
2+
3+
import { getDecodedToken } from "../src/utils/getDecodedToken";
4+
5+
describe("Testing the getDecodedToken function", () => {
6+
it("should throw an error when there is no authorization header passed", async () => {
7+
expect(() => getDecodedToken({})).toThrow(/Authorization header missing.../);
8+
});
9+
10+
it("should throw an error when the JWT_SECRET environment variable is not set", async () => {
11+
expect(() => getDecodedToken({ req: { headers: { authorization: "token" } } })).toThrow(
12+
/Missing JWT_SECRET environment variable.../,
13+
);
14+
});
15+
});

tests/hasPermission.test.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ describe("Testing hasPermission directive without handler overriding", () => {
99
let client: ApolloServerTestClient;
1010

1111
beforeAll(() => {
12-
const authDirectives = createAuthDirectives();
1312
client = createClient({
1413
typeDefs: gql`
1514
input TestInput {
@@ -23,19 +22,6 @@ describe("Testing hasPermission directive without handler overriding", () => {
2322
protectedMutation(data: TestInput!): String!
2423
}
2524
`,
26-
resolvers: {
27-
Query: {
28-
protectedQuery: (parent, args) =>
29-
`@QUERY Input: ${args.data.input} Protected Input: ${args.data.protectedInput}`,
30-
},
31-
Mutation: {
32-
protectedMutation: (parent, args) =>
33-
`@MUTATION Input: ${args.data.input} Protected Input: ${args.data.protectedInput}`,
34-
},
35-
},
36-
schemaDirectives: {
37-
...authDirectives,
38-
},
3925
});
4026
});
4127

@@ -58,7 +44,7 @@ describe("Testing hasPermission directive without handler overriding", () => {
5844
});
5945

6046
it("should prevent accessing a query without the necessary permissions", async () => {
61-
(getDecodedToken as any) = jest.fn(() => ({ permissions: ["INVALID_PERMISSION"] }));
47+
(getDecodedToken as any) = jest.fn(() => ({ permissions: ["PROTECTED_INPUT"] }));
6248
const res = await client.query({
6349
query: gql`
6450
query protectedQuery($data: TestInput!) {

tests/hasRole.test.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ describe("Testing hasRole directive without handler overriding", () => {
99
let client: ApolloServerTestClient;
1010

1111
beforeAll(() => {
12-
const authDirectives = createAuthDirectives();
1312
client = createClient({
1413
typeDefs: gql`
1514
input TestInput {
16-
input: String! @hasRole(roles: ["USER", "ADMIN", "SUPER_ADMIN"])
15+
input: String!
1716
protectedInput: String @hasRole(roles: ["SUPER_ADMIN"])
1817
}
1918
type Query {
@@ -23,19 +22,6 @@ describe("Testing hasRole directive without handler overriding", () => {
2322
protectedMutation(data: TestInput!): String! @hasRole(roles: ["ADMIN", "SUPER_ADMIN"])
2423
}
2524
`,
26-
resolvers: {
27-
Query: {
28-
protectedQuery: (parent, args) =>
29-
`@QUERY Input: ${args.data.input} Protected Input: ${args.data.protectedInput}`,
30-
},
31-
Mutation: {
32-
protectedMutation: (parent, args) =>
33-
`@MUTATION Input: ${args.data.input} Protected Input: ${args.data.protectedInput}`,
34-
},
35-
},
36-
schemaDirectives: {
37-
...authDirectives,
38-
},
3925
});
4026
});
4127

@@ -58,7 +44,7 @@ describe("Testing hasRole directive without handler overriding", () => {
5844
});
5945

6046
it("should prevent accessing a query without the necessary roles", async () => {
61-
(getDecodedToken as any) = jest.fn(() => ({ roles: ["INVALID_ROLE"] }));
47+
(getDecodedToken as any) = jest.fn(() => ({ roles: ["ADMIN"] }));
6248
const res = await client.query({
6349
query: gql`
6450
query protectedQuery($data: TestInput!) {

tests/isAuthenticated.test.ts

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { ApolloServerTestClient } from "apollo-server-testing";
2+
import gql from "graphql-tag";
3+
import jwt from "jsonwebtoken";
4+
5+
import { createAuthDirectives } from "../src";
6+
import { createClient } from "./utils/createClient";
7+
8+
describe("Testing isAuthenticated directive without handler overriding", () => {
9+
let client: ApolloServerTestClient;
10+
11+
beforeAll(() => {
12+
process.env.JWT_SECRET = "jest";
13+
const token = jwt.sign({}, process.env.JWT_SECRET);
14+
client = createClient(
15+
{
16+
typeDefs: gql`
17+
input TestInput {
18+
input: String!
19+
protectedInput: String @isAuthenticated
20+
}
21+
type Query {
22+
protectedQuery(data: TestInput!): String!
23+
}
24+
type Mutation {
25+
protectedMutation(data: TestInput!): String! @isAuthenticated
26+
}
27+
`,
28+
},
29+
{
30+
req: { headers: { authorization: `Bearer ${token}` } },
31+
},
32+
);
33+
});
34+
35+
afterAll(() => {
36+
delete process.env.JWT_SECRET;
37+
});
38+
39+
it("should allow accessing a query's input authenticated", async () => {
40+
const res = await client.query({
41+
query: gql`
42+
query protectedQuery($data: TestInput!) {
43+
protectedQuery(data: $data)
44+
}
45+
`,
46+
variables: {
47+
data: {
48+
input: "foo",
49+
},
50+
},
51+
});
52+
53+
expect(res.data).toMatchSnapshot();
54+
});
55+
56+
it("should allow accessing a mutation authenticated", async () => {
57+
const res = await client.mutate({
58+
mutation: gql`
59+
mutation protectedMutation($data: TestInput!) {
60+
protectedMutation(data: $data)
61+
}
62+
`,
63+
variables: {
64+
data: {
65+
input: "foo",
66+
},
67+
},
68+
});
69+
70+
expect(res.data).toMatchSnapshot();
71+
});
72+
73+
it("should allow accessing a mutation's input authenticated", async () => {
74+
const res = await client.mutate({
75+
mutation: gql`
76+
mutation protectedMutation($data: TestInput!) {
77+
protectedMutation(data: $data)
78+
}
79+
`,
80+
variables: {
81+
data: {
82+
input: "foo",
83+
protectedInput: "bar",
84+
},
85+
},
86+
});
87+
88+
expect(res.data).toMatchSnapshot();
89+
});
90+
});
91+
92+
describe("Testing isAuthenticated directive with handler overriding", () => {
93+
let client: ApolloServerTestClient;
94+
95+
beforeAll(() => {
96+
const authDirectives = createAuthDirectives({
97+
isAuthenticatedHandler: ctx => {
98+
throw new Error(`Authorization header: ${ctx.req.headers.authorization}`);
99+
},
100+
});
101+
client = createClient(
102+
{
103+
typeDefs: gql`
104+
type Query {
105+
protectedQuery: String! @isAuthenticated
106+
}
107+
`,
108+
resolvers: {
109+
Query: {
110+
protectedQuery: () => "Protected Query",
111+
},
112+
},
113+
schemaDirectives: {
114+
...authDirectives,
115+
},
116+
},
117+
{
118+
req: { headers: { authorization: `Bearer TOKEN` } },
119+
},
120+
);
121+
});
122+
123+
it("should override the isAuthenticated default handler correctly and throw an error", async () => {
124+
const res = await client.query({
125+
query: gql`
126+
{
127+
protectedQuery
128+
}
129+
`,
130+
});
131+
132+
expect(res.errors).toMatchSnapshot();
133+
});
134+
});

tests/utils/createClient.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,35 @@
11
import { ApolloServer, makeExecutableSchema, IExecutableSchemaDefinition } from "apollo-server-express";
22
import { ApolloServerTestClient, createTestClient } from "apollo-server-testing";
33

4-
import { authTypeDefs } from "../../src";
4+
import { authTypeDefs, createAuthDirectives } from "../../src";
55

6-
export const createClient = (schemaDefinition: IExecutableSchemaDefinition<any>): ApolloServerTestClient => {
6+
export const createClient = (
7+
schemaDefinition: IExecutableSchemaDefinition<any>,
8+
additionalContext?: any,
9+
): ApolloServerTestClient => {
10+
const authDirectives = createAuthDirectives();
711
const schema = makeExecutableSchema({
12+
resolvers: {
13+
Query: {
14+
protectedQuery: (parent, args) =>
15+
`@QUERY Input: ${args.data.input} Protected Input: ${args.data.protectedInput}`,
16+
},
17+
Mutation: {
18+
protectedMutation: (parent, args) =>
19+
`@MUTATION Input: ${args.data.input} Protected Input: ${args.data.protectedInput}`,
20+
},
21+
},
22+
schemaDirectives: {
23+
...authDirectives,
24+
},
825
...schemaDefinition,
926
typeDefs: [schemaDefinition.typeDefs as any, authTypeDefs],
1027
});
1128
return createTestClient(
1229
new ApolloServer({
1330
schema,
1431
context(ctx) {
15-
return { ...ctx };
32+
return { ...ctx, ...additionalContext };
1633
},
1734
}),
1835
);

0 commit comments

Comments
 (0)