Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 1 addition & 15 deletions api/src/services/pub-code-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,12 @@ async function insertOrUpdate(payload, notInsertedArray) {
}
}

async function sendEmailForError(error) {
if (EMAIL_RECIPIENTS) {
try {
const email = emailService.generateHtmlEmail("Error During Bulk Load of Pub Codes Saving to Database Failed", EMAIL_RECIPIENTS, "Error During Bulk Load of Pub Codes Saving to Database Failed.", `<p>${error.message}</p>`);
await emailService.send(email);
} catch (e) {
logger.error("bulkLoad: ", e);
}
}
}

const bulkLoad = async (req, res) => {
try {
const notInsertedArray = [];
const payload = req.body;
if (payload && Array.isArray(payload) && payload.length > 0) {
insertOrUpdate(payload, notInsertedArray).catch(async (error) => {
await sendEmailForError(error);
logger.error("bulkLoad: ", error);
});
await insertOrUpdate(payload, notInsertedArray);
res.status(200).json({});
} else {
res.status(400).json({ message: "Invalid request body" });
Expand Down
69 changes: 69 additions & 0 deletions api/test/bulk-load.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use strict";
const { test } = require("node:test");
const assert = require("node:assert/strict");

process.env.LOG_LEVEL = "error";
// The email service refuses to load without configuration; nothing is sent while EMAIL_RECIPIENTS is unset.
process.env.CHES_TOKEN_URL = "http://localhost/token";
process.env.CHES_CLIENT_ID = "test";
process.env.CHES_CLIENT_SECRET = "test";
process.env.CHES_API_URL = "http://localhost/ches";
delete process.env.EMAIL_RECIPIENTS;

const pubcodeEntity = require("../src/entities/pub-code-entity");
const { bulkLoad } = require("../src/services/pub-code-service");

function fakeResponse() {
const res = { statusCode: undefined, body: undefined };
res.status = (code) => {
res.statusCode = code;
return res;
};
res.json = (body) => {
res.body = body;
return res;
};
return res;
}

const validPubcode = {
repo_name: "some-repo",
version: 1,
product_information: { product_name: "Some product" },
data_management_roles: { product_owner: "Owner" },
product_technology_information: { backend_language: ["JavaScript"] },
};

test("bulk load answers 500 when saving fails", async (t) => {
t.mock.method(pubcodeEntity, "findOneAndReplace", () => ({
exec: () => Promise.reject(new Error("database unavailable")),
}));
const res = fakeResponse();

await bulkLoad({ body: [validPubcode] }, res);

assert.equal(res.statusCode, 500);
assert.deepEqual(res.body, { message: "Internal server error" });
});

test("bulk load answers 200 only after saving", async (t) => {
let saved = false;
t.mock.method(pubcodeEntity, "findOneAndReplace", () => ({
exec: async () => {
await new Promise((resolve) => setTimeout(resolve, 20));
saved = true;
return { _id: "existing" };
},
}));
const res = fakeResponse();
let savedWhenAnswered;
res.json = () => {
savedWhenAnswered = saved;
return res;
};

await bulkLoad({ body: [validPubcode] }, res);

assert.equal(res.statusCode, 200);
assert.equal(savedWhenAnswered, true);
});
Loading