mirror of
https://seed.radicle.dev/rad:z4D5UCArafTzTQpDZNQRuqswh3ury.git
synced 2026-10-18 19:10:45 +08:00
134 lines
4.2 KiB
TypeScript
134 lines
4.2 KiB
TypeScript
import type { Page } from "@playwright/test";
|
|
import type { PeerManager } from "@tests/support/peerManager.js";
|
|
|
|
import {
|
|
clone,
|
|
createCollaborators,
|
|
createProject,
|
|
} from "@tests/support/collaboration.js";
|
|
import {
|
|
expect,
|
|
goto,
|
|
test,
|
|
useBackend,
|
|
waitForCommand,
|
|
} from "@tests/support/fixtures.js";
|
|
|
|
// Opens bob's project as eve, who cloned it but isn't a delegate.
|
|
async function asContributor(page: Page, peerManager: PeerManager) {
|
|
const { bob, eve } = await createCollaborators(peerManager);
|
|
const project = await createProject(bob);
|
|
await bob.rad(
|
|
[
|
|
"issue",
|
|
"comment",
|
|
project.issueId,
|
|
"--message",
|
|
"Bob's own comment",
|
|
"--quiet",
|
|
],
|
|
{ cwd: project.repoFolder },
|
|
);
|
|
await clone(eve, project.rid);
|
|
await eve.startHttpd();
|
|
await useBackend(page, eve);
|
|
return project;
|
|
}
|
|
|
|
test("a contributor can't edit an issue's metadata or delete it", async ({
|
|
page,
|
|
peerManager,
|
|
}) => {
|
|
const { rid, issueId } = await asContributor(page, peerManager);
|
|
await page.goto(`/repos/${rid}/issues/${issueId}`);
|
|
await expect(page.getByText("Nobody reads them.")).toBeVisible();
|
|
|
|
await expect(page.getByRole("button", { name: "Add labels" })).toBeDisabled();
|
|
await expect(
|
|
page.getByRole("button", { name: "Add assignees" }),
|
|
).toBeDisabled();
|
|
await expect(
|
|
page.getByTitle(
|
|
"Only the issue author and delegates can change the issue state",
|
|
),
|
|
).toBeVisible();
|
|
await expect(page.getByTitle("Delete issue from your node")).toBeHidden();
|
|
});
|
|
|
|
test("a contributor can't edit or delete someone else's comment", async ({
|
|
page,
|
|
peerManager,
|
|
}) => {
|
|
const { rid, issueId } = await asContributor(page, peerManager);
|
|
await page.goto(`/repos/${rid}/issues/${issueId}`);
|
|
|
|
await page.getByText("Bob's own comment").hover();
|
|
const toggle = page.getByTitle("Comment actions").last();
|
|
await toggle.click();
|
|
const menuItem = (action: string) =>
|
|
toggle.locator(
|
|
`xpath=following::*[@role="button"][normalize-space()="${action}"][1]`,
|
|
);
|
|
await expect(menuItem("Copy ID")).toBeVisible();
|
|
await expect(menuItem("Edit")).toHaveCount(0);
|
|
await expect(menuItem("Delete")).toHaveCount(0);
|
|
});
|
|
|
|
test("a contributor can't change a patch's state or delete it", async ({
|
|
page,
|
|
peerManager,
|
|
}) => {
|
|
const { rid, patchId } = await asContributor(page, peerManager);
|
|
await page.goto(`/repos/${rid}/patches/${patchId}`);
|
|
await expect(
|
|
page.getByRole("button", { name: "Shout the third line" }),
|
|
).toBeVisible();
|
|
|
|
await expect(
|
|
page.getByTitle(
|
|
"Only delegates and the patch author can change the patch state",
|
|
),
|
|
).toBeVisible();
|
|
await expect(page.getByRole("button", { name: "Add labels" })).toBeDisabled();
|
|
await expect(page.getByTitle("Delete patch from your node")).toBeHidden();
|
|
});
|
|
|
|
test("a contributor can't resolve someone else's review comment", async ({
|
|
page,
|
|
peerManager,
|
|
}) => {
|
|
const { bob, eve } = await createCollaborators(peerManager);
|
|
const { rid, patchId } = await createProject(bob);
|
|
await clone(eve, rid);
|
|
await bob.startHttpd();
|
|
await useBackend(page, bob);
|
|
|
|
// Bob reviews his own patch with a comment on the changed line.
|
|
await page.goto(`/repos/${rid}/patches/${patchId}?view=changes`);
|
|
await page
|
|
.locator(
|
|
'[data-unified] [data-column-number="3"]:not([data-line-type="change-deletion"])',
|
|
)
|
|
.hover();
|
|
await page.locator("[data-utility-button]").click();
|
|
await page.getByPlaceholder("Leave a comment").fill("Keep it loud");
|
|
await page
|
|
.getByLabel("extended-textarea")
|
|
.filter({ has: page.getByPlaceholder("Leave a comment") })
|
|
.getByRole("button", { name: /^Start review/ })
|
|
.click();
|
|
await waitForCommand(page, "create_patch_review", () =>
|
|
page.getByRole("button", { name: "Accept revision", exact: true }).click(),
|
|
);
|
|
await eve.rad(["sync", rid, "--fetch"]);
|
|
|
|
// Now as eve.
|
|
await eve.startHttpd();
|
|
await useBackend(page, eve);
|
|
await goto(page, `/repos/${rid}/patches/${patchId}?view=changes`);
|
|
const thread = page.getByRole("group").filter({ hasText: "Keep it loud" });
|
|
await thread.hover();
|
|
await expect(thread.getByTitle("Reply")).toBeVisible();
|
|
await expect(thread.getByTitle("Mark as resolved")).toHaveCount(0);
|
|
});
|