Ctrl K
ComunidadGuías…

schema/list-view-personal-default.integration.test.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * An owner has at most one live personal default list view per record type.
 *
 * The unique partial index admits defaults for other owners, organization
 * views, inactive views and non-default personal views, and refuses a second
 * live personal default for the same organization, owner and record type.
 */
import assert from "node:assert/strict";
import { randomUUID } from "node:crypto";
import test from "node:test";
import pg from "pg";

const DB = Boolean(process.env.OPENBOOKS_DB_URL);

function adminConnectionString() {
  const explicit = process.env.OPENBOOKS_TEST_ADMIN_DB_URL;
  if (explicit) return explicit.trim();
  const runtime = process.env.OPENBOOKS_DB_URL;
  if (!runtime) return "";
  const url = new URL(runtime);
  url.username = "openbooks";
  url.password = process.env.PGPASSWORD || "openbooks";
  return url.href;
}

function postgresCode(error) {
  let current = error;
  for (let depth = 0; depth < 5 && current && typeof current === "object"; depth += 1) {
    if (current.code) return current.code;
    current = current.cause;
  }
  return undefined;
}

async function seedTenant(client) {
  const orgId = randomUUID();
  const ownerId = randomUUID();
  const otherOwnerId = randomUUID();
  await client.query(
    `insert into orgs (id, name, base_currency, country, settings, env_kind)
     values ($1, 'List view tenant', 'CAD', 'CA', '{}'::jsonb, 'production')`,
    [orgId],
  );
  for (const [id, name] of [
    [ownerId, "Owner"],
    [otherOwnerId, "Other owner"],
  ]) {
    await client.query(
      `insert into users (id, org_id, email, name, password_hash, is_active)
       values ($1, $2, $3, $4, 'x', true)`,
      [id, orgId, `${id.slice(0, 8)}@list-view.test`, name],
    );
  }
  return { orgId, ownerId, otherOwnerId };
}

async function insertListView(client, { orgId, name, scope, ownerId, isDefault, isActive }) {
  const id = randomUUID();
  await client.query(
    `insert into list_views (
       id, org_id, record_type, name, scope, owner_id, is_default, is_active, config
     ) values ($1, $2, 'invoice', $3, $4, $5, $6, $7, '{}'::jsonb)`,
    [id, orgId, name, scope, ownerId, isDefault, isActive],
  );
  return id;
}

test(
  "a second live personal list-view default for the same owner and record type is refused",
  { skip: !DB },
  async () => {
    const client = new pg.Client({ connectionString: adminConnectionString() });
    await client.connect();
    try {
      await client.query("begin");
      await client.query("select set_config('app.bypass_rls', 'on', true)");
      const index = await client.query(
        `select pg_get_indexdef(oid) as definition from pg_class
          where relname = 'list_views_one_live_personal_default' and relkind = 'i'`,
      );
      assert.equal(index.rows.length, 1, "list_views_one_live_personal_default must exist");
      assert.match(
        index.rows[0].definition,
        /^CREATE UNIQUE INDEX list_views_one_live_personal_default ON (?:public\.)?list_views USING btree \(org_id, owner_id, record_type\) WHERE \(\(scope = 'user'::text\) AND is_default AND is_active\)$/,
      );

      const tenant = await seedTenant(client);
      const firstId = await insertListView(client, {
        orgId: tenant.orgId,
        name: "My invoices",
        scope: "user",
        ownerId: tenant.ownerId,
        isDefault: true,
        isActive: true,
      });
      for (const admitted of [
        {
          name: "Other owner invoices",
          scope: "user",
          ownerId: tenant.otherOwnerId,
          isDefault: true,
          isActive: true,
        },
        { name: "Shared invoices", scope: "org", ownerId: null, isDefault: true, isActive: true },
        {
          name: "Inactive personal",
          scope: "user",
          ownerId: tenant.ownerId,
          isDefault: true,
          isActive: false,
        },
        {
          name: "Non-default personal",
          scope: "user",
          ownerId: tenant.ownerId,
          isDefault: false,
          isActive: true,
        },
      ]) {
        await insertListView(client, { orgId: tenant.orgId, ...admitted });
      }

      await client.query("savepoint before_second_live_default");
      await assert.rejects(
        insertListView(client, {
          orgId: tenant.orgId,
          name: "Second default",
          scope: "user",
          ownerId: tenant.ownerId,
          isDefault: true,
          isActive: true,
        }),
        (error) => {
          assert.equal(postgresCode(error), "23505");
          return true;
        },
      );
      await client.query("rollback to savepoint before_second_live_default");

      const stored = await client.query(
        `select id from list_views
          where org_id = $1 and owner_id = $2 and record_type = 'invoice'
            and scope = 'user' and is_default and is_active`,
        [tenant.orgId, tenant.ownerId],
      );
      assert.deepEqual(
        stored.rows.map((row) => row.id),
        [firstId],
      );
    } finally {
      await client.query("rollback").catch(() => undefined);
      await client.end();
    }
  },
);