diff --git a/lib/database.js b/lib/database.js index e3b1a65..5198f99 100644 --- a/lib/database.js +++ b/lib/database.js @@ -11,13 +11,38 @@ const COLLECTION_NAME = 'feedback'; const { validateInitialResponse, validateTextComments } = require('./validation.js'); +let dbClient; + +/** + * @returns {Promise} - A promise which returns a mongo database connection + */ +const getDb = async () => { + if (!dbClient) { + dbClient = await mongoClient.connect(CONNECTION_STRING, { + useUnifiedTopology: true, + }); + } + return dbClient.db(DB_NAME); +}; + +/** + * Close the mongodb connection. + * This function usually shouldn't be used by application code since we want to re-use connections. + * It is useful for closing database connections between tests. + */ +module.exports.closeConnection = () => { + if (!dbClient) { + return; + } + dbClient.close(); +}; + /** * @returns {Promise} - A promise which returns true for healthy connection, false for unhealthy. */ module.exports.healthcheck = async () => { try { - const client = await mongoClient.connect(CONNECTION_STRING); - const db = client.db(DB_NAME); + const db = await getDb(); const result = await db.admin().ping(); return result.ok === 1; } catch (err) { @@ -31,26 +56,21 @@ module.exports.healthcheck = async () => { * @returns {Promise} - A promise which resolves to a unique token */ const insertOrUpdate = async (data) => { - const client = await mongoClient.connect(CONNECTION_STRING); - const db = client.db(DB_NAME); + const db = await getDb(); const collection = db.collection(COLLECTION_NAME); - try { - if (data.token) { - const filter = { token: data.token }; - const options = { upsert: true }; - await collection.updateOne(filter, { $set: data }, options); - return data.token; - } - - const token = uuid(); - await collection.insertOne({ - ...data, - token, - }); - return token; - } finally { - client.close(); + if (data.token) { + const filter = { token: data.token }; + const options = { upsert: true }; + await collection.updateOne(filter, { $set: data }, options); + return data.token; } + + const token = uuid(); + await collection.insertOne({ + ...data, + token, + }); + return token; }; /** diff --git a/lib/database.test.js b/lib/database.test.js index 453094a..5ceec80 100644 --- a/lib/database.test.js +++ b/lib/database.test.js @@ -23,7 +23,11 @@ describe('database', () => { }); afterAll(async () => { + // Close the connection used by tests to set up data await connection.close(); + + // Close the connection used by the application + await database.closeConnection(); }); it('inserts true answer into database', async () => {