746 lines
27 KiB
JavaScript
746 lines
27 KiB
JavaScript
import test, { after } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { spawnSync } from "node:child_process";
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import {
|
|
catalogSaysApiMetricsAreRawRows,
|
|
catalogSaysCurrentWorkloadDefaults,
|
|
catalogSaysPreserveMixedRows,
|
|
catalogSaysUseRevenueLineCloseDate,
|
|
parseDefaultWeekYear,
|
|
parseCurrentWorkloadDefaults,
|
|
parsePrimaryCommercialSubjectArea,
|
|
parseSaAttachAliases,
|
|
parseSaAttachDateWindowField,
|
|
parseSaAttachDefaults,
|
|
parseWeekRow,
|
|
readSkillCatalogs,
|
|
} from "./helpers/catalogs.mjs";
|
|
import { skillHome } from "./helpers/cli.mjs";
|
|
|
|
const catalogs = await readSkillCatalogs();
|
|
const fetchModule = await import(
|
|
pathToFileURL(path.join(skillHome, "scripts", "fetch-sales-intelligence.mjs")).href
|
|
);
|
|
|
|
const functionTestRows = [];
|
|
|
|
function functionTest(id, title, details, fn) {
|
|
test(title, async () => {
|
|
const row = {
|
|
id,
|
|
teste: title,
|
|
entrada: details.entrada,
|
|
saida: details.saida || "",
|
|
avaliacao: "PASS",
|
|
};
|
|
try {
|
|
const output = await fn();
|
|
if (output) row.saida = output;
|
|
} catch (error) {
|
|
row.avaliacao = `FAIL; ${error.message}`;
|
|
throw error;
|
|
} finally {
|
|
functionTestRows.push(row);
|
|
}
|
|
});
|
|
}
|
|
|
|
after((t) => {
|
|
t.diagnostic(formatFunctionResultsTable(functionTestRows));
|
|
});
|
|
|
|
functionTest(
|
|
"auth-refresh-json-stdout",
|
|
"automatic auth refresh notice is emitted on stderr",
|
|
{
|
|
entrada: "source scan for the automatic refresh notice in fetch-sales-intelligence.mjs",
|
|
},
|
|
async () => {
|
|
const source = await fs.readFile(
|
|
path.join(skillHome, "scripts", "fetch-sales-intelligence.mjs"),
|
|
"utf8"
|
|
);
|
|
const notice = "Oracle DV session is missing or expired. Opening browser login to refresh auth...";
|
|
assert.match(source, new RegExp(`console\\.error\\(${JSON.stringify(notice)}\\)`));
|
|
assert.doesNotMatch(source, new RegExp(`console\\.log\\(${JSON.stringify(notice)}\\)`));
|
|
|
|
const originalLog = console.log;
|
|
const originalError = console.error;
|
|
const stdoutMessages = [];
|
|
const stderrMessages = [];
|
|
console.log = (...args) => stdoutMessages.push(args.join(" "));
|
|
console.error = (...args) => stderrMessages.push(args.join(" "));
|
|
try {
|
|
await fetchModule.withConsoleLogRoutedToStderr(async () => {
|
|
console.log("helper progress");
|
|
});
|
|
} finally {
|
|
console.log = originalLog;
|
|
console.error = originalError;
|
|
}
|
|
assert.deepEqual(stdoutMessages, []);
|
|
assert.deepEqual(stderrMessages, ["helper progress"]);
|
|
return "auto-refresh notice and imported helper progress use stderr, preserving JSON-only stdout";
|
|
}
|
|
);
|
|
|
|
functionTest(
|
|
"date-window",
|
|
"date-window functions follow documented shortcuts and week catalog",
|
|
{
|
|
entrada: "resolveDateWindow com --date, --month, --quarter, --week e combinação inválida",
|
|
},
|
|
() => {
|
|
const exact = fetchModule.resolveDateWindow({ date: "2026-05-02" });
|
|
assert.equal(exact.preset, "single-date");
|
|
assert.equal(exact.fromDate, "2026-05-02");
|
|
assert.equal(exact.toDate, "2026-05-02");
|
|
|
|
const leapDay = fetchModule.resolveDateWindow({ date: "2024-02-29" });
|
|
assert.equal(leapDay.fromDate, "2024-02-29");
|
|
assert.equal(leapDay.toDate, "2024-02-29");
|
|
|
|
assert.throws(
|
|
() => fetchModule.resolveDateWindow({ date: "2026-99-99" }),
|
|
/Invalid calendar date "2026-99-99"/
|
|
);
|
|
assert.throws(
|
|
() => fetchModule.resolveDateWindow({ date: "2026-02-29" }),
|
|
/Invalid calendar date "2026-02-29"/
|
|
);
|
|
|
|
const apiaCheck = spawnSync(
|
|
process.execPath,
|
|
[
|
|
"--input-type=module",
|
|
"-e",
|
|
`
|
|
const fetchModule = await import(${JSON.stringify(pathToFileURL(path.join(skillHome, "scripts", "fetch-sales-intelligence.mjs")).href)});
|
|
const window = fetchModule.resolveDateWindow({ date: "2011-12-30" });
|
|
console.log(window.fromDate);
|
|
`,
|
|
],
|
|
{
|
|
env: { ...process.env, TZ: "Pacific/Apia" },
|
|
encoding: "utf8",
|
|
}
|
|
);
|
|
assert.equal(apiaCheck.status, 0, apiaCheck.stderr);
|
|
assert.equal(apiaCheck.stdout.trim(), "2011-12-30");
|
|
|
|
const month = fetchModule.resolveDateWindow({ month: "2026-04" });
|
|
assert.equal(month.preset, "calendar-month");
|
|
assert.equal(month.fromDate, "2026-04-01");
|
|
assert.equal(month.toDate, "2026-04-30");
|
|
|
|
const quarter = fetchModule.resolveDateWindow({ quarter: "FY26-Q4" });
|
|
assert.equal(quarter.preset, "fiscal-quarter");
|
|
assert.equal(quarter.fiscalYear, "FY26");
|
|
assert.equal(quarter.fiscalQuarter, "Q4");
|
|
assert.equal(quarter.fromDate, "2026-03-01");
|
|
assert.equal(quarter.toDate, "2026-05-31");
|
|
|
|
const weekYear = parseDefaultWeekYear(catalogs.scriptCatalog);
|
|
const firstWeek = fetchModule.resolveDateWindow({
|
|
week: "week 1",
|
|
"week-year": String(weekYear),
|
|
});
|
|
assert.equal(firstWeek.weekLabel, "W1");
|
|
assert.equal(firstWeek.fromDate, `${weekYear}-06-01`);
|
|
assert.equal(firstWeek.toDate, `${weekYear}-06-07`);
|
|
|
|
const lastWeek = fetchModule.resolveDateWindow({
|
|
week: "w53",
|
|
"week-year": String(weekYear),
|
|
});
|
|
assert.equal(lastWeek.weekLabel, "W53");
|
|
assert.equal(lastWeek.fromDate, `${weekYear + 1}-05-31`);
|
|
assert.equal(lastWeek.toDate, `${weekYear + 1}-05-31`);
|
|
|
|
const expectedWeek = parseWeekRow(catalogs.scriptCatalog, "W43");
|
|
const week = fetchModule.resolveDateWindow({
|
|
week: expectedWeek.weekLabel.toLowerCase(),
|
|
"week-year": String(weekYear),
|
|
});
|
|
assert.equal(week.weekLabel, expectedWeek.weekLabel);
|
|
assert.equal(week.fromDate, expectedWeek.fromDate);
|
|
assert.equal(week.toDate, expectedWeek.toDate);
|
|
|
|
assert.throws(
|
|
() => fetchModule.resolveDateWindow({ date: "2026-05-02", month: "2026-05" }),
|
|
/Use either --date/
|
|
);
|
|
assert.throws(
|
|
() => fetchModule.resolveDateWindow({ week: "w54", "week-year": String(weekYear) }),
|
|
/Unsupported week token/
|
|
);
|
|
assert.throws(
|
|
() => fetchModule.resolveDateWindow({ "from-date": "2026-05-10", "to-date": "2026-05-02" }),
|
|
/from-date 2026-05-10 is after to-date 2026-05-02/
|
|
);
|
|
return `single=${exact.fromDate}; month=${month.fromDate}..${month.toDate}; quarter=${quarter.fromDate}..${quarter.toDate}; week=${week.fromDate}..${week.toDate}; first=${firstWeek.fromDate}; last=${lastWeek.fromDate}; invalid-combo/window rejected`;
|
|
});
|
|
|
|
functionTest(
|
|
"sa-attach-defaults",
|
|
"SA Attach defaults and aliases come from initial-context-catalog",
|
|
{
|
|
entrada: "parseSaAttachDefaults/parseSaAttachAliases + resolveSaAttachFilters",
|
|
},
|
|
() => {
|
|
const defaults = parseSaAttachDefaults(catalogs.initialContext);
|
|
const aliases = parseSaAttachAliases(catalogs.initialContext);
|
|
|
|
const filters = fetchModule.resolveSaAttachFilters({}, {
|
|
defaultStatuses: defaults.revenueLineStatus,
|
|
});
|
|
assert.equal(filters.cluster, defaults.cluster[0]);
|
|
assert.deepEqual(filters.solutions, defaults.solution);
|
|
assert.deepEqual(filters.statuses, defaults.revenueLineStatus);
|
|
assert.deepEqual(filters.productLobs, defaults.executiveProductLob);
|
|
assert.deepEqual(filters.revenueTypeGroups, defaults.revenueTypeGroup);
|
|
assert.equal(filters.salesCreditType, defaults.salesCreditType[0]);
|
|
assert.equal(filters.minOpportunityProbability, Number(defaults.minOpportunityProbability[0]));
|
|
|
|
const lobAlias = Object.entries(aliases).find(([, values]) => values.length > 1);
|
|
const targetRevenueType = defaults.revenueTypeGroup.at(-1);
|
|
const revenueTypeAlias = Object.entries(aliases).find(([, values]) => values.includes(targetRevenueType));
|
|
assert.ok(lobAlias, "Expected at least one multi-value LOB alias in the catalog.");
|
|
assert.ok(revenueTypeAlias, "Expected a revenue-type alias for the catalog default workload group.");
|
|
|
|
const aliasFilters = fetchModule.resolveSaAttachFilters(
|
|
{
|
|
"executive-product-lob": lobAlias[0],
|
|
"revenue-type-group": revenueTypeAlias[0].split("|")[0],
|
|
},
|
|
{ defaultStatuses: defaults.revenueLineStatus }
|
|
);
|
|
assert.deepEqual(aliasFilters.productLobs, lobAlias[1]);
|
|
assert.deepEqual(aliasFilters.revenueTypeGroups, revenueTypeAlias[1]);
|
|
return `cluster=${filters.cluster}; solutions=${filters.solutions.length}; statuses=${filters.statuses.length}; aliases validated`;
|
|
});
|
|
|
|
functionTest(
|
|
"close-window-explicit-cluster",
|
|
"close-window commercial SQL honors explicit cluster without SA Attach defaults",
|
|
{
|
|
entrada: "buildPrimaryOpportunityWhereClauses com cluster Mexico",
|
|
},
|
|
() => {
|
|
const clauses = fetchModule.buildPrimaryOpportunityWhereClauses({
|
|
fromDateSql: "DATE '2026-05-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
statuses: ["Open"],
|
|
cluster: "Mexico",
|
|
});
|
|
|
|
const sql = clauses.join("\n");
|
|
assert.match(sql, /"Revenue Line Close Date" >= DATE '2026-05-01'/);
|
|
assert.match(sql, /"Revenue Line Close Date" <= DATE '2026-05-31'/);
|
|
assert.match(sql, /"Opportunity Status" IN \('Open'\)/);
|
|
assert.match(sql, /"Cluster" = 'Mexico'/);
|
|
assert.doesNotMatch(sql, /"Solution" IN/);
|
|
assert.doesNotMatch(sql, /"Revenue Type Group" IN/);
|
|
assert.doesNotMatch(sql, /"Sales Credit Type" =/);
|
|
|
|
const withoutCluster = fetchModule.buildPrimaryOpportunityWhereClauses({
|
|
fromDateSql: "DATE '2026-05-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
statuses: ["Open"],
|
|
}).join("\n");
|
|
assert.doesNotMatch(withoutCluster, /"Cluster" =/);
|
|
|
|
const ownerClauses = fetchModule.buildPrimaryOpportunityWhereClauses({
|
|
fromDateSql: "DATE '2026-05-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
statuses: ["Open"],
|
|
cluster: "Brazil",
|
|
ownerEmail: "seller.one@oracle.com",
|
|
}).join("\n");
|
|
assert.match(ownerClauses, /"Level 7 Territory Owner E-mail" = 'seller.one@oracle.com'/);
|
|
|
|
const ownerManagerClauses = fetchModule.buildPrimaryOpportunityWhereClauses({
|
|
fromDateSql: "DATE '2026-05-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
statuses: ["Open"],
|
|
ownerManagerEmail: "sales.manager@oracle.com",
|
|
}).join("\n");
|
|
assert.match(ownerManagerClauses, /"Level 2 Territory Owner E-mail" = 'sales.manager@oracle.com'/);
|
|
assert.match(ownerManagerClauses, /"Level 6 Territory Owner E-mail" = 'sales.manager@oracle.com'/);
|
|
|
|
return "explicit cluster is applied; absent cluster preserves existing unfiltered geography behavior; owner filters are applied";
|
|
});
|
|
|
|
functionTest(
|
|
"manager-resource-workload-explicit-cluster",
|
|
"manager/resource workload SQL honors explicit cluster and defaults to Brazil",
|
|
{
|
|
entrada: "buildManagerResourceWorkloadSql com cluster Mexico e default",
|
|
},
|
|
() => {
|
|
const mexicoSql = fetchModule.buildManagerResourceWorkloadSql({
|
|
fromDateSql: "DATE '2026-05-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
cluster: "Mexico",
|
|
});
|
|
assert.match(mexicoSql, /"Cluster" = 'Mexico'/);
|
|
|
|
const defaultSql = fetchModule.buildManagerResourceWorkloadSql({
|
|
fromDateSql: "DATE '2026-05-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
});
|
|
assert.match(defaultSql, /"Cluster" = 'Brazil'/);
|
|
|
|
return "manager/resource workload cluster is explicit when provided and Brazil by default";
|
|
});
|
|
|
|
functionTest(
|
|
"workload-close-window-sql",
|
|
"workload close-window SQL supports date, cluster, owner, manager, and forecast filters",
|
|
{
|
|
entrada: "buildWorkloadCloseWindowSql com owner, manager e forecast",
|
|
},
|
|
() => {
|
|
const sql = fetchModule.buildWorkloadCloseWindowSql({
|
|
fromDateSql: "DATE '2026-05-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
cluster: "Mexico",
|
|
ownerEmail: "territory.owner@oracle.com",
|
|
ownerManagerEmail: "territory.manager@oracle.com",
|
|
forecastTypes: ["Forecast"],
|
|
});
|
|
|
|
assert.match(sql, /"Cluster" = 'Mexico'/);
|
|
assert.match(sql, /"Revenue Line Close Date" >= DATE '2026-05-01'/);
|
|
assert.match(sql, /"Level 7 Territory Owner E-mail" = 'territory.owner@oracle.com'/);
|
|
assert.match(sql, /"Level 2 Territory Owner E-mail" = 'territory.manager@oracle.com'/);
|
|
assert.match(sql, /"Revenue Line Forecast Type Group" IN \('Forecast'\)/);
|
|
return "workload SQL includes geography, window, owner hierarchy, and forecast filters";
|
|
});
|
|
|
|
functionTest(
|
|
"manager-email-list-normalization",
|
|
"manager email list filters normalize short ids, merge flags, and deduplicate",
|
|
{
|
|
entrada: "resolveManagerEmailListFilter com lista mista + --manager-email duplicado",
|
|
},
|
|
() => {
|
|
const result = fetchModule.resolveManagerEmailListFilter({
|
|
"manager-email-list": " Resource.Manager.B , resource.manager.a@oracle.com, RESOURCE.MANAGER.B@ORACLE.COM ",
|
|
"manager-email": "resource.manager.a",
|
|
});
|
|
|
|
assert.deepEqual(result.managerEmails, [
|
|
"resource.manager.a@oracle.com",
|
|
"resource.manager.b@oracle.com",
|
|
]);
|
|
assert.equal(
|
|
result.managerEmailsSqlList,
|
|
"'resource.manager.a@oracle.com', 'resource.manager.b@oracle.com'"
|
|
);
|
|
assert.throws(
|
|
() => fetchModule.resolveManagerEmailListFilter({ "manager-email-list": " , " }),
|
|
/Pass --manager-email-list or --manager-email/
|
|
);
|
|
return `managerEmails=${result.managerEmails.join(",")}`;
|
|
});
|
|
|
|
functionTest(
|
|
"coverage-limit-cap",
|
|
"coverage enrichment limit never exceeds Oracle DV maximum",
|
|
{
|
|
entrada: "resolveCoverageLimit com limites baixo, normal e alto",
|
|
},
|
|
() => {
|
|
assert.equal(fetchModule.resolveCoverageLimit(10), 5000);
|
|
assert.equal(fetchModule.resolveCoverageLimit(1000), 8000);
|
|
assert.equal(fetchModule.resolveCoverageLimit(5000), 10000);
|
|
assert.equal(fetchModule.resolveCoverageLimit(10000), 10000);
|
|
|
|
return "coverage limit is bounded to 5,000..10,000";
|
|
});
|
|
|
|
functionTest(
|
|
"current-workload-defaults",
|
|
"current workload defaults are documented and applied locally",
|
|
{
|
|
entrada: "applyCurrentWorkloadIntentDefaults para owner atual e month explícito",
|
|
},
|
|
() => {
|
|
assert.equal(catalogSaysCurrentWorkloadDefaults(catalogs, "workloads-by-owner-current"), true);
|
|
assert.equal(catalogSaysCurrentWorkloadDefaults(catalogs, "workloads-by-owner-manager-current"), true);
|
|
const expectedDefaults = parseCurrentWorkloadDefaults(catalogs, "workloads-by-owner-current");
|
|
|
|
const defaults = fetchModule.applyCurrentWorkloadIntentDefaults({
|
|
intent: "workloads-by-owner-current",
|
|
"owner-email": "territory.owner@oracle.com",
|
|
});
|
|
assert.equal(defaults.quarter, expectedDefaults.quarter);
|
|
assert.equal(defaults.solution, expectedDefaults.solution);
|
|
assert.equal(defaults["revenue-type-group"], expectedDefaults.revenueTypeGroup);
|
|
assert.equal(fetchModule.hasAnyDateWindowArgs(defaults), true);
|
|
|
|
const explicitMonth = fetchModule.applyCurrentWorkloadIntentDefaults({
|
|
month: "2026-04",
|
|
"owner-email": "territory.owner@oracle.com",
|
|
});
|
|
assert.equal(explicitMonth.month, "2026-04");
|
|
assert.equal(explicitMonth.quarter, undefined);
|
|
assert.equal(explicitMonth.solution, expectedDefaults.solution);
|
|
|
|
const ownerWindowDefaults = fetchModule.applyCloseWindowIntentDefaults({
|
|
intent: "workloads-by-owner-close-window",
|
|
"owner-email": "territory.owner@oracle.com",
|
|
});
|
|
assert.equal(ownerWindowDefaults["from-date"], "today");
|
|
assert.equal(ownerWindowDefaults["to-date"], "+7d");
|
|
assert.equal(ownerWindowDefaults.quarter, undefined);
|
|
|
|
const explicitWeek = fetchModule.applyCloseWindowIntentDefaults({
|
|
intent: "workloads-by-owner-close-window",
|
|
"owner-email": "territory.owner@oracle.com",
|
|
week: "w43",
|
|
});
|
|
assert.equal(explicitWeek.week, "w43");
|
|
assert.equal(explicitWeek["from-date"], undefined);
|
|
assert.equal(explicitWeek["to-date"], undefined);
|
|
return `quarter=${defaults.quarter}; solution=${defaults.solution}; revenueTypeGroup=${defaults["revenue-type-group"]}; explicitMonth preserved; closeWindowDefaults=${ownerWindowDefaults["from-date"]}..${ownerWindowDefaults["to-date"]}`;
|
|
});
|
|
|
|
functionTest(
|
|
"sa-attach-window-sql",
|
|
"SA Attach window SQL uses the documented revenue-line close date field",
|
|
{
|
|
entrada: "buildSaAttachOpportunityWhereClauses com janela 2026-03-01..2026-05-31",
|
|
},
|
|
() => {
|
|
assert.equal(catalogSaysUseRevenueLineCloseDate(catalogs), true);
|
|
|
|
const defaults = parseSaAttachDefaults(catalogs.initialContext);
|
|
const dateField = parseSaAttachDateWindowField(catalogs);
|
|
const dataset = parsePrimaryCommercialSubjectArea(catalogs.apiMap);
|
|
const clauses = fetchModule.buildSaAttachOpportunityWhereClauses({
|
|
dataset,
|
|
fiscalYear: null,
|
|
previousFiscalYear: null,
|
|
fromDateSql: "DATE '2026-03-01'",
|
|
toDateSql: "DATE '2026-05-31'",
|
|
cluster: defaults.cluster[0],
|
|
solutions: [defaults.solution[0]],
|
|
statuses: defaults.revenueLineStatus,
|
|
productLobs: [defaults.executiveProductLob[0]],
|
|
revenueTypeGroups: [defaults.revenueTypeGroup.at(-1)],
|
|
salesCreditType: defaults.salesCreditType[0],
|
|
minOpportunityProbability: Number(defaults.minOpportunityProbability[0]),
|
|
ownerEmail: "territory.owner@oracle.com",
|
|
ownerManagerEmail: "territory.manager@oracle.com",
|
|
forecastTypes: ["Forecast"],
|
|
});
|
|
const sql = clauses.join("\n");
|
|
|
|
assert.match(sql, new RegExp(escapeRegExp(dateField)));
|
|
assert.match(sql, /DATE '2026-03-01'/);
|
|
assert.match(sql, /DATE '2026-05-31'/);
|
|
assert.match(sql, /Level 7 Territory Owner E-mail/);
|
|
assert.match(sql, /Revenue Line Forecast Type Group/);
|
|
assert.doesNotMatch(sql, /Revenue Line Close Year/);
|
|
return `field=${dateField}; SQL inclui forecast/owner e não usa Revenue Line Close Year`;
|
|
});
|
|
|
|
functionTest(
|
|
"scope-sql",
|
|
"scope-related SQL follows catalog-backed org-wide and my-team rules",
|
|
{
|
|
entrada: "renderViewSql para Presales Aux, Hours e srs-by-resource-email",
|
|
},
|
|
() => {
|
|
const coverageOrg = fetchModule.renderViewSql("sa-attach-presales-coverage");
|
|
const coverageTeam = fetchModule.renderViewSql("sa-attach-presales-coverage", { scope: "my-team" });
|
|
const hoursOrg = fetchModule.renderViewSql("sa-attach-hours-by-opportunity");
|
|
const hoursTeam = fetchModule.renderViewSql("sa-attach-hours-by-opportunity", { scope: "my-team" });
|
|
const srTeam = fetchModule.renderViewSql("srs-by-resource-email", {
|
|
resourceEmailSql: "'resource.member@oracle.com'",
|
|
matchRole: "team",
|
|
srStatuses: [],
|
|
});
|
|
const srLead = fetchModule.renderViewSql("srs-by-resource-email", {
|
|
resourceEmailSql: "'resource.member@oracle.com'",
|
|
matchRole: "lead",
|
|
srStatuses: [],
|
|
});
|
|
|
|
assert.match(catalogs.skill, /Presales Involvement Aux - V1.*org-wide/s);
|
|
assert.doesNotMatch(coverageOrg, /SEC_ARIA_SI-SR-TEAM/);
|
|
assert.match(coverageTeam, /SEC_ARIA_SI-SR-TEAM/);
|
|
assert.doesNotMatch(hoursOrg, /SEC_ARIA_SI-SR-TEAM/);
|
|
assert.match(hoursTeam, /SEC_ARIA_SI-SR-TEAM/);
|
|
assert.match(srTeam, /SE Team Level 1 Email Address/);
|
|
assert.match(srTeam, /SE Team Level 4 Email Address/);
|
|
assert.match(srLead, /"Service Request"\."Lead Email" = 'resource.member@oracle.com'/);
|
|
return "org-wide sem SEC_ARIA; my-team com SEC_ARIA; SR team usa levels 1..4; lead só quando explícito";
|
|
});
|
|
|
|
functionTest(
|
|
"scope-components-contract",
|
|
"scope descriptors expose component-level source and scope details",
|
|
{
|
|
entrada: "buildIntentScopeDescriptor para mixed current-team e workload manager/resource",
|
|
},
|
|
() => {
|
|
const mixed = fetchModule.buildIntentScopeDescriptor(
|
|
"opportunities-current-team-close-window",
|
|
{ view: "opportunities-close-window" }
|
|
);
|
|
assert.equal(mixed.scopeMode, "mixed-consistent");
|
|
assert.equal(mixed.preserveUnmatchedRows, true);
|
|
assert.deepEqual(
|
|
mixed.components.map((component) => [component.name, component.scope]),
|
|
[
|
|
["commercialRows", "org-wide"],
|
|
["resourceCoverage", "my-team-only"],
|
|
]
|
|
);
|
|
assert.match(mixed.explanation, /Rows without a resource match stay/);
|
|
|
|
const orgWide = fetchModule.buildIntentScopeDescriptor(
|
|
"workloads-by-manager-resource-close-window",
|
|
{ view: "opportunities-close-window" }
|
|
);
|
|
assert.equal(orgWide.scopeMode, "org-wide");
|
|
assert.deepEqual(
|
|
orgWide.components.map((component) => [component.name, component.scope]),
|
|
[
|
|
["commercialRows", "org-wide"],
|
|
["managerResourceAllocation", "org-wide"],
|
|
]
|
|
);
|
|
assert.match(orgWide.explanation, /Manager\/resource allocation: org-wide/);
|
|
return `mixed=${mixed.components.length}; orgWide=${orgWide.components.length}`;
|
|
});
|
|
|
|
functionTest(
|
|
"current-team-summary",
|
|
"current-team coverage summaries preserve unmatched commercial rows",
|
|
{
|
|
entrada: "summarizeCurrentTeamOpportunityCoverage com 2 oportunidades e 1 cobertura",
|
|
},
|
|
() => {
|
|
assert.equal(catalogSaysPreserveMixedRows(catalogs), true);
|
|
|
|
const result = fetchModule.summarizeCurrentTeamOpportunityCoverage(
|
|
[
|
|
{
|
|
opportunityId: "OPP-1",
|
|
opportunityName: "Alpha",
|
|
customerName: "Acme",
|
|
opportunityStatus: "Open",
|
|
closeDate: "2026-03-31",
|
|
salesStage: "Develop",
|
|
bookingValue: 100000,
|
|
workloadAmount: 50000,
|
|
},
|
|
{
|
|
opportunityId: "OPP-2",
|
|
opportunityName: "Beta",
|
|
customerName: "Bravo",
|
|
opportunityStatus: "Open",
|
|
closeDate: "2026-04-01",
|
|
salesStage: "Close",
|
|
bookingValue: 200000,
|
|
workloadAmount: 75000,
|
|
},
|
|
],
|
|
[
|
|
{
|
|
opportunityId: "OPP-1",
|
|
seTeamLevel5EmailAddress: "engineer.one@oracle.com",
|
|
opportunityHoursAttribute: 6,
|
|
},
|
|
]
|
|
);
|
|
|
|
assert.equal(result.records.length, 2);
|
|
assert.equal(result.summary.totalWindowOpportunities, 2);
|
|
assert.equal(result.summary.matchedOpportunities, 1);
|
|
assert.equal(result.summary.unmatchedOpportunities, 1);
|
|
assert.equal(result.summary.totalBookingValue, 300000);
|
|
assert.equal(result.summary.totalWorkloadAmount, 125000);
|
|
|
|
const unmatched = result.records.find((record) => record.opportunityId === "OPP-2");
|
|
assert.deepEqual(unmatched.teamMemberEmails, []);
|
|
assert.equal(unmatched.coverageRows, 0);
|
|
return `records=${result.records.length}; matched=${result.summary.matchedOpportunities}; unmatched=${result.summary.unmatchedOpportunities}; totalWorkload=${result.summary.totalWorkloadAmount}`;
|
|
});
|
|
|
|
functionTest(
|
|
"manager-resource-summary",
|
|
"manager-resource workload summaries keep resource involvement details",
|
|
{
|
|
entrada: "summarizeOrgWideRevenueLineCoverage com cobertura Aux e cenário opcional com SR injetado",
|
|
},
|
|
() => {
|
|
const defaultResult = fetchModule.summarizeOrgWideRevenueLineCoverage(
|
|
[
|
|
{
|
|
closeDate: "2026-04-06",
|
|
revenueLineId: "RL-1",
|
|
opportunityId: "OPP-1",
|
|
opportunityName: "Alpha",
|
|
customerName: "Acme",
|
|
workloadAmount: 240000,
|
|
},
|
|
],
|
|
[
|
|
{
|
|
opportunityId: "OPP-1",
|
|
seTeamLevel4EmailAddress: "resource.manager.a@oracle.com",
|
|
seTeamLevel5EmailAddress: "resource.member.a@oracle.com",
|
|
},
|
|
{
|
|
opportunityId: "OPP-1",
|
|
seTeamLevel4EmailAddress: "resource.manager.b@oracle.com",
|
|
seTeamLevel5EmailAddress: "resource.member.b@oracle.com",
|
|
},
|
|
]
|
|
);
|
|
|
|
assert.deepEqual(defaultResult.records[0].resourceDetails, [
|
|
{
|
|
resourceEmail: "resource.member.a@oracle.com",
|
|
companionEmails: ["resource.member.b@oracle.com"],
|
|
},
|
|
{
|
|
resourceEmail: "resource.member.b@oracle.com",
|
|
companionEmails: ["resource.member.a@oracle.com"],
|
|
},
|
|
]);
|
|
assert.equal(Object.hasOwn(defaultResult.records[0].resourceDetails[0], "srNumbers"), false);
|
|
|
|
const result = fetchModule.summarizeOrgWideRevenueLineCoverage(
|
|
[
|
|
{
|
|
closeDate: "2026-04-06",
|
|
revenueLineId: "RL-1",
|
|
opportunityId: "OPP-1",
|
|
opportunityName: "Alpha",
|
|
customerName: "Acme",
|
|
workloadAmount: 240000,
|
|
},
|
|
{
|
|
closeDate: "2026-04-07",
|
|
revenueLineId: "RL-2",
|
|
opportunityId: "OPP-2",
|
|
opportunityName: "Beta",
|
|
customerName: "Bravo",
|
|
workloadAmount: 367000,
|
|
},
|
|
],
|
|
[
|
|
{
|
|
opportunityId: "OPP-1",
|
|
seTeamLevel4EmailAddress: "resource.manager.a@oracle.com",
|
|
seTeamLevel5EmailAddress: "resource.member.a@oracle.com",
|
|
},
|
|
{
|
|
opportunityId: "OPP-1",
|
|
seTeamLevel4EmailAddress: "resource.manager.b@oracle.com",
|
|
seTeamLevel5EmailAddress: "resource.member.b@oracle.com",
|
|
},
|
|
],
|
|
new Map([["OPP-1::resource.member.a@oracle.com", new Set(["SR-100"])] ]),
|
|
new Map([
|
|
[
|
|
"resource.member.a@oracle.com",
|
|
new Map([
|
|
["SR-900", { srNumber: "SR-900", customerName: "Acme", title: "Internal follow-up" }],
|
|
["SR-901", { srNumber: "SR-901", customerName: "Other Corp", title: "Ignore me" }],
|
|
]),
|
|
],
|
|
])
|
|
);
|
|
|
|
assert.equal(result.records.length, 1);
|
|
assert.equal(result.records[0].revenueLineId, "RL-1");
|
|
assert.deepEqual(result.records[0].managerEmails, [
|
|
"resource.manager.a@oracle.com",
|
|
"resource.manager.b@oracle.com",
|
|
]);
|
|
assert.deepEqual(result.records[0].resourceEmails, [
|
|
"resource.member.a@oracle.com",
|
|
"resource.member.b@oracle.com",
|
|
]);
|
|
|
|
const resourceA = result.records[0].resourceDetails.find(
|
|
(detail) => detail.resourceEmail === "resource.member.a@oracle.com"
|
|
);
|
|
assert.deepEqual(resourceA.srNumbers, ["SR-100", "SR-900"]);
|
|
assert.deepEqual(resourceA.directSrNumbers, ["SR-100"]);
|
|
assert.deepEqual(resourceA.candidateInternalSrNumbers, ["SR-900"]);
|
|
assert.equal(resourceA.srLinkageMode, "direct-plus-candidate-internal");
|
|
assert.deepEqual(resourceA.companionEmails, ["resource.member.b@oracle.com"]);
|
|
|
|
assert.equal(result.summary.totalWindowRevenueLines, 2);
|
|
assert.equal(result.summary.matchedRevenueLines, 1);
|
|
assert.equal(result.summary.matchedOpportunities, 1);
|
|
assert.equal(result.summary.totalWorkloadAmount, 240000);
|
|
assert.equal(result.summary.resourcesMatched, 2);
|
|
return `defaultResourceDetails=${defaultResult.records[0].resourceDetails.length}; defaultSrFields=omitted; optionalSrLinkage=${resourceA.srLinkageMode}; resourcesMatched=${result.summary.resourcesMatched}`;
|
|
});
|
|
|
|
functionTest(
|
|
"api-metrics",
|
|
"API metrics count raw backend rows and ignore local-cache-only rows",
|
|
{
|
|
entrada: "buildApiMetrics com rows 3 + 2 e cache local não contado",
|
|
},
|
|
() => {
|
|
assert.equal(catalogSaysApiMetricsAreRawRows(catalogs), true);
|
|
|
|
const metrics = fetchModule.buildApiMetrics([
|
|
{
|
|
label: "window",
|
|
result: { aResults: [[1], [2], [3]] },
|
|
},
|
|
{
|
|
label: "coverage",
|
|
result: { aResults: [[1], [2]] },
|
|
},
|
|
{
|
|
label: "sessionMetaCache",
|
|
rowsReturned: 0,
|
|
source: "session-meta-cache",
|
|
countedInTotal: false,
|
|
},
|
|
]);
|
|
|
|
assert.equal(metrics.totalRowsPulledFromApi, 5);
|
|
assert.equal(metrics.queries.length, 3);
|
|
assert.equal(metrics.explanation, "Raw rows pulled from API: 5.");
|
|
return `totalRowsPulledFromApi=${metrics.totalRowsPulledFromApi}; queries=${metrics.queries.length}; local-cache ignored`;
|
|
});
|
|
|
|
function formatFunctionResultsTable(rows) {
|
|
const header = ["id", "teste", "entrada", "saida", "avaliacao"];
|
|
const lines = [
|
|
`| ${header.join(" | ")} |`,
|
|
`| ${header.map(() => "---").join(" | ")} |`,
|
|
...rows.map((row) =>
|
|
`| ${markdownCell(row.id)} | ${markdownCell(row.teste)} | ${markdownCell(row.entrada)} | ${markdownCell(row.saida)} | ${markdownCell(row.avaliacao)} |`
|
|
),
|
|
];
|
|
return lines.join("\n");
|
|
}
|
|
|
|
function markdownCell(value) {
|
|
return String(value ?? "")
|
|
.replace(/\r?\n/g, "<br>")
|
|
.replace(/\|/g, "\\|");
|
|
}
|
|
|
|
function escapeRegExp(value) {
|
|
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
}
|