Files
MineGeo/scripts/test-bug-retention-http.mjs
pavel444-byte 1f254b29a2
All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 5m57s
Update MineGeo domain and harden process supervision
2026-10-15 20:35:39 +05:00

147 lines
4.4 KiB
JavaScript

import assert from "node:assert/strict";
import { randomUUID } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import { createClient } from "@supabase/supabase-js";
import sharp from "sharp";
process.loadEnvFile(".env.local");
const origin = new URL(process.argv[2] || "https://minegeo.site").origin;
const db = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.SUPABASE_SECRET_KEY,
{ auth: { persistSession: false, autoRefreshToken: false } },
);
const checked = (r) => {
if (r.error) throw new Error(r.error.message);
return r.data;
};
const cookies = new Map();
let id;
await mkdir(".data/retention-check", { recursive: true });
async function api(path, body, expected = 200, stranger = false) {
const response = await fetch(`${origin}/api/v1/bug-reports${path}`, {
method: body === undefined ? "GET" : "POST",
headers: {
origin,
"content-type": "application/json",
cookie: stranger
? ""
: [...cookies].map(([k, v]) => `${k}=${v}`).join("; "),
},
...(body === undefined ? {} : { body: JSON.stringify(body) }),
signal: AbortSignal.timeout(60000),
});
if (!stranger)
for (const cookie of response.headers.getSetCookie()) {
const part = cookie.split(";")[0],
at = part.indexOf("=");
cookies.set(part.slice(0, at), part.slice(at + 1));
}
const result = await response.json();
assert.equal(response.status, expected, `${path}: ${JSON.stringify(result)}`);
return result;
}
async function row() {
return checked(
await db.from("bug_reports").select("*").eq("id", id).maybeSingle(),
);
}
async function waitFor(predicate, label) {
for (let n = 0; n < 40; n++) {
const current = await row();
if (predicate(current)) return current;
if (current?.cleanup_error) throw new Error(current.cleanup_error);
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error(`Timed out: ${label}`);
}
assert.equal((await api("")).ready, true);
const created = await api("", {
clientId: randomUUID(),
title: `[Verification] Retention ${randomUUID()}`,
description:
"Automated temporary verification fixture for three-day report retention. This is not a real player bug.",
displayName: "Support verification",
pagePath: "/support",
screenshot: true,
});
id = created.id;
await writeFile(
".data/retention-check/fixture.json",
JSON.stringify({ id, cookies: [...cookies] }),
);
const image = await sharp({
create: { width: 8, height: 8, channels: 3, background: "#334455" },
})
.png()
.toBuffer();
assert.equal(
(
await fetch(created.upload, {
method: "PUT",
headers: { "content-type": "image/png" },
body: image,
})
).ok,
true,
);
await api(`/${id}/submit`, {});
await waitFor((r) => r?.issue_synced, "Linear issue creation");
await api(`/${id}/close`, {}, 404, true);
const closed = await api(`/${id}/close`, {});
assert.equal(closed.state, "done");
assert.equal(
Date.parse(closed.delete_after) - Date.parse(closed.closed_at),
3 * 86400000,
);
assert.equal((await api(`/${id}/close`, {})).delete_after, closed.delete_after);
await api(
`/${id}/messages`,
{ clientId: randomUUID(), text: "Blocked after closure" },
409,
);
await waitFor((r) => r?.linear_done_synced, "Linear Done status");
console.log(
JSON.stringify({
fixture: id,
checkpoint: "Done synchronized; three-day deadline and ownership verified",
}),
);
// Accelerate only this journaled verification fixture; no real report is modified.
const backdated = new Date(Date.now() - 3 * 86400000 - 60000).toISOString();
checked(
await db
.from("bug_reports")
.update({
closed_at: backdated,
delete_after: new Date(Date.now() - 60000).toISOString(),
cleanup_run_id: null,
cleanup_lease_until: null,
status_checked_at: new Date().toISOString(),
})
.eq("id", id)
.like("title", "[Verification] Retention %"),
);
await api(`/${id}/retry-cleanup`, {});
await waitFor((r) => r === null, "both-system deletion");
assert.equal(
checked(await db.from("bug_report_messages").select("id").eq("report_id", id))
.length,
0,
);
assert.equal(
checked(await db.storage.from("minegeo-support").list(id)).length,
0,
);
await api(`/${id}`, undefined, 404);
await writeFile(
".data/retention-check/fixture.json",
JSON.stringify({ id, deleted: true }),
);
console.log(
JSON.stringify({
fixture: id,
checkpoint:
"Expired report, messages, screenshots and Linear issue deleted",
}),
);