Skip to content

Commit

Permalink
Refactor server and added email and user tests
Browse files Browse the repository at this point in the history
  • Loading branch information
priyanshuxkumar committed Oct 2, 2024
1 parent b9f936d commit 2c64b1f
Show file tree
Hide file tree
Showing 14 changed files with 2,971 additions and 100 deletions.
57 changes: 57 additions & 0 deletions __tests__/email.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
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 sendOtp_1 = require("../src/helper/sendOtp");
const redisClient_1 = __importDefault(require("../src/redis/redisClient"));
const mailTransporter_1 = __importDefault(require("../src/helper/mailTransporter"));
const dotenv_1 = __importDefault(require("dotenv"));
dotenv_1.default.config();
// Mock redis client and transporter
jest.mock("../src/redis/redisClient");
jest.mock("../src/helper/mailTransporter");
describe("sendPasswordResetEmail", () => {
it("should send a password reset email successfully", () => __awaiter(void 0, void 0, void 0, function* () {
// Mock the redisClient setex method
redisClient_1.default.setex.mockResolvedValue(true);
// Mock the transporter sendMail method
mailTransporter_1.default.sendMail.mockResolvedValue({ messageId: "123" });
const result = yield (0, sendOtp_1.sendPasswordResetEmail)("[email protected]");
expect(redisClient_1.default.setex).toHaveBeenCalledWith("passwordResetToken:[email protected]", 600, expect.any(String));
expect(mailTransporter_1.default.sendMail).toHaveBeenCalledWith({
from: process.env.EMAIL,
to: "[email protected]",
subject: "Reset your password for StealShow",
html: expect.any(String),
});
expect(result).toEqual({ message: "Password reset email sent successfully." });
}));
});
describe("sendVerificationOtpToEmail", () => {
it("should send a verification OTP email successfully", () => __awaiter(void 0, void 0, void 0, function* () {
// Mock the redisClient setex method
redisClient_1.default.setex.mockResolvedValue(true);
// Mock the transporter sendMail method
mailTransporter_1.default.sendMail.mockResolvedValue({ messageId: "123" });
const result = yield (0, sendOtp_1.sendVerificationOtpToEmail)("[email protected]");
expect(redisClient_1.default.setex).toHaveBeenCalledWith("otpSecret:[email protected]", 600, expect.any(String));
expect(mailTransporter_1.default.sendMail).toHaveBeenCalledWith({
from: process.env.EMAIL,
to: "[email protected]",
subject: "Verify your email for StealShow",
text: expect.any(String),
html: expect.any(String),
});
expect(result).toEqual({ message: "OTP sent successfully." });
}));
});
56 changes: 56 additions & 0 deletions __tests__/email.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {sendPasswordResetEmail , sendVerificationOtpToEmail} from "../src/helper/sendOtp"
import redisClient from "../src/redis/redisClient";
import transporter from "../src/helper/mailTransporter";
import dotenv from 'dotenv';

dotenv.config();

jest.mock("../src/redis/redisClient");
jest.mock("../src/helper/mailTransporter");

describe("sendPasswordResetEmail", () => {
it("should send a password reset email successfully", async () => {
(redisClient.setex as jest.Mock).mockResolvedValue(true);

(transporter.sendMail as jest.Mock).mockResolvedValue({ messageId: "123" });

const result = await sendPasswordResetEmail("[email protected]");

expect(redisClient.setex).toHaveBeenCalledWith(
"passwordResetToken:[email protected]",
600,
expect.any(String)
);
expect(transporter.sendMail).toHaveBeenCalledWith({
from: process.env.EMAIL,
to: "[email protected]",
subject: "Reset your password for StealShow",
html: expect.any(String),
});
expect(result).toEqual({ message: "Password reset email sent successfully." });
});
});

describe("sendVerificationOtpToEmail", () => {
it("should send a verification OTP email successfully", async () => {
(redisClient.setex as jest.Mock).mockResolvedValue(true);

(transporter.sendMail as jest.Mock).mockResolvedValue({ messageId: "123" });

const result = await sendVerificationOtpToEmail("[email protected]");

expect(redisClient.setex).toHaveBeenCalledWith(
"otpSecret:[email protected]",
600,
expect.any(String)
);
expect(transporter.sendMail).toHaveBeenCalledWith({
from: process.env.EMAIL,
to: "[email protected]",
subject: "Verify your email for StealShow",
text: expect.any(String),
html: expect.any(String),
});
expect(result).toEqual({ message: "OTP sent successfully." });
});
});
50 changes: 50 additions & 0 deletions __tests__/user.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
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 supertest_1 = __importDefault(require("supertest"));
const server_1 = __importDefault(require("../src/server"));
const index_1 = require("../src/db/index");
describe('POST /api/v1/user/signup', () => {
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
// Cleanup: Remove any test users created during tests
yield index_1.prismaClient.user.deleteMany(); // Clean up test users after tests
}));
it('should sign up a new user successfully', () => __awaiter(void 0, void 0, void 0, function* () {
const newUser = {
name: 'Test User',
email: '[email protected]',
password: 'password123',
};
const response = yield (0, supertest_1.default)(server_1.default)
.post('/api/v1/user/signup')
.send(newUser);
expect(response.status).toBe(200);
expect(response.body.message).toBe('User signed up successfully!');
}));
it('should return an error if user already exists', () => __awaiter(void 0, void 0, void 0, function* () {
const existingUser = {
name: 'Existing User',
email: '[email protected]',
password: 'password123',
};
// First signup to create the user
yield (0, supertest_1.default)(server_1.default).post('/api/v1/user/signup').send(existingUser);
// Attempt to sign up again with the same email
const response = yield (0, supertest_1.default)(server_1.default)
.post('/api/v1/user/signup')
.send(existingUser);
expect(response.status).toBe(403);
expect(response.body.message).toBe('User with this email already signed up!');
}));
});
94 changes: 94 additions & 0 deletions __tests__/user.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import supertest from "supertest";
import createServer from "../src/app";
import redisClient from "../src/redis/redisClient";
import { prismaClient } from "../src/db";

const app = createServer();


afterAll(async () => {
await redisClient.quit();
});

describe("POST signup", () => {
beforeAll(() => {
prismaClient.user.deleteMany()
});

describe("signup route", () => {
describe("given a email, name and password",() => {
it("should respond with a 200 status code", async () => {
const response = await supertest(app).post("/api/v1/user/signup").send({
email: "[email protected]",
name: "John Doe",
password: "zxcvzxcv",
});
expect(response.statusCode).toBe(200);
});
});

describe("given a email is already exists",() => {
it("should respond with a 403 status code", async () => {
const response = await supertest(app).post("/api/v1/user/signup").send({
email: "[email protected]",
name: "test account",
password: "qwert1231",
});
expect(response.statusCode).toBe(403);
});
});

describe("given a password is less than 8 character",() => {
it("should respond with a 411 status code", async () => {
const response = await supertest(app).post("/api/v1/user/signup").send({
email: "[email protected]",
name: "John Doe",
password: "zxcvzx",
});
expect(response.statusCode).toBe(411);
});
});
});
});

describe("POST signin" , () => {
describe("given a email and password",() => {
it("should respond with a 200 status code", async () => {
const response = await supertest(app).post("/api/v1/user/signin").send({
email: "[email protected]",
password: "zxcvzxcv",
});
expect(response.statusCode).toBe(200);
});
});

describe("given a email user does not exists" , () => {
it("should response with a 404 status code" , async () => {
const response = await supertest(app).post("/api/v1/user/signin").send({
email: "[email protected]",
password: "qwerqwt",
});
expect(response.statusCode).toBe(403);
})
})

describe("given a password is incorrect",() => {
it("should respond with a 401 status code", async () => {
const response = await supertest(app).post("/api/v1/user/signin").send({
email: "[email protected]",
password: "zxcvvcxz",
});
expect(response.statusCode).toBe(403);
});
});
})

describe("GET get-current-user" , () => {
describe("given a user is authenticated and respond with user" , () => {
it("should respond with a 200 status code" , async () => {
const response = await supertest(app).get("/api/v1/user").set("Authorization" , "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjlkYmRhYjVkLTkyYzMtNDk4Yi05YTEyLTAwNGEwODcxMGRiYSIsImlhdCI6MTcyNzg1ODY0Mn0.-vSwW4FWD_u45HfQ3EaaVUr95gI9eNYm2xbBck-oTO4");
expect(response.statusCode).toBe(200);
expect(response.body).toHaveProperty("user");
})
})
})
3 changes: 3 additions & 0 deletions env_sample
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
DATABASE_URL=""
JWT_PASSWORD=""

REDIS_HOST=
REDIS_PORT=
REDIS_PASSWORD=

KEY_ID=""
KEY_SECRET=""
Expand Down
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/__tests__/**/*.+(ts|tsx|js)', '**/?(*.)+(spec|test).+(ts|tsx|js)'],
verbose: true,
forceExit: true,
};
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "",
"main": "server.js",
"scripts": {
"test": "NODE_ENV=test jest",
"build": "tsc",
"start": "node dist/server.js",
"dev": "tsc -w & nodemon dist/server.js",
Expand Down Expand Up @@ -35,10 +36,16 @@
"@types/cookie-parser": "^1.4.7",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.13",
"@types/jsonwebtoken": "^9.0.7",
"@types/node": "^22.5.5",
"@types/nodemailer": "^6.4.16",
"@types/supertest": "^6.0.2",
"dotenv": "^16.4.5",
"jest": "^29.7.0",
"nodemon": "^3.1.7",
"supertest": "^7.0.0",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.6.2"
}
Expand Down
Loading

0 comments on commit 2c64b1f

Please sign in to comment.