Local Postgres not() only handled eq/cs, so archived=1 threw and the sidebar archive view returned 500. Compile is not null/true/false instead of inequality.
98 lines
4.9 KiB
TypeScript
98 lines
4.9 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 {
|
|
closeLocalPostgresDataPools,
|
|
createLocalPostgresDataClient,
|
|
} from "../src/lib/db/local-postgres-client-core.ts";
|
|
import {
|
|
applyArchiveFilter,
|
|
cloudListIncludesSession,
|
|
excludeEmptyConsultations,
|
|
} from "../src/lib/session-list-filter.ts";
|
|
import { startPostgresFixture } from "./helpers/postgres-fixture.ts";
|
|
|
|
const runner = fileURLToPath(new URL("../scripts/db-migrate.mjs", import.meta.url));
|
|
const docker = spawnSync("docker", ["version", "--format", "{{.Server.Version}}"], { stdio: "ignore" }).status === 0;
|
|
|
|
const emptyConsultation = "11111111-1111-4111-8111-111111111111";
|
|
const emptyRectification = "22222222-2222-4222-8222-222222222222";
|
|
const filledConsultation = "33333333-3333-4333-8333-333333333333";
|
|
const archivedRectification = "44444444-4444-4444-8444-444444444444";
|
|
const archivedEmptyConsultation = "55555555-5555-4555-8555-555555555555";
|
|
|
|
test("session list query keeps empty rectification rows and drops empty consultations", {
|
|
skip: docker ? false : "docker unavailable",
|
|
}, async () => {
|
|
const fixture = startPostgresFixture();
|
|
try {
|
|
const migration = spawnSync(process.execPath, [runner], {
|
|
encoding: "utf8",
|
|
env: {
|
|
...process.env,
|
|
SCHEMA_DATABASE_URL: fixture.connectionUrl("schema_owner", "schema-owner-test-password"),
|
|
},
|
|
});
|
|
assert.equal(migration.status, 0, migration.stderr);
|
|
fixture.psqlAs(
|
|
"identity_runtime",
|
|
"identity-runtime-test-password",
|
|
`insert into identity.users(name,email,email_verified,email_verified_at) values ('Fictional List','list-visibility@example.com',true,now());`,
|
|
);
|
|
const userId = fixture.psql("select id from identity.users where email='list-visibility@example.com'");
|
|
fixture.psql(`
|
|
insert into public.chat_sessions (id, user_id, title, theme, model_id, messages, session_type, pinned, archived_at, updated_at)
|
|
values
|
|
('${emptyConsultation}', '${userId}', 'Empty consult', 'general', 'test-model', '[]', 'consultation', false, null, now()),
|
|
('${emptyRectification}', '${userId}', 'Empty rectification', 'general', 'test-model', '[]', 'birth_time_rectification', false, null, now()),
|
|
('${filledConsultation}', '${userId}', 'Filled consult', 'general', 'test-model', '[{"role":"user","text":"问一句"}]', 'consultation', false, null, now()),
|
|
('${archivedRectification}', '${userId}', 'Archived rectification', 'general', 'test-model', '[]', 'birth_time_rectification', false, '2026-09-08T00:00:00Z', now()),
|
|
('${archivedEmptyConsultation}', '${userId}', 'Archived empty consult', 'general', 'test-model', '[]', 'consultation', false, '2026-09-08T00:00:00Z', now());
|
|
`);
|
|
const local = createLocalPostgresDataClient(
|
|
fixture.connectionUrl("app_runtime", "app-runtime-test-password"),
|
|
{ id: userId, email: "list-visibility@example.com" },
|
|
);
|
|
const live = await excludeEmptyConsultations(
|
|
applyArchiveFilter(
|
|
local.from("chat_sessions").select("id").eq("user_id", userId).eq("pinned", false),
|
|
false,
|
|
),
|
|
);
|
|
assert.equal(live.error, null, live.error?.message);
|
|
const liveIds = (live.data as { id: string }[]).map((row) => row.id).sort();
|
|
assert.deepEqual(liveIds, [emptyRectification, filledConsultation].sort());
|
|
const archived = await excludeEmptyConsultations(
|
|
applyArchiveFilter(
|
|
local.from("chat_sessions").select("id").eq("user_id", userId).eq("pinned", false),
|
|
true,
|
|
),
|
|
);
|
|
assert.equal(archived.error, null, archived.error?.message);
|
|
const archivedIds = (archived.data as { id: string }[]).map((row) => row.id).sort();
|
|
assert.deepEqual(archivedIds, [archivedRectification]);
|
|
assert.equal(archivedIds.includes(archivedEmptyConsultation), false);
|
|
assert.equal(liveIds.some((id) => archivedIds.includes(id)), false);
|
|
const rows = [
|
|
{ id: emptyConsultation, sessionType: "consultation" as const, messagesEmpty: true, archived: false },
|
|
{ id: emptyRectification, sessionType: "birth_time_rectification" as const, messagesEmpty: true, archived: false },
|
|
{ id: filledConsultation, sessionType: "consultation" as const, messagesEmpty: false, archived: false },
|
|
{ id: archivedRectification, sessionType: "birth_time_rectification" as const, messagesEmpty: true, archived: true },
|
|
{ id: archivedEmptyConsultation, sessionType: "consultation" as const, messagesEmpty: true, archived: true },
|
|
];
|
|
assert.deepEqual(
|
|
rows.filter((row) => cloudListIncludesSession({ ...row, archivedView: false })).map((row) => row.id).sort(),
|
|
liveIds,
|
|
);
|
|
assert.deepEqual(
|
|
rows.filter((row) => cloudListIncludesSession({ ...row, archivedView: true })).map((row) => row.id).sort(),
|
|
archivedIds,
|
|
);
|
|
} finally {
|
|
await closeLocalPostgresDataPools();
|
|
fixture.stop();
|
|
}
|
|
});
|