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