v4: an instance that takes no users of others still blocks instances its own users may not sign in to — with GERBEUR_FEDERATION_INCOMING=0, /manage hid its list of instances, though a blocked one still kept the instance's users from signing in there, and no admin could block another. The list now stays while federated sign-in goes either way: without incoming sign-ins it shows and adds only blocked instances, the trusted ones kept for when they're back, and says what blocking does there. Where both ways are on, its note now says that users here can't sign in to a blocked instance either.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-10-09 16:33:08 +00:00
parent 83dc44050e
commit 52a23db504
6 changed files with 195 additions and 65 deletions

View File

@@ -1,4 +1,4 @@
import { describe, expect, test } from "vitest";
import { afterEach, describe, expect, test, vi } from "vitest";
import { screen, waitFor, within } from "@testing-library/react";
import { userEvent } from "@testing-library/user-event";
import { Manage } from "../../pages/Manage.tsx";
@@ -6,6 +6,20 @@ import { calls, fail, route } from "../fetch.ts";
import { makeCategory, makeSession, wire } from "../fixtures.ts";
import { renderApp } from "../render.tsx";
const instance = vi.hoisted(() => ({
federationIncoming: true,
federationOutgoing: true,
}));
vi.mock("../../config/instance.ts", async (importOriginal) => ({
...await importOriginal<typeof import("../../config/instance.ts")>(),
get FEDERATION_INCOMING() {
return instance.federationIncoming;
},
get FEDERATION_OUTGOING() {
return instance.federationOutgoing;
},
}));
const admin = makeSession({ id: "ann", username: "ann", role: "admin" });
function open(session = admin) {
@@ -16,6 +30,11 @@ function open(session = admin) {
}
describe("Manage", () => {
afterEach(() => {
instance.federationIncoming = true;
instance.federationOutgoing = true;
});
test("an admin manages categories", async () => {
const music = makeCategory({ id: "c1", slug: "music", name: "Music" });
let list = [music];
@@ -128,6 +147,52 @@ describe("Manage", () => {
);
});
test("where users of other instances don't sign in, an admin only blocks instances", async () => {
instance.federationIncoming = false;
route("GET /api/categories", () => []);
const peer = (name: string, host: string, status: string) => ({
issuer: `https://${host}`,
host,
name,
status,
createdAt: new Date().toISOString(),
});
route("GET /api/federation/peers", () => [
peer("Films", "films.example", "trusted"),
peer("Spam", "spam.example", "blocked"),
]);
route(
"PUT /api/federation/peers",
() => peer("Music", "music.example", "blocked"),
);
const user = open();
expect(await screen.findByText("Spam")).toBeInTheDocument();
expect(screen.queryByText("Films")).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Trust" })).not
.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Blocked" })).not
.toBeInTheDocument();
await user.type(
screen.getByPlaceholderText("An instance's address, like music.example"),
"music.example{Enter}",
);
await waitFor(() =>
expect(calls("PUT /api/federation/peers")[0]?.body).toEqual({
instance: "music.example",
status: "blocked",
})
);
});
test("without federated sign-in either way, there are no instances to manage", async () => {
instance.federationIncoming = false;
instance.federationOutgoing = false;
route("GET /api/categories", () => []);
open();
expect(await screen.findByText("Categories")).toBeInTheDocument();
expect(screen.queryByText("Instances")).not.toBeInTheDocument();
});
test("without category:manage, the page isn't found", async () => {
open(makeSession({ id: "mod", role: "moderator" }));
expect(await screen.findByText("This page does not exist."))