From 7fa2d1ce796de2728189568c2eceb652e477df37 Mon Sep 17 00:00:00 2001 From: Harish G M Date: Sun, 23 Feb 2025 19:04:43 +0530 Subject: [PATCH 1/5] Added test for mysql template. Ensured proper opening and closing of normal connection. --- templates/basic/package.json | 6 +-- .../connection/normalConnection.js | 1 + templates/express_mysql/db/reInitDb.js | 45 +++++++------------ templates/express_mysql/index.js | 6 ++- templates/express_mysql/index.test.js | 38 ++++++++++++++++ templates/express_mysql/package.json | 7 ++- 6 files changed, 67 insertions(+), 36 deletions(-) create mode 100644 templates/express_mysql/index.test.js diff --git a/templates/basic/package.json b/templates/basic/package.json index 84fa255c..5c046f9a 100644 --- a/templates/basic/package.json +++ b/templates/basic/package.json @@ -12,12 +12,12 @@ "author": "", "license": "ISC", "dependencies": { - "express": "^4.17.1", - "dotenv": "^16.4.7" + "dotenv": "^16.4.7", + "express": "^4.17.1" }, "devDependencies": { - "nodemon": "^3.1.9", "jest": "^29.7.0", + "nodemon": "^3.1.9", "supertest": "^7.0.0" } } diff --git a/templates/express_mysql/connection/normalConnection.js b/templates/express_mysql/connection/normalConnection.js index e1a9ee55..f8359f71 100644 --- a/templates/express_mysql/connection/normalConnection.js +++ b/templates/express_mysql/connection/normalConnection.js @@ -6,6 +6,7 @@ const connectToDb = () => { let db = null; try { db = createConnection(appConfig.db); + db.connect(); return db; } catch (err) { const timeStamp = new Date().toLocaleString(); diff --git a/templates/express_mysql/db/reInitDb.js b/templates/express_mysql/db/reInitDb.js index 2b9c2976..14de3057 100644 --- a/templates/express_mysql/db/reInitDb.js +++ b/templates/express_mysql/db/reInitDb.js @@ -1,36 +1,23 @@ -import { readFile, appendFileSync } from "fs"; +import { readFile } from "fs/promises"; import { appConfig } from "../config/appConfig.js"; -const reInitDb = (db) => { +const reInitDb = async (db) => { try { - readFile("./db/reInitDb.sql", "utf8", (err, data) => { - if (err) { - const timeStamp = new Date().toLocaleString(); - const errMessage = `[ERROR]: ${timeStamp} - reInitDb - ${err.message}`; - console.error(errMessage); - } else { - db.query(data, (err, _) => { - if (err) { - const timeStamp = new Date().toLocaleString(); - const errMessage = `[ERROR]: ${timeStamp} - reInitDb - ${err.message}`; - console.error(errMessage); - - if (err.message.includes("Unknown database")) { - console.warn( - `[HINT]: Database '${appConfig.db.database}' does not exist. Please create it by running the following command in your MySQL shell: 'CREATE DATABASE ${appConfig.db.database}'.`, - ); - } - } else { - console.info("[INFO]: Database re-initialized."); - } - }); - } - }); + const data = await readFile("./db/reInitDb.sql", "utf8"); + await db.promise().query(data); + console.info("[INFO]: Database re-initialized."); } catch (err) { - const timeStamp = new Date().toLocaleString(); - const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; - console.error(errMessage); - appendFileSync("./logs/db/reInitDb.log", `${errMessage}\n`); + console.error(`[ERROR]: ${new Date().toLocaleString()} - reInitDb - ${err.message}`); + if (err.message.includes("Unknown database")) { + console.warn(`[HINT]: Database '${appConfig.db.database}' does not exist. Please create it by running the following command in your MySQL shell: 'CREATE DATABASE ${appConfig.db.database}'.`); + } + } finally { + return new Promise((resolve, reject) => { + db.end((err) => { + if (err) reject(err); + else resolve(); + }); + }); } }; diff --git a/templates/express_mysql/index.js b/templates/express_mysql/index.js index 8ddca6bb..786693b2 100644 --- a/templates/express_mysql/index.js +++ b/templates/express_mysql/index.js @@ -27,9 +27,9 @@ app.use(appConfig.router.SAMPLE_PREFIX, sampleRouter); initLog(); const db = connectToDb(); -reInitDb(db); +await reInitDb(db); -app.listen(appConfig.PORT, (err) => { +const server = app.listen(appConfig.PORT, (err) => { if (err) { const timeStamp = new Date().toLocaleString(); const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; @@ -44,3 +44,5 @@ app.listen(appConfig.PORT, (err) => { ); } }); + +export { app, server }; \ No newline at end of file diff --git a/templates/express_mysql/index.test.js b/templates/express_mysql/index.test.js new file mode 100644 index 00000000..299cafeb --- /dev/null +++ b/templates/express_mysql/index.test.js @@ -0,0 +1,38 @@ +import request from "supertest"; +import { expect } from "@jest/globals"; +import { app, server } from "./index.js"; +import db from "./connection/poolConnection.js"; + +afterAll(async () => { + await db.promise().end().catch(err => console.error("Error closing DB:", err)); + console.log("Database pool closed."); + server.close(); +}); + + + +describe("API Endpoints", () => { + it("should return success message on GET /api/sample/test", async () => { + const res = await request(app).get("/api/sample/test"); + expect(res.statusCode).toBe(200); + expect(res.body).toEqual({ + MESSAGE: "It's Working. 👍🏻", + }); + }); + + it("should return all samples on GET /api/sample/all", async () => { + const [expectedSamples] = (await db.promise().query("SELECT * FROM sample_table")); + const res = await request(app).get("/api/sample/all"); + expect(res.statusCode).toBe(200); + expect(res.body).toHaveProperty("MESSAGE", "Data fetched successfully."); + expect(res.body).toHaveProperty("DATA"); + expect(Array.isArray(res.body.DATA)).toBe(true); + res.body.DATA.forEach((item) => { + expect(item).toHaveProperty("id"); + expect(item).toHaveProperty("name"); + expect(typeof item.id).toBe("number"); + expect(typeof item.name).toBe("string"); + }); + expect(res.body.DATA).toEqual(expect.arrayContaining(expectedSamples)); + }); +}); \ No newline at end of file diff --git a/templates/express_mysql/package.json b/templates/express_mysql/package.json index 7202f7ff..e6e2a589 100644 --- a/templates/express_mysql/package.json +++ b/templates/express_mysql/package.json @@ -5,7 +5,8 @@ "main": "index.js", "scripts": { "start": "node index.js", - "dev": "nodemon index.js" + "dev": "nodemon index.js", + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js" }, "author": "quick_start_express", "license": "ISC", @@ -18,7 +19,9 @@ "mysql2": "^3.11.3" }, "devDependencies": { - "nodemon": "^3.1.9" + "jest": "^29.7.0", + "nodemon": "^3.1.9", + "supertest": "^7.0.0" }, "type": "module" } From 498a7f583545785ab3bd5dad01e1a07b7c07abd3 Mon Sep 17 00:00:00 2001 From: Harish G M Date: Sun, 23 Feb 2025 19:05:19 +0530 Subject: [PATCH 2/5] Code formatting --- templates/express_mysql/db/reInitDb.js | 8 ++- templates/express_mysql/index.js | 2 +- templates/express_mysql/index.test.js | 82 ++++++++++++++------------ 3 files changed, 51 insertions(+), 41 deletions(-) diff --git a/templates/express_mysql/db/reInitDb.js b/templates/express_mysql/db/reInitDb.js index 14de3057..b607a615 100644 --- a/templates/express_mysql/db/reInitDb.js +++ b/templates/express_mysql/db/reInitDb.js @@ -7,9 +7,13 @@ const reInitDb = async (db) => { await db.promise().query(data); console.info("[INFO]: Database re-initialized."); } catch (err) { - console.error(`[ERROR]: ${new Date().toLocaleString()} - reInitDb - ${err.message}`); + console.error( + `[ERROR]: ${new Date().toLocaleString()} - reInitDb - ${err.message}`, + ); if (err.message.includes("Unknown database")) { - console.warn(`[HINT]: Database '${appConfig.db.database}' does not exist. Please create it by running the following command in your MySQL shell: 'CREATE DATABASE ${appConfig.db.database}'.`); + console.warn( + `[HINT]: Database '${appConfig.db.database}' does not exist. Please create it by running the following command in your MySQL shell: 'CREATE DATABASE ${appConfig.db.database}'.`, + ); } } finally { return new Promise((resolve, reject) => { diff --git a/templates/express_mysql/index.js b/templates/express_mysql/index.js index 786693b2..90597ef5 100644 --- a/templates/express_mysql/index.js +++ b/templates/express_mysql/index.js @@ -45,4 +45,4 @@ const server = app.listen(appConfig.PORT, (err) => { } }); -export { app, server }; \ No newline at end of file +export { app, server }; diff --git a/templates/express_mysql/index.test.js b/templates/express_mysql/index.test.js index 299cafeb..9342c102 100644 --- a/templates/express_mysql/index.test.js +++ b/templates/express_mysql/index.test.js @@ -1,38 +1,44 @@ -import request from "supertest"; -import { expect } from "@jest/globals"; -import { app, server } from "./index.js"; -import db from "./connection/poolConnection.js"; - -afterAll(async () => { - await db.promise().end().catch(err => console.error("Error closing DB:", err)); - console.log("Database pool closed."); - server.close(); -}); - - - -describe("API Endpoints", () => { - it("should return success message on GET /api/sample/test", async () => { - const res = await request(app).get("/api/sample/test"); - expect(res.statusCode).toBe(200); - expect(res.body).toEqual({ - MESSAGE: "It's Working. 👍🏻", - }); - }); - - it("should return all samples on GET /api/sample/all", async () => { - const [expectedSamples] = (await db.promise().query("SELECT * FROM sample_table")); - const res = await request(app).get("/api/sample/all"); - expect(res.statusCode).toBe(200); - expect(res.body).toHaveProperty("MESSAGE", "Data fetched successfully."); - expect(res.body).toHaveProperty("DATA"); - expect(Array.isArray(res.body.DATA)).toBe(true); - res.body.DATA.forEach((item) => { - expect(item).toHaveProperty("id"); - expect(item).toHaveProperty("name"); - expect(typeof item.id).toBe("number"); - expect(typeof item.name).toBe("string"); - }); - expect(res.body.DATA).toEqual(expect.arrayContaining(expectedSamples)); - }); -}); \ No newline at end of file +import request from "supertest"; +import { expect } from "@jest/globals"; +import { app, server } from "./index.js"; +import db from "./connection/poolConnection.js"; + +afterAll(async () => { + await db + .promise() + .end() + .catch((err) => console.error("Error closing DB:", err)); + console.log("Database pool closed."); + server.close(); +}); + +describe("API Endpoints", () => { + it("should return success message on GET /api/sample/test", async () => { + const res = await request(app).get("/api/sample/test"); + expect(res.statusCode).toBe(200); + expect(res.body).toEqual({ + MESSAGE: "It's Working. 👍🏻", + }); + }); + + it("should return all samples on GET /api/sample/all", async () => { + const [expectedSamples] = await db + .promise() + .query("SELECT * FROM sample_table"); + const res = await request(app).get("/api/sample/all"); + expect(res.statusCode).toBe(200); + expect(res.body).toHaveProperty( + "MESSAGE", + "Data fetched successfully.", + ); + expect(res.body).toHaveProperty("DATA"); + expect(Array.isArray(res.body.DATA)).toBe(true); + res.body.DATA.forEach((item) => { + expect(item).toHaveProperty("id"); + expect(item).toHaveProperty("name"); + expect(typeof item.id).toBe("number"); + expect(typeof item.name).toBe("string"); + }); + expect(res.body.DATA).toEqual(expect.arrayContaining(expectedSamples)); + }); +}); From 0a583925ee7d2dbc809d6b63e44f7a21b38ace6d Mon Sep 17 00:00:00 2001 From: Harish G M Date: Thu, 27 Feb 2025 23:12:25 +0530 Subject: [PATCH 3/5] Mock db used for testing. --- templates/express_mysql/app.js | 23 +++++ .../{index.test.js => app.test.js} | 92 ++++++++++--------- .../controller/sampleController.js | 38 ++------ templates/express_mysql/db/database.js | 32 +++++++ templates/express_mysql/index.js | 78 ++++++---------- .../express_mysql/router/sampleRouter.js | 13 ++- 6 files changed, 148 insertions(+), 128 deletions(-) create mode 100644 templates/express_mysql/app.js rename templates/express_mysql/{index.test.js => app.test.js} (65%) create mode 100644 templates/express_mysql/db/database.js diff --git a/templates/express_mysql/app.js b/templates/express_mysql/app.js new file mode 100644 index 00000000..a621cd5e --- /dev/null +++ b/templates/express_mysql/app.js @@ -0,0 +1,23 @@ +import express, { json } from "express"; +import helmet from "helmet"; +import cors from "cors"; + +import sampleRouter from "./router/sampleRouter.js"; +import { appConfig } from "./config/appConfig.js"; + +export default function (database) { + const app = express(); + + app.use(helmet()); + + app.use(cors()); + app.use(json()); + + // Disable the X-Powered-By header to make it harder + // for attackers to find the tech stack. + app.disable("x-powered-by"); + + app.use(appConfig.router.SAMPLE_PREFIX, sampleRouter(database)); + + return app; +} \ No newline at end of file diff --git a/templates/express_mysql/index.test.js b/templates/express_mysql/app.test.js similarity index 65% rename from templates/express_mysql/index.test.js rename to templates/express_mysql/app.test.js index 9342c102..f7afbfa9 100644 --- a/templates/express_mysql/index.test.js +++ b/templates/express_mysql/app.test.js @@ -1,44 +1,48 @@ -import request from "supertest"; -import { expect } from "@jest/globals"; -import { app, server } from "./index.js"; -import db from "./connection/poolConnection.js"; - -afterAll(async () => { - await db - .promise() - .end() - .catch((err) => console.error("Error closing DB:", err)); - console.log("Database pool closed."); - server.close(); -}); - -describe("API Endpoints", () => { - it("should return success message on GET /api/sample/test", async () => { - const res = await request(app).get("/api/sample/test"); - expect(res.statusCode).toBe(200); - expect(res.body).toEqual({ - MESSAGE: "It's Working. 👍🏻", - }); - }); - - it("should return all samples on GET /api/sample/all", async () => { - const [expectedSamples] = await db - .promise() - .query("SELECT * FROM sample_table"); - const res = await request(app).get("/api/sample/all"); - expect(res.statusCode).toBe(200); - expect(res.body).toHaveProperty( - "MESSAGE", - "Data fetched successfully.", - ); - expect(res.body).toHaveProperty("DATA"); - expect(Array.isArray(res.body.DATA)).toBe(true); - res.body.DATA.forEach((item) => { - expect(item).toHaveProperty("id"); - expect(item).toHaveProperty("name"); - expect(typeof item.id).toBe("number"); - expect(typeof item.name).toBe("string"); - }); - expect(res.body.DATA).toEqual(expect.arrayContaining(expectedSamples)); - }); -}); +import request from "supertest"; +import { expect, jest } from "@jest/globals"; +import makeApp from "./app.js" + +const expectedSamples = [ + { id: 1, name: "sample1" }, + { id: 2, name: "sample2" } +] + +const getSamples = jest.fn().mockImplementation(async (req, res) => { + return res.status(200).send({ + MESSAGE: "Data fetched successfully.", + DATA: expectedSamples, + }); +}); + + +const app = makeApp({ getSamples }) + +describe("API Endpoints", () => { + it("should return success message on GET /api/sample/test", async () => { + const res = await request(app).get("/api/sample/test"); + expect(res.statusCode).toBe(200); + expect(res.body).toEqual({ + MESSAGE: "It's Working. 👍🏻", + }); + }); + + it("should return all samples on GET /api/sample/all", async () => { + const res = await request(app).get("/api/sample/all"); + expect(getSamples.mock.calls.length).toBe(1); + expect(getSamples).toHaveBeenCalledWith(expect.any(Object), expect.any(Object)); + expect(res.statusCode).toBe(200); + expect(res.body).toHaveProperty( + "MESSAGE", + "Data fetched successfully.", + ); + expect(res.body).toHaveProperty("DATA"); + expect(Array.isArray(res.body.DATA)).toBe(true); + res.body.DATA.forEach((item) => { + expect(item).toHaveProperty("id"); + expect(item).toHaveProperty("name"); + expect(typeof item.id).toBe("number"); + expect(typeof item.name).toBe("string"); + }); + expect(res.body.DATA).toEqual(expect.arrayContaining(expectedSamples)); + }); +}); \ No newline at end of file diff --git a/templates/express_mysql/controller/sampleController.js b/templates/express_mysql/controller/sampleController.js index 69f59cc0..6a99a794 100644 --- a/templates/express_mysql/controller/sampleController.js +++ b/templates/express_mysql/controller/sampleController.js @@ -1,35 +1,11 @@ -import { appendFileSync } from "fs"; -import db from "../connection/poolConnection.js"; - -export async function test(_, res) { - return res.status(200).send({ - MESSAGE: "It's Working. 👍🏻", - }); -} - -export async function getAllSamples(_, res) { - const db_conn = await db.promise().getConnection(); - try { - await db_conn.query("LOCK TABLES sample_table READ"); - const [data] = await db_conn.query("SELECT * FROM sample_table"); +export default { + async test(_, res) { return res.status(200).send({ - MESSAGE: "Data fetched successfully.", - DATA: data, + MESSAGE: "It's Working. 👍🏻", }); - } catch { - const timeStamp = new Date().toLocaleString(); - const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; - console.error(errMessage); - appendFileSync( - "./logs/controller/sampleController.log", - `${errMessage}\n`, - ); + }, - return res.status(500).send({ - MESSAGE: "Something went wrong. Please try again later.", - }); - } finally { - await db_conn.query("UNLOCK TABLES"); - db_conn.release(); + async getAllSamples(_, res, database) { + await database.getSamples(_, res); } -} +} \ No newline at end of file diff --git a/templates/express_mysql/db/database.js b/templates/express_mysql/db/database.js new file mode 100644 index 00000000..5f8ef2d0 --- /dev/null +++ b/templates/express_mysql/db/database.js @@ -0,0 +1,32 @@ +import { appendFileSync } from "fs"; +import db from "../connection/poolConnection.js"; + +export default { + async getSamples(req, res) { + const db_conn = await db.promise().getConnection(); + + try { + await db_conn.query("LOCK TABLES sample_table READ"); + const [data] = await db_conn.query("SELECT * FROM sample_table"); + return res.status(200).send({ + MESSAGE: "Data fetched successfully.", + DATA: data, + }); + } catch (err) { + const timeStamp = new Date().toLocaleString(); + const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; + console.error(errMessage); + appendFileSync( + "./logs/controller/sampleController.log", + `${errMessage}\n`, + ); + + return res.status(500).send({ + MESSAGE: "Something went wrong. Please try again later.", + }); + } finally { + await db_conn.query("UNLOCK TABLES"); + db_conn.release(); + } + } +} \ No newline at end of file diff --git a/templates/express_mysql/index.js b/templates/express_mysql/index.js index 90597ef5..8765b9ee 100644 --- a/templates/express_mysql/index.js +++ b/templates/express_mysql/index.js @@ -1,48 +1,30 @@ -import "dotenv/config.js"; - -import express, { json } from "express"; -import helmet from "helmet"; -import { appendFileSync } from "fs"; -import cors from "cors"; - -import { initLog } from "./logs/initLog.js"; -import sampleRouter from "./router/sampleRouter.js"; -import { appConfig } from "./config/appConfig.js"; -import connectToDb from "./connection/normalConnection.js"; -import reInitDb from "./db/reInitDb.js"; - -const app = express(); - -// Helmet sets HTTP headers for security. -app.use(helmet()); - -app.use(cors()); -app.use(json()); - -// Disable the X-Powered-By header to make it harder -// for attackers to find the tech stack. -app.disable("x-powered-by"); - -app.use(appConfig.router.SAMPLE_PREFIX, sampleRouter); - -initLog(); -const db = connectToDb(); -await reInitDb(db); - -const server = app.listen(appConfig.PORT, (err) => { - if (err) { - const timeStamp = new Date().toLocaleString(); - const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; - console.error(errMessage); - appendFileSync("./logs/index.log", `${errMessage}\n`); - } else { - console.info( - `[INFO]: Server is running on http://127.0.0.1:${appConfig.PORT}.`, - ); - console.warn( - `[TEST]: Test the server by sending a GET request to http://127.0.0.1:${appConfig.PORT}${appConfig.router.SAMPLE_PREFIX}/test.`, - ); - } -}); - -export { app, server }; +import { appendFileSync } from "fs"; + +import makeApp from "./app.js" +import database from "./db/database.js" +import { initLog } from "./logs/initLog.js"; +import connectToDb from "./connection/normalConnection.js" +import reInitDb from "./db/reInitDb.js" +import { appConfig } from "./config/appConfig.js"; + +const app = makeApp(database); + +initLog(); +const db = connectToDb(); +await reInitDb(db); + +app.listen(appConfig.PORT, (err) => { + if (err) { + const timeStamp = new Date().toLocaleString(); + const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; + console.error(errMessage); + appendFileSync("./logs/index.log", `${errMessage}\n`); + } else { + console.info( + `[INFO]: Server is running on http://127.0.0.1:${appConfig.PORT}.`, + ); + console.warn( + `[TEST]: Test the server by sending a GET request to http://127.0.0.1:${appConfig.PORT}${appConfig.router.SAMPLE_PREFIX}/test.`, + ); + } +}); \ No newline at end of file diff --git a/templates/express_mysql/router/sampleRouter.js b/templates/express_mysql/router/sampleRouter.js index fca4d735..5c287430 100644 --- a/templates/express_mysql/router/sampleRouter.js +++ b/templates/express_mysql/router/sampleRouter.js @@ -1,9 +1,12 @@ -import { test, getAllSamples } from "../controller/sampleController.js"; import { Router } from "express"; -const sampleRouter = Router(); +import sampleController from "../controller/sampleController.js"; -sampleRouter.get("/test", test); -sampleRouter.get("/all", getAllSamples); +export default function (database) { + const router = Router(); -export default sampleRouter; + router.get("/test", (req, res) => sampleController.test(req, res)); + router.get("/all", (req, res) => sampleController.getAllSamples(req, res, database)); + + return router +} \ No newline at end of file From 6b5dc352cd58a0ef07852acc5af9b7bbb1f2dfdb Mon Sep 17 00:00:00 2001 From: Harish G M Date: Thu, 27 Feb 2025 23:13:14 +0530 Subject: [PATCH 4/5] Formatting. --- templates/express_mysql/app.js | 46 ++++----- templates/express_mysql/app.test.js | 98 ++++++++++--------- .../controller/sampleController.js | 4 +- templates/express_mysql/db/database.js | 64 ++++++------ templates/express_mysql/index.js | 60 ++++++------ .../express_mysql/router/sampleRouter.js | 8 +- 6 files changed, 142 insertions(+), 138 deletions(-) diff --git a/templates/express_mysql/app.js b/templates/express_mysql/app.js index a621cd5e..f8ea6e11 100644 --- a/templates/express_mysql/app.js +++ b/templates/express_mysql/app.js @@ -1,23 +1,23 @@ -import express, { json } from "express"; -import helmet from "helmet"; -import cors from "cors"; - -import sampleRouter from "./router/sampleRouter.js"; -import { appConfig } from "./config/appConfig.js"; - -export default function (database) { - const app = express(); - - app.use(helmet()); - - app.use(cors()); - app.use(json()); - - // Disable the X-Powered-By header to make it harder - // for attackers to find the tech stack. - app.disable("x-powered-by"); - - app.use(appConfig.router.SAMPLE_PREFIX, sampleRouter(database)); - - return app; -} \ No newline at end of file +import express, { json } from "express"; +import helmet from "helmet"; +import cors from "cors"; + +import sampleRouter from "./router/sampleRouter.js"; +import { appConfig } from "./config/appConfig.js"; + +export default function (database) { + const app = express(); + + app.use(helmet()); + + app.use(cors()); + app.use(json()); + + // Disable the X-Powered-By header to make it harder + // for attackers to find the tech stack. + app.disable("x-powered-by"); + + app.use(appConfig.router.SAMPLE_PREFIX, sampleRouter(database)); + + return app; +} diff --git a/templates/express_mysql/app.test.js b/templates/express_mysql/app.test.js index f7afbfa9..9662eeb4 100644 --- a/templates/express_mysql/app.test.js +++ b/templates/express_mysql/app.test.js @@ -1,48 +1,50 @@ -import request from "supertest"; -import { expect, jest } from "@jest/globals"; -import makeApp from "./app.js" - -const expectedSamples = [ - { id: 1, name: "sample1" }, - { id: 2, name: "sample2" } -] - -const getSamples = jest.fn().mockImplementation(async (req, res) => { - return res.status(200).send({ - MESSAGE: "Data fetched successfully.", - DATA: expectedSamples, - }); -}); - - -const app = makeApp({ getSamples }) - -describe("API Endpoints", () => { - it("should return success message on GET /api/sample/test", async () => { - const res = await request(app).get("/api/sample/test"); - expect(res.statusCode).toBe(200); - expect(res.body).toEqual({ - MESSAGE: "It's Working. 👍🏻", - }); - }); - - it("should return all samples on GET /api/sample/all", async () => { - const res = await request(app).get("/api/sample/all"); - expect(getSamples.mock.calls.length).toBe(1); - expect(getSamples).toHaveBeenCalledWith(expect.any(Object), expect.any(Object)); - expect(res.statusCode).toBe(200); - expect(res.body).toHaveProperty( - "MESSAGE", - "Data fetched successfully.", - ); - expect(res.body).toHaveProperty("DATA"); - expect(Array.isArray(res.body.DATA)).toBe(true); - res.body.DATA.forEach((item) => { - expect(item).toHaveProperty("id"); - expect(item).toHaveProperty("name"); - expect(typeof item.id).toBe("number"); - expect(typeof item.name).toBe("string"); - }); - expect(res.body.DATA).toEqual(expect.arrayContaining(expectedSamples)); - }); -}); \ No newline at end of file +import request from "supertest"; +import { expect, jest } from "@jest/globals"; +import makeApp from "./app.js"; + +const expectedSamples = [ + { id: 1, name: "sample1" }, + { id: 2, name: "sample2" }, +]; + +const getSamples = jest.fn().mockImplementation(async (req, res) => { + return res.status(200).send({ + MESSAGE: "Data fetched successfully.", + DATA: expectedSamples, + }); +}); + +const app = makeApp({ getSamples }); + +describe("API Endpoints", () => { + it("should return success message on GET /api/sample/test", async () => { + const res = await request(app).get("/api/sample/test"); + expect(res.statusCode).toBe(200); + expect(res.body).toEqual({ + MESSAGE: "It's Working. 👍🏻", + }); + }); + + it("should return all samples on GET /api/sample/all", async () => { + const res = await request(app).get("/api/sample/all"); + expect(getSamples.mock.calls.length).toBe(1); + expect(getSamples).toHaveBeenCalledWith( + expect.any(Object), + expect.any(Object), + ); + expect(res.statusCode).toBe(200); + expect(res.body).toHaveProperty( + "MESSAGE", + "Data fetched successfully.", + ); + expect(res.body).toHaveProperty("DATA"); + expect(Array.isArray(res.body.DATA)).toBe(true); + res.body.DATA.forEach((item) => { + expect(item).toHaveProperty("id"); + expect(item).toHaveProperty("name"); + expect(typeof item.id).toBe("number"); + expect(typeof item.name).toBe("string"); + }); + expect(res.body.DATA).toEqual(expect.arrayContaining(expectedSamples)); + }); +}); diff --git a/templates/express_mysql/controller/sampleController.js b/templates/express_mysql/controller/sampleController.js index 6a99a794..074bf5f0 100644 --- a/templates/express_mysql/controller/sampleController.js +++ b/templates/express_mysql/controller/sampleController.js @@ -7,5 +7,5 @@ export default { async getAllSamples(_, res, database) { await database.getSamples(_, res); - } -} \ No newline at end of file + }, +}; diff --git a/templates/express_mysql/db/database.js b/templates/express_mysql/db/database.js index 5f8ef2d0..f4e5dcd6 100644 --- a/templates/express_mysql/db/database.js +++ b/templates/express_mysql/db/database.js @@ -1,32 +1,32 @@ -import { appendFileSync } from "fs"; -import db from "../connection/poolConnection.js"; - -export default { - async getSamples(req, res) { - const db_conn = await db.promise().getConnection(); - - try { - await db_conn.query("LOCK TABLES sample_table READ"); - const [data] = await db_conn.query("SELECT * FROM sample_table"); - return res.status(200).send({ - MESSAGE: "Data fetched successfully.", - DATA: data, - }); - } catch (err) { - const timeStamp = new Date().toLocaleString(); - const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; - console.error(errMessage); - appendFileSync( - "./logs/controller/sampleController.log", - `${errMessage}\n`, - ); - - return res.status(500).send({ - MESSAGE: "Something went wrong. Please try again later.", - }); - } finally { - await db_conn.query("UNLOCK TABLES"); - db_conn.release(); - } - } -} \ No newline at end of file +import { appendFileSync } from "fs"; +import db from "../connection/poolConnection.js"; + +export default { + async getSamples(req, res) { + const db_conn = await db.promise().getConnection(); + + try { + await db_conn.query("LOCK TABLES sample_table READ"); + const [data] = await db_conn.query("SELECT * FROM sample_table"); + return res.status(200).send({ + MESSAGE: "Data fetched successfully.", + DATA: data, + }); + } catch (err) { + const timeStamp = new Date().toLocaleString(); + const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; + console.error(errMessage); + appendFileSync( + "./logs/controller/sampleController.log", + `${errMessage}\n`, + ); + + return res.status(500).send({ + MESSAGE: "Something went wrong. Please try again later.", + }); + } finally { + await db_conn.query("UNLOCK TABLES"); + db_conn.release(); + } + }, +}; diff --git a/templates/express_mysql/index.js b/templates/express_mysql/index.js index 8765b9ee..26944ce3 100644 --- a/templates/express_mysql/index.js +++ b/templates/express_mysql/index.js @@ -1,30 +1,30 @@ -import { appendFileSync } from "fs"; - -import makeApp from "./app.js" -import database from "./db/database.js" -import { initLog } from "./logs/initLog.js"; -import connectToDb from "./connection/normalConnection.js" -import reInitDb from "./db/reInitDb.js" -import { appConfig } from "./config/appConfig.js"; - -const app = makeApp(database); - -initLog(); -const db = connectToDb(); -await reInitDb(db); - -app.listen(appConfig.PORT, (err) => { - if (err) { - const timeStamp = new Date().toLocaleString(); - const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; - console.error(errMessage); - appendFileSync("./logs/index.log", `${errMessage}\n`); - } else { - console.info( - `[INFO]: Server is running on http://127.0.0.1:${appConfig.PORT}.`, - ); - console.warn( - `[TEST]: Test the server by sending a GET request to http://127.0.0.1:${appConfig.PORT}${appConfig.router.SAMPLE_PREFIX}/test.`, - ); - } -}); \ No newline at end of file +import { appendFileSync } from "fs"; + +import makeApp from "./app.js"; +import database from "./db/database.js"; +import { initLog } from "./logs/initLog.js"; +import connectToDb from "./connection/normalConnection.js"; +import reInitDb from "./db/reInitDb.js"; +import { appConfig } from "./config/appConfig.js"; + +const app = makeApp(database); + +initLog(); +const db = connectToDb(); +await reInitDb(db); + +app.listen(appConfig.PORT, (err) => { + if (err) { + const timeStamp = new Date().toLocaleString(); + const errMessage = `[ERROR]: ${timeStamp} - ${err.message}`; + console.error(errMessage); + appendFileSync("./logs/index.log", `${errMessage}\n`); + } else { + console.info( + `[INFO]: Server is running on http://127.0.0.1:${appConfig.PORT}.`, + ); + console.warn( + `[TEST]: Test the server by sending a GET request to http://127.0.0.1:${appConfig.PORT}${appConfig.router.SAMPLE_PREFIX}/test.`, + ); + } +}); diff --git a/templates/express_mysql/router/sampleRouter.js b/templates/express_mysql/router/sampleRouter.js index 5c287430..f77e6896 100644 --- a/templates/express_mysql/router/sampleRouter.js +++ b/templates/express_mysql/router/sampleRouter.js @@ -6,7 +6,9 @@ export default function (database) { const router = Router(); router.get("/test", (req, res) => sampleController.test(req, res)); - router.get("/all", (req, res) => sampleController.getAllSamples(req, res, database)); + router.get("/all", (req, res) => + sampleController.getAllSamples(req, res, database), + ); - return router -} \ No newline at end of file + return router; +} From 3a98a80454ea259661629fef4c532a8356a5896c Mon Sep 17 00:00:00 2001 From: Harish G M Date: Fri, 28 Feb 2025 07:44:27 +0530 Subject: [PATCH 5/5] dotenv added to index.js --- templates/express_mysql/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/express_mysql/index.js b/templates/express_mysql/index.js index 26944ce3..9456e9e6 100644 --- a/templates/express_mysql/index.js +++ b/templates/express_mysql/index.js @@ -1,4 +1,5 @@ import { appendFileSync } from "fs"; +import "dotenv/config.js"; import makeApp from "./app.js"; import database from "./db/database.js";