fix: final review pass — email collision, orphaned-run loop, null confidence guards
- changeEmail validates and refuses an address another account owns (users.email is UNIQUE; a collision was a 500 inside the settings form). - /app/[id] no longer redirects a 'running' row to itself; it renders what exists and says the run was interrupted. - ScoreBar / OptionRow / VerdictBlock survive null numbers from the model instead of throwing and losing the block (seen live: '[openui] runtime/render-error: Component ScoreBar render failed'). - drop the ad-hoc render-debug scripts now that Playwright covers the browser. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
07dd3d6bf8
commit
5160a00db5
@@ -18,3 +18,16 @@ test("token hash is stable, 64 hex", () => {
|
||||
assert.equal(hashToken("abc"), hashToken("abc"));
|
||||
assert.match(hashToken("abc"), /^[0-9a-f]{64}$/);
|
||||
});
|
||||
test("changeEmail refuses an address another account already has", async () => {
|
||||
const { signUpNewUser, changeEmail } = await import("../lib/auth.ts");
|
||||
const db = await import("../lib/db.ts");
|
||||
const a = signUpNewUser("first@x.test", "0123456789ab");
|
||||
const b = signUpNewUser("second@x.test", "0123456789ab");
|
||||
assert.ok(a.ok && b.ok);
|
||||
assert.deepEqual(changeEmail(b.id, "first@x.test"), { ok: false, error: "That email already has an account." });
|
||||
assert.deepEqual(changeEmail(b.id, "not an email"), { ok: false, error: "Enter a valid email address." });
|
||||
assert.deepEqual(changeEmail(b.id, " FIRST@X.TEST "), { ok: false, error: "That email already has an account." });
|
||||
assert.equal(changeEmail(a.id, "first@x.test").ok, true, "own address is not a conflict");
|
||||
assert.equal(changeEmail(b.id, "fresh@x.test").ok, true);
|
||||
assert.equal(db.userByEmail("fresh@x.test")!.id, b.id, "stored lower-cased");
|
||||
});
|
||||
|
||||
@@ -13,3 +13,16 @@ test("every spec has a renderer, so the model can never emit an unrenderable blo
|
||||
const { library } = await import("../lib/report-ui.ts");
|
||||
for (const s of specs) assert.ok(library.components[s.name], `no renderer for ${s.name}`);
|
||||
});
|
||||
|
||||
test("a null confidence from the model does not blank the block", async () => {
|
||||
// The prompt says optional; models still send null. confidence != undefined let null through to .toFixed().
|
||||
const { library } = await import("../lib/report-ui.ts");
|
||||
const renderNode = () => null;
|
||||
for (const [name, props] of [
|
||||
["ScoreBar", { label: "fit", value: 0.5, confidence: null }],
|
||||
["VerdictBlock", { headline: "h", why: "w", source: "jev", confidence: null }],
|
||||
] as const) {
|
||||
const el = library.components[name].component({ props: props as any, renderNode } as any);
|
||||
assert.ok(el, `${name} returned nothing`);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user