From 695c4e20be9c6a0a5c80db81a7549f2c5f87461d Mon Sep 17 00:00:00 2001 From: Charlie Astrada Date: Mon, 10 May 2021 18:21:12 -0300 Subject: [PATCH] Update user resolver tests to be more robust and have higher confidence Previously, the apollo-server-testing was used for the tests. This had key limitations, such as non-access to context without a low-confidence workaround (see https://github.com/apollographql/apollo-server/issues/2277 fof more info). This limitation also made creating some tests, such as ?should return current user if logged in" impossible. To resolve, migrate to https://github.com/zapier/apollo-server-integration-testing and create the tests that were previously impossible. * Update queries-mutations constant with queries/mutations for new tests * refactor the user.test file to remove old approach * add missing test coverage --- server/dist/resolvers/user.test.js | 128 ++++++--- server/dist/resolvers/user.test.js.map | 2 +- server/dist/test-utils/queries-mutations.js | 55 ++-- .../dist/test-utils/queries-mutations.js.map | 2 +- server/dist/utils/validations.js | 1 + server/dist/utils/validations.js.map | 1 + server/src/resolvers/user.test.ts | 272 +++++++++++------- server/src/test-utils/queries-mutations.ts | 57 ++-- 8 files changed, 338 insertions(+), 180 deletions(-) create mode 100644 server/dist/utils/validations.js create mode 100644 server/dist/utils/validations.js.map diff --git a/server/dist/resolvers/user.test.js b/server/dist/resolvers/user.test.js index f31640e..d624a65 100644 --- a/server/dist/resolvers/user.test.js +++ b/server/dist/resolvers/user.test.js @@ -8,19 +8,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const apollo_server_testing_1 = require("apollo-server-testing"); -require("reflect-metadata"); -const testConn_1 = require("../test-utils/testConn"); const apollo_server_express_1 = require("apollo-server-express"); -const createSchema_1 = require("../utils/createSchema"); +const apollo_server_integration_testing_1 = require("apollo-server-integration-testing"); +const ioredis_1 = __importDefault(require("ioredis")); +require("reflect-metadata"); const User_1 = require("../entities/User"); const factories_1 = require("../test-utils/factories"); const queries_mutations_1 = require("../test-utils/queries-mutations"); +const testConn_1 = require("../test-utils/testConn"); +const createSchema_1 = require("../utils/createSchema"); +const sendEmail_1 = require("../utils/sendEmail"); +jest.mock("../utils/sendEmail", () => { + return { + sendEmail: jest.fn(), + }; +}); let dbConn; let em; -let server; -describe("Transaction Resolver", () => { +let apolloServer; +let testClientQuery; +let testClientMutate; +let testClientSetOptions; +describe("User Resolver", () => { describe("Happy Path", () => { test("should register a new user successfully ", () => __awaiter(void 0, void 0, void 0, function* () { var _a, _b, _c; @@ -35,17 +48,16 @@ describe("Transaction Resolver", () => { expect((_c = registeredUserResponse.user) === null || _c === void 0 ? void 0 : _c.username).toBe(dbUser === null || dbUser === void 0 ? void 0 : dbUser.username); })); test("should log in a new user successfully with username ", () => __awaiter(void 0, void 0, void 0, function* () { - const { mutate } = server; + var _d; const user = factories_1.genUserOptions(); yield registerUser(user.username, user.password, user.email); - const response = yield mutate({ - mutation: queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, + const response = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, { variables: { usernameOrEmail: user.username, password: user.password, }, }); - const loginResponse = response.data.login; + const loginResponse = (_d = response.data) === null || _d === void 0 ? void 0 : _d.login; const loggedInUser = loginResponse.user; const dbUser = yield em.findOne(User_1.User, { id: loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.id, @@ -55,17 +67,16 @@ describe("Transaction Resolver", () => { expect(loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.id).toBe(dbUser === null || dbUser === void 0 ? void 0 : dbUser.id); })); test("should log in a new user successfully with email ", () => __awaiter(void 0, void 0, void 0, function* () { - const { mutate } = server; + var _e; const user = factories_1.genUserOptions(); yield registerUser(user.username, user.password, user.email); - const response = yield mutate({ - mutation: queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, + const response = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, { variables: { usernameOrEmail: user.email, password: user.password, }, }); - const loginResponse = response.data.login; + const loginResponse = (_e = response.data) === null || _e === void 0 ? void 0 : _e.login; const loggedInUser = loginResponse.user; const dbUser = yield em.findOne(User_1.User, { id: loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.id, @@ -74,9 +85,46 @@ describe("Transaction Resolver", () => { expect(loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.username).toBe(user.username); expect(loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.id).toBe(dbUser === null || dbUser === void 0 ? void 0 : dbUser.id); })); - xtest("should return current user if logged in", () => __awaiter(void 0, void 0, void 0, function* () { + test("should return current user if logged in", () => __awaiter(void 0, void 0, void 0, function* () { + var _f, _g; + const userOptions = factories_1.genUserOptions(); + yield registerUser(userOptions.username, userOptions.password, userOptions.email); + const response = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, { + variables: { + usernameOrEmail: userOptions.username, + password: userOptions.password, + }, + }); + const loginResponse = (_f = response.data) === null || _f === void 0 ? void 0 : _f.login; + const loggedInUser = loginResponse.user; + const res = yield testClientQuery(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.ME); + const me = (_g = res.data) === null || _g === void 0 ? void 0 : _g.me; + expect(me.id).toBe(loggedInUser === null || loggedInUser === void 0 ? void 0 : loggedInUser.id); + })); + test("should log out a user successfull ", () => __awaiter(void 0, void 0, void 0, function* () { + var _h; + testClientSetOptions({ + request: { + session: { + destroy: jest.fn((cb) => cb()), + }, + }, + }); + const user = factories_1.genUserOptions(); + yield registerUser(user.username, user.password, user.email); + const logoutResponse = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGOUT); + expect((_h = logoutResponse.data) === null || _h === void 0 ? void 0 : _h.logout).toBe(true); + })); + test("should send a forgot password email if requested ", () => __awaiter(void 0, void 0, void 0, function* () { + var _j; + const user = factories_1.genUserOptions(); + yield registerUser(user.username, user.password, user.email); + const forgotPasswordResponse = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.FORGOT_PASSWORD, { + variables: { email: user.email }, + }); + expect(sendEmail_1.sendEmail).toHaveBeenCalledTimes(1); + expect((_j = forgotPasswordResponse.data) === null || _j === void 0 ? void 0 : _j.forgotPassword).toBe(true); })); - xtest("should log out a user successfull ", () => { }); }); describe("Registration Validations", () => { test("should not permit registration with username with lengths <= 2", () => __awaiter(void 0, void 0, void 0, function* () { @@ -143,59 +191,56 @@ describe("Transaction Resolver", () => { }); describe("Login Validations", () => { test("should not permit login with incorrect username", () => __awaiter(void 0, void 0, void 0, function* () { - const { mutate } = server; + var _a; const defaultUserOptions = factories_1.genUserOptions(); const newUser = Object.assign(Object.assign({}, defaultUserOptions), { username: "nonexistent" }); const expectedErrors = [ { field: "usernameOrEmail", message: "user does not exist!" }, ]; - const response = yield mutate({ - mutation: queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, + const response = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, { variables: { usernameOrEmail: newUser.username, password: newUser.password, }, }); - const loginResponse = response.data.login; + const loginResponse = (_a = response.data) === null || _a === void 0 ? void 0 : _a.login; const errors = loginResponse.errors; expect(loginResponse.user).toBe(null); expect(errors).not.toBe(null); expect(errors).toEqual(expect.arrayContaining(expectedErrors)); })); test("should not permit login with incorrect email", () => __awaiter(void 0, void 0, void 0, function* () { - const { mutate } = server; + var _b; const defaultUserOptions = factories_1.genUserOptions(); const newUser = Object.assign(Object.assign({}, defaultUserOptions), { email: "incorrectemail@test.com" }); const expectedErrors = [ { field: "usernameOrEmail", message: "user does not exist!" }, ]; - const response = yield mutate({ - mutation: queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, + const response = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, { variables: { usernameOrEmail: newUser.email, password: newUser.password, }, }); - const loginResponse = response.data.login; + const loginResponse = (_b = response.data) === null || _b === void 0 ? void 0 : _b.login; const errors = loginResponse.errors; expect(loginResponse.user).toBe(null); expect(errors).not.toBe(null); expect(errors).toEqual(expect.arrayContaining(expectedErrors)); })); test("should not permit login with incorrect password", () => __awaiter(void 0, void 0, void 0, function* () { - const { mutate } = server; + var _c; const userToRegister = factories_1.genUserOptions(); yield registerUser(userToRegister.username, userToRegister.password, userToRegister.email); const userWrongPassword = Object.assign(Object.assign({}, userToRegister), { password: "wrongpassword" }); const expectedErrors = [{ field: "password", message: "Invalid login!" }]; - const response = yield mutate({ - mutation: queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, + const response = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.LOGIN, { variables: { usernameOrEmail: userWrongPassword.username, password: userWrongPassword.password, }, }); - const loginResponse = response.data.login; + const loginResponse = (_c = response.data) === null || _c === void 0 ? void 0 : _c.login; const errors = loginResponse.errors; expect(loginResponse.user).toBe(null); expect(errors).not.toBe(null); @@ -206,32 +251,39 @@ describe("Transaction Resolver", () => { beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { dbConn = yield testConn_1.testConn(); em = dbConn.em; - const apolloServer = new apollo_server_express_1.ApolloServer({ + const redis = new ioredis_1.default(); + apolloServer = new apollo_server_express_1.ApolloServer({ schema: yield createSchema_1.createSchema(), - context: () => ({ - em, - req: { session: {} }, - }), + context: ({ req, res }) => ({ em, req, res, redis }), + }); + const { query, mutate, setOptions } = apollo_server_integration_testing_1.createTestClient({ + apolloServer, + extendMockRequest: { + session: { + userId: null, + }, + }, }); - server = apollo_server_testing_1.createTestClient(apolloServer); + testClientMutate = mutate; + testClientQuery = query; + testClientSetOptions = setOptions; yield em.nativeDelete(User_1.User, {}); })); afterAll(() => __awaiter(void 0, void 0, void 0, function* () { yield dbConn.close(); })); function registerUser(username, password, email) { + var _a; return __awaiter(this, void 0, void 0, function* () { - const { mutate } = server; const userToCreate = { username, password, email, }; - const response = yield mutate({ - mutation: queries_mutations_1.USER_QUERIES_AND_MUTATIONS.REGISTER, + const response = yield testClientMutate(queries_mutations_1.USER_QUERIES_AND_MUTATIONS.REGISTER, { variables: { options: userToCreate }, }); - const userResponse = response.data.register; + const userResponse = (_a = response.data) === null || _a === void 0 ? void 0 : _a.register; return userResponse; }); } diff --git a/server/dist/resolvers/user.test.js.map b/server/dist/resolvers/user.test.js.map index 54bc1a9..4eefbd0 100644 --- a/server/dist/resolvers/user.test.js.map +++ b/server/dist/resolvers/user.test.js.map @@ -1 +1 @@ -{"version":3,"file":"user.test.js","sourceRoot":"","sources":["../../src/resolvers/user.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"user.test.js","sourceRoot":"","sources":["../../src/resolvers/user.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/server/dist/test-utils/queries-mutations.js b/server/dist/test-utils/queries-mutations.js index 5a1d7ba..8cd475a 100644 --- a/server/dist/test-utils/queries-mutations.js +++ b/server/dist/test-utils/queries-mutations.js @@ -2,21 +2,24 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.USER_QUERIES_AND_MUTATIONS = exports.TXN_QUERIES_AND_MUTATIONS = void 0; exports.TXN_QUERIES_AND_MUTATIONS = { - GET_ALL_TXNS: `query allTransactions{ - transactions { + CREATE_TXN: `mutation createTransaction($title:String!){ + createTransaction(title:$title) { id title createdAt updatedAt - } }`, - CREATE_TXN: `mutation createTransaction($title:String!){ - createTransaction(title:$title) { + DELETE_TXN: `mutation deleteTransaction($id:String!){ +deleteTransaction(id:$id) +}`, + GET_ALL_TXNS: `query allTransactions{ + transactions { id title createdAt updatedAt + } }`, GET_TXN: `query getTransactionById($id:String!) { @@ -34,28 +37,25 @@ exports.TXN_QUERIES_AND_MUTATIONS = { createdAt updatedAt } -}`, - DELETE_TXN: `mutation deleteTransaction($id:String!){ - deleteTransaction(id:$id) }`, }; exports.USER_QUERIES_AND_MUTATIONS = { - REGISTER: `mutation register($options: UsernamePasswordInput!) { - register(options: $options) { - user { - id - createdAt - updatedAt - username - } + CHANGE_PASSWORD: `mutation ChangePassword($token: String!, $newPassword: String!) { + ChangePassword(token: $token, newPassword: $newPassword) { errors { field message } + user { + id + username + } } } - `, + FORGOT_PASSWORD: `mutation ForgotPassword($email:String!) { + forgotPassword(email:$email ) +}`, LOGIN: `mutation Login($usernameOrEmail: String!, $password: String!) { login(usernameOrEmail: $usernameOrEmail, password: $password) { errors { @@ -67,15 +67,32 @@ exports.USER_QUERIES_AND_MUTATIONS = { username } } -} - +}, `, + LOGOUT: `mutation Logout{ + logout +}`, ME: `query me { me { id username } } +`, + REGISTER: `mutation register($options: UsernamePasswordInput!) { + register(options: $options) { + user { + id + createdAt + updatedAt + username + } + errors { + field + message + } + } +} `, }; //# sourceMappingURL=queries-mutations.js.map \ No newline at end of file diff --git a/server/dist/test-utils/queries-mutations.js.map b/server/dist/test-utils/queries-mutations.js.map index bb7cf0b..bf4e2a8 100644 --- a/server/dist/test-utils/queries-mutations.js.map +++ b/server/dist/test-utils/queries-mutations.js.map @@ -1 +1 @@ -{"version":3,"file":"queries-mutations.js","sourceRoot":"","sources":["../../src/test-utils/queries-mutations.ts"],"names":[],"mappings":";;;AAAa,QAAA,yBAAyB,GAAG;IACvC,YAAY,EAAE;;;;;;;;EAQd;IACA,UAAU,EAAE;;;;;;;EAOZ;IACA,OAAO,EAAE;;;;;;;EAOT;IACA,UAAU,EAAE;;;;;;;EAOZ;IACA,UAAU,EAAE;;EAEZ;CACD,CAAC;AAEW,QAAA,0BAA0B,GAAG;IACxC,QAAQ,EAAE;;;;;;;;;;;;;;;CAeX;IACC,KAAK,EAAE;;;;;;;;;;;;;CAaR;IACC,EAAE,EAAE;;;;;;CAML;CACA,CAAC"} \ No newline at end of file +{"version":3,"file":"queries-mutations.js","sourceRoot":"","sources":["../../src/test-utils/queries-mutations.ts"],"names":[],"mappings":";;;AAAa,QAAA,yBAAyB,GAAG;IACvC,UAAU,EAAE;;;;;;;EAOZ;IACA,UAAU,EAAE;;EAEZ;IACA,YAAY,EAAE;;;;;;;;EAQd;IACA,OAAO,EAAE;;;;;;;EAOT;IAEA,UAAU,EAAE;;;;;;;EAOZ;CACD,CAAC;AAEW,QAAA,0BAA0B,GAAG;IACxC,eAAe,EAAE;;;;;;;;;;;;CAYlB;IACC,eAAe,EAAE;;EAEjB;IAEA,KAAK,EAAE;;;;;;;;;;;;CAYR;IACC,MAAM,EAAE;;EAER;IACA,EAAE,EAAE;;;;;;CAML;IACC,QAAQ,EAAE;;;;;;;;;;;;;;CAcX;CACA,CAAC"} \ No newline at end of file diff --git a/server/dist/utils/validations.js b/server/dist/utils/validations.js new file mode 100644 index 0000000..c3654d0 --- /dev/null +++ b/server/dist/utils/validations.js @@ -0,0 +1 @@ +//# sourceMappingURL=validations.js.map \ No newline at end of file diff --git a/server/dist/utils/validations.js.map b/server/dist/utils/validations.js.map new file mode 100644 index 0000000..a86e244 --- /dev/null +++ b/server/dist/utils/validations.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validations.js","sourceRoot":"","sources":["../../src/utils/validations.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/server/src/resolvers/user.test.ts b/server/src/resolvers/user.test.ts index f04216c..997ea1d 100644 --- a/server/src/resolvers/user.test.ts +++ b/server/src/resolvers/user.test.ts @@ -1,29 +1,41 @@ -import { - createTestClient, - ApolloServerTestClient, -} from "apollo-server-testing"; - -import "reflect-metadata"; import { Connection, EntityManager, IDatabaseDriver, MikroORM, } from "@mikro-orm/core"; - -import { testConn } from "../test-utils/testConn"; import { ApolloServer } from "apollo-server-express"; -import { createSchema } from "../utils/createSchema"; -import { UserResponse } from "./user"; +import { + createTestClient, + TestQuery, + TestSetOptions, +} from "apollo-server-integration-testing"; +import Redis from "ioredis"; + +import "reflect-metadata"; import { User } from "../entities/User"; import { genUserOptions } from "../test-utils/factories"; import { USER_QUERIES_AND_MUTATIONS } from "../test-utils/queries-mutations"; +import { testConn } from "../test-utils/testConn"; +import { Context } from "../types/context"; +import { createSchema } from "../utils/createSchema"; +import { UserResponse } from "./user"; +import { sendEmail } from "../utils/sendEmail"; + +jest.mock("../utils/sendEmail", () => { + return { + sendEmail: jest.fn(), + }; +}); let dbConn: MikroORM>; let em: EntityManager>; //entity manager for ORM -let server: ApolloServerTestClient; +let apolloServer: ApolloServer; +let testClientQuery: TestQuery; +let testClientMutate: TestQuery; +let testClientSetOptions: TestSetOptions; -describe("Transaction Resolver", () => { +describe("User Resolver", () => { describe("Happy Path", () => { test("should register a new user successfully ", async () => { //Arrange @@ -48,21 +60,21 @@ describe("Transaction Resolver", () => { }); test("should log in a new user successfully with username ", async () => { //ARRANGE - const { mutate } = server; - - //[ARRANGE] Register user that will be logged in const user = genUserOptions(); await registerUser(user.username, user.password, user.email); - const response = await mutate({ - mutation: USER_QUERIES_AND_MUTATIONS.LOGIN, - variables: { - usernameOrEmail: user.username, - password: user.password, - }, - }); + //ACT + const response = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.LOGIN, + { + variables: { + usernameOrEmail: user.username, + password: user.password, + }, + } + ); - const loginResponse: UserResponse = response.data.login; + const loginResponse: UserResponse = response.data?.login; const loggedInUser = loginResponse.user; const dbUser = await em.findOne(User, { @@ -76,21 +88,21 @@ describe("Transaction Resolver", () => { }); test("should log in a new user successfully with email ", async () => { //ARRANGE - const { mutate } = server; - - //[ARRANGE] Register user that will be logged in const user = genUserOptions(); await registerUser(user.username, user.password, user.email); - const response = await mutate({ - mutation: USER_QUERIES_AND_MUTATIONS.LOGIN, - variables: { - usernameOrEmail: user.email, - password: user.password, - }, - }); + //ACT + const response = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.LOGIN, + { + variables: { + usernameOrEmail: user.email, + password: user.password, + }, + } + ); - const loginResponse: UserResponse = response.data.login; + const loginResponse: UserResponse = response.data?.login; const loggedInUser = loginResponse.user; const dbUser = await em.findOne(User, { @@ -102,33 +114,81 @@ describe("Transaction Resolver", () => { expect(loggedInUser?.username).toBe(user.username); expect(loggedInUser?.id).toBe(dbUser?.id); }); - xtest("should return current user if logged in", async () => { - // //session cookie set on user's machine if logged in. - // //session exists if cookie exists - // //ARRANGE - // const { query, mutate } = server; - // const userOptions = genUserOptions(); - // await registerUser(userOptions.username, userOptions.password); - // const response = await mutate({ - // mutation: USER_QUERIES_AND_MUTATIONS.LOGIN, - // variables: { - // options: { - // username: userOptions.username, - // password: userOptions.password, - // }, - // }, - // }); - // const loginResponse: UserResponse = response.data.login; - // const loggedInUser = loginResponse.user; - // //ACT - // const res = await query({ - // query: USER_QUERIES_AND_MUTATIONS.ME, - // }); - // // console.log(res.data.me); - // //ASSERT - // expect(true).toBe(true); - }); //TODO: write log in test - xtest("should log out a user successfull ", () => {}); //TODO: Write log out test + test("should return current user if logged in", async () => { + //session cookie set on user's machine if logged in. + //session exists if cookie exists + //ARRANGE + const userOptions = genUserOptions(); + await registerUser( + userOptions.username, + userOptions.password, + userOptions.email + ); + + const response = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.LOGIN, + { + variables: { + usernameOrEmail: userOptions.username, + password: userOptions.password, + }, + } + ); + + const loginResponse: UserResponse = response.data?.login; + const loggedInUser = loginResponse.user; + + //ACT + const res = await testClientQuery(USER_QUERIES_AND_MUTATIONS.ME); + const me = res.data?.me; + + //ASSERT + expect(me.id).toBe(loggedInUser?.id); + }); + test("should log out a user successfull ", async () => { + //ARRANGE + //Set mocks + testClientSetOptions({ + request: { + session: { + destroy: jest.fn((cb) => cb()), + }, + }, + }); + //gen random user + const user = genUserOptions(); + + //register new user, which logs in automatically by default + await registerUser(user.username, user.password, user.email); + + //ACT + const logoutResponse = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.LOGOUT + ); + + //assert + expect(logoutResponse.data?.logout).toBe(true); + }); + test("should send a forgot password email if requested ", async () => { + //ARRANGE + //gen random user + const user = genUserOptions(); + + //register new user + await registerUser(user.username, user.password, user.email); + + //ACT + const forgotPasswordResponse = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.FORGOT_PASSWORD, + { + variables: { email: user.email }, + } + ); + + //assert + expect(sendEmail).toHaveBeenCalledTimes(1); + expect(forgotPasswordResponse.data?.forgotPassword).toBe(true); + }); }); describe("Registration Validations", () => { @@ -250,7 +310,6 @@ describe("Transaction Resolver", () => { describe("Login Validations", () => { test("should not permit login with incorrect username", async () => { //ARRANGE - const { mutate } = server; const defaultUserOptions = genUserOptions(); const newUser = { ...defaultUserOptions, username: "nonexistent" }; const expectedErrors = [ @@ -258,15 +317,17 @@ describe("Transaction Resolver", () => { ]; //ACT - const response = await mutate({ - mutation: USER_QUERIES_AND_MUTATIONS.LOGIN, - variables: { - usernameOrEmail: newUser.username, - password: newUser.password, - }, - }); + const response = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.LOGIN, + { + variables: { + usernameOrEmail: newUser.username, + password: newUser.password, + }, + } + ); - const loginResponse: UserResponse = response.data.login; + const loginResponse: UserResponse = response.data?.login; const errors = loginResponse.errors; //ASSERT @@ -276,7 +337,6 @@ describe("Transaction Resolver", () => { }); test("should not permit login with incorrect email", async () => { //ARRANGE - const { mutate } = server; const defaultUserOptions = genUserOptions(); const newUser = { ...defaultUserOptions, @@ -287,15 +347,17 @@ describe("Transaction Resolver", () => { ]; //ACT - const response = await mutate({ - mutation: USER_QUERIES_AND_MUTATIONS.LOGIN, - variables: { - usernameOrEmail: newUser.email, - password: newUser.password, - }, - }); + const response = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.LOGIN, + { + variables: { + usernameOrEmail: newUser.email, + password: newUser.password, + }, + } + ); - const loginResponse: UserResponse = response.data.login; + const loginResponse: UserResponse = response.data?.login; const errors = loginResponse.errors; //ASSERT @@ -305,7 +367,6 @@ describe("Transaction Resolver", () => { }); test("should not permit login with incorrect password", async () => { //ARRANGE - const { mutate } = server; const userToRegister = genUserOptions(); //register user with a username + password await registerUser( @@ -322,15 +383,17 @@ describe("Transaction Resolver", () => { const expectedErrors = [{ field: "password", message: "Invalid login!" }]; //ACT - const response = await mutate({ - mutation: USER_QUERIES_AND_MUTATIONS.LOGIN, - variables: { - usernameOrEmail: userWrongPassword.username, - password: userWrongPassword.password, - }, - }); + const response = await testClientMutate( + USER_QUERIES_AND_MUTATIONS.LOGIN, + { + variables: { + usernameOrEmail: userWrongPassword.username, + password: userWrongPassword.password, + }, + } + ); - const loginResponse: UserResponse = response.data.login; + const loginResponse: UserResponse = response.data?.login; const errors = loginResponse.errors; //ASSERT @@ -346,19 +409,26 @@ beforeAll(async () => { dbConn = await testConn(); em = dbConn.em; - //TODO: in order to inject context, you need to make creating a test server something you can invoke FOR EACH test - //Check https://github.com/apollographql/fullstack-tutorial/blob/b25df2e9fd45ec5bcd07e4c2f34b79b7a8bd0817/final/server/src/__tests__/__utils.js#L21 - //TODO: Or just re-write using this project which solves the req in context issue: https://github.com/zapier/apollo-server-integration-testing - //Setup an Apollo test server - const apolloServer = new ApolloServer({ + const redis = new Redis(); + + apolloServer = new ApolloServer({ schema: await createSchema(), - context: () => ({ - em, - req: { session: {} }, - }), //TODO is this the best way? + context: ({ req, res }): Context => ({ em, req, res, redis }), + }); + + const { query, mutate, setOptions } = createTestClient({ + apolloServer, + extendMockRequest: { + session: { + userId: null, + }, + }, }); - server = createTestClient(apolloServer); + //Set values to variables for use in other tests + testClientMutate = mutate; + testClientQuery = query; + testClientSetOptions = setOptions; await em.nativeDelete(User, {}); //clear all users in test db }); @@ -368,19 +438,17 @@ afterAll(async () => { }); async function registerUser(username: string, password: string, email: string) { - const { mutate } = server; const userToCreate = { username, password, email, }; - const response = await mutate({ - mutation: USER_QUERIES_AND_MUTATIONS.REGISTER, + const response = await testClientMutate(USER_QUERIES_AND_MUTATIONS.REGISTER, { variables: { options: userToCreate }, }); - const userResponse: UserResponse = response.data.register; + const userResponse: UserResponse = response.data?.register; //TODO: Fix this type error return userResponse; } diff --git a/server/src/test-utils/queries-mutations.ts b/server/src/test-utils/queries-mutations.ts index 12d4c66..4f00bf4 100644 --- a/server/src/test-utils/queries-mutations.ts +++ b/server/src/test-utils/queries-mutations.ts @@ -1,19 +1,22 @@ export const TXN_QUERIES_AND_MUTATIONS = { - GET_ALL_TXNS: `query allTransactions{ - transactions { + CREATE_TXN: `mutation createTransaction($title:String!){ + createTransaction(title:$title) { id title createdAt updatedAt - } }`, - CREATE_TXN: `mutation createTransaction($title:String!){ - createTransaction(title:$title) { + DELETE_TXN: `mutation deleteTransaction($id:String!){ +deleteTransaction(id:$id) +}`, + GET_ALL_TXNS: `query allTransactions{ + transactions { id title createdAt updatedAt + } }`, GET_TXN: `query getTransactionById($id:String!) { @@ -24,6 +27,7 @@ export const TXN_QUERIES_AND_MUTATIONS = { updatedAt } }`, + UPDATE_TXN: `mutation updateTransaction($id:String!, $title:String!){ updateTransaction(id:$id ,title:$title){ id @@ -31,29 +35,27 @@ export const TXN_QUERIES_AND_MUTATIONS = { createdAt updatedAt } -}`, - DELETE_TXN: `mutation deleteTransaction($id:String!){ - deleteTransaction(id:$id) }`, }; export const USER_QUERIES_AND_MUTATIONS = { - REGISTER: `mutation register($options: UsernamePasswordInput!) { - register(options: $options) { - user { - id - createdAt - updatedAt - username - } + CHANGE_PASSWORD: `mutation ChangePassword($token: String!, $newPassword: String!) { + ChangePassword(token: $token, newPassword: $newPassword) { errors { field message } + user { + id + username + } } } - `, + FORGOT_PASSWORD: `mutation ForgotPassword($email:String!) { + forgotPassword(email:$email ) +}`, + LOGIN: `mutation Login($usernameOrEmail: String!, $password: String!) { login(usernameOrEmail: $usernameOrEmail, password: $password) { errors { @@ -65,14 +67,31 @@ export const USER_QUERIES_AND_MUTATIONS = { username } } -} - +}, `, + LOGOUT: `mutation Logout{ + logout +}`, ME: `query me { me { id username } } +`, + REGISTER: `mutation register($options: UsernamePasswordInput!) { + register(options: $options) { + user { + id + createdAt + updatedAt + username + } + errors { + field + message + } + } +} `, };