BlueSky & more on desktop
lazurite.stormlightlabs.org/
tauri
rust
typescript
bluesky
appview
atproto
solid
1import type { ModerationLabel } from "$/lib/types";
2import { render, waitFor } from "@solidjs/testing-library";
3import { beforeEach, describe, expect, it, vi } from "vitest";
4import { useModerationDecision } from "../hooks/useModerationDecision";
5
6const moderateContentMock = vi.hoisted(() => vi.fn());
7
8vi.mock("$/lib/api/moderation", () => ({ ModerationController: { moderateContent: moderateContentMock } }));
9
10function DecisionProbe(props: { context: "contentList" | "contentMedia"; labels: ModerationLabel[] }) {
11 const labels = () => props.labels;
12 const ctx = () => props.context;
13 const decision = useModerationDecision(labels, ctx());
14 return <span>{decision().blur}</span>;
15}
16
17describe("useModerationDecision", () => {
18 beforeEach(() => {
19 moderateContentMock.mockReset();
20 moderateContentMock.mockResolvedValue({
21 alert: false,
22 blur: "none",
23 filter: false,
24 inform: false,
25 noOverride: false,
26 });
27 });
28
29 it("includes context in its cache key", async () => {
30 const labels: ModerationLabel[] = [{ src: "did:plc:labeler", val: "warn", uri: "at://did:plc:alice/app.test/1" }];
31
32 const first = render(() => <DecisionProbe context="contentList" labels={labels} />);
33 await waitFor(() => expect(moderateContentMock).toHaveBeenCalledWith(labels, "contentList"));
34 expect(moderateContentMock).toHaveBeenCalledTimes(1);
35 first.unmount();
36
37 const second = render(() => <DecisionProbe context="contentList" labels={labels} />);
38 await waitFor(() => expect(moderateContentMock).toHaveBeenCalledTimes(1));
39 second.unmount();
40
41 render(() => <DecisionProbe context="contentMedia" labels={labels} />);
42 await waitFor(() => expect(moderateContentMock).toHaveBeenCalledWith(labels, "contentMedia"));
43 expect(moderateContentMock).toHaveBeenCalledTimes(2);
44 });
45});