import assert from "node:assert/strict"; import { InventoryResponseSchema } from "@metis/assets/common"; import { SoftwareInstallationResponseSchema, SoftwareInstallationsResponseSchema, } from "@metis/companies/common"; import { CatalogResponseSchema, ResourceResponseSchema } from "@metis/resources/common"; import type { Sequelize } from "sequelize"; import { migrateSoftwareInstallations } from "../../../modules/companies/src/api/infrastructure/persistence/software-installation-migration"; type Request = (path: string, body?: unknown, origin?: string, token?: string) => Promise; export async function verifySoftwareInstallations( request: Request, companyId: string, otherId: string, database: Sequelize ) { await migrateSoftwareInstallations(database); const inventory = InventoryResponseSchema.parse( await (await request(`/assets/${companyId}`)).json() ); const host = inventory.assets.find((asset) => asset.values.status !== "retired"); const otherHost = InventoryResponseSchema.parse( await (await request(`/assets/${otherId}`)).json() ).assets[0]; const catalog = CatalogResponseSchema.parse( await (await request(`/resource-catalog/${companyId}`)).json() ); const template = catalog.items.find((item) => item.builtinKey === "template:os"); const application = catalog.items.find((item) => item.builtinKey === "template:application"); const certificate = catalog.items.find((item) => item.builtinKey === "template:certificate"); assert.ok(host && otherHost && template && application && certificate); assert.ok(template.values.kind === "template" && template.values.usage === "os"); const addResource = async (templateId: string, name: string) => { const response = await request(`/resources/${companyId}`, { values: { name, templateId, active: true, notes: "", characteristics: {} }, }); assert.equal(response.status, 201, await response.clone().text()); return ResourceResponseSchema.parse(await response.json()).resource; }; const os = await addResource(template.id, "Windows 11 Pro test"); const app = await addResource(application.id, "Office equipo test"); const cert = await addResource(certificate.id, "Certificado no instalable como software"); const path = `/software-installations/${companyId}`; const values = { assetId: host.id, resourceId: os.id, version: "24H2", state: "configured", notes: null, }; const foreign = await request(path, { values: { ...values, assetId: otherHost.id } }); assert.equal(foreign.status, 404); assert.equal((await request(path, { values: { ...values, resourceId: cert.id } })).status, 404); assert.equal((await request(path, { values: { ...values, profileId: host.id } })).status, 400); assert.equal((await request(path, { values }, "https://other.example")).status, 403); assert.equal((await request(path, { values }, undefined, "a".repeat(64))).status, 403); const responses = await Promise.all([request(path, { values }), request(path, { values })]); assert.deepEqual(responses.map((response) => response.status).sort(), [201, 409]); const success = responses.find((response) => response.status === 201); assert.ok(success); const created = SoftwareInstallationResponseSchema.parse(await success.json()).configuration; const save = async (data: typeof values) => { const response = await request(`${path}/${created.id}/update`, { values: data }); assert.equal(response.status, 200, await response.clone().text()); return SoftwareInstallationResponseSchema.parse(await response.json()).configuration; }; assert.deepEqual(await save(values), created); const updated = await save({ ...values, version: "25H2" }); assert.equal(updated.history.length, 2); assert.equal(updated.history[0]?.values.version, "24H2"); assert.equal(updated.history[1]?.values.version, "25H2"); assert.equal((await request(path, { values: { ...values, resourceId: app.id } })).status, 201); assert.equal( (await request(`/software-installations/${otherId}/${created.id}/update`, { values })).status, 404 ); assert.equal( SoftwareInstallationsResponseSchema.parse( await (await request(`/software-installations/${otherId}`)).json() ).configurations.length, 0 ); const deactivate = await request(`/resources/${companyId}/${os.id}/update`, { values: { ...os.values, active: false }, }); assert.equal(deactivate.status, 200); const listed = SoftwareInstallationsResponseSchema.parse(await (await request(path)).json()); assert.equal(listed.configurations.find((item) => item.id === created.id)?.needsReview, true); await save({ ...values, version: "25H2", state: "removal_pending" }); await save({ ...values, version: "25H2", state: "removed" }); assert.equal((await request(`${path}/${created.id}/delete`, {})).status, 200); assert.equal((await request(`${path}/${created.id}/delete`, {})).status, 404); }