mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: klopez4212 <klopez4212@gmail.com> Co-authored-by: npub14vtk7pvazqrq9639qu7e560wnqtl0d53ca4gjuvq6jzf3k2el23qqlwa7f <ab176f059d100602ea25073d9a69ee9817f7b691c76a897180d48498d959faa2@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Marge <marge@users.noreply.github.com> Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
139 lines
5.0 KiB
TypeScript
139 lines
5.0 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
import { installMockBridge } from "../helpers/bridge";
|
|
|
|
// NIP-IA archive button + "Archived" flair gate matrix.
|
|
//
|
|
// Guards the composition `canArchive = isSelf || isRelayAdminOrOwner ||
|
|
// isOaOwnerOfViewee` in UserProfilePanel.tsx. Unit tests cover each input in
|
|
// isolation; this spec covers the OR composition where silent regressions
|
|
// (refactor turns OR into AND, role expansion bypasses a branch, etc.) would
|
|
// otherwise slip past code review.
|
|
|
|
const ALICE_PUBKEY =
|
|
"953d3363262e86b770419834c53d2446409db6d918a57f8f339d495d54ab001f";
|
|
|
|
async function openSelfProfile(page: import("@playwright/test").Page) {
|
|
await page.goto("/");
|
|
await page.getByTestId("channel-general").click();
|
|
await expect(page.getByTestId("chat-title")).toHaveText("general");
|
|
// First seed message in #general is from the active identity.
|
|
const firstMessage = page.getByTestId("message-row").first();
|
|
await firstMessage.locator("button", { hasText: "npub1mock..." }).click();
|
|
await expect(page.getByTestId("user-profile-panel")).toBeVisible();
|
|
}
|
|
|
|
async function openAliceProfile(page: import("@playwright/test").Page) {
|
|
await page.goto("/");
|
|
await page.getByTestId("channel-general").click();
|
|
await expect(page.getByTestId("chat-title")).toHaveText("general");
|
|
// Second seed message in #general is from Alice. Her display name "alice"
|
|
// is registered in mockDisplayNames, so the author button text is "alice".
|
|
const aliceMessage = page.getByTestId("message-row").nth(1);
|
|
await aliceMessage.locator("button", { hasText: "alice" }).first().click();
|
|
const panel = page.getByTestId("user-profile-panel");
|
|
await expect(panel).toBeVisible();
|
|
await expect(panel).toContainText(ALICE_PUBKEY.slice(0, 8));
|
|
}
|
|
|
|
async function openProfileSettingsMenu(page: import("@playwright/test").Page) {
|
|
const trigger = page.getByTestId("user-profile-settings-menu-trigger");
|
|
await expect(trigger).toBeVisible();
|
|
await trigger.click();
|
|
}
|
|
|
|
test.describe("NIP-IA archive button gate", () => {
|
|
test("case 1 — self viewer + self target: Archive visible, no flair", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, { relayRole: null, oaOwnerIsMe: false });
|
|
await openSelfProfile(page);
|
|
await openProfileSettingsMenu(page);
|
|
const archiveButton = page.getByTestId("user-profile-archive-identity");
|
|
await expect(archiveButton).toBeVisible();
|
|
await expect(page.getByTestId("user-profile-archived-flair")).toHaveCount(
|
|
0,
|
|
);
|
|
|
|
// Archive is now gated behind a confirmation modal — clicking the button
|
|
// opens the dialog rather than firing immediately. Drive the full flow so
|
|
// the gate stays meaningful: the modal must surface, then confirm fires.
|
|
await expect(page.getByTestId("archive-confirm-dialog")).toHaveCount(0);
|
|
await archiveButton.click();
|
|
await expect(page.getByTestId("archive-confirm-dialog")).toBeVisible();
|
|
const confirm = page.getByTestId("archive-confirm-action");
|
|
await expect(confirm).toBeVisible();
|
|
await confirm.click();
|
|
await expect(page.getByTestId("archive-confirm-dialog")).toHaveCount(0);
|
|
});
|
|
|
|
test("case 2 — relay admin viewing Alice: Archive visible", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
relayRole: "admin",
|
|
oaOwnerIsMe: false,
|
|
archivedIdentities: [],
|
|
});
|
|
await openAliceProfile(page);
|
|
await openProfileSettingsMenu(page);
|
|
await expect(
|
|
page.getByTestId("user-profile-archive-identity"),
|
|
).toBeVisible();
|
|
});
|
|
|
|
test("case 3 — verified OA owner viewing Alice: Archive visible", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
relayRole: null,
|
|
oaOwnerIsMe: true,
|
|
archivedIdentities: [],
|
|
});
|
|
await openAliceProfile(page);
|
|
await openProfileSettingsMenu(page);
|
|
await expect(
|
|
page.getByTestId("user-profile-archive-identity"),
|
|
).toBeVisible();
|
|
});
|
|
|
|
test("case 4 — no authority viewing Alice: Archive hidden", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
relayRole: null,
|
|
oaOwnerIsMe: false,
|
|
archivedIdentities: [],
|
|
});
|
|
await openAliceProfile(page);
|
|
await expect(
|
|
page.getByTestId("user-profile-settings-menu-trigger"),
|
|
).toHaveCount(0);
|
|
await expect(page.getByTestId("user-profile-archive-identity")).toHaveCount(
|
|
0,
|
|
);
|
|
await expect(
|
|
page.getByTestId("user-profile-unarchive-identity"),
|
|
).toHaveCount(0);
|
|
});
|
|
|
|
test("case 5 — Alice archived: flair + Unarchive button (under admin gate)", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
relayRole: "admin",
|
|
oaOwnerIsMe: false,
|
|
archivedIdentities: [ALICE_PUBKEY],
|
|
});
|
|
await openAliceProfile(page);
|
|
await expect(page.getByTestId("user-profile-archived-flair")).toBeVisible();
|
|
await openProfileSettingsMenu(page);
|
|
await expect(
|
|
page.getByTestId("user-profile-unarchive-identity"),
|
|
).toBeVisible();
|
|
await expect(page.getByTestId("user-profile-archive-identity")).toHaveCount(
|
|
0,
|
|
);
|
|
});
|
|
});
|