Ctrl K
ComunidadGuías…

tests/e2e/repository-visibility.spec.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { expect, test } from "@playwright/test";
import {
  connected,
  dashboard,
  repoLink,
} from "./helpers/repository-settings-fixtures";

test("connected repositories are grouped by GitHub owner and open on GitHub in a new tab", async ({
  page,
}) => {
  await dashboard(page);
  await expect(connected(page).getByRole("heading", { level: 2 })).toHaveText([
    "acme",
    "alex",
    "team",
  ]);
  const alex = connected(page).getByRole("region", {
    name: "alex",
    exact: true,
  });
  await expect(alex.getByText("2 repositories")).toBeVisible();
  await expect(
    alex.getByRole("link", { name: "alex", exact: true })
  ).toHaveAttribute("href", "https://github.com/alex");
  const alpha = repoLink(page, "alex/alpha");
  await expect(alpha).toHaveText("alpha");
  await expect(alpha).toHaveAttribute("href", "https://github.com/alex/alpha");
  await expect(alpha).toHaveAttribute("target", "_blank");
  await expect(alpha).toHaveAttribute("rel", "noopener noreferrer");
});

test("repositories without the GitHub App stay out of the list and can be removed together", async ({
  page,
}) => {
  const { writes } = await dashboard(page);
  await expect(connected(page).getByText("skhard99")).toHaveCount(0);
  await expect(
    page
      .getByLabel("Owner", { exact: true })
      .locator("option", { hasText: "skhard99" })
  ).toHaveCount(0);
  // Removed legacy rows are not offered for restore either.
  await expect(
    page.getByRole("button", { name: "Show removed (1)" })
  ).toBeVisible();

  const notice = page.getByRole("region", {
    name: "Not connected repositories",
  });
  await expect(notice.getByText("2 repositories not connected")).toBeVisible();
  await notice.getByText("Show repositories").click();
  // An owner with the App installed is told the repository isn't selected,
  // not that the App is missing.
  await expect(
    notice.getByRole("listitem").filter({ hasText: "alex/legacy" })
  ).toContainText("not selected in the GitHub App's repository access");
  await expect(
    notice.getByRole("listitem").filter({ hasText: "skhard99/docs" })
  ).toContainText("GitHub App not installed for this owner");
  await notice
    .getByRole("button", { name: "Remove all not-connected repositories" })
    .click();
  const dialog = page.getByRole("alertdialog", {
    name: "Remove 2 not-connected repositories?",
  });
  await expect(dialog).toContainText(
    "add them to an existing installation's repository access"
  );
  await dialog.getByRole("button", { name: "Remove 2 repositories" }).click();
  await expect(notice).toHaveCount(0);
  expect(writes).toEqual([
    { id: "alex-legacy", is_hidden: true },
    { id: "fork", is_hidden: true },
  ]);
});

test("remove owner persists, and a removed repository can be restored", async ({
  page,
}) => {
  const { writes } = await dashboard(page);
  await page.getByLabel("Owner", { exact: true }).selectOption("alex");
  await page
    .getByRole("button", { name: "Remove all from alex", exact: true })
    .click();
  await page
    .getByRole("alertdialog", { name: "Remove all 2 repositories from alex?" })
    .getByRole("button", { name: "Remove 2 repositories" })
    .click();
  await expect(repoLink(page, "alex/alpha")).toHaveCount(0);
  await expect(repoLink(page, "alex/beta")).toHaveCount(0);
  await expect(
    page
      .locator('[data-variant="info"]')
      .filter({ hasText: "Removed 2 repositories" })
  ).toBeVisible();
  expect(writes).toEqual([
    { id: "alpha", is_hidden: true },
    { id: "beta", is_hidden: true },
  ]);
  await page.getByRole("button", { name: /Show removed/ }).click();
  await page.getByRole("button", { name: "Restore alex/alpha" }).click();
  await expect(
    page.getByText("Repository restored", { exact: true })
  ).toBeVisible();
  await expect(repoLink(page, "alex/alpha")).toBeVisible();
  await page.reload();
  await expect(repoLink(page, "alex/alpha")).toBeVisible();
  await expect(repoLink(page, "alex/beta")).toHaveCount(0);
});

test("bulk removal waits for confirmation", async ({ page }) => {
  const { writes } = await dashboard(page);
  await page.getByLabel("Owner", { exact: true }).selectOption("alex");
  await page
    .getByRole("button", { name: "Remove all from alex", exact: true })
    .click();
  await page.getByRole("button", { name: "Cancel", exact: true }).click();

  await expect(repoLink(page, "alex/alpha")).toBeVisible();
  expect(writes).toEqual([]);
});

test("bulk removal stays available while a search hides that owner's repositories", async ({
  page,
}) => {
  await dashboard(page);
  await page.getByLabel("Owner", { exact: true }).selectOption("alex");
  await page.getByLabel("Search repositories").fill("no-such-repo");

  await expect(
    page.getByRole("button", { name: "Remove all from alex", exact: true })
  ).toBeVisible();
});

test("restore failures show a retryable error and leave the repository removed", async ({
  page,
}) => {
  await dashboard(page, ["removed"]);
  await page.getByRole("button", { name: /Show removed/ }).click();
  await page.getByLabel("Search repositories").fill("removed");
  await page.getByRole("button", { name: "Restore alex/removed" }).click();
  await expect(
    page.getByText("Could not restore alex/removed", { exact: true })
  ).toBeVisible();
  await expect(
    page.getByText("Database unavailable", { exact: true })
  ).toBeVisible();
  await expect(
    page.getByText("Repository restored", { exact: true })
  ).toHaveCount(0);
  await expect(repoLink(page, "alex/removed")).toHaveCount(0);
  await expect(
    page
      .getByRole("list", { name: "Removed repositories" })
      .getByText("alex/removed")
  ).toBeVisible();
});

test("bulk removal reports partial failures without claiming every repository was removed", async ({
  page,
}) => {
  await dashboard(page, ["beta"]);
  await page.getByLabel("Owner", { exact: true }).selectOption("alex");
  await page
    .getByRole("button", { name: "Remove all from alex", exact: true })
    .click();
  await page
    .getByRole("alertdialog", { name: "Remove all 2 repositories from alex?" })
    .getByRole("button", { name: "Remove 2 repositories" })
    .click();
  await expect(
    page.getByText("Could not remove all repositories", { exact: true })
  ).toBeVisible();
  await expect(
    page
      .locator('[data-variant="warning"]')
      .filter({ hasText: "Could not remove all repositories" })
  ).toBeVisible();
  await expect(
    page.getByText("1 removed; 1 could not be removed. Database unavailable", {
      exact: true,
    })
  ).toBeVisible();
  await expect(
    page.getByText("Removed 2 repositories", { exact: true })
  ).toHaveCount(0);
  await expect(repoLink(page, "alex/alpha")).toHaveCount(0);
  await expect(repoLink(page, "alex/beta")).toBeVisible();
});

test("bulk removal reports a full failure when no repositories were removed", async ({
  page,
}) => {
  await dashboard(page, ["alpha", "beta"]);
  await page.getByLabel("Owner", { exact: true }).selectOption("alex");
  await page
    .getByRole("button", { name: "Remove all from alex", exact: true })
    .click();
  await page
    .getByRole("alertdialog", { name: "Remove all 2 repositories from alex?" })
    .getByRole("button", { name: "Remove 2 repositories" })
    .click();
  const failure = page
    .locator('[data-variant="destructive"]')
    .filter({ hasText: "Could not remove all repositories" });
  await expect(failure).toContainText("0 removed; 2 could not be removed.");
  await expect(repoLink(page, "alex/alpha")).toBeVisible();
  await expect(repoLink(page, "alex/beta")).toBeVisible();
});

test("network failures during removal are visible", async ({ page }) => {
  await dashboard(page);
  await page.route("**/api/repos**", (route) =>
    route.request().method() === "PATCH"
      ? route.abort("failed")
      : route.fallback()
  );
  await page.getByRole("button", { name: "Remove alex/alpha" }).click();
  await page
    .getByRole("alertdialog", { name: "Remove alex/alpha?" })
    .getByRole("button", { name: "Remove repository" })
    .click();
  await expect(
    page.getByText("Could not remove alex/alpha", { exact: true })
  ).toBeVisible();
  await expect(
    page.getByText(
      "Could not reach Mogplex. Check your connection and try again.",
      { exact: true }
    )
  ).toBeVisible();
  await expect(repoLink(page, "alex/alpha")).toBeVisible();
});

test("removing one repository waits for confirmation", async ({ page }) => {
  const { writes } = await dashboard(page);
  await page.getByRole("button", { name: "Remove alex/alpha" }).click();
  await page
    .getByRole("alertdialog", { name: "Remove alex/alpha?" })
    .getByRole("button", { name: "Cancel", exact: true })
    .click();
  await expect(repoLink(page, "alex/alpha")).toBeVisible();
  expect(writes).toEqual([]);

  await page.getByRole("button", { name: "Remove alex/alpha" }).click();
  await page
    .getByRole("alertdialog", { name: "Remove alex/alpha?" })
    .getByRole("button", { name: "Remove repository" })
    .click();
  await expect(
    page.getByText("Repository removed", { exact: true })
  ).toBeVisible();
  await expect(repoLink(page, "alex/alpha")).toHaveCount(0);
  expect(writes).toEqual([{ id: "alpha", is_hidden: true }]);
});

test("project settings open from a repository with no sessions", async ({
  page,
}) => {
  await dashboard(page);
  await page.getByRole("button", { name: "Settings for alex/beta" }).click();
  const drawer = page.getByRole("dialog", { name: "Project settings" });
  await expect(drawer).toBeVisible();
  await expect(drawer.getByText("alex/beta")).toBeVisible();
  await expect(
    drawer.getByRole("tab", { name: "Environment variables" })
  ).toHaveAttribute("aria-selected", "true");
  await expect(
    drawer.getByRole("button", { name: "Save variables" })
  ).toBeVisible();
});

test("the not-connected card waits for filters to clear and shows removal progress", async ({
  page,
}) => {
  await dashboard(page);
  const notice = page.getByRole("region", {
    name: "Not connected repositories",
  });
  await expect(notice).toBeVisible();
  await page.getByLabel("Search repositories").fill("alpha");
  await expect(notice).toHaveCount(0);
  await page.getByLabel("Search repositories").fill("");
  await expect(notice).toBeVisible();

  let release = () => {};
  const held = new Promise<void>((resolve) => {
    release = resolve;
  });
  await page.route("**/api/repos**", async (route) => {
    if (route.request().method() !== "PATCH") return route.fallback();
    await held;
    return route.fallback();
  });
  await notice
    .getByRole("button", { name: "Remove all not-connected repositories" })
    .click();
  await page
    .getByRole("alertdialog", { name: "Remove 2 not-connected repositories?" })
    .getByRole("button", { name: "Remove 2 repositories" })
    .click();
  await expect(
    notice.getByRole("button", {
      name: "Remove all not-connected repositories",
    })
  ).toHaveText("Removing 0/2…");
  release();
  await expect(notice).toHaveCount(0);
});

test("Show removed counts only the removed repositories the filters would show", async ({
  page,
}) => {
  await dashboard(page);
  await page.getByLabel("Owner", { exact: true }).selectOption("team");
  await expect(page.getByRole("button", { name: /Show removed/ })).toHaveCount(
    0
  );
  await page.getByLabel("Owner", { exact: true }).selectOption("alex");
  await expect(
    page.getByRole("button", { name: "Show removed (1)" })
  ).toBeVisible();
});

test("the signed-in GitHub account's repositories are listed first", async ({
  page,
}) => {
  await dashboard(page, [], "team");
  await expect(connected(page).getByRole("heading", { level: 2 })).toHaveText([
    "team",
    "acme",
    "alex",
  ]);
});