188 lines
6.8 KiB
TypeScript
188 lines
6.8 KiB
TypeScript
import assert from "node:assert/strict";
|
|
|
|
import { InventoryResponseSchema } from "@metis/assets/common";
|
|
import {
|
|
type AccessFieldsDTO,
|
|
AccessResponseSchema,
|
|
CompanyResponseSchema,
|
|
WorkProfileResponseSchema,
|
|
WorkProfilesResponseSchema,
|
|
} from "@metis/companies/common";
|
|
import type { Sequelize } from "sequelize";
|
|
import { z } from "zod/v4";
|
|
|
|
type Request = (path: string, body?: unknown, origin?: string, token?: string) => Promise<Response>;
|
|
export async function verifyWorkProfiles(
|
|
request: Request,
|
|
companyId: string,
|
|
otherId: string,
|
|
database: Sequelize
|
|
) {
|
|
const path = `/work-profiles/${companyId}`;
|
|
const inventory = InventoryResponseSchema.parse(
|
|
await (await request(`/assets/${companyId}`)).json()
|
|
);
|
|
const first = inventory.assets[0];
|
|
const second = inventory.assets[1];
|
|
assert.ok(first && second);
|
|
for (const item of [first, second]) {
|
|
if (item.values.status === "retired") {
|
|
assert.equal(
|
|
(
|
|
await request(`/assets/${companyId}/${item.id}/update`, {
|
|
values: { ...item.values, status: "available" },
|
|
})
|
|
).status,
|
|
200
|
|
);
|
|
}
|
|
}
|
|
const fields = {
|
|
name: "Persona perfiles",
|
|
position: null,
|
|
email: null,
|
|
phone: null,
|
|
active: true,
|
|
isContact: false,
|
|
};
|
|
const people = await request(`/companies/${companyId}/people`, fields);
|
|
assert.equal(people.status, 201);
|
|
const person = CompanyResponseSchema.parse(await people.json()).company.people.at(-1);
|
|
assert.ok(person);
|
|
const foreign = CompanyResponseSchema.parse(await (await request(`/companies/${otherId}`)).json())
|
|
.company.people[0];
|
|
assert.ok(foreign);
|
|
const input = {
|
|
name: "Perfil Ana",
|
|
personId: person.id,
|
|
assetId: first.id,
|
|
accountId: null,
|
|
active: true,
|
|
notes: null,
|
|
};
|
|
const save = async (values: unknown, id?: string) => {
|
|
const response = await request(path + (id ? `/${id}/update` : ""), { values });
|
|
assert.equal(response.status, id ? 200 : 201, await response.clone().text());
|
|
return WorkProfileResponseSchema.parse(await response.json()).profile;
|
|
};
|
|
const error = async (values: unknown, code: string, id?: string, status = 409) => {
|
|
const response = await request(path + (id ? `/${id}/update` : ""), { values });
|
|
assert.equal(response.status, status, await response.clone().text());
|
|
assert.equal(z.object({ code: z.string() }).parse(await response.json()).code, code);
|
|
};
|
|
await error({ ...input, personId: foreign.id }, "PROFILE_REFERENCE_NOT_FOUND", undefined, 404);
|
|
await error({ ...input, actorId: person.id }, "INVALID_REQUEST", undefined, 400);
|
|
assert.equal((await request(path, { values: input }, "https://other.example")).status, 403);
|
|
assert.equal((await request(path, { values: input }, undefined, "a".repeat(64))).status, 403);
|
|
const responses = await Promise.all([
|
|
request(path, { values: input }),
|
|
request(path, { values: input }),
|
|
]);
|
|
assert.deepEqual(responses.map((response) => response.status).sort(), [201, 409]);
|
|
const response = responses.find((response) => response.status === 201);
|
|
assert.ok(response);
|
|
const created = WorkProfileResponseSchema.parse(await response.json()).profile;
|
|
assert.equal(created.id.charAt(14), "7");
|
|
assert.equal(created.history[0]?.id.charAt(14), "7");
|
|
assert.ok(created.history[0]?.actorName);
|
|
assert.deepEqual(await save(input, created.id), created);
|
|
const another = await save({ ...input, assetId: second.id });
|
|
assert.equal(another.values.personId, created.values.personId);
|
|
const otherPersonResponse = await request(`/companies/${companyId}/people`, {
|
|
...fields,
|
|
name: "Otra persona perfiles",
|
|
});
|
|
const otherPerson = CompanyResponseSchema.parse(
|
|
await otherPersonResponse.json()
|
|
).company.people.at(-1);
|
|
assert.ok(otherPerson);
|
|
await save({ ...input, personId: otherPerson.id });
|
|
await error({ ...input, assetId: second.id }, "PROFILE_TARGET_IMMUTABLE", created.id);
|
|
const createAccess = async (values: AccessFieldsDTO) => {
|
|
const res = await request(`/access/${companyId}`, { values });
|
|
assert.equal(res.status, 201, await res.clone().text());
|
|
const item = AccessResponseSchema.parse(await res.json()).items.at(-1);
|
|
assert.ok(item);
|
|
return item;
|
|
};
|
|
const system = await createAccess({ kind: "system", name: "Dominio perfiles", active: true });
|
|
const account = await createAccess({
|
|
kind: "account",
|
|
systemId: system.id,
|
|
environmentId: null,
|
|
login: "ana-perfil",
|
|
usage: "personal",
|
|
active: true,
|
|
expiresOn: null,
|
|
notes: null,
|
|
});
|
|
await error({ ...input, accountId: account.id }, "PROFILE_REFERENCE_UNAVAILABLE", created.id);
|
|
await createAccess({
|
|
kind: "account_person",
|
|
accountId: account.id,
|
|
personId: person.id,
|
|
startDate: new Date().toISOString().slice(0, 10),
|
|
endDate: null,
|
|
configuration: "pending",
|
|
});
|
|
const withAccount = await save({ ...input, accountId: account.id }, created.id);
|
|
assert.equal(withAccount.history.length, 2);
|
|
assert.equal(withAccount.history[0]?.values.accountId, null);
|
|
assert.equal(
|
|
(
|
|
await request(`/access/${companyId}/${account.id}/update`, {
|
|
values: { ...account.values, active: false },
|
|
})
|
|
).status,
|
|
200
|
|
);
|
|
const reviewed = WorkProfilesResponseSchema.parse(
|
|
await (await request(path)).json()
|
|
).profiles.find((item) => item.id === created.id);
|
|
assert.equal(reviewed?.needsReview, true);
|
|
const archived = await save({ ...withAccount.values, active: false }, created.id);
|
|
assert.equal(archived.needsReview, false);
|
|
await error(withAccount.values, "PROFILE_REFERENCE_UNAVAILABLE", created.id);
|
|
const replacement = await save(input);
|
|
assert.notEqual(replacement.id, created.id);
|
|
assert.equal(
|
|
(await request(`/work-profiles/${otherId}/${created.id}/update`, { values: input })).status,
|
|
404
|
|
);
|
|
assert.equal(
|
|
WorkProfilesResponseSchema.parse(await (await request(`/work-profiles/${otherId}`)).json())
|
|
.profiles.length,
|
|
0
|
|
);
|
|
await database.query("UPDATE work_profiles SET currentKey=NULL WHERE id=:id", {
|
|
replacements: { id: replacement.id },
|
|
});
|
|
try {
|
|
assert.equal((await request(path)).status, 500);
|
|
} finally {
|
|
await database.query("UPDATE work_profiles SET currentKey=:key WHERE id=:id", {
|
|
replacements: { id: replacement.id, key: [person.id, first.id].join(":") },
|
|
});
|
|
}
|
|
const listed = WorkProfilesResponseSchema.parse(await (await request(path)).json());
|
|
assert.deepEqual(
|
|
listed.profiles.find((item) => item.id === created.id),
|
|
archived
|
|
);
|
|
assert.equal(
|
|
(
|
|
await request(`/companies/${companyId}/people/${person.id}/update`, {
|
|
...fields,
|
|
active: false,
|
|
})
|
|
).status,
|
|
200
|
|
);
|
|
assert.equal(
|
|
WorkProfilesResponseSchema.parse(await (await request(path)).json()).profiles.find(
|
|
(item) => item.id === replacement.id
|
|
)?.needsReview,
|
|
true
|
|
);
|
|
}
|