@accounter/server
Version:
Accounter GraphQL server
146 lines (126 loc) • 5.67 kB
text/typescript
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { EntityEnsureProvider } from '../modules/financial-entities/providers/entity-ensure.provider.js';
import { UUID_REGEX } from '../shared/constants.js';
import { TestDatabase } from './helpers/db-setup.js';
import { TenantAwareDBClient } from '../modules/app-providers/tenant-db-client.js';
/**
* Integration tests for the green-field client bootstrap flow.
*
* These tests validate the DB-side logic (entity creation, user_context, super_admins table)
* without invoking Auth0 or the full GraphQL stack.
*/
describe('bootstrapNewClient integration', () => {
let db: TestDatabase;
let entityEnsure: EntityEnsureProvider;
beforeAll(async () => {
db = new TestDatabase();
await db.connect();
entityEnsure = new EntityEnsureProvider(db as unknown as TenantAwareDBClient);
});
afterAll(async () => {
// Pool managed by global vitest setup — do not close here.
});
it('should create all required entities for a new client tenant', async () => {
await db.withTransaction(async client => {
const { makeUUID } = await import('../demo-fixtures/helpers/deterministic-uuid.js');
const businessName = 'Test Corp';
const adminId = makeUUID('business', businessName);
// Set RLS context (allow_bootstrap_root policy: permits INSERT where id = current_business_id)
await client.query(`SELECT set_config('app.current_business_id', $1, true)`, [adminId]);
// Insert admin entity via direct SQL (same as manual DB test that passes)
await client.query(
`INSERT INTO accounter_schema.financial_entities (id, name, type, owner_id)
VALUES ($1, $2, 'business', NULL)
ON CONFLICT (id) DO NOTHING`,
[adminId, businessName],
);
await client.query(
`INSERT INTO accounter_schema.businesses (id, country, owner_id)
VALUES ($1, 'ISR', $1)
ON CONFLICT (id) DO NOTHING`,
[adminId],
);
await client.query(`UPDATE accounter_schema.financial_entities SET owner_id = $1 WHERE id = $1`, [adminId]);
expect(adminId).toMatch(UUID_REGEX);
// Verify self-owned
const entity = await client.query(
`SELECT owner_id FROM accounter_schema.financial_entities WHERE id = $1`,
[adminId],
);
expect(entity.rows[0].owner_id).toBe(adminId);
// Authority businesses
for (const name of ['VAT', 'Tax', 'Social Security']) {
const { id } = await entityEnsure.ensureFinancialEntity({
name,
type: 'business',
ownerId: adminId,
}, client);
await entityEnsure.ensureBusinessForEntity(id, {
isDocumentsOptional: true,
ownerId: adminId,
}, client);
expect(id).toMatch(UUID_REGEX);
}
// Authority tax categories
for (const name of ['Input Vat', 'Output Vat', 'Property Output Vat', 'Tax Expenses']) {
const { id } = await entityEnsure.ensureFinancialEntity({
name,
type: 'tax_category',
ownerId: adminId,
} ,client, );
await entityEnsure.ensureTaxCategoryForEntity(id, { ownerId: adminId }, client);
expect(id).toMatch(UUID_REGEX);
}
// Verify business count
const businesses = await client.query(
`SELECT id FROM accounter_schema.businesses WHERE owner_id = $1 OR id = $1`,
[adminId],
);
expect(businesses.rows.length).toBeGreaterThanOrEqual(4); // admin + 3 authorities
});
});
it('should be idempotent when called twice', async () => {
await db.withTransaction(async client => {
const { makeUUID } = await import('../demo-fixtures/helpers/deterministic-uuid.js');
const precomputedId = makeUUID('business', 'Idempotent Corp');
const bootstrap = async () => {
await client.query(`SELECT set_config('app.current_business_id', $1, true)`, [precomputedId]);
await entityEnsure.ensureFinancialEntity({ id: precomputedId, name: 'Idempotent Corp', type: 'business' }, client);
await entityEnsure.ensureBusinessForEntity(precomputedId, { ownerId: precomputedId }, client);
await client.query(`UPDATE accounter_schema.financial_entities SET owner_id = $1 WHERE id = $1`, [precomputedId]);
return precomputedId;
};
const id1 = await bootstrap();
const id2 = await bootstrap();
expect(id1).toBe(id2);
const result = await client.query(
`SELECT COUNT(*) FROM accounter_schema.financial_entities WHERE name = 'Idempotent Corp'`,
);
expect(Number(result.rows[0].count)).toBe(1);
});
});
it('should register and verify a super-admin', async () => {
await db.withTransaction(async client => {
const testAuth0Id = 'auth0|test-super-admin-123';
// Insert super admin
await client.query(
`INSERT INTO accounter_schema.super_admins (auth0_user_id, note)
VALUES ($1, $2) ON CONFLICT (auth0_user_id) DO NOTHING`,
[testAuth0Id, 'integration test'],
);
// Verify it exists
const result = await client.query(
`SELECT auth0_user_id FROM accounter_schema.super_admins WHERE auth0_user_id = $1`,
[testAuth0Id],
);
expect(result.rows).toHaveLength(1);
expect(result.rows[0].auth0_user_id).toBe(testAuth0Id);
// Verify a non-super-admin returns empty
const none = await client.query(
`SELECT auth0_user_id FROM accounter_schema.super_admins WHERE auth0_user_id = $1`,
['auth0|not-a-super-admin'],
);
expect(none.rows).toHaveLength(0);
});
});
});