Added a badge to display the monthly ramp
This commit is contained in:
47
tests/buildOutput.test.cjs
Normal file
47
tests/buildOutput.test.cjs
Normal file
@@ -0,0 +1,47 @@
|
||||
const assert = require("node:assert/strict");
|
||||
const { test } = require("node:test");
|
||||
const fs = require("node:fs/promises");
|
||||
const os = require("node:os");
|
||||
const path = require("node:path");
|
||||
const vm = require("node:vm");
|
||||
const { writeOutput } = require("../scripts/write-output.cjs");
|
||||
|
||||
test("build output keeps the previous script available until complete replacement", async t => {
|
||||
const folder = await fs.mkdtemp(path.join(os.tmpdir(), "opportunities-build-"));
|
||||
t.after(() => fs.rm(folder, { recursive: true, force: true }));
|
||||
const file = path.join(folder, "background.js");
|
||||
await writeOutput(file, "old script");
|
||||
await writeOutput(file, "new script", { ...fs, async rename(from, to) {
|
||||
assert.equal(await fs.readFile(to, "utf8"), "old script");
|
||||
assert.equal(await fs.readFile(from, "utf8"), "new script");
|
||||
return fs.rename(from, to);
|
||||
} });
|
||||
assert.equal(await fs.readFile(file, "utf8"), "new script");
|
||||
await writeOutput(file, "new script", { ...fs, writeFile() { assert.fail("Unchanged scripts must not be rewritten"); } });
|
||||
for (const operation of ["writeFile", "rename"]) {
|
||||
await assert.rejects(writeOutput(file, "failed update", { ...fs, async [operation]() {
|
||||
throw new Error("Synthetic publication failure");
|
||||
} }), /Synthetic publication failure/);
|
||||
assert.equal(await fs.readFile(file, "utf8"), "new script");
|
||||
assert.deepEqual(await fs.readdir(folder), ["background.js"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("packaged background scripts start and register listeners without DOM or network", async () => {
|
||||
for (const target of ["chromium", "firefox"]) {
|
||||
const folder = path.join(__dirname, "../dist", target);
|
||||
const manifest = JSON.parse(await fs.readFile(path.join(folder, "manifest.json"), "utf8"));
|
||||
const files = manifest.background.scripts || [manifest.background.service_worker];
|
||||
const listeners = [];
|
||||
const api = { runtime: { onMessage: { addListener: handler => listeners.push(handler) } } };
|
||||
const context = vm.createContext({ [target === "firefox" ? "browser" : "chrome"]: api,
|
||||
setTimeout, fetch() { assert.fail("No startup network requests"); } });
|
||||
for (const file of files) {
|
||||
new vm.Script(await fs.readFile(path.join(folder, file), "utf8"), { filename: file }).runInContext(context);
|
||||
}
|
||||
assert.equal(listeners.length, 1, target);
|
||||
for (const entry of manifest.content_scripts) {
|
||||
for (const file of entry.js) new vm.Script(await fs.readFile(path.join(folder, file), "utf8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -68,6 +68,29 @@ test("ten columns retain their links and put product/customer controls below the
|
||||
assert.equal(findClass(h.cell("customer"), "opportunities-extension-products-count"), undefined);
|
||||
});
|
||||
|
||||
test("ramp months preserve zero and flag missing values beside the product count", () => {
|
||||
const h = setup();
|
||||
const badge = () => findClass(h.cell("name"), "opportunities-extension-products-ramp");
|
||||
assert.equal(badge(), undefined);
|
||||
for (const [values, expected] of [
|
||||
[[], null], [[null], "RM N/D"], [[null, undefined, "", " "], "RM N/D"], [[6], "RM 6"],
|
||||
[[0], "RM 0"], [[0, "3", null, " 6 ", 3], "RM 0,3,N/D,6,3"]
|
||||
]) {
|
||||
h.app.productsContentState.opptyProductsByNumber.set("TEST-1", {
|
||||
fromCache: true, items: values.map(RampMonths_c => ({ RampMonths_c }))
|
||||
});
|
||||
h.app.opportunitiesTable.renderOpportunitiesTable();
|
||||
if (expected === null) assert.equal(badge(), undefined);
|
||||
else {
|
||||
assert.equal(badge().textContent, expected);
|
||||
assert.equal(badge().attributes["data-missing"], String(expected.includes("N/D")));
|
||||
assert.match(badge().title, /^Ramp Months:/);
|
||||
assert.equal(h.cell("name").children[0].children[1].children[1], badge());
|
||||
}
|
||||
assert.equal(findClass(h.cell("name"), "opportunities-extension-products-count").textContent, String(values.length));
|
||||
}
|
||||
});
|
||||
|
||||
test("products remain expandable with AI summary and a ten-column detail row after sorting", () => {
|
||||
const h = setup([synthetic("B", "Zulu"), synthetic("A", "Alpha")]);
|
||||
h.app.productsContentState.opptyProductsByNumber.set("B", { items: [{ ProdGroupName: "Cloud", RevnAmount: "10" }] });
|
||||
@@ -86,6 +109,18 @@ test("products remain expandable with AI summary and a ten-column detail row aft
|
||||
assert.deepEqual(h.summaries, ["B"], "collapsing does not generate another summary");
|
||||
});
|
||||
|
||||
test("product table distinguishes unavailable ramp months from numeric zero", () => {
|
||||
const h = setup();
|
||||
h.app.productsContentState.opptyProductsByNumber.set("TEST-1", {
|
||||
items: [null, undefined, "", " ", 0, "0", 6].map(RampMonths_c => ({ RampMonths_c }))
|
||||
});
|
||||
h.app.opportunitiesTable.renderOpportunitiesTable();
|
||||
findClass(h.cell("name"), "opportunities-extension-products-count").click();
|
||||
const table = findClass(h.rows()[1], "opportunities-extension-products-table");
|
||||
const rows = table.children.find(child => child.tag === "tbody").children;
|
||||
assert.deepEqual(rows.map(row => row.children[9].textContent), ["N/D", "N/D", "N/D", "N/D", "0", "0", "6"]);
|
||||
});
|
||||
|
||||
test("customer consumption still opens immediately, uses the right customer and preserves loading state", async () => {
|
||||
const h = setup();
|
||||
const opens = [];
|
||||
@@ -151,7 +186,10 @@ test("table styles reserve compact widths, prioritize Name/Customer and keep nes
|
||||
assert.match(css, /flex: 0 0 24px/);
|
||||
assert.match(css, /td\[data-column="customer"\] \{\s*position: relative;/);
|
||||
assert.match(css, /grid-template-columns: minmax\(0, 1fr\) 12px/);
|
||||
assert.doesNotMatch(css, /text-overflow: ellipsis|overflow: hidden|th:nth-child|td:nth-child/);
|
||||
const tableRules = css.replace(/[^{}]*\.opportunities-extension-products-ramp\s*\{[^}]*\}/g, "");
|
||||
assert.doesNotMatch(tableRules, /text-overflow: ellipsis|overflow: hidden|th:nth-child|td:nth-child/);
|
||||
assert.match(css, /\.opportunities-extension-products-ramp\s*\{[^}]*background: #f0e8f7/);
|
||||
assert.match(css, /\[data-theme="dark"\] \.opportunities-extension-products-ramp\s*\{[^}]*color: #ead5fc/);
|
||||
for (const width of [1120, 1280, 1440, 1840]) {
|
||||
const remaining = width - fixed;
|
||||
assert.equal(fixed + remaining / 2 + remaining / 2, width);
|
||||
|
||||
Reference in New Issue
Block a user