Skip to content

Commit

Permalink
refactor user route to controller and test it
Browse files Browse the repository at this point in the history
  • Loading branch information
groovecoder committed Aug 18, 2018
1 parent 69d9028 commit 878a824
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 59 deletions.
73 changes: 73 additions & 0 deletions controllers/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use strict";

const AppConstants = require("../app-constants");

const DB = require("../db/DB");
const EmailUtils = require("../email-utils");

const ResponseCodes = Object.freeze({
InternalError: 999,
EmailNotProvided: 100,
EmailNotFound: 101,
TokenMismatch: 102,
});


async function add(req, res) {
const email = req.body.email;
const unverifiedSubscriber = await DB.addSubscriberUnverifiedEmailHash(email);
const verificationToken = unverifiedSubscriber.verification_token;

const url = `${AppConstants.SERVER_URL}/user/verify?token=${encodeURIComponent(verificationToken)}`;

try {
await EmailUtils.sendEmail(
email,
"Verify your email address to subscribe to Firefox Monitor.",
"email_verify",
{ email, url}
);

res.send({
title: "Firefox Monitor : Confirm Email",
});
} catch (e) {
console.error(e);
res.status(500).json({
error_code: ResponseCodes.InternalError,
info: "SMTP error.",
});
}
}


async function verify(req, res) {
const verifiedEmailHash = await DB.verifyEmailHash(req.query.token);
if (!verifiedEmailHash) {
res.status(400).json({
error_code: ResponseCodes.EmailNotFound,
info: "Email not found or verification token does not match.",
});
return;
}

res.render("confirm", {
title: "Firefox Breach Alerts: Subscribed",
email: verifiedEmailHash.email,
});
}


async function remove (req, res) {
await DB.removeSubscriber(req.body.email);
res.status(200).json({
info: "Deleted user.",
});
}


module.exports = {
add,
verify,
remove,
};
63 changes: 4 additions & 59 deletions routes/user.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,17 @@
"use strict";

const AppConstants = require("../app-constants");

const express = require("express");
const bodyParser = require("body-parser");

const DB = require("../db/DB");
const EmailUtils = require("../email-utils");

const ResponseCodes = Object.freeze({
InternalError: 999,
EmailNotProvided: 100,
EmailNotFound: 101,
TokenMismatch: 102,
});
const { add, verify, remove } = require("../controllers/user");

const router = express.Router();
const jsonParser = bodyParser.json();


router.post("/add", jsonParser, async (req, res) => {
const email = req.body.email;
const unverifiedSubscriber = await DB.addSubscriberUnverifiedEmailHash(email);
const verificationToken = unverifiedSubscriber.verification_token;

const url = `${AppConstants.SERVER_URL}/user/verify?token=${encodeURIComponent(verificationToken)}`;

try {
await EmailUtils.sendEmail(
email,
"Verify your email address to subscribe to Firefox Monitor.",
"email_verify",
{ email, url}
);

res.send({
title: "Firefox Monitor : Confirm Email",
});
} catch (e) {
console.error(e);
res.status(500).json({
error_code: ResponseCodes.InternalError,
info: "SMTP error.",
});
}
});

router.get("/verify", jsonParser, async (req, res) => {
const verifiedEmailHash = await DB.verifyEmailHash(req.query.token);
if (!verifiedEmailHash) {
res.status(400).json({
error_code: ResponseCodes.EmailNotFound,
info: "Email not found or verification token does not match.",
});
return;
}

res.render("confirm", {
title: "Firefox Breach Alerts: Subscribed",
email: verifiedEmailHash.email,
});
});
router.post("/add", jsonParser, add);
router.get("/verify", jsonParser, verify);
router.post("/remove", jsonParser, remove);

router.post("/remove", jsonParser, async (req, res) => {
await DB.removeSubscriber(req.body.email);
res.status(200).json({
info: "Deleted user.",
});
});

module.exports = router;
46 changes: 46 additions & 0 deletions tests/user.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use strict";

const httpMocks = require("node-mocks-http");

const DB = require("../db/DB");
const EmailUtils = require("../email-utils");
const user = require("../controllers/user");

require("./resetDB");


jest.mock("../email-utils");


test("POST with email adds unverified subscriber and sends verification email", async () => {
// Set up test context
const userAddEmail = "userAdd@test.com";
let subscribers = await DB.getSubscribersByEmail(userAddEmail);
expect(subscribers.length).toEqual(0);

// Set up mocks
const req = httpMocks.createRequest({
method: "POST",
url: "/user/add",
body: {email:"userAdd@test.com"},
});
const resp = httpMocks.createResponse();
EmailUtils.sendEmail.mockResolvedValue(true);

// Call code-under-test
await user.add(req, resp);

// Check expectations
expect(resp.statusCode).toEqual(200);
subscribers = await DB.getSubscribersByEmail(userAddEmail);
expect(subscribers.length).toEqual(1);
const userAdded = subscribers[0];
expect(userAdded.email).toEqual(userAddEmail);
expect(userAdded.verified).toBeFalsy();

const mockCalls = EmailUtils.sendEmail.mock.calls;
expect(mockCalls.length).toEqual(1);
const mockCallArgs = mockCalls[0];
expect(mockCallArgs).toContain(userAddEmail);
expect(mockCallArgs).toContain("email_verify");
});

0 comments on commit 878a824

Please sign in to comment.