Files
Jyotisha/frontend/tests/database-report-candidate-range.test.ts
T
Jesse_Chen 7baf230066 fix(report): load candidate ranges through a read-only RPC
Accepted profiles were selecting a revoked rectification table and failing the report before the engine ran. Degrade to a null window when that optional read fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 19:17:14 +08:00

187 lines
7.0 KiB
TypeScript

import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import test from "node:test";
import { startPostgresFixture } from "./helpers/postgres-fixture.ts";
const runnerPath = fileURLToPath(
new URL("../scripts/db-migrate.mjs", import.meta.url),
);
function dockerAvailable(): boolean {
return spawnSync("docker", ["version", "--format", "{{.Server.Version}}"], {
encoding: "utf8",
stdio: "ignore",
}).status === 0;
}
const skipWithoutDocker = dockerAvailable() ? false : "docker unavailable on this host";
const ids = {
user: "a1111111-1111-4111-8111-111111111111",
otherUser: "a2222222-2222-4222-8222-222222222222",
session: "b1111111-1111-4111-8111-111111111111",
otherSession: "b2222222-2222-4222-8222-222222222222",
caseId: "c1111111-1111-4111-8111-111111111111",
otherCase: "c2222222-2222-4222-8222-222222222222",
legacyCase: "d1111111-1111-4111-8111-111111111111",
};
function sqlLiteral(value: string): string {
return `'${value.replaceAll("'", "''")}'`;
}
test("read_report_candidate_range is service_role-only, returns only the window, and stays empty without rows", { skip: skipWithoutDocker }, () => {
const fixture = startPostgresFixture();
const migrate = () =>
spawnSync(process.execPath, [runnerPath], {
encoding: "utf8",
env: {
...process.env,
SCHEMA_DATABASE_URL: fixture.connectionUrl(
"schema_owner",
"schema-owner-test-password",
),
},
});
const serviceSql = (statement: string) =>
fixture
.psqlAs(
"service_runtime",
"service-runtime-test-password",
`set role service_role; ${statement}`,
)
.replace(/^SET\n/, "");
try {
const first = migrate();
assert.equal(first.status, 0, `${first.stdout}${first.stderr}`);
assert.match(first.stdout, /applied 20260904010000_read_report_candidate_range\.sql/);
const second = migrate();
assert.equal(second.status, 0, `${second.stdout}${second.stderr}`);
assert.match(second.stdout, /already applied 20260904010000_read_report_candidate_range\.sql/);
assert.equal(
fixture.psql(`
select concat_ws(':',
has_table_privilege('service_role', 'public.agentic_rectification_cases', 'SELECT'),
has_table_privilege('service_role', 'public.agentic_rectification_cases', 'INSERT'),
has_table_privilege('service_role', 'public.agentic_rectification_cases', 'UPDATE'),
has_table_privilege('service_role', 'public.agentic_rectification_cases', 'DELETE'),
has_function_privilege('service_role', 'public.read_report_candidate_range(uuid, uuid)', 'EXECUTE'),
has_function_privilege('anon', 'public.read_report_candidate_range(uuid, uuid)', 'EXECUTE'),
has_function_privilege('authenticated', 'public.read_report_candidate_range(uuid, uuid)', 'EXECUTE')
)
`),
"f:f:f:f:t:f:f",
);
const catalog = fixture.psql(`
select concat_ws(':',
pg_catalog.pg_get_userbyid(p.proowner),
p.prosecdef::text,
coalesce(array_to_string(p.proconfig, ','), ''),
p.provolatile::text
)
from pg_catalog.pg_proc p
join pg_catalog.pg_namespace n on n.oid = p.pronamespace
where n.nspname = 'public' and p.proname = 'read_report_candidate_range'
`);
assert.match(catalog, /^schema_owner:true:search_path="":s$/);
fixture.psqlAs(
"identity_runtime",
"identity-runtime-test-password",
`insert into identity.users (id, name, email, email_verified, email_verified_at)
values (${sqlLiteral(ids.user)}, 'Range User', 'range-user@example.com', true, now()),
(${sqlLiteral(ids.otherUser)}, 'Other User', 'range-other@example.com', true, now());`,
);
assert.equal(
serviceSql(`select public.read_report_candidate_range(${sqlLiteral(ids.user)}::uuid) is null`),
"t",
);
fixture.psql(`
insert into public.chat_sessions (id, user_id, title, theme, session_type, messages)
values (
${sqlLiteral(ids.session)}, ${sqlLiteral(ids.user)}, '生时校正', 'general',
'birth_time_rectification', '[]'::jsonb
), (
${sqlLiteral(ids.otherSession)}, ${sqlLiteral(ids.otherUser)}, '生时校正', 'general',
'birth_time_rectification', '[]'::jsonb
);
insert into public.agentic_rectification_cases (
id, user_id, session_id, status, skill_name, skill_version,
skill_sha256, skill_source_commit, baseline_profile_fingerprint,
baseline_birth_snapshot, candidate_range
) values (
${sqlLiteral(ids.caseId)}, ${sqlLiteral(ids.user)}, ${sqlLiteral(ids.session)},
'candidate_accepted', 'jyotish-birth-time-rectification', '9.0.0',
${sqlLiteral("a".repeat(64))}, ${sqlLiteral("0".repeat(40))}, ${sqlLiteral("a".repeat(64))},
'{"birth_date":"1997-08-08"}'::jsonb,
'{"start_time":"10:00","end_time":"10:04","secret":"must-not-leak"}'::jsonb
), (
${sqlLiteral(ids.otherCase)}, ${sqlLiteral(ids.otherUser)}, ${sqlLiteral(ids.otherSession)},
'candidate_accepted', 'jyotish-birth-time-rectification', '9.0.0',
${sqlLiteral("b".repeat(64))}, ${sqlLiteral("1".repeat(40))}, ${sqlLiteral("b".repeat(64))},
'{"birth_date":"1997-08-08"}'::jsonb,
'{"start_time":"11:00","end_time":"11:20"}'::jsonb
);
`);
assert.throws(
() => serviceSql(`select candidate_range from public.agentic_rectification_cases limit 1`),
/permission denied for table agentic_rectification_cases/,
);
assert.equal(
serviceSql(
`select public.read_report_candidate_range(${sqlLiteral(ids.user)}::uuid) = '{"start_time":"10:00","end_time":"10:04"}'::jsonb`,
),
"t",
);
const keys = serviceSql(`
select array_to_string(array(
select jsonb_object_keys(public.read_report_candidate_range(${sqlLiteral(ids.user)}::uuid))
order by 1
), ',')
`);
assert.equal(keys, "end_time,start_time");
assert.equal(
serviceSql(
`select public.read_report_candidate_range(${sqlLiteral(ids.user)}::uuid) ? 'secret'`,
),
"f",
);
try {
fixture.psql(`
insert into public.birth_time_rectification_cases (
id, user_id, status, reported_date, source, candidate_start, candidate_end
) values (
${sqlLiteral(ids.legacyCase)}, ${sqlLiteral(ids.user)}, 'confirmed',
'1997-08-08', 'family_exact', '08:16', '08:20'
);
`);
assert.equal(
serviceSql(
`select public.read_report_candidate_range(${sqlLiteral(ids.user)}::uuid, ${sqlLiteral(ids.legacyCase)}::uuid) = '{"start_time":"08:16","end_time":"08:20"}'::jsonb`,
),
"t",
);
} catch (error) {
assert.ok(
false,
`legacy birth_time_rectification_cases seed failed: ${error instanceof Error ? error.message : error}`,
);
}
} finally {
fixture.stop();
}
});