189 lines
8.2 KiB
TypeScript
189 lines
8.2 KiB
TypeScript
import assert from "node:assert/strict";
|
|
|
|
import { AccessResponseSchema, MailboxesResponseSchema } from "@metis/companies/common";
|
|
import type { ResourceDTO } from "@metis/resources/common";
|
|
import { InventoryResponseSchema, ResourceResponseSchema } from "@metis/resources/common";
|
|
import { createResourceModule } from "@metis/resources/module";
|
|
import { QueryTypes, type Sequelize } from "sequelize";
|
|
import { z } from "zod/v4";
|
|
|
|
type Request = (path: string, body?: unknown) => Promise<Response>;
|
|
export async function verifyResourceMigration(
|
|
request: Request,
|
|
companyId: string,
|
|
otherId: string,
|
|
database: Sequelize
|
|
) {
|
|
const sources = await database.query<{ id: string; kind: string }>(
|
|
"SELECT id,'mailbox' AS kind FROM mailboxes WHERE companyId=:companyId UNION ALL SELECT i.id,'access' AS kind FROM access_items i JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:companyId AND i.kind='resource'",
|
|
{ replacements: { companyId }, type: QueryTypes.SELECT }
|
|
);
|
|
const originalMail = MailboxesResponseSchema.parse(
|
|
await (await request(`/mailboxes/${companyId}`)).json()
|
|
);
|
|
const originalAccess = AccessResponseSchema.parse(
|
|
await (await request(`/access/${companyId}`)).json()
|
|
);
|
|
const result = await request(`/resources/${companyId}`);
|
|
assert.equal(result.status, 200);
|
|
const inventory = InventoryResponseSchema.parse(await result.json());
|
|
for (const source of sources) {
|
|
const resource = inventory.resources.find((item) => item.id === source.id);
|
|
assert.ok(resource);
|
|
assert.equal(resource.values.integration?.kind, source.kind);
|
|
verifySourceValues(resource, originalMail, originalAccess);
|
|
const table = source.kind === "mailbox" ? "mailbox_revisions" : "access_revisions";
|
|
const revisions = await database.query<{ id: string; actorId: string; recordedAt: string }>(
|
|
`SELECT id,actorId,recordedAt FROM ${table} WHERE itemId=:id`,
|
|
{ replacements: { id: source.id }, type: QueryTypes.SELECT }
|
|
);
|
|
assert.equal(resource.history.length, revisions.length);
|
|
for (const old of revisions) {
|
|
const current: ResourceDTO["history"][number] | undefined = resource.history.find(
|
|
(item) => item.id === old.id
|
|
);
|
|
assert.ok(current);
|
|
assert.equal(current.actorId, old.actorId);
|
|
assert.equal(current.recordedAt, old.recordedAt);
|
|
}
|
|
}
|
|
const module = await createResourceModule(database, (_request, _response, next) => next());
|
|
await module.migrateLegacy();
|
|
const again = InventoryResponseSchema.parse(
|
|
await (await request(`/resources/${companyId}`)).json()
|
|
);
|
|
assert.deepEqual(
|
|
again.resources.map((item) => [item.id, item.history.map((row) => row.id)]).sort(),
|
|
inventory.resources.map((item) => [item.id, item.history.map((row) => row.id)]).sort()
|
|
);
|
|
const mailbox = inventory.resources.find((item) => item.values.integration?.kind === "mailbox");
|
|
assert.ok(mailbox && mailbox.values.integration?.kind === "mailbox");
|
|
const integration = mailbox.values.integration;
|
|
const values = { ...mailbox.values, active: false, notes: "Revisión desde Recursos" };
|
|
const system = inventory.references?.find((item) => item.kind === "system");
|
|
assert.ok(system);
|
|
const wrongReference = await request(`/resources/${companyId}/${mailbox.id}/update`, {
|
|
values: { ...values, integration: { ...integration, accountId: system.id } },
|
|
});
|
|
assert.equal(wrongReference.status, 409);
|
|
assert.equal(
|
|
z.object({ code: z.string() }).parse(await wrongReference.json()).code,
|
|
"REFERENCE_UNAVAILABLE"
|
|
);
|
|
const invalidEmail = await request(`/resources/${companyId}/${mailbox.id}/update`, {
|
|
values: {
|
|
...values,
|
|
characteristics: {
|
|
...values.characteristics,
|
|
[integration.addressFieldId]: "correo-invalido",
|
|
},
|
|
},
|
|
});
|
|
assert.equal(invalidEmail.status, 409);
|
|
assert.equal(
|
|
z.object({ code: z.string() }).parse(await invalidEmail.json()).code,
|
|
"INVALID_EMAIL"
|
|
);
|
|
const duplicate = await request(`/resources/${companyId}`, {
|
|
values: {
|
|
...mailbox.values,
|
|
name: "Otro nombre",
|
|
characteristics: {
|
|
...mailbox.values.characteristics,
|
|
[integration.addressFieldId]: String(
|
|
mailbox.values.characteristics[integration.addressFieldId]
|
|
).toUpperCase(),
|
|
},
|
|
},
|
|
});
|
|
assert.equal(duplicate.status, 409);
|
|
assert.equal(z.object({ code: z.string() }).parse(await duplicate.json()).code, "NAME_EXISTS");
|
|
const changed = await request(`/resources/${companyId}/${mailbox.id}/update`, { values });
|
|
assert.equal(changed.status, 200);
|
|
const updated = ResourceResponseSchema.parse(await changed.json()).resource;
|
|
assert.equal(updated.history.length, mailbox.history.length + 1);
|
|
assert.equal(updated.id, mailbox.id);
|
|
const boxes = MailboxesResponseSchema.parse(
|
|
await (await request(`/mailboxes/${companyId}`)).json()
|
|
);
|
|
assert.equal(boxes.mailboxes.find((item) => item.id === mailbox.id)?.values.active, false);
|
|
assert.equal(
|
|
boxes.mailboxes.find((item) => item.id === mailbox.id)?.values.accountId,
|
|
integration.accountId
|
|
);
|
|
assert.equal(
|
|
(await request(`/resources/${otherId}/${mailbox.id}/update`, { values })).status,
|
|
404
|
|
);
|
|
assert.equal(
|
|
(
|
|
await request(`/mailboxes/${companyId}/${mailbox.id}/update`, {
|
|
values: {
|
|
address: mailbox.values.characteristics[integration.addressFieldId],
|
|
kind: integration.mailboxKind,
|
|
context: null,
|
|
accountId: integration.accountId,
|
|
active: true,
|
|
notes: null,
|
|
},
|
|
})
|
|
).status,
|
|
409
|
|
);
|
|
const access = inventory.resources.find((item) => item.values.integration?.kind === "access");
|
|
assert.ok(access && access.values.integration?.kind === "access");
|
|
const referenceField = access.values.integration.referenceFieldId;
|
|
const nextValues = {
|
|
...access.values,
|
|
characteristics: { ...access.values.characteristics, [referenceField]: "\\\\SERVER\\Revision" },
|
|
};
|
|
const saved = await request(`/resources/${companyId}/${access.id}/update`, {
|
|
values: nextValues,
|
|
});
|
|
assert.equal(saved.status, 200);
|
|
const snapshot = AccessResponseSchema.parse(await (await request(`/access/${companyId}`)).json());
|
|
const projected = snapshot.items.find((item) => item.id === access.id);
|
|
assert.ok(projected && projected.values.kind === "resource");
|
|
assert.equal(projected.values.reference, nextValues.characteristics[referenceField]);
|
|
const oldWrite = await request(`/access/${companyId}/${access.id}/update`, {
|
|
values: projected.values,
|
|
});
|
|
assert.equal(oldWrite.status, 409);
|
|
assert.equal(z.object({ code: z.string() }).parse(await oldWrite.json()).code, "RESOURCE_MOVED");
|
|
}
|
|
|
|
function verifySourceValues(
|
|
resource: ResourceDTO,
|
|
originalMail: z.infer<typeof MailboxesResponseSchema>,
|
|
originalAccess: z.infer<typeof AccessResponseSchema>
|
|
) {
|
|
const source = { id: resource.id };
|
|
const integration = resource.values.integration;
|
|
if (integration?.kind === "mailbox") {
|
|
const sourceValues = originalMail.mailboxes.find((item) => item.id === source.id)?.values;
|
|
assert.ok(sourceValues);
|
|
assert.equal(resource.values.characteristics[integration.addressFieldId], sourceValues.address);
|
|
assert.equal(
|
|
resource.values.characteristics[integration.contextFieldId] ?? null,
|
|
sourceValues.context
|
|
);
|
|
assert.equal(integration.mailboxKind, sourceValues.kind);
|
|
assert.equal(integration.accountId, sourceValues.accountId);
|
|
assert.equal(resource.values.active, sourceValues.active);
|
|
assert.equal(resource.values.notes, sourceValues.notes ?? "");
|
|
} else if (integration?.kind === "access") {
|
|
const sourceValues = originalAccess.items.find((item) => item.id === source.id)?.values;
|
|
assert.ok(sourceValues?.kind === "resource");
|
|
assert.equal(resource.values.name, sourceValues.name);
|
|
assert.equal(
|
|
resource.values.characteristics[integration.referenceFieldId] ?? null,
|
|
sourceValues.reference
|
|
);
|
|
assert.equal(integration.resourceTypeId, sourceValues.resourceTypeId);
|
|
assert.equal(integration.systemId, sourceValues.systemId);
|
|
assert.equal(integration.environmentId, sourceValues.environmentId);
|
|
assert.equal(resource.values.active, sourceValues.active);
|
|
assert.equal(resource.values.notes, sourceValues.notes ?? "");
|
|
}
|
|
}
|