Skip to content

Commit ffb65a9

Browse files
utkarsh86798sean98
andauthored
Overall test code coverage and code reliability (#39)
* #36: works towards making the code type-safe * #38: add remark String field to booking datamodel * #38: add remark field to booking mutation resolvers * #36: adds tests for user queries, refactors code for making test server * #36: adds eslint configs and fixes linting issues * #36: adds tests for bookings query Co-authored-by: Sean Chok <[email protected]>
1 parent af07e33 commit ffb65a9

24 files changed

+1115
-195
lines changed

.eslintignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
dist
3+
/src/generated

.eslintrc.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
root: true,
3+
parser: "@typescript-eslint/parser",
4+
plugins: ["@typescript-eslint", "jest", "prettier"],
5+
extends: [
6+
"eslint:recommended",
7+
"plugin:@typescript-eslint/eslint-recommended",
8+
"plugin:@typescript-eslint/recommended",
9+
"plugin:jest/recommended",
10+
"prettier",
11+
"prettier/@typescript-eslint",
12+
],
13+
rules: {
14+
"@typescript-eslint/camelcase": "off",
15+
},
16+
};

__tests__/bookings.ts

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import * as env from "dotenv";
2+
import { createTestServerWithUserLoggedIn } from "./utils/server";
3+
import { Room, User } from "../src/generated/prisma-client";
4+
import { createTestClient } from "apollo-server-testing";
5+
import { createUser, deleteUsers } from "./utils/users";
6+
import { createRoom, deleteRooms } from "./utils/rooms";
7+
import { createBooking, deleteBookings } from "./utils/bookings";
8+
import { GraphQLResponse } from "apollo-server-types";
9+
10+
env.config();
11+
12+
const testUserInfo = {
13+
username: "test123",
14+
15+
image_url: "http://url",
16+
phone: "12345678",
17+
first_name: "Test",
18+
last_name: "Test",
19+
room_no: "111A",
20+
};
21+
22+
const testRoomInfo: Room = {
23+
id: "",
24+
number: "123",
25+
name: "test",
26+
};
27+
28+
const testBookingInfo = {
29+
user: "test123",
30+
room: "123",
31+
start: new Date(),
32+
end: new Date(),
33+
remark: "Hello",
34+
};
35+
36+
describe("Booking queries", () => {
37+
test("can query all bookings", async () => {
38+
// Create a sample user that will make the booking
39+
await deleteUsers();
40+
await deleteRooms();
41+
await deleteBookings();
42+
43+
// Create user in the database
44+
const user: User = await createUser(testUserInfo);
45+
const testServer = await createTestServerWithUserLoggedIn(user);
46+
// Create a test client connected to the test server
47+
const client = createTestClient(testServer);
48+
//Create the required rooms
49+
await createRoom(testRoomInfo);
50+
// Create a test client connected to the test server
51+
// Create a booking
52+
await createBooking(testBookingInfo);
53+
const query = `{
54+
bookings{
55+
user {
56+
username
57+
}
58+
room {
59+
number
60+
}
61+
start
62+
end
63+
remark
64+
}
65+
}`;
66+
const result: GraphQLResponse = await client.query({ query });
67+
expect(result.data).toEqual({
68+
bookings: [
69+
{
70+
user: {
71+
username: testUserInfo.username,
72+
},
73+
room: {
74+
number: testRoomInfo.number,
75+
},
76+
start: testBookingInfo.start.toISOString(),
77+
end: testBookingInfo.end.toISOString(),
78+
remark: testBookingInfo.remark,
79+
},
80+
],
81+
});
82+
await deleteUsers();
83+
await deleteRooms();
84+
await deleteBookings();
85+
});
86+
});

__tests__/users.ts

+44-54
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
import * as env from "dotenv";
2-
env.config();
3-
4-
import { prisma } from "../src/generated/prisma-client";
2+
import { User } from "../src/generated/prisma-client";
53
import testServer from "../src/server";
64
import { createTestClient } from "apollo-server-testing";
5+
import { createTestServerWithToken } from "./utils/server";
6+
import { generateToken } from "../src/utils/authToken";
7+
import { GraphQLResponse } from "apollo-server-types";
8+
import { createUser, createUserSession, deleteUsers } from "./utils/users";
79

8-
const createUser = async user => {
9-
await prisma.createUser(user);
10-
};
11-
12-
const deleteUsers = async () => {
13-
await prisma.deleteManyBookings({});
14-
await prisma.deleteManyRooms({});
15-
return prisma.deleteManyUsers({});
16-
};
10+
env.config();
1711

1812
const testUserInfo = {
1913
username: "test123",
20-
email: "test@gmail.com",
14+
email: "test@connect.hku.hk",
2115
image_url: "http://url",
2216
phone: "12345678",
2317
first_name: "Test",
@@ -26,10 +20,15 @@ const testUserInfo = {
2620
};
2721

2822
beforeAll(async () => await deleteUsers());
23+
2924
describe("User query and mutations", () => {
30-
test("can query user", async done => {
25+
/**
26+
* @author utkarsh867
27+
*/
28+
test("can query user", async () => {
3129
await deleteUsers();
3230
await createUser(testUserInfo);
31+
3332
const client = createTestClient(testServer);
3433
const userQuery = `{
3534
user (username: "${testUserInfo.username}") {
@@ -38,7 +37,7 @@ describe("User query and mutations", () => {
3837
last_name,
3938
room_no
4039
}}`;
41-
const result = await client.query({ query: userQuery });
40+
const result: GraphQLResponse = await client.query({ query: userQuery });
4241
expect(result.data).toEqual({
4342
user: {
4443
username: testUserInfo.username,
@@ -48,49 +47,40 @@ describe("User query and mutations", () => {
4847
},
4948
});
5049
await deleteUsers();
51-
done();
5250
});
53-
test("can add user", async done => {
54-
await deleteUsers();
55-
const client = createTestClient(testServer);
56-
const userMutation = `mutation addUser
57-
{
58-
createUser(
59-
username: "${testUserInfo.username}",
60-
email: "${testUserInfo.email}",
61-
image_url:"${testUserInfo.image_url}",
62-
phone: "${testUserInfo.phone}",
63-
first_name:"${testUserInfo.first_name}",
64-
last_name:"${testUserInfo.last_name}",
65-
room_no:"${testUserInfo.room_no}"
66-
){
67-
username
68-
}
69-
}`;
70-
await client.mutate({ mutation: userMutation });
71-
const userQueryResult = await prisma.user({
72-
username: testUserInfo.username,
73-
});
74-
expect(userQueryResult).toMatchObject(testUserInfo);
75-
await deleteUsers();
76-
done();
77-
});
78-
test("can delete user", async done => {
51+
52+
/**
53+
* @author utkarsh867
54+
*/
55+
test("can resolve user from the session", async () => {
7956
await deleteUsers();
57+
// Create user in the database
58+
const user: User = await createUser(testUserInfo);
59+
// Create the user session (bypass login)
60+
const userSession = await createUserSession(user);
61+
// Generate a token for the session
62+
const token = generateToken(userSession);
63+
// Create a test server from the token
64+
const testServer = createTestServerWithToken(token);
65+
// Create a test client connected to the test server
8066
const client = createTestClient(testServer);
81-
await createUser(testUserInfo);
82-
const userDeleteMutation = `
83-
mutation delete{
84-
deleteUser(username: "${testUserInfo.username}"){
85-
username
86-
}
87-
}`;
88-
await client.mutate({ mutation: userDeleteMutation });
89-
const userQueryResult = await prisma.user({
90-
username: testUserInfo.username,
67+
68+
// Make a request to resolve the user
69+
const query = `{
70+
me {
71+
id
72+
}
73+
}`;
74+
const response: GraphQLResponse = await client.query({ query });
75+
76+
// Check if the user from the query is correct
77+
expect(response.data).toEqual({
78+
me: {
79+
id: user.id,
80+
},
9181
});
92-
expect(userQueryResult).toEqual(null);
82+
83+
// Cleanup after the test
9384
await deleteUsers();
94-
done();
9585
});
9686
});

__tests__/utils/bookings.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as env from "dotenv";
2+
import {
3+
BatchPayloadPromise,
4+
Booking,
5+
prisma,
6+
} from "../../src/generated/prisma-client";
7+
8+
env.config();
9+
10+
export const createBooking = (testBookingInfo: any): Promise<Booking> => {
11+
return prisma.createBooking({
12+
start: testBookingInfo.start,
13+
end: testBookingInfo.end,
14+
room: {
15+
connect: {
16+
number: testBookingInfo.room,
17+
},
18+
},
19+
user: {
20+
connect: {
21+
username: testBookingInfo.user,
22+
},
23+
},
24+
remark: testBookingInfo.remark,
25+
});
26+
};
27+
28+
export const deleteBookings = (): BatchPayloadPromise => {
29+
return prisma.deleteManyBookings({});
30+
};

__tests__/utils/rooms.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as env from "dotenv";
2+
import {
3+
BatchPayloadPromise,
4+
prisma,
5+
Room,
6+
} from "../../src/generated/prisma-client";
7+
env.config();
8+
export const createRoom = (room: Room): Promise<Room> => {
9+
return prisma.createRoom({
10+
name: room.name,
11+
number: room.number,
12+
});
13+
};
14+
15+
export const deleteRooms = (): BatchPayloadPromise => {
16+
return prisma.deleteManyRooms({});
17+
};

__tests__/utils/server.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { ApolloServer } from "apollo-server-express";
2+
import * as env from "dotenv";
3+
import typeDefs from "../../src/schema";
4+
import resolvers from "../../src/resolvers";
5+
import { prisma } from "../../src/generated/prisma-client";
6+
import { createUserSession } from "./users";
7+
import { generateToken } from "../../src/utils/authToken";
8+
9+
env.config();
10+
11+
export const createTestServerWithToken = (token): ApolloServer => {
12+
return new ApolloServer({
13+
typeDefs,
14+
resolvers,
15+
context: (): object => ({
16+
prisma,
17+
token,
18+
}),
19+
});
20+
};
21+
22+
export const createTestServerWithUserLoggedIn = async (
23+
user
24+
): Promise<ApolloServer> => {
25+
const userSession = await createUserSession(user);
26+
// Generate a token for the session
27+
const token = generateToken(userSession);
28+
//Create a test server
29+
return createTestServerWithToken(token);
30+
};

__tests__/utils/users.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import * as env from "dotenv";
2+
import {
3+
BatchPayload,
4+
prisma,
5+
User,
6+
UserSessions,
7+
} from "../../src/generated/prisma-client";
8+
9+
env.config();
10+
11+
export const createUser = (user): Promise<User> => {
12+
return prisma.createUser(user);
13+
};
14+
15+
export const deleteUsers = (): Promise<BatchPayload> => {
16+
return prisma.deleteManyUsers({});
17+
};
18+
19+
export const createUserSession = (user: User): Promise<UserSessions> => {
20+
return prisma.createUserSessions({
21+
user: {
22+
connect: {
23+
id: user.id,
24+
},
25+
},
26+
});
27+
};

0 commit comments

Comments
 (0)