forked from hiteshchoudhary/apihub
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add test cases for health check and todo app
- Loading branch information
1 parent
6889dd2
commit 94359c7
Showing
8 changed files
with
1,159 additions
and
987 deletions.
There are no files selected for viewing
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,139 @@ | ||
import { test, expect, request } from "@playwright/test"; | ||
import { getApiContext } from "../common.js"; | ||
let apiContext; | ||
|
||
let todoId = null; | ||
|
||
test.beforeAll(async ({ playwright }) => { | ||
apiContext = await getApiContext(playwright); | ||
}); | ||
|
||
test.afterAll(async ({}) => { | ||
await apiContext.dispose(); | ||
}); | ||
|
||
test.describe("GET:/api/v1/todos - Get All Todos", () => { | ||
test("should return all todos", async () => { | ||
const res = await apiContext.get(`/api/v1/todos`); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(200); | ||
expect(json.data.length).toEqual(0); | ||
}); | ||
}); | ||
|
||
test.describe("POST:/api/v1/todos - Create Todo", () => { | ||
test("should create todo with valid data", async () => { | ||
const todo = { | ||
title: "test-todo-title", | ||
description: "test-todo-description", | ||
}; | ||
const res = await apiContext.post(`/api/v1/todos`, { | ||
data: todo, | ||
}); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(201); | ||
expect(json.statusCode).toEqual(201); | ||
expect(json.data).toMatchObject(todo); | ||
todoId = json.data._id; | ||
}); | ||
|
||
test("should return a 422 with title error when `title` is not provided", async () => { | ||
const todo = {}; | ||
const res = await apiContext.post(`/api/v1/todos`, { | ||
data: todo, | ||
}); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(422); | ||
expect(json.statusCode).toEqual(422); | ||
expect(json.errors).toContainEqual( | ||
expect.objectContaining({ title: expect.anything() }) | ||
); | ||
}); | ||
|
||
test("should return a 422 with title and description error when `title` and `description` is empty", async () => { | ||
const todo = { title: "", description: "" }; | ||
const res = await apiContext.post(`/api/v1/todos`, { | ||
data: todo, | ||
}); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(422); | ||
expect(json.statusCode).toEqual(422); | ||
expect(json.errors).toContainEqual( | ||
expect.objectContaining({ title: expect.anything() }) | ||
); | ||
expect(json.errors).toContainEqual( | ||
expect.objectContaining({ description: expect.anything() }) | ||
); | ||
}); | ||
}); | ||
|
||
test.describe("PATCH:/api/v1/todos/:id - Update Todo", () => { | ||
const todo = { | ||
title: "update-test-todo-title", | ||
description: "update-test-todo-description", | ||
}; | ||
|
||
test("should update todo with valid data", async () => { | ||
const res = await apiContext.patch(`/api/v1/todos/${todoId}`, { | ||
data: todo, | ||
}); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(200); | ||
expect(json.statusCode).toEqual(200); | ||
expect(json.data).toMatchObject(todo); | ||
}); | ||
|
||
test("should return a 422 with title and description error when `title` and `description` is empty", async () => { | ||
const todo = { title: "", description: "" }; | ||
const res = await apiContext.patch(`/api/v1/todos/${todoId}`, { | ||
data: todo, | ||
}); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(422); | ||
expect(json.statusCode).toEqual(422); | ||
expect(json.errors).toContainEqual( | ||
expect.objectContaining({ title: expect.anything() }) | ||
); | ||
expect(json.errors).toContainEqual( | ||
expect.objectContaining({ description: expect.anything() }) | ||
); | ||
}); | ||
}); | ||
|
||
test.describe("PATCH:/api/v1/todos/toggle/status/:id - Toggle todo status", () => { | ||
test("should toggle todo status", async () => { | ||
const res = await apiContext.patch(`/api/v1/todos/toggle/status/${todoId}`); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(200); | ||
expect(json.statusCode).toEqual(res.status()); | ||
expect(json.data.isComplete).toBeTruthy(); | ||
}); | ||
}); | ||
|
||
test.describe("GET:/api/v1/todos - Get All Todos", () => { | ||
test("should return todo when valid id passed", async () => { | ||
const res = await apiContext.get(`/api/v1/todos/${todoId}`); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(200); | ||
expect(json.statusCode).toEqual(res.status()); | ||
}); | ||
|
||
test("should return 422 with todoId error when invalid id passed", async () => { | ||
const res = await apiContext.get(`/api/v1/todos/__1`); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(422); | ||
expect(json.statusCode).toEqual(res.status()); | ||
expect(json.errors).toContainEqual( | ||
expect.objectContaining({ todoId: expect.anything() }) | ||
); | ||
}); | ||
}); | ||
|
||
test.describe("DELETE:/api/v1/todos/:id - Delete Todo", () => { | ||
test("should delete todo", async () => { | ||
const res = await apiContext.delete(`/api/v1/todos/${todoId}`); | ||
const json = await res.json(); | ||
expect(res.status()).toEqual(200); | ||
expect(json.statusCode).toEqual(res.status()); | ||
}); | ||
}); |
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,12 @@ | ||
import dotenv from "dotenv"; | ||
|
||
dotenv.config({ | ||
path: "../.env", | ||
}); | ||
|
||
export const URL = `http://localhost:${process.env.PORT || 8080}`; | ||
|
||
export const getApiContext = async (playwright) => | ||
playwright.request.newContext({ | ||
baseURL: URL, | ||
}); |
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,17 @@ | ||
import { test, expect } from "@playwright/test"; | ||
import { getApiContext, URL } from "./common.js"; | ||
|
||
let apiContext; | ||
|
||
test.beforeAll(async ({ playwright }) => { | ||
apiContext = await getApiContext(playwright); | ||
}); | ||
|
||
test.afterAll(async ({}) => { | ||
await apiContext.dispose(); | ||
}); | ||
|
||
test("should return ok", async ({ page }) => { | ||
const res = await apiContext.get(`/api/v1/healthcheck`); | ||
expect(res.ok()).toBeTruthy(); | ||
}); |
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,62 @@ | ||
import dotenv from "dotenv"; | ||
import { httpServer } from "../src/app.js"; | ||
import mongoose from "mongoose"; | ||
import { MongoMemoryServer } from "mongodb-memory-server"; | ||
|
||
dotenv.config({ | ||
path: "../.env", | ||
}); | ||
|
||
let mongoServer = null; | ||
let dbInstance = undefined; | ||
const PORT = process.env.PORT || 8080; | ||
|
||
const connectDB = async () => { | ||
try { | ||
await mongoose.disconnect(); | ||
mongoServer = await MongoMemoryServer.create(); | ||
dbInstance = await mongoose.connect(`${mongoServer.getUri()}`); | ||
await clearDB(); | ||
} catch (error) { | ||
console.log("MongoDB connection error: ", error); | ||
process.exit(1); | ||
} | ||
}; | ||
export const clearDB = async () => { | ||
const collections = mongoose.connection.collections; | ||
|
||
for (const key in collections) { | ||
const collection = collections[key]; | ||
await collection.deleteMany({}); | ||
} | ||
}; | ||
|
||
/** | ||
* Starting from Node.js v14 top-level await is available and it is only available in ES modules. | ||
* This means you can not use it with common js modules or Node version < 14. | ||
*/ | ||
const majorNodeVersion = +process.env.NODE_VERSION?.split(".")[0] || 0; | ||
|
||
const startServer = () => { | ||
httpServer.listen(PORT, () => { | ||
console.info(`📑 Visit the documentation at: http://localhost:${PORT}`); | ||
console.log("⚙️ Server is running on port: " + PORT); | ||
}); | ||
}; | ||
|
||
if (majorNodeVersion >= 14) { | ||
try { | ||
await connectDB(); | ||
startServer(); | ||
} catch (err) { | ||
console.log("Mongo db connect error: ", err); | ||
} | ||
} else { | ||
connectDB() | ||
.then(() => { | ||
startServer(); | ||
}) | ||
.catch((err) => { | ||
console.log("Mongo db connect error: ", err); | ||
}); | ||
} |
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
Oops, something went wrong.