From 2ba38729d77208b05fe55b3f6ac2816a4f3a0e6a Mon Sep 17 00:00:00 2001 From: Doug Lagemann <douglagemann@seed-innovations.com> Date: Fri, 20 Dec 2024 09:32:40 -0700 Subject: [PATCH] Add dataLayer unit tests, tweak dataLayer to match changes in hello-express --- db-updates/node/postgres/dataLayer.js | 14 +-- db-updates/node/postgres/dayaLayer.spec.js | 104 +++++++++++++++++++++ 2 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 db-updates/node/postgres/dayaLayer.spec.js diff --git a/db-updates/node/postgres/dataLayer.js b/db-updates/node/postgres/dataLayer.js index 95f8337..ae88325 100644 --- a/db-updates/node/postgres/dataLayer.js +++ b/db-updates/node/postgres/dataLayer.js @@ -18,7 +18,7 @@ exports.runMigrations = async () => { await migrations.run('init'); await migrations.run('migrate'); await client.end(); -} +}; /** * Check connectivity with the database and report results. @@ -32,18 +32,18 @@ exports.healthCheck = async () => { await client.end(); } catch (err) { - console.log(`Database connection error during health check: ${err}`); + console.error(`Database connection error during health check: ${err}`); return { - status: 500, - message: "Internal Server Error" + healthy: false, + message: "Unable to connect to database." }; } return { - status: 200, + healthy: true, message: "Database connection succeeded. Health check passed." }; -} +}; /** * Return the version number stored in the database. @@ -57,4 +57,4 @@ exports.getDbVersion = async () => { await client.end(); return queryResult.rows[0].version_number; -} +}; diff --git a/db-updates/node/postgres/dayaLayer.spec.js b/db-updates/node/postgres/dayaLayer.spec.js new file mode 100644 index 0000000..812c85b --- /dev/null +++ b/db-updates/node/postgres/dayaLayer.spec.js @@ -0,0 +1,104 @@ +const { Client } = require('pg') +const { CommandsRunner, PsqlDriver } = require('node-db-migration'); +const { getDbVersion, healthCheck, runMigrations } = require('./dataLayer'); + +jest.mock('pg'); +jest.mock('node-db-migration'); + +afterEach(() => { + jest.restoreAllMocks(); +}); + +describe('Data', () => { + describe('runMigrations', () => { + it('connects to the database and runs migrations', async () => { + await runMigrations(); + + // Make sure a client was constructed with a postgres connection string + expect(Client).toHaveBeenCalled(); + expect(Client.mock.calls[0][0].connectionString).toContain('postgresql://'); + + // Assert that the client connects, executes the expected migration commands, and disconnects. + const mockClientInstance = Client.mock.instances[0]; + expect(mockClientInstance.connect).toHaveBeenCalled(); + + expect(PsqlDriver).toHaveBeenCalledWith(mockClientInstance); + const mockPsqlDriverInstance = PsqlDriver.mock.instances[0]; + + expect(CommandsRunner).toHaveBeenCalledWith({ + driver: mockPsqlDriverInstance, + directoryWithScripts: expect.any(String) + }); + const mockCommandsRunnerInstance = CommandsRunner.mock.instances[0]; + + expect(mockCommandsRunnerInstance.run).toHaveBeenCalledTimes(2); + expect(mockCommandsRunnerInstance.run).toHaveBeenCalledWith('init'); + expect(mockCommandsRunnerInstance.run).toHaveBeenCalledWith('migrate'); + + expect(mockClientInstance.end).toHaveBeenCalled(); + }); + }); + + describe('healthCheck', () => { + it('returns healthy if database connection succeeds', async () => { + const result = await healthCheck(); + + expect(Client).toHaveBeenCalled(); + expect(Client.mock.calls[0][0].connectionString).toContain('postgresql://'); + + const mockClientInstance = Client.mock.instances[0]; + expect(mockClientInstance.connect).toHaveBeenCalled(); + expect(mockClientInstance.end).toHaveBeenCalled(); + + expect(result).toEqual({ + healthy: true, + message: "Database connection succeeded. Health check passed." + }); + }); + + it('returns unhealthy if database connection fails', async () => { + Client.mockImplementation(() => { + return { + connect: () => { + throw new Error("Boom!"); + } + } + }); + jest.spyOn(console, 'error').mockReturnValue(); + + const result = await healthCheck(); + + expect(result).toEqual({ + healthy: false, + message: "Unable to connect to database." + }); + expect(console.error).toHaveBeenCalled(); + }); + }); + + describe('getDbVersion', () => { + it('queries the database for the version and returns the result', async () => { + const mockConnect = jest.fn(); + const mockQuery = jest.fn().mockResolvedValue({ rows: [ { version_number: 41 } ] }); + const mockEnd = jest.fn(); + + Client.mockImplementation(() => { + return { + connect: mockConnect, + query: mockQuery, + end: mockEnd + } + }); + + const result = await getDbVersion(); + expect(result).toEqual(41); + + expect(Client).toHaveBeenCalled(); + expect(Client.mock.calls[0][0].connectionString).toContain('postgresql://'); + + expect(mockConnect).toHaveBeenCalledTimes(1); + expect(mockQuery).toHaveBeenCalled(); + expect(mockEnd).toHaveBeenCalled(); + }); + }); +}); -- GitLab