FactuGES_ERP/tests/e2e/identity/tenant-cache.spec.ts

86 lines
3.8 KiB
TypeScript

import { randomUUID } from "node:crypto";
import { expect, test } from "@playwright/test";
import bcrypt from "../../../apps/server/node_modules/bcrypt/bcrypt.js";
import mysql from "../../../apps/server/node_modules/mysql2/promise.js";
import { loginViaUi } from "../support/login-via-ui";
// La cuenta secundaria solo se inserta en la BD efímera del launcher oficial.
test("IDENTITY-TENANT-CACHE: cambio de empresa y logout/login descartan el formulario anterior", async ({
page,
request,
}) => {
const email = process.env.E2E_USER_EMAIL;
const password = process.env.E2E_USER_PASSWORD;
if (!(email && password && process.env.DB_NAME?.startsWith("factuges_erp_e2e_"))) {
throw new Error("Requires the official isolated E2E environment.");
}
const login = await request.post("http://127.0.0.1:3002/api/v1/identity/auth/login", {
data: { email, password },
});
expect(login.status()).toBe(200);
await loginViaUi(page);
const tokens = await login.json();
const companyId = randomUUID();
const created = await request.post("http://127.0.0.1:3002/api/v1/companies", {
headers: { authorization: `Bearer ${tokens.access_token}` },
data: { id: companyId, legal_name: "Tenant cache B", slug: `cache-${companyId}` },
});
expect(created.status()).toBe(201);
const accountId = randomUUID();
const secondEmail = `cache-${accountId}@example.test`;
const connection = await mysql.createConnection({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASS,
});
try {
await connection.execute(
"INSERT INTO identity_accounts (id,email,password_hash,name,language_code,status,created_at,updated_at) VALUES (?,?,?,?, 'es','active',NOW(),NOW())",
[accountId, secondEmail, await bcrypt.hash(password, 4), "Tenant cache second user"]
);
const membershipId = randomUUID();
const roleId = randomUUID();
await connection.execute(
"INSERT INTO identity_roles (id,company_id,code,name,is_system,permission_codes,created_at,updated_at) VALUES (?,?,'commercial','Commercial',false,?,NOW(),NOW())",
[roleId, companyId, JSON.stringify(["identity:permissions:read"])]
);
await connection.execute(
"INSERT INTO identity_company_memberships (id,account_id,company_id,status,created_at,updated_at) VALUES (?,?,?,'active',NOW(),NOW())",
[membershipId, accountId, companyId]
);
await connection.execute(
"INSERT INTO identity_company_membership_roles (membership_id,role_id) VALUES (?,?)",
[membershipId, roleId]
);
await connection.execute(
"INSERT INTO initial_onboardings (id,account_id,status,company_id,created_at,updated_at,completed_at) VALUES (?,?,'completed',?,NOW(),NOW(),NOW())",
[randomUUID(), accountId, companyId]
);
} finally {
await connection.end();
}
await page.goto("/settings/company/details");
const name = page.locator('input[name="legalName"]');
await expect(name).toBeVisible();
await name.fill("Unsaved tenant A");
await page.getByTestId("company-switcher-trigger").click();
await page.getByTestId(`company-option-${companyId}`).click();
await expect(name).toHaveValue("Tenant cache B");
await name.fill("Unsaved old account");
await page.locator("#account-menu").click();
await page.locator("#account-logout").click();
await expect(page.locator("#login-email")).toBeVisible();
await page.locator("#login-email").fill(secondEmail);
await page.locator("#login-password").fill(password);
await page.locator("#login-submit").click();
await expect(page.locator("#account-menu")).toBeVisible();
await page.goto("/settings/company/details");
await expect(name).toHaveValue("Tenant cache B");
await expect(page.getByTestId("company-switcher-trigger")).toContainText("Tenant cache B");
});