Add player bug reports and profile identity features
This commit is contained in:
259
scripts/test-bug-reports-sql.mjs
Normal file
259
scripts/test-bug-reports-sql.mjs
Normal file
@@ -0,0 +1,259 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { readFile, readdir } from "node:fs/promises";
|
||||
import { PGlite } from "../.data/sql-verification/node_modules/@electric-sql/pglite/dist/index.js";
|
||||
const db = new PGlite();
|
||||
try {
|
||||
await db.exec(`create role anon;create role authenticated;create role service_role;
|
||||
create schema auth;create table auth.users(id uuid primary key);
|
||||
create function auth.uid() returns uuid language sql as $$select null::uuid$$;
|
||||
create schema storage;create table storage.buckets(id text primary key,name text,public boolean,file_size_limit bigint);`);
|
||||
for (const file of (await readdir("supabase/migrations"))
|
||||
.filter((file) => file.endsWith(".sql"))
|
||||
.sort())
|
||||
await db.exec(await readFile(`supabase/migrations/${file}`, "utf8"));
|
||||
const account = randomUUID();
|
||||
await db.query("insert into auth.users values($1)", [account]);
|
||||
await db.query(
|
||||
"insert into public.profiles(id,display_name) values($1,'Support fixture')",
|
||||
[account],
|
||||
);
|
||||
const hash = "a".repeat(64),
|
||||
nonce = randomUUID();
|
||||
const report = (
|
||||
await db.query(
|
||||
"insert into public.bug_reports(client_id,access_hash,display_name,title,description,state) values($1,$2,'Guest','Test issue','A valid test bug description.','pending') returning id",
|
||||
[nonce, hash],
|
||||
)
|
||||
).rows[0].id;
|
||||
assert.notEqual(
|
||||
report,
|
||||
nonce,
|
||||
"Linear issue IDs are server generated, not chosen by the player",
|
||||
);
|
||||
const rpc = async (sql, params) => (await db.query(sql, params)).rows[0];
|
||||
assert.equal(
|
||||
(await rpc("select public.claim_bug_sync($1,'worker-a') as ok", [report]))
|
||||
.ok,
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
(await rpc("select public.claim_bug_sync($1,'worker-b') as ok", [report]))
|
||||
.ok,
|
||||
false,
|
||||
);
|
||||
await db.query(
|
||||
"update public.bug_reports set lease_until=now()-interval '1 second' where id=$1",
|
||||
[report],
|
||||
);
|
||||
assert.equal(
|
||||
(await rpc("select public.claim_bug_sync($1,'worker-b') as ok", [report]))
|
||||
.ok,
|
||||
true,
|
||||
);
|
||||
const command = randomUUID();
|
||||
await db.query("select public.receive_bug_reply($1,$2,'Staff','',true)", [
|
||||
report,
|
||||
command,
|
||||
]);
|
||||
assert.equal(
|
||||
(
|
||||
await db.query(
|
||||
"select glow_requested from public.bug_reports where id=$1",
|
||||
[report],
|
||||
)
|
||||
).rows[0].glow_requested,
|
||||
true,
|
||||
);
|
||||
await assert.rejects(
|
||||
db.query("select public.claim_bug_report($1,$2,$3)", [
|
||||
report,
|
||||
"b".repeat(64),
|
||||
account,
|
||||
]),
|
||||
/Report not found/,
|
||||
);
|
||||
await db.query("select public.claim_bug_report($1,$2,$3)", [
|
||||
report,
|
||||
hash,
|
||||
account,
|
||||
]);
|
||||
assert.equal(
|
||||
(
|
||||
await db.query("select name_glow from public.profiles where id=$1", [
|
||||
account,
|
||||
])
|
||||
).rows[0].name_glow,
|
||||
true,
|
||||
);
|
||||
await db.query("select public.receive_bug_reply($1,$2,'Staff','',false)", [
|
||||
report,
|
||||
randomUUID(),
|
||||
]);
|
||||
await db.query("select public.receive_bug_reply($1,$2,'Staff','',true)", [
|
||||
report,
|
||||
command,
|
||||
]);
|
||||
assert.equal(
|
||||
(
|
||||
await db.query("select name_glow from public.profiles where id=$1", [
|
||||
account,
|
||||
])
|
||||
).rows[0].name_glow,
|
||||
false,
|
||||
"old duplicate grant cannot override a revoke",
|
||||
);
|
||||
await db.query(
|
||||
"select public.receive_bug_reply($1,$2,'Staff','We found the bug.',null)",
|
||||
[report, randomUUID()],
|
||||
);
|
||||
assert.equal(
|
||||
(
|
||||
await db.query(
|
||||
"select count(*)::integer as n from public.bug_report_messages where report_id=$1",
|
||||
[report],
|
||||
)
|
||||
).rows[0].n,
|
||||
3,
|
||||
);
|
||||
for (const role of ["anon", "authenticated"]) {
|
||||
await db.exec(`set role ${role}`);
|
||||
for (const table of ["bug_reports", "bug_report_messages"])
|
||||
await assert.rejects(
|
||||
db.query(`select * from public.${table}`),
|
||||
/permission denied/,
|
||||
);
|
||||
await assert.rejects(
|
||||
db.query("select public.receive_bug_reply($1,$2,'Spoof','Fake',true)", [
|
||||
report,
|
||||
randomUUID(),
|
||||
]),
|
||||
/permission denied/,
|
||||
);
|
||||
await assert.rejects(
|
||||
db.query("select public.claim_bug_report($1,$2,$3)", [
|
||||
report,
|
||||
hash,
|
||||
account,
|
||||
]),
|
||||
/permission denied/,
|
||||
);
|
||||
await db.exec("reset role");
|
||||
}
|
||||
await db.exec(
|
||||
"create role reward_probe bypassrls;grant update on public.profiles to reward_probe;grant select on public.profiles to reward_probe;set role reward_probe;",
|
||||
);
|
||||
await assert.rejects(
|
||||
db.query("update public.profiles set name_glow=true where id=$1", [
|
||||
account,
|
||||
]),
|
||||
/Reward permission/,
|
||||
);
|
||||
await db.exec("reset role");
|
||||
assert.equal(
|
||||
(
|
||||
await db.query("select bug_finder from public.profiles where id=$1", [
|
||||
account,
|
||||
])
|
||||
).rows[0].bug_finder,
|
||||
true,
|
||||
"revoking glow keeps the confirmed bug-finder badge",
|
||||
);
|
||||
await assert.rejects(
|
||||
db.query("update public.profiles set glow_color='#123456' where id=$1", [
|
||||
account,
|
||||
]),
|
||||
/Earn a username glow/,
|
||||
);
|
||||
const mod = randomUUID();
|
||||
await db.query("insert into auth.users values($1)", [mod]);
|
||||
await db.query(
|
||||
"insert into public.profiles(id,role) values($1,'moderator')",
|
||||
[mod],
|
||||
);
|
||||
await assert.rejects(
|
||||
db.query("select public.set_user_prefix($1,$2,'Builder','gem')", [
|
||||
account,
|
||||
mod,
|
||||
]),
|
||||
/Moderator permission/,
|
||||
);
|
||||
await db.query("select public.set_user_prefix($1,$2,'Builder','gem')", [
|
||||
mod,
|
||||
account,
|
||||
]);
|
||||
assert.equal(
|
||||
(
|
||||
await db.query("select custom_prefix from public.profiles where id=$1", [
|
||||
account,
|
||||
])
|
||||
).rows[0].custom_prefix,
|
||||
"Builder",
|
||||
);
|
||||
await db.query("select public.set_user_prefix($1,$2,null,'star')", [
|
||||
mod,
|
||||
account,
|
||||
]);
|
||||
assert.equal(
|
||||
(
|
||||
await db.query("select custom_prefix from public.profiles where id=$1", [
|
||||
account,
|
||||
])
|
||||
).rows[0].custom_prefix,
|
||||
null,
|
||||
);
|
||||
await db.exec("set role reward_probe");
|
||||
for (const column of [
|
||||
"role='moderator'",
|
||||
"bug_finder=false",
|
||||
"custom_prefix='Spoof'",
|
||||
"custom_prefix_icon='crown'",
|
||||
])
|
||||
await assert.rejects(
|
||||
db.query(`update public.profiles set ${column} where id=$1`, [account]),
|
||||
/Moderator permission/,
|
||||
);
|
||||
await assert.rejects(
|
||||
db.query("select public.set_user_prefix($1,$2,'Spoof','star')", [
|
||||
mod,
|
||||
account,
|
||||
]),
|
||||
/permission denied/,
|
||||
);
|
||||
await db.exec("reset role");
|
||||
const guest = (
|
||||
await db.query(
|
||||
"insert into public.bug_reports(client_id,access_hash,display_name,title,description,state) values($1,$2,'Guest','Guest verification','A guest verification description.','pending') returning id",
|
||||
[randomUUID(), hash],
|
||||
)
|
||||
).rows[0].id;
|
||||
await db.query("select public.receive_bug_reply($1,$2,'Staff','',true)", [
|
||||
guest,
|
||||
randomUUID(),
|
||||
]);
|
||||
await db.query("select public.receive_bug_reply($1,$2,'Staff','',false)", [
|
||||
guest,
|
||||
randomUUID(),
|
||||
]);
|
||||
await db.query("select public.claim_bug_report($1,$2,$3)", [
|
||||
guest,
|
||||
hash,
|
||||
mod,
|
||||
]);
|
||||
const claimed = (
|
||||
await db.query(
|
||||
"select bug_finder,name_glow from public.profiles where id=$1",
|
||||
[mod],
|
||||
)
|
||||
).rows[0];
|
||||
assert.equal(claimed.bug_finder, true);
|
||||
assert.equal(claimed.name_glow, false);
|
||||
console.log(
|
||||
"Bug report SQL passed: private tables, lease retries, guest claims, staff reply deduplication, grant/revoke rewards and privilege isolation.",
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
await db.close();
|
||||
}
|
||||
Reference in New Issue
Block a user