-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Established Basis for Unit and Integration Testing (#142)
* Established Basis for Unit and Integration Testing * Documentation for test files. * Documentation for test integration * remove unused references * update testdocs to use pnpm * resovle pnpm lock issue --------- Co-authored-by: Amar Cerim <[email protected]>
- Loading branch information
Showing
10 changed files
with
6,550 additions
and
482 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const AgencyController = require('../controllers/agency.controller'); | ||
const request = require('supertest'); | ||
const express = require('express'); | ||
|
||
|
||
jest.mock('fs'); | ||
jest.mock('ajv'); | ||
|
||
|
||
const app = express(); | ||
app.use(express.json()); | ||
app.use("/agencies", require("../routes/agency.routes")); | ||
|
||
describe("AgencyController", () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
|
||
it("should return all agencies", async () => { | ||
|
||
fs.readFile.mockImplementation((filePath, encoding, callback) => { | ||
callback(null, JSON.stringify([{ _id: "1", cityId: "123", address: "123 Street", website: "https://example.com", email: "[email protected]", phoneNumber: "+123456789" }])); | ||
}); | ||
|
||
const response = await request(app).get("/agencies"); | ||
|
||
expect(response.statusCode).toBe(200); | ||
expect(response.body).toEqual([ | ||
{ _id: "1", cityId: "123", address: "123 Street", website: "https://example.com", email: "[email protected]", phoneNumber: "+123456789" } | ||
]); | ||
}); | ||
|
||
|
||
it("should return an agency by id", async () => { | ||
fs.readFile.mockImplementation((filePath, encoding, callback) => { | ||
callback(null, JSON.stringify([{ _id: "1", cityId: "123", address: "123 Street", website: "https://example.com", email: "[email protected]", phoneNumber: "+123456789" }])); | ||
}); | ||
|
||
const response = await request(app).get("/agencies/1"); | ||
|
||
expect(response.statusCode).toBe(200); | ||
expect(response.body).toEqual({ | ||
_id: "1", cityId: "123", address: "123 Street", website: "https://example.com", email: "[email protected]", phoneNumber: "+123456789" | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
const request = require('supertest'); | ||
const express = require('express'); | ||
const fs = require('fs'); | ||
const cityRoutes = require('../routes/city.routes'); | ||
const app = express(); | ||
|
||
jest.mock('fs'); | ||
|
||
app.use(express.json()); | ||
app.use('/cities', cityRoutes); | ||
|
||
describe('CityController', () => { | ||
let mockCities; | ||
|
||
beforeEach(() => { | ||
mockCities = [ | ||
{ | ||
"_id": "1", | ||
"countryId": "101", | ||
"name": "CityOne", | ||
"zipCode": 12345, | ||
"coordinates": [1.2345, 2.3456] | ||
}, | ||
{ | ||
"_id": "2", | ||
"countryId": "102", | ||
"name": "CityTwo", | ||
"zipCode": 67890, | ||
"coordinates": [3.4567, 4.5678] | ||
} | ||
]; | ||
|
||
fs.readFile.mockImplementation((filePath, encoding, callback) => { | ||
callback(null, JSON.stringify(mockCities)); | ||
}); | ||
|
||
fs.writeFile.mockImplementation((filePath, data, callback) => { | ||
callback(null); | ||
}); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should return all cities', async () => { | ||
const response = await request(app).get('/cities'); | ||
expect(response.statusCode).toBe(200); | ||
expect(response.body.length).toBe(2); | ||
expect(response.body).toEqual(mockCities); | ||
}); | ||
|
||
it('should return a city by ID', async () => { | ||
const response = await request(app).get('/cities/1'); | ||
expect(response.statusCode).toBe(200); | ||
expect(response.body).toEqual(mockCities[0]); | ||
}); | ||
|
||
it('should return 404 if city not found', async () => { | ||
const response = await request(app).get('/cities/999'); | ||
expect(response.statusCode).toBe(404); | ||
expect(response.body).toEqual({ message: 'Item not found' }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
const request = require('supertest'); | ||
const express = require('express'); | ||
const fs = require('fs'); | ||
const countryRoutes = require('../routes/country.routes'); | ||
const app = express(); | ||
|
||
jest.mock('fs'); | ||
|
||
app.use(express.json()); | ||
|
||
app.use('/countries', countryRoutes); | ||
|
||
describe('CountryController', () => { | ||
const mockCountries = [ | ||
{ _id: '1', name: 'Country1', code: '001', acronym: 'C1' }, | ||
{ _id: '2', name: 'Country2', code: '002', acronym: 'C2' }, | ||
]; | ||
|
||
beforeEach(() => { | ||
fs.readFile.mockImplementation((filePath, encoding, callback) => { | ||
callback(null, JSON.stringify(mockCountries)); | ||
}); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should return all countries', async () => { | ||
const response = await request(app).get('/countries'); | ||
expect(response.statusCode).toBe(200); | ||
expect(response.body).toEqual(mockCountries); | ||
}); | ||
|
||
it('should return a country by id', async () => { | ||
const response = await request(app).get('/countries/1'); | ||
expect(response.statusCode).toBe(200); | ||
expect(response.body).toEqual(mockCountries[0]); | ||
}); | ||
|
||
it('should return 404 if country not found', async () => { | ||
const response = await request(app).get('/countries/999'); | ||
expect(response.statusCode).toBe(404); | ||
expect(response.body).toEqual({ message: 'Item not found' }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
const request = require("supertest"); | ||
const express = require("express"); | ||
const EmailController = require("../controllers/email.controller"); | ||
const nodemailer = require("nodemailer"); | ||
|
||
jest.mock("nodemailer"); | ||
|
||
const app = express(); | ||
app.use(express.json()); | ||
|
||
app.post("/email", EmailController.sendEmail); | ||
|
||
describe("EmailController", () => { | ||
let transporterMock; | ||
|
||
beforeAll(() => { | ||
jest.spyOn(console, 'log').mockImplementation(() => {}); | ||
jest.spyOn(console, 'error').mockImplementation(() => {}); | ||
}); | ||
|
||
afterAll(() => { | ||
console.log.mockRestore(); | ||
console.error.mockRestore(); | ||
}); | ||
|
||
beforeEach(() => { | ||
transporterMock = { | ||
sendMail: jest.fn().mockResolvedValue({ | ||
response: "250 OK: message queued", | ||
}), | ||
}; | ||
nodemailer.createTransport.mockReturnValue(transporterMock); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it("should send an email successfully with valid input", async () => { | ||
const validPayload = { | ||
subject: "Test Subject", | ||
text: "This is a test email body.", | ||
senderName: "John Doe", | ||
senderEmail: "[email protected]", | ||
}; | ||
|
||
const response = await request(app) | ||
.post("/email") | ||
.send(validPayload); | ||
|
||
expect(response.statusCode).toBe(200); | ||
expect(response.body).toHaveProperty("success", "Email sent successfully."); | ||
expect(transporterMock.sendMail).toHaveBeenCalledTimes(1); | ||
expect(transporterMock.sendMail).toHaveBeenCalledWith({ | ||
from: "John Doe <[email protected]>", | ||
to: `${process.env.DEFAULT_RECEIVER_NAME} <${process.env.DEFAULT_RECEIVER_EMAIL}>`, | ||
subject: "Test Subject", | ||
text: "This is a test email body.", | ||
}); | ||
}); | ||
|
||
|
||
it("should return a 400 error if required fields are missing", async () => { | ||
const invalidPayload = { | ||
text: "This is a test email body.", | ||
}; | ||
|
||
const response = await request(app) | ||
.post("/email") | ||
.send(invalidPayload); | ||
|
||
expect(response.statusCode).toBe(400); | ||
expect(response.body).toHaveProperty( | ||
"error", | ||
"Subject, text, and sender name are required." | ||
); | ||
expect(transporterMock.sendMail).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it("should return an authentication error if SMTP credentials are invalid", async () => { | ||
transporterMock.sendMail.mockRejectedValue({ | ||
code: "EAUTH", | ||
message: "Invalid login credentials", | ||
}); | ||
|
||
const validPayload = { | ||
subject: "Test Subject", | ||
text: "This is a test email body.", | ||
senderName: "John Doe", | ||
senderEmail: "[email protected]", | ||
}; | ||
|
||
const response = await request(app) | ||
.post("/email") | ||
.send(validPayload); | ||
|
||
expect(response.statusCode).toBe(500); | ||
expect(response.body).toHaveProperty( | ||
"error", | ||
"Authentication failed. Check your SMTP credentials." | ||
); | ||
expect(transporterMock.sendMail).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it("should return 404 error if SMTP service is not found", async () => { | ||
transporterMock.sendMail.mockRejectedValue({ | ||
responseCode: 404, | ||
message: "SMTP service not found", | ||
}); | ||
|
||
const validPayload = { | ||
subject: "Test Subject", | ||
text: "This is a test email body.", | ||
senderName: "John Doe", | ||
senderEmail: "[email protected]", | ||
}; | ||
|
||
const response = await request(app) | ||
.post("/email") | ||
.send(validPayload); | ||
|
||
expect(response.statusCode).toBe(404); | ||
expect(response.body).toHaveProperty( | ||
"error", | ||
"SMTP service not found. Check your API configuration." | ||
); | ||
expect(transporterMock.sendMail).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it("should return 500 error for server-related issues", async () => { | ||
transporterMock.sendMail.mockRejectedValue({ | ||
responseCode: 500, | ||
message: "Internal server error", | ||
}); | ||
|
||
const validPayload = { | ||
subject: "Test Subject", | ||
text: "This is a test email body.", | ||
senderName: "John Doe", | ||
senderEmail: "[email protected]", | ||
}; | ||
|
||
const response = await request(app) | ||
.post("/email") | ||
.send(validPayload); | ||
|
||
expect(response.statusCode).toBe(500); | ||
expect(response.body).toHaveProperty( | ||
"error", | ||
"Server error. Please try again later." | ||
); | ||
expect(transporterMock.sendMail).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
Oops, something went wrong.