diff --git a/src/adapter-express/application-express.early.spec/close.early.spec.ts b/src/adapter-express/application-express.early.spec/close.early.spec.ts index 5fe31bc..192fb5a 100644 --- a/src/adapter-express/application-express.early.spec/close.early.spec.ts +++ b/src/adapter-express/application-express.early.spec/close.early.spec.ts @@ -13,7 +13,11 @@ class MockConsole { } class MockHTTPServer { - close = jest.fn((callback: (err?: Error) => void) => callback()); + close = jest.fn((callback?: (err?: Error) => void) => { + if (callback) { + callback(); + } + }); } jest.mock("express", () => { @@ -48,47 +52,50 @@ describe("AppExpress.close() close method", () => { }); describe("Happy paths", () => { - it("should close the server successfully without logging", async () => { - // Test to ensure the server closes without logging - await expect(appExpress.close()).resolves.toBeUndefined(); - expect(mockHTTPServer.close).toHaveBeenCalled(); - expect(mockLogger.info).not.toHaveBeenCalled(); - }); + it("should close the server successfully", async () => { + const server = await appExpress.getHttpServer(); + await new Promise((resolve, reject) => { + server.close((err?: Error) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); - it("should close the server successfully with logging", async () => { - // Test to ensure the server closes with logging - await expect(appExpress.close(true)).resolves.toBeUndefined(); expect(mockHTTPServer.close).toHaveBeenCalled(); - expect(mockLogger.info).toHaveBeenCalledWith("Server closed successfully", "adapter-express"); }); }); describe("Edge cases", () => { - it("should handle error during server close without logging", async () => { - // Test to ensure error handling during server close without logging - const error = new Error("Close error"); - mockHTTPServer.close = jest.fn((callback: (err?: Error) => void) => callback(error)); - - await expect(appExpress.close()).rejects.toThrow("Close error"); - expect(mockLogger.error).not.toHaveBeenCalled(); - }); - - it("should handle error during server close with logging", async () => { - // Test to ensure error handling during server close with logging + it("should handle error during server close", async () => { const error = new Error("Close error"); - mockHTTPServer.close = jest.fn((callback: (err?: Error) => void) => callback(error)); - - await expect(appExpress.close(true)).rejects.toThrow("Close error"); - expect(mockLogger.error).toHaveBeenCalledWith( - "Error closing server: Close error", - "adapter-express", - ); + mockHTTPServer.close = jest.fn((callback?: (err?: Error) => void) => { + if (callback) { + callback(error); + } + }); + + const server = await appExpress.getHttpServer(); + await expect( + new Promise((resolve, reject) => { + server.close((err?: Error) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }), + ).rejects.toThrow("Close error"); }); - it("should resolve immediately if serverInstance is null", async () => { - // Test to ensure immediate resolution if serverInstance is null + it("should throw error if serverInstance is null when calling getHttpServer", async () => { appExpress["serverInstance"] = null; - await expect(appExpress.close()).resolves.toBeUndefined(); + await expect(appExpress.getHttpServer()).rejects.toThrow( + "Server instance not initialized yet", + ); }); }); }); diff --git a/src/adapter-express/application-express.early.spec/getHttpServer.early.spec.ts b/src/adapter-express/application-express.early.spec/getHttpServer.early.spec.ts index 33d54fb..46efd22 100644 --- a/src/adapter-express/application-express.early.spec/getHttpServer.early.spec.ts +++ b/src/adapter-express/application-express.early.spec/getHttpServer.early.spec.ts @@ -2,6 +2,7 @@ import express from "express"; import { AppExpress } from "../application-express"; +import { Logger } from "@expressots/core"; // Mocking necessary functions and classes jest.mock("../render/engine", () => { @@ -14,47 +15,49 @@ jest.mock("../render/engine", () => { }; }); -class MockLogger { - error = jest.fn(); -} - -class MockConsole { - messageServer = jest.fn(); +class MockHTTPServer { + close = jest.fn(); } -class MockAppContainer { - Container = {}; +class MockLogger extends Logger { + error = jest.fn(); + warn = jest.fn(); + info = jest.fn(); + debug = jest.fn(); } -class MockProviderManager {} - describe("AppExpress.getHttpServer() getHttpServer method", () => { let appExpress: AppExpress; + let mockLogger: MockLogger; + let mockHTTPServer: MockHTTPServer; beforeEach(() => { - appExpress = new AppExpress() as any; - appExpress["logger"] = new MockLogger() as any; - appExpress["console"] = new MockConsole() as any; - appExpress["appContainer"] = new MockAppContainer() as any; - appExpress["middlewareManager"] = { getErrorHandler: jest.fn() } as any; - appExpress["providerManager"] = new MockProviderManager() as any; - appExpress["app"] = express() as any; + appExpress = new AppExpress(); + mockLogger = new MockLogger(); + mockHTTPServer = new MockHTTPServer(); + + (appExpress as any)["logger"] = mockLogger; + (appExpress as any)["serverInstance"] = mockHTTPServer; }); describe("Happy Paths", () => { - it("should return the express application instance when app is initialized", async () => { + it("should return the Http server instance when app is initialized", async () => { // Test to ensure the method returns the express app instance when initialized const appInstance = await appExpress.getHttpServer(); - expect(appInstance).toBe(appExpress["app"]); + expect(appInstance).toBe(mockHTTPServer); }); }); describe("Edge Cases", () => { - it("should throw an error if the app is not initialized", async () => { - // Test to ensure an error is thrown when the app is not initialized - appExpress["app"] = null as any; + it("should throw an error if the server instance is not initialized", async () => { + (appExpress as any)["serverInstance"] = null; await expect(appExpress.getHttpServer()).rejects.toThrow( - "Incorrect usage of `getHttpServer` method", + "Server instance not initialized yet", + ); + + expect(mockLogger.error).toHaveBeenCalledWith( + "Server instance not initialized yet", + "adapter-express", ); }); }); diff --git a/src/adapter-express/application-express.early.spec/globalConfiguration.early.spec.ts b/src/adapter-express/application-express.early.spec/globalConfiguration.early.spec.ts index edc6655..0ce28aa 100644 --- a/src/adapter-express/application-express.early.spec/globalConfiguration.early.spec.ts +++ b/src/adapter-express/application-express.early.spec/globalConfiguration.early.spec.ts @@ -43,7 +43,7 @@ describe("AppExpress.globalConfiguration() globalConfiguration method", () => { it("should initialize global configuration without errors", () => { // Test to ensure globalConfiguration initializes correctly const result = appExpress.callGlobalConfiguration(); - expect(result).toBeUndefined(); + return expect(result).resolves.toBeUndefined(); }); }); diff --git a/src/adapter-express/application-express.early.spec/isDevelopment.early.spec.ts b/src/adapter-express/application-express.early.spec/isDevelopment.early.spec.ts index 9071365..8b7e38f 100644 --- a/src/adapter-express/application-express.early.spec/isDevelopment.early.spec.ts +++ b/src/adapter-express/application-express.early.spec/isDevelopment.early.spec.ts @@ -19,13 +19,14 @@ class MockLogger { class MockAppContainer { Container = { - get: jest.fn(() => new MockLogger()), + get: jest.fn(), }; } describe("AppExpress.isDevelopment() method", () => { let appExpress: AppExpress; let mockApp: express.Application; + let mockLogger = new MockLogger(); beforeEach(() => { mockApp = { @@ -35,29 +36,33 @@ describe("AppExpress.isDevelopment() method", () => { use: jest.fn(), } as any; + mockLogger = new MockLogger(); + appExpress = new AppExpress() as any; appExpress["app"] = mockApp; appExpress["appContainer"] = new MockAppContainer() as any; + + (appExpress["appContainer"].Container.get as jest.Mock).mockReturnValue(mockLogger); }); describe("Happy Path", () => { - it("should return true when environment is set to development", () => { + it("should return true when environment is set to development", async () => { // Arrange (mockApp.get as jest.Mock).mockReturnValue("development"); // Act - const result = appExpress["isDevelopment"](); + const result = await appExpress.isDevelopment(); // Assert expect(result).toBe(true); }); - it("should return false when environment is not set to development", () => { + it("should return false when environment is not set to development", async () => { // Arrange (mockApp.get as jest.Mock).mockReturnValue("production"); // Act - const result = appExpress["isDevelopment"](); + const result = await appExpress.isDevelopment(); // Assert expect(result).toBe(false); @@ -65,14 +70,12 @@ describe("AppExpress.isDevelopment() method", () => { }); describe("Edge Cases", () => { - it("should return false and log error when app is not initialized", () => { + it("should return false and log error when app is not initialized", async () => { // Arrange appExpress["app"] = undefined as any; - const mockLogger = new MockLogger(); - jest.spyOn(appExpress["appContainer"].Container, "get").mockReturnValue(mockLogger); // Act - const result = appExpress["isDevelopment"](); + const result = await appExpress.isDevelopment(); // Assert expect(result).toBe(false); diff --git a/src/adapter-express/application-express.early.spec/serverShutdown.early.spec.ts b/src/adapter-express/application-express.early.spec/serverShutdown.early.spec.ts index c46c438..ef839c4 100644 --- a/src/adapter-express/application-express.early.spec/serverShutdown.early.spec.ts +++ b/src/adapter-express/application-express.early.spec/serverShutdown.early.spec.ts @@ -13,14 +13,6 @@ jest.mock("../render/engine", () => { }; }); -jest.mock("fs"); -jest.mock("process", () => ({ - ...jest.requireActual("process"), - exit: jest.fn((code?: number) => { - throw new Error(`Mocked process.exit called with code ${code}`); - }), -})); - class MockLogger { error = jest.fn(); } @@ -29,33 +21,51 @@ class MockConsole { messageServer = jest.fn(); } -describe("AppExpress.serverShutdown() serverShutdown method", () => { +describe("AppExpress.serverShutdown() method", () => { let appExpress: AppExpress; + let processExitSpy: jest.SpyInstance; beforeEach(() => { - appExpress = new AppExpress(); + appExpress = new AppExpress() as any; // Cast to 'any' to access private methods appExpress["logger"] = new MockLogger() as any; appExpress["console"] = new MockConsole() as any; + // Mock serverShutdown method jest.spyOn(appExpress as any, "serverShutdown").mockImplementation(() => { console.log("Mocked serverShutdown called"); }); + + // Spy on process.exit + processExitSpy = jest + .spyOn(process, "exit") + .mockImplementation((code?: string | number | null | undefined) => { + throw new Error(`Mocked process.exit called with code ${code}`); + }); + }); + + afterEach(() => { + // Restore the original process.exit after each test + processExitSpy.mockRestore(); }); describe("Happy Paths", () => { - it("should call serverShutdown and exit the process", () => { + it("should call serverShutdown and exit the process", async () => { // Act & Assert - expect(() => appExpress["handleExit"]()).toThrow("Mocked process.exit called with code 0"); - expect((appExpress as any).serverShutdown).toHaveBeenCalled(); + await expect(appExpress["handleExit"]()).rejects.toThrow( + "Mocked process.exit called with code 0", + ); + expect(appExpress["serverShutdown"]).toHaveBeenCalled(); expect(process.exit).toHaveBeenCalledWith(0); }); }); describe("Edge Cases", () => { - it("should handle serverShutdown gracefully when no additional logic is present", () => { + it("should handle serverShutdown gracefully when no additional logic is present", async () => { // Act & Assert - expect(() => appExpress["handleExit"]()).toThrow("Mocked process.exit called with code 0"); - expect((appExpress as any).serverShutdown).toHaveBeenCalled(); + await expect(appExpress["handleExit"]()).rejects.toThrow( + "Mocked process.exit called with code 0", + ); + expect(appExpress["serverShutdown"]).toHaveBeenCalled(); expect(process.exit).toHaveBeenCalledWith(0); }); });