test/unit/services/asset.type.systemtype.mappings.service.spec.tsaddedimport sinon from "sinon";
import * as chai from "chai";
import chaiAsPromised from "chai-as-promised";
import sinonChai from "sinon-chai";
import * as db from "../../../src/db/db";
import * as service from "../../../src/services/asset.type.systemtype.mappings.service";
import { DB_ConstraintViolationError, NotFoundError, ResourceConflictError } from "../../../src/types/errortypes";
const expect = chai.expect;
chai.use(chaiAsPromised).use(sinonChai);
/* eslint-disable @typescript-eslint/no-explicit-any */
describe("AssetTypeSystemTypeMappings Service unit tests", () => {
let queryStub: sinon.SinonStub;
const projectId = "443b4964-09df-4f86-9e98-7bec5a9fcdab";
const mappingId = "8b141d85-3305-4bdd-b802-e83639c260e8";
const assetTypeId = "cccccccc-dddd-eeee-ffff-aaaaaaaaaaaa";
const systemTypeId = "66666666-7777-8888-9999-000000000000";
const dbRow = {
AssetTypeSystemTypeMappingId: mappingId,
AssetTypeId: assetTypeId,
SystemTypeId: systemTypeId,
CreatedBy: "user@example.com",
InsertedOn: new Date("2025-01-01T00:00:00Z"),
LastModifiedOn: null,
LastModifiedBy: null,
};
beforeEach(() => {
queryStub = sinon.stub(db, "query");
});
afterEach(() => {
sinon.restore();
});
describe("listMappings", () => {
it("should map the rows returned by the DB", async () => {
queryStub.resolves({ rows: [dbRow] });
const result = await service.listMappings(projectId);
expect(result).to.have.length(1);
expect(result[0]).to.deep.equal({
mappingId,
assetTypeId,
systemTypeId,
createdBy: "user@example.com",
insertedOn: dbRow.InsertedOn,
lastModifiedOn: null,
lastModifiedBy: null,
});
});
});
describe("getMappingById", () => {
it("should return the mapping when found", async () => {
queryStub.resolves({ rows: [dbRow] });
const result = await service.getMappingById(projectId, mappingId);
expect(result.mappingId).to.equal(mappingId);
});
it("should throw NotFoundError when no row is returned", async () => {
queryStub.resolves({ rows: [] });
await expect(service.getMappingById(projectId, mappingId)).to.be.rejectedWith(NotFoundError);
});
});
describe("createMapping", () => {
it("should insert and return the created mapping", async () => {
queryStub.resolves({ rows: [dbRow] });
const result = await service.createMapping(projectId, assetTypeId, systemTypeId);
expect(result.assetTypeId).to.equal(assetTypeId);
expect(result.systemTypeId).to.equal(systemTypeId);
});
it("should map a missing asset type to NotFoundError", async () => {
queryStub.rejects(new Error("AssetType with id does not exist"));
await expect(service.createMapping(projectId, assetTypeId, systemTypeId)).to.be.rejectedWith(NotFoundError);
});
it("should map a missing system type to NotFoundError", async () => {
queryStub.rejects(new Error("SystemType with id does not exist"));
await expect(service.createMapping(projectId, assetTypeId, systemTypeId)).to.be.rejectedWith(NotFoundError);
});
it("should map a unique constraint violation to ResourceConflictError", async () => {
queryStub.rejects(new DB_ConstraintViolationError('duplicate key value violates unique constraint "AssetTypeSystemTypeMapping_ProjectShardId_AssetTypeId_key"'));
await expect(service.createMapping(projectId, assetTypeId, systemTypeId)).to.be.rejectedWith(ResourceConflictError);
});
});
describe("deleteMapping", () => {
it("should throw NotFoundError when the mapping does not exist", async () => {
queryStub.resolves({ rows: [] });
await expect(service.deleteMapping(projectId, mappingId)).to.be.rejectedWith(NotFoundError);
});
it("should delete the mapping when it exists", async () => {
queryStub.onCall(0).resolves({ rows: [dbRow] });
queryStub.onCall(1).resolves({ rows: [] });
await service.deleteMapping(projectId, mappingId);
expect(queryStub.callCount).to.equal(2);
});
});
describe("getAssetTypeToSystemTypeMap", () => {
it("should build a map keyed by assetTypeId", async () => {
queryStub.resolves({ rows: [dbRow] });
const map = await service.getAssetTypeToSystemTypeMap(projectId);
expect(map.get(assetTypeId)).to.equal(systemTypeId);
});
});
});