Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Move last two title helpers from dist-api #170

Merged
merged 5 commits into from
Jul 29, 2024
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
1 change: 1 addition & 0 deletions config/product-mapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ const productConfig = {
{
title: "ht",
alternativeTitles: [ "hudiksvalsstidning", "hudiksvallstidning" ],
complaintSenderId: "TBD", // needed for tests, but not used in production, will be filled in when needed
tsCode: "0990",
shortName: "",
subDirectory: "",
Expand Down
30 changes: 25 additions & 5 deletions lib/titles.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ function getAllTitles() {
return realTitlesConfig.map((p) => p.title);
}

function getSenderId(namespace, title) {
const product = getTitleConfig(title);
assert(product?.complaintSenderId, "No senderId for report complaint was found. Update product-mapping config");
assert(
product.namespace === namespace,
`title ${title} not valid for namespace ${namespace}. Check product-mapping config`
);

return product?.complaintSenderId;
}

function getTitlesByNamespace(namespace) {
return realTitlesConfig.filter((p) => p.namespace === namespace).map((p) => p.title);
}
Expand All @@ -59,6 +70,13 @@ function getTitleConfig(title) {
return productMapping.find((p) => p.title === title || (p.alternativeTitles && p.alternativeTitles.includes(title)));
}

function getTsCode(title) {
assert(title, "No title was provided");
const product = getTitleConfig(title);

return product?.tsCode;
}

function getDeliveryDays(namespace, title) {
const product = getTitleConfig(title);
assert(product?.deliveryDays, `No delivery days for title ${title} was found. Update product-mapping config`);
Expand Down Expand Up @@ -147,17 +165,19 @@ export {
alternativeTitleConfig,
allTitlesConfig,
deliveryDaysToNumberOfJobs,
numberOfJobsToJobOffsets,
postalDeliveryAllowed,
getAllPrintTitles,
getAllTitles,
getDeliveryDays,
getNamespaceByTitle,
getPrintTitlesByNamespace,
getAllTitles,
getSenderId,
getTitlesByNamespace,
getTitleConfig,
getNamespaceByTitle,
productMapping,
getTsCode,
numberOfJobsToJobOffsets,
postalDeliveryAllowed,
productConfig,
productMapping,
realTitlesConfig,
validNamespaces,
};
28 changes: 28 additions & 0 deletions test/unit/titles-get-sender-id-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getSenderId, productMapping } from "../../lib/titles.js";

const allPrintProducts = productMapping.filter((p) => p.title && p.tsCode);

describe("get complaints sender id", () => {
describe("titles with sender id", () => {
allPrintProducts
.filter((p) => Boolean(p.complaintSenderId))
.forEach(({ namespace, title }) => {
it(`${namespace}/${title}`, () => {
getSenderId(namespace, title).should.eql(productMapping.find((pm) => pm.title === title).complaintSenderId);
});
});
});
describe("titles without sender id", () => {
allPrintProducts
.filter((p) => !p.complaintSenderId)
.forEach(({ namespace, title }) => {
it(`${namespace}/${title}`, () => {
try {
getSenderId(namespace, title);
} catch (error) {
error.message.should.eql("No senderId for report complaint was found. Update product-mapping config");
}
});
});
});
});
78 changes: 78 additions & 0 deletions test/unit/titles-get-ts-code-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { getTsCode, productMapping } from "../../lib/titles.js";

const titleTsCodeMapping = [
{
tsCode: "0550",
title: "expressen",
text: "Expressen",
singleTitle: false,
},
{
tsCode: "0760",
title: "gt",
text: "GT",
singleTitle: false,
},
{
tsCode: "1160",
title: "kvp",
text: "Kvällsposten",
singleTitle: false,
},
{
tsCode: "0440",
title: "dn",
text: "DN",
singleTitle: false,
},
{
tsCode: "0435",
title: "di",
text: "DI",
singleTitle: true,
},
{
tsCode: "0990",
title: "ht",
text: "Hudiksvalls Tidning",
singleTitle: false,
},
{
tsCode: "0990",
title: "hudiksvalsstidning",
expectedTitle: "ht",
text: "Hudiksvalls Tidning (wrong spelling)",
singleTitle: false,
},
];

describe("get tsCode test", () => {
describe("get tsCode by title", () => {
for (const s of titleTsCodeMapping) {
describe(s.text, () => {
it(`should find tsCode ${s.tsCode} based on title ${s.title}`, () => {
const tsCode = getTsCode(s.title);
tsCode.should.eql(s.tsCode);
});
});
}
});

describe("get title by tsCode", () => {
for (const s of titleTsCodeMapping) {
describe(s.text, () => {
it(`should find title ${s.title} based on tsCode ${s.tsCode}`, () => {
const { title } = productMapping.find((pm) => pm.tsCode === s.tsCode);
title.should.eql(s.expectedTitle || s.title);
});
});
}
});

describe("get tsCode for invalid title", () => {
it("should not find a tsCode for some-title", () => {
const tsCode = getTsCode("some-title");
Boolean(tsCode).should.eql(false);
});
});
});
88 changes: 88 additions & 0 deletions test/unit/titles-sanity-check-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { productMapping, productConfig } from "../../lib/titles.js";

describe("sanity check productMapping", () => {
describe("check for duplicate productCode/type combinations", () => {
it("should not find any duplicate productCode/type combinations", () => {
const allProductCodeTypeCombos = productMapping
.filter((pm) => pm.productCode)
.map((pm) => pm.type + pm.productCode);
const thereAreDuplicates = hasDuplicates(allProductCodeTypeCombos);
thereAreDuplicates.should.eql(false);
});
});

describe("check for duplicate titles", () => {
it("should not find any duplicate titles", () => {
const allTitles = productMapping.filter((pm) => pm.title).map((pm) => pm.title);
const thereAreDuplicates = hasDuplicates(allTitles);
thereAreDuplicates.should.eql(false);
});
});
});

describe("sanity check productConfig", () => {
const flattenedProductConfig = [];
Object.keys(productConfig).map((namespace) => {
flattenedProductConfig.push(...productConfig[namespace]);
});

describe("check for duplicate tsCodes", () => {
it("should not find any duplicate tsCodes", () => {
const allTsCodes = flattenedProductConfig.filter((pm) => pm.tsCode).map((pm) => pm.tsCode);
const thereAreDuplicates = hasDuplicates(allTsCodes);
if (thereAreDuplicates) reportDuplicates(flattenedProductConfig, "tsCode");
thereAreDuplicates.should.eql(false);
});
});

describe("check for duplicate titles", () => {
it("should not find any duplicate titles", () => {
const allTitles = flattenedProductConfig.filter((pm) => pm.title).map((pm) => pm.title);
const thereAreDuplicates = hasDuplicates(allTitles);
if (thereAreDuplicates) reportDuplicates(flattenedProductConfig, "title");
thereAreDuplicates.should.eql(false);
});
});

describe("check for duplicate short names", () => {
it("should not find any duplicate short names", () => {
const allShortNames = flattenedProductConfig.filter((pm) => pm.shortName).map((pm) => pm.shortName);
const thereAreDuplicates = hasDuplicates(allShortNames);
if (thereAreDuplicates) reportDuplicates(flattenedProductConfig, "shortName");
thereAreDuplicates.should.eql(false);
});
});

describe("check for duplicate subdirectories", () => {
it("should not find any duplicate subdirectories", () => {
const allSubDirectories = flattenedProductConfig.filter((pm) => pm.subDirectory).map((pm) => pm.subDirectory);
const thereAreDuplicates = hasDuplicates(allSubDirectories);
if (thereAreDuplicates) reportDuplicates(flattenedProductConfig, "subDirectory");
thereAreDuplicates.should.eql(false);
});
});
});

function hasDuplicates(arr) {
return new Set(arr).size !== arr.length;
}

function reportDuplicates(arr, property) {
const propertyMap = {};
arr
.filter((o) => o[property])
.map((o) => {
const thisProperty = o[property];
if (!propertyMap[thisProperty]) propertyMap[thisProperty] = [];
propertyMap[thisProperty].push(o.title || o.shortName || o.productName);
});
const foundMultiples = [];
Object.keys(propertyMap).forEach((p) => {
if (propertyMap[p].length > 1) {
const multiple = {};
multiple[p] = propertyMap[p];
foundMultiples.push(multiple);
}
});
if (foundMultiples.length) console.log(foundMultiples); // eslint-disable-line no-console
}
Loading