Skip to content

Commit

Permalink
feat: graceful shutdown and integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
hhow09 committed Jan 23, 2025
1 parent 06c4a01 commit 9970ec2
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 7 deletions.
76 changes: 76 additions & 0 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.7.3",
"typescript-eslint": "^8.21.0"
"typescript-eslint": "^8.21.0",
"socket.io-client": "^4.8.1"
}
}
73 changes: 73 additions & 0 deletions backend/src/app.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ChatServer } from "./chat-server";
import CommandService from "./command-service";
import ChatRepo, { ChatSession } from "./repositories/chat-repo";
import { pino } from "pino";
import { io as ioc, type Socket as ClientSocket } from "socket.io-client";
import { MongoClient } from "mongodb";

describe("App Integration Test", () => {
let chatServer: ChatServer;
let mongoClient: MongoClient;
let clientSocket: ClientSocket;
let close: () => void;
const mongoUri = process.env.MONGODB_URI || "mongodb://localhost:27017";
const serverPort = 3001;
const serverUri = `http://localhost:${serverPort}`;

beforeAll(async () => {
const dbName = "test" + Date.now();
const collectionName = "chat-session";
const logger = pino();
mongoClient = await new MongoClient(mongoUri).connect();
logger.info("Connected to MongoDB");
const db = mongoClient.db(dbName);
const collection = db.collection<ChatSession>(collectionName);
const commandService = new CommandService(logger, new ChatRepo(collection));
chatServer = new ChatServer(logger, commandService, serverPort);
close = chatServer.listen();
});

beforeEach(async () => {
clientSocket = await ioc(serverUri).connect();
});

afterEach(async () => {
await clientSocket.close();
});

afterAll(async () => {
await close();
await mongoClient.close();
});

it("should return result", (done: jest.DoneCallback) => {
clientSocket.on("result", (arg) => {
expect(arg).toBe("2");
done();
});
clientSocket.emit("operation", "1+1");
});
it("should return error", (done: jest.DoneCallback) => {
clientSocket.on("error", (arg) => {
expect(arg).toBe("Invalid command");
done();
});
clientSocket.emit("operation", "1--2");
});
it("should return history", (done: jest.DoneCallback) => {
const expected = [{ expression: "1+1", result: "2" }, { expression: "2+3", result: "5" }];

clientSocket.on("result", (arg) => {
if (arg===expected[expected.length-1].result) {
clientSocket.emit("history");
}
});
clientSocket.on("history", (arg) => {
expect(arg).toEqual(expected);
done();
});

clientSocket.emit("operation", "1+1"); // step 1
clientSocket.emit("operation", "2+3"); // step 2
});
});
20 changes: 15 additions & 5 deletions backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,30 @@ const uri = process.env.MONGODB_URI || "mongodb://localhost:27017";
const dbName = "math-chat";
const collectionName = "chat-session";

async function getMongoCollection(uri: string, dbName: string, collectionName: string): Promise<Collection<ChatSession>> {
const mongoClient = new MongoClient(uri);
await mongoClient.connect();
async function getMongoCollection(mongoClient: MongoClient, dbName: string, collectionName: string): Promise<Collection<ChatSession>> {
const db = mongoClient.db(dbName);
const collection = db.collection<ChatSession>(collectionName);
return collection;
}
function connectMongo(uri: string): Promise<MongoClient> {
return new MongoClient(uri).connect();
}

async function main() {
const logger = pino();
const collection = await getMongoCollection(uri, dbName, collectionName);
const mongoClient = await connectMongo(uri);
const collection = await getMongoCollection(mongoClient, dbName, collectionName);
const commandService = new CommandService(logger, new ChatRepo(collection));
const chatServer = new ChatServer(logger, commandService, 3000);
chatServer.listen();
const serverClose = await chatServer.listen();

// graceful shutdown
const shutdown = () => {
serverClose();
mongoClient.close();
}
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);
}

main();
7 changes: 6 additions & 1 deletion backend/src/chat-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class ChatServer {

public listen() {
const httpServer = this.app.listen(this.port,
() => { console.log(`Server listening on port ${this.port}`) }
() => { this.logger.info(`Server listening on port ${this.port}`) }
);

// Express server and socket.io server is sharing the same http server
Expand All @@ -70,5 +70,10 @@ export class ChatServer {
}
});
this.setupSocketHandler(io);
return async function close() {
httpServer.close();
await io.close();
}
}
}

0 comments on commit 9970ec2

Please sign in to comment.