mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
## Summary - add database-backed v2 invite links with optional maximum-use limits and atomic final-slot redemption - preserve v1 invite compatibility while adding exhausted/expired/invalid client handling across desktop, web, and mobile - emit structured claim-outcome logs with community, invite ID, outcome, maximum uses, and post-claim count ## Verification - `cargo fmt --all -- --check` - `cargo test -p buzz-db` (85 passed, 134 Postgres-dependent ignored) - `cargo clippy -p buzz-db --all-targets -- -D warnings` - desktop `npm run typecheck` - push hook: desktop checks/tests, desktop Tauri tests, Rust tests, and branch-skew passed - Postgres integration tests were previously reviewed green at the pre-rebase tree; local rerun on this session was unavailable because Postgres/Docker were not running - mobile push-hook check could not start because Flutter is unavailable locally --------- Signed-off-by: Kalvin Chau <kalvin@block.xyz> Signed-off-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz> Co-authored-by: npub1c4alndp82zyt9veaklm5d965quss79vlhk9awv7qu5erwhmf42qqlvc25c <c57bf9b4275088b2b33db7f746975407210f159fbd8bd733c0e532375f69aa80@buzz.block.builderlab.xyz> Co-authored-by: npub122y0pqkertljmedu303rl0aqrj3w8pvu43t6jxm6875lzg6f2pwqegc3xc <5288f082d91aff2de5bc8be23fbfa01ca2e3859cac57a91b7a3fa9f12349505c@buzz.block.builderlab.xyz> Co-authored-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
44 lines
1.3 KiB
JavaScript
44 lines
1.3 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
inviteErrorMessage,
|
|
isInviteExhaustedError,
|
|
isInviteExpiredError,
|
|
relayHttpFromWs,
|
|
} from "./inviteHelpers.ts";
|
|
|
|
test("relayHttpFromWs maps secure and local relay schemes", () => {
|
|
assert.equal(
|
|
relayHttpFromWs("wss://relay.example/path"),
|
|
"https://relay.example/path",
|
|
);
|
|
assert.equal(relayHttpFromWs("ws://localhost:7000"), "http://localhost:7000");
|
|
});
|
|
|
|
test("relayHttpFromWs rejects unexpected schemes", () => {
|
|
assert.throws(
|
|
() => relayHttpFromWs("https://relay.example"),
|
|
/Expected ws:\/\/ or wss:\/\//,
|
|
);
|
|
assert.throws(
|
|
() => relayHttpFromWs("relay.example"),
|
|
/Expected ws:\/\/ or wss:\/\//,
|
|
);
|
|
});
|
|
|
|
test("invite expiry sentinel is recognized without hiding other errors", () => {
|
|
assert.equal(isInviteExpiredError(new Error("invite_expired")), true);
|
|
assert.equal(isInviteExpiredError(new Error("invite_invalid")), false);
|
|
assert.equal(
|
|
inviteErrorMessage("network unavailable"),
|
|
"network unavailable",
|
|
);
|
|
});
|
|
|
|
test("invite exhaustion sentinel is recognized distinctly from expiry", () => {
|
|
assert.equal(isInviteExhaustedError(new Error("invite_exhausted")), true);
|
|
assert.equal(isInviteExhaustedError(new Error("invite_expired")), false);
|
|
assert.equal(isInviteExhaustedError(new Error("invite_invalid")), false);
|
|
});
|