NODEDC_PLATFORM/packages/external-provider-contract/test/data-product.test.mjs

112 lines
4.6 KiB
JavaScript

import assert from "node:assert/strict";
import {
DATA_PRODUCT_PATCH_SCHEMA_VERSION,
DATA_PRODUCT_PUBLISH_SCHEMA_VERSION,
DATA_PRODUCT_SNAPSHOT_SCHEMA_VERSION,
validateDataProductPatch,
validateDataProductPublish,
validateDataProductSnapshot,
} from "../src/index.mjs";
const fact = {
sourceId: "unit-42",
semanticType: "map.moving_object",
observedAt: "2026-07-15T10:00:00.000Z",
attributes: { status: "online" },
geometry: { type: "Point", coordinates: [37.6173, 55.7558] },
};
const attributesWithSerializedSize = (size) => ({
blob: "x".repeat(size - Buffer.byteLength(JSON.stringify({ blob: "" }))),
});
const publish = {
schemaVersion: DATA_PRODUCT_PUBLISH_SCHEMA_VERSION,
batch: { runId: "execution-42", sequence: 0, idempotencyKey: "execution-42.node-01.chunk-0" },
facts: [fact],
};
assert.equal(validateDataProductPublish(publish).ok, true);
assert.equal(validateDataProductPublish({
...publish,
source: { tenantId: "forged" },
}).errors.includes("publish.source_not_allowed"), true);
assert.equal(validateDataProductPublish({
...publish,
facts: [{ ...fact, attributes: { accessToken: "must-never-cross-the-boundary" } }],
}).errors.includes("publish_must_not_contain_secret_material"), true);
assert.equal(validateDataProductPublish({
...publish,
facts: [fact, { ...fact, observedAt: "2026-07-15T10:00:01.000Z" }],
}).errors.includes("facts_duplicate_entity_key"), true);
assert.equal(validateDataProductPublish({
...publish,
batch: { ...publish.batch, sequence: 2_147_483_647 },
}).ok, true);
assert.equal(validateDataProductPublish({
...publish,
batch: { ...publish.batch, sequence: 2_147_483_648 },
}).errors.includes("batch.sequence_must_be_integer_0_to_2147483647"), true);
assert.equal(validateDataProductPublish({
...publish,
facts: [{ ...fact, attributes: attributesWithSerializedSize(64 * 1024) }],
}).ok, true);
assert.equal(validateDataProductPublish({
...publish,
facts: [{ ...fact, attributes: attributesWithSerializedSize((64 * 1024) + 1) }],
}).errors.includes("facts[0].attributes_size_exceeded"), true);
assert.equal(validateDataProductPublish({
...publish,
facts: [{ ...fact, attributes: attributesWithSerializedSize((64 * 1024) + 1) }],
}, { maxAttributesBytes: 1024 * 1024 }).errors.includes("facts[0].attributes_size_exceeded"), true);
assert.equal(validateDataProductPublish({
...publish,
facts: [{ ...fact, geometry: { type: "Point", coordinates: [-180.0001, 55.7558] } }],
}).errors.includes("facts[0].geometry.longitude_out_of_range"), true);
assert.equal(validateDataProductPublish({
...publish,
facts: [{ ...fact, geometry: { type: "Point", coordinates: [37.6173, 90.0001] } }],
}).errors.includes("facts[0].geometry.latitude_out_of_range"), true);
const canonicalFact = { ...fact, receivedAt: "2026-07-15T10:00:01.000Z" };
const snapshot = {
schemaVersion: DATA_PRODUCT_SNAPSHOT_SCHEMA_VERSION,
dataProduct: { id: "fleet.positions.current.v1", version: "1.0.0" },
generatedAt: "2026-07-15T10:00:01.000Z",
cursor: "12",
facts: [canonicalFact],
};
assert.equal(validateDataProductSnapshot(snapshot).ok, true);
assert.equal(validateDataProductSnapshot({ ...snapshot, transport: "sse" }).errors.includes("snapshot.transport_not_allowed"), true);
assert.equal(validateDataProductSnapshot({
...snapshot,
facts: [{ ...canonicalFact, attributes: attributesWithSerializedSize((64 * 1024) + 1) }],
}).errors.includes("facts[0].attributes_size_exceeded"), true);
assert.equal(validateDataProductSnapshot({
...snapshot,
facts: [{ ...canonicalFact, attributes: { status: "ndc_edprb_forbidden-reader-token" } }],
}).errors.includes("snapshot_must_not_contain_secret_material"), true);
const patch = {
schemaVersion: DATA_PRODUCT_PATCH_SCHEMA_VERSION,
dataProduct: { id: "fleet.positions.current.v1", version: "1.0.0" },
cursor: "13",
previousCursor: "12",
emittedAt: "2026-07-15T10:00:02.000Z",
operations: [{ op: "upsert", fact: canonicalFact }],
};
assert.equal(validateDataProductPatch(patch).ok, true);
assert.equal(validateDataProductPatch({
...patch,
operations: [{ op: "delete", fact: canonicalFact }],
}).errors.includes("operations[0].op_must_be_upsert"), true);
assert.equal(validateDataProductPatch({
...patch,
operations: [{ op: "upsert", fact: { ...canonicalFact, attributes: attributesWithSerializedSize((64 * 1024) + 1) } }],
}).errors.includes("operations[0].fact.attributes_size_exceeded"), true);
assert.equal(validateDataProductPatch({
...patch,
operations: [{ op: "upsert", fact: { ...canonicalFact, attributes: { status: "ndc_edpwb_forbidden-writer-token" } } }],
}).errors.includes("patch_must_not_contain_secret_material"), true);
console.log("data-product-contract: ok");