Files
Jyotisha/frontend/tests/database-personal-report-sections.test.ts
T
Jesse_Chen 0ae3e2d796
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
feat(reports): generate personal reports by section
2026-08-30 22:59:17 +08:00

157 lines
5.3 KiB
TypeScript

import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import test from "node:test";
import { startPostgresFixture } from "./helpers/postgres-fixture.ts";
const runnerPath = new URL("../scripts/db-migrate.mjs", import.meta.url).pathname;
const USER_A = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa";
const USER_B = "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
const REPORT_ID = "cccccccc-cccc-4ccc-8ccc-cccccccccccc";
const REQUEST_ID = "dddddddd-dddd-4ddd-8ddd-dddddddddddd";
const SECTION_ID = "theme-career";
function selectAsAuthenticated(userId: string, sql: string): string {
return `
set role authenticated;
select set_config('request.jwt.claim.sub', '${userId}', true);
${sql}
`;
}
function serviceSql(sql: string): string {
return `set role service_role;\n${sql}`;
}
test("personal report sections enforce owner-read RLS and service-owned durable transitions", () => {
const fixture = startPostgresFixture();
const schemaUrl = fixture.connectionUrl("schema_owner", "schema-owner-test-password");
try {
const migration = spawnSync(process.execPath, [runnerPath], {
encoding: "utf8",
env: { ...process.env, SCHEMA_DATABASE_URL: schemaUrl },
});
assert.equal(migration.status, 0, migration.stderr);
assert.match(migration.stdout, /applied 20260830020000_personal_report_sections\.sql/);
fixture.psql(`
insert into identity.users (id, name, email, email_verified, email_verified_at)
values
('${USER_A}', 'Section User A', 'section-a@example.com', true, now()),
('${USER_B}', 'Section User B', 'section-b@example.com', true, now());
insert into public.personal_reports (
id, user_id, request_id, request_fingerprint, report_type, status,
schema_version, presentation_mode, requested_themes, depth,
skill_name, skill_version, skill_source_commit, skill_snapshot_sha256
) values (
'${REPORT_ID}', '${USER_A}', '${REQUEST_ID}', '1111111111111111111111111111111111111111111111111111111111111111', 'personal_full', 'generating',
'report_document.v2', 'default', array['career']::text[], 'standard',
'jyotish-personal-report', '1.0.0', '2222222222222222222222222222222222222222', '3333333333333333333333333333333333333333333333333333333333333333'
);
`);
const own = fixture.psqlAs(
"app_runtime",
"app-runtime-test-password",
selectAsAuthenticated(USER_A, `
select count(*) from public.personal_report_sections
where user_id = '${USER_A}' and request_id = '${REQUEST_ID}'
`),
);
assert.equal(own, `SET\n${USER_A}\n0`);
fixture.psqlAs(
"service_runtime",
"service-runtime-test-password",
serviceSql(`
select status from public.ensure_personal_report_section(
'${USER_A}', '${REQUEST_ID}', '${SECTION_ID}', 2
);
select status from public.ensure_personal_report_section(
'${USER_A}', '${REQUEST_ID}', '${SECTION_ID}', 2
);
`),
);
assert.equal(
fixture.psql(`
select count(*) from public.personal_report_sections
where user_id = '${USER_A}' and request_id = '${REQUEST_ID}' and section_id = '${SECTION_ID}'
`),
"1",
);
assert.equal(
fixture.psqlAs(
"app_runtime",
"app-runtime-test-password",
selectAsAuthenticated(USER_A, `
select status || ':' || attempt_count from public.personal_report_sections
where user_id = '${USER_A}' and request_id = '${REQUEST_ID}' and section_id = '${SECTION_ID}'
`),
),
`SET\n${USER_A}\npending:0`,
);
assert.equal(
fixture.psqlAs(
"app_runtime",
"app-runtime-test-password",
selectAsAuthenticated(USER_B, `
select count(*) from public.personal_report_sections
where user_id = '${USER_A}' and request_id = '${REQUEST_ID}'
`),
),
`SET\n${USER_B}\n0`,
);
assert.throws(
() => fixture.psqlAs(
"app_runtime",
"app-runtime-test-password",
selectAsAuthenticated(USER_A, `
insert into public.personal_report_sections (user_id, request_id, section_id)
values ('${USER_A}', '${REQUEST_ID}', 'theme-wealth');
`),
),
/permission denied for table personal_report_sections/,
);
assert.equal(
fixture.psqlAs(
"service_runtime",
"service-runtime-test-password",
serviceSql(`
select status || ':' || attempt_count
from public.start_personal_report_section('${USER_A}', '${REQUEST_ID}', '${SECTION_ID}');
`),
),
"SET\npending:1",
);
assert.equal(
fixture.psqlAs(
"service_runtime",
"service-runtime-test-password",
serviceSql(`
select status || ':' || attempt_count
from public.complete_personal_report_section(
'${USER_A}', '${REQUEST_ID}', '${SECTION_ID}', '{"title":"事业"}'::jsonb
);
`),
),
"SET\nready:1",
);
assert.equal(
fixture.psqlAs(
"service_runtime",
"service-runtime-test-password",
serviceSql(`
select count(*) from public.start_personal_report_section('${USER_A}', '${REQUEST_ID}', '${SECTION_ID}');
`),
),
"SET\n0",
);
} finally {
fixture.stop();
}
});