Skip to content

Commit

Permalink
Merge pull request hiteshchoudhary#81 from shrey-dadhaniya/feat/cover…
Browse files Browse the repository at this point in the history
…age-seed

feat: added test cases for seeds
  • Loading branch information
wajeshubham authored Feb 13, 2024
2 parents 8e518dd + b455937 commit cc7fa92
Show file tree
Hide file tree
Showing 11 changed files with 240 additions and 28 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# ################# REQUIRED ENV VARS START #################
PORT=8080
MONGO_MEMORY_SERVER_PORT=10000 # mongodb port for e2e testing
MONGODB_URI=mongodb://mongodb:27017 # `mongodb://localhost:27017` in case using local mongodb
NODE_ENV=development # changing this will avoid stack traces in the error response
EXPRESS_SESSION_SECRET=7fdOMCFRSLD9cv1k-5n3Dz5n3DmVmVHVIg9GG_OGTUkBfLNdgZAwKDNtoCJ0X0cyqaM0ogR80-zh9kx0Mkx # ok to change
Expand Down
40 changes: 40 additions & 0 deletions e2e/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import mongoose, { mongo } from "mongoose";
import { MongoMemoryServer } from "mongodb-memory-server";

const MONGO_MEMORY_SERVER_PORT = process.env.MONGO_MEMORY_SERVER_PORT || 10000;
const MONGODB_URL = `mongodb://127.0.0.1:${MONGO_MEMORY_SERVER_PORT}/`;

let mongoServer = null;
let dbInstance = undefined;

const connectDB = async () => {
try {
await mongoose.disconnect();
mongoServer = await MongoMemoryServer.create({
instance: {
port: +MONGO_MEMORY_SERVER_PORT,
},
});
dbInstance = await mongoose.connect(MONGODB_URL);
} catch (error) {
console.error("Mongo db connect error: ", error);
process.exit(1);
}
};
export const clearDB = async (collectionName = null) => {
if (!dbInstance) {
dbInstance = await mongoose.connect(MONGODB_URL);
}
const connection = mongoose.connection;
if (collectionName) {
await connection.db.collection(collectionName).deleteMany({});
} else {
const collections = await connection.db.listCollections().toArray();
const collectionNames = collections.map((col) => col.name);
for (let name of collectionNames) {
await connection.db.collection(name).deleteMany({});
}
}
};

export default connectDB;
2 changes: 2 additions & 0 deletions e2e/routes/apps/todo.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { test, expect } from "@playwright/test";
import { getApiContext } from "../../common.js";
import { clearDB } from "../../db.js";
let apiContext;

let todoId = null;

test.describe("Todo App", () => {
test.beforeAll(async ({ playwright }) => {
apiContext = await getApiContext(playwright);
await clearDB();
});
test.afterAll(async ({}) => {
await apiContext.dispose();
Expand Down
22 changes: 22 additions & 0 deletions e2e/routes/seeds/chat-app.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { test, expect } from "@playwright/test";
import { getApiContext } from "../../common.js";
import { clearDB } from "../../db.js";

let apiContext;

test.describe("Seed Chat App", () => {
test.beforeAll(async ({ playwright }) => {
apiContext = await getApiContext(playwright);
await clearDB();
});
test.afterAll(async ({}) => {
await apiContext.dispose();
});

test.describe("POST:/api/v1/seed/chat-app - Seed Chat", async () => {
test("should seed Chat App DB", async ({ page }) => {
const res = await apiContext.post("/api/v1/seed/chat-app");
expect(res.status()).toEqual(201);
});
});
});
62 changes: 62 additions & 0 deletions e2e/routes/seeds/ecommerce.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { test, expect } from "@playwright/test";
import { getApiContext } from "../../common.js";
import { clearDB } from "../../db.js";
import {
CATEGORIES_COUNT,
PRODUCTS_COUNT,
} from "../../../src/seeds/_constants.js";

let apiContext;

test.describe("Seed Ecommerce App", () => {
test.beforeAll(async ({ playwright }) => {
apiContext = await getApiContext(playwright);
await clearDB();
});
test.afterAll(async ({}) => {
await apiContext.dispose();
});

test.describe("POST:/api/v1/seed/ecommerce - Seed Ecommerce", async () => {
test("should return 0 products before seed", async ({ page }) => {
const res = await apiContext.get(
"/api/v1/ecommerce/products?page=1&limit=1"
);
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data.totalProducts).toEqual(0);
});
test("should return 0 categories before seed", async ({ page }) => {
const res = await apiContext.get(
"/api/v1/ecommerce/categories?page=1&limit=1"
);
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data.totalCategories).toEqual(0);
});
test("should seed ecommerce DB", async ({ page }) => {
const res = await apiContext.post("/api/v1/seed/ecommerce");
expect(res.status()).toEqual(201);
});
test(`should return ${PRODUCTS_COUNT} products after seed`, async ({
page,
}) => {
const res = await apiContext.get(
"/api/v1/ecommerce/products?page=1&limit=1"
);
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data.totalProducts).toEqual(PRODUCTS_COUNT);
});
test(`should return ${CATEGORIES_COUNT} categories after seed`, async ({
page,
}) => {
const res = await apiContext.get(
"/api/v1/ecommerce/categories?page=1&limit=1"
);
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data.totalCategories).toEqual(CATEGORIES_COUNT);
});
});
});
30 changes: 30 additions & 0 deletions e2e/routes/seeds/generated-credentials.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import fs from "fs";
import { test, expect } from "@playwright/test";
import { getApiContext } from "../../common.js";

let apiContext;

test.describe("Get credentials", () => {
test.beforeAll(async ({ playwright }) => {
apiContext = await getApiContext(playwright);
});
test.afterAll(async ({}) => {
await apiContext.dispose();
});

test.describe("GET:/api/v1/seed/generated-credentials - Get credentials", async () => {
test("should return public/temp/seed-credentials.json content", async ({
page,
}) => {
const seedCredentialsText = fs.readFileSync(
"./public/temp/seed-credentials.json",
"utf8"
);
const seedCredentials = JSON.parse(seedCredentialsText);
const res = await apiContext.get("/api/v1/seed/generated-credentials");
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data).toMatchObject(seedCredentials);
});
});
});
41 changes: 41 additions & 0 deletions e2e/routes/seeds/social-media.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { test, expect } from "@playwright/test";
import { getApiContext } from "../../common.js";
import { clearDB } from "../../db.js";
import { SOCIAL_POSTS_COUNT } from "../../../src/seeds/_constants.js";

let apiContext;

test.describe("Seed social-media App", () => {
test.beforeAll(async ({ playwright }) => {
apiContext = await getApiContext(playwright);
await clearDB();
});
test.afterAll(async ({}) => {
await apiContext.dispose();
});

test.describe("POST:/api/v1/seed/social-media - Seed social-media", async () => {
test("should return 0 posts before seed", async ({ page }) => {
const res = await apiContext.get(
"/api/v1/social-media/posts?page=1&limit=1"
);
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data.totalPosts).toEqual(0);
});
test("should seed social-media DB", async ({ page }) => {
const res = await apiContext.post("/api/v1/seed/social-media");
expect(res.status()).toEqual(201);
});
test(`should return ${SOCIAL_POSTS_COUNT} post after seed`, async ({
page,
}) => {
const res = await apiContext.get(
"/api/v1/social-media/posts?page=1&limit=1"
);
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data.totalPosts).toEqual(SOCIAL_POSTS_COUNT);
});
});
});
37 changes: 37 additions & 0 deletions e2e/routes/seeds/todo.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { test, expect } from "@playwright/test";
import { getApiContext } from "../../common.js";
import { clearDB } from "../../db.js";
import { TODOS_COUNT } from "../../../src/seeds/_constants.js";

let apiContext;

test.describe("Seed Todo App", () => {
test.beforeAll(async ({ playwright }) => {
apiContext = await getApiContext(playwright);
await clearDB();
});
test.afterAll(async ({}) => {
await apiContext.dispose();
});

test.describe("POST:/api/v1/seed/todos - Seed Todos", async () => {
test("should return 0 todos before seed", async ({ page }) => {
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("should seed todo DB", async ({ page }) => {
const res = await apiContext.post("/api/v1/seed/todos");
expect(res.status()).toEqual(201);
});

test(`should return ${TODOS_COUNT} todos after seed`, async ({ page }) => {
const res = await apiContext.get("/api/v1/todos");
const json = await res.json();
expect(res.status()).toEqual(200);
expect(json.data.length).toEqual(TODOS_COUNT);
});
});
});
28 changes: 2 additions & 26 deletions e2e/test-server.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,12 @@
import dotenv from "dotenv";
import mongoose from "mongoose";
import { MongoMemoryServer } from "mongodb-memory-server";
import { httpServer } from "../src/app.js";

dotenv.config({
path: "../.env",
});
import { httpServer } from "../src/app.js";
import connectDB from "./db.js";

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("Mongo db connect 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.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"pre-commit": "lint-staged",
"prepare": "node prepare.js",
"start:test-server": "node -r dotenv/config --experimental-json-modules e2e/test-server.js",
"test:playwright": "set NODE_OPTIONS=--experimental-vm-modules && npx playwright test"
"test:playwright": "set NODE_OPTIONS=--experimental-vm-modules -r dotenv/config --experimental-json-modules && npx playwright test"
},
"repository": {
"type": "git",
Expand Down
3 changes: 2 additions & 1 deletion playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export default defineConfig({
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
// using multiple workers will create DB overwrite issue because we use one DB to test everything
workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
Expand Down

0 comments on commit cc7fa92

Please sign in to comment.