···
import { beforeEach, describe, expect, it, vi } from "vitest";
2
-
import { agent } from "../agent.js";
3
-
import { logger } from "../logger.js";
4
-
import { checkAccountLabels } from "../moderation.js";
3
+
// --- Mocks First ---
vi.mock("../agent.js", () => ({
···
isLoggedIn: Promise.resolve(true),
20
+
vi.mock("../redis.js", () => ({
21
+
tryClaimPostLabel: vi.fn(),
22
+
tryClaimAccountLabel: vi.fn(),
vi.mock("../logger.js", () => ({
···
limit: vi.fn((fn) => fn()),
37
-
describe("checkAccountLabels", () => {
42
+
// --- Imports Second ---
44
+
import { agent } from "../agent.js";
45
+
import { checkAccountLabels, createPostLabel } from "../moderation.js";
46
+
import { tryClaimPostLabel } from "../redis.js";
47
+
import { logger } from "../logger.js";
49
+
describe("Moderation Logic", () => {
42
-
it("should return true if label exists on account", async () => {
43
-
(agent.tools.ozone.moderation.getRepo as any).mockResolvedValueOnce({
47
-
{ val: "harassment" },
48
-
{ val: "window-reply" },
53
-
const result = await checkAccountLabels("did:plc:test123", "window-reply");
55
-
expect(result).toBe(true);
56
-
expect(agent.tools.ozone.moderation.getRepo).toHaveBeenCalledWith(
57
-
{ did: "did:plc:test123" },
60
-
"atproto-proxy": "did:plc:moderator123#atproto_labeler",
61
-
"atproto-accept-labelers": "did:plc:ar7c4by46qjdydhdevvrndac;redact",
54
+
describe("checkAccountLabels", () => {
55
+
it("should return true if label exists on account", async () => {
56
+
vi.mocked(agent.tools.ozone.moderation.getRepo).mockResolvedValueOnce({
59
+
{ val: "spam", src: "did:plc:test", uri: "at://test", cts: "2024-01-01T00:00:00Z" },
60
+
{ val: "window-reply", src: "did:plc:test", uri: "at://test", cts: "2024-01-01T00:00:00Z" }
67
-
it("should return false if label does not exist on account", async () => {
68
-
(agent.tools.ozone.moderation.getRepo as any).mockResolvedValueOnce({
70
-
labels: [{ val: "spam" }, { val: "harassment" }],
64
+
const result = await checkAccountLabels("did:plc:test123", "window-reply");
65
+
expect(result).toBe(true);
74
-
const result = await checkAccountLabels("did:plc:test123", "window-reply");
76
-
expect(result).toBe(false);
79
-
it("should return false if account has no labels", async () => {
80
-
(agent.tools.ozone.moderation.getRepo as any).mockResolvedValueOnce({
69
+
describe("createPostLabel with Caching", () => {
70
+
const URI = "at://did:plc:test/app.bsky.feed.post/123";
71
+
const CID = "bafybeig6xv5nwph5j7grrlp3pdeolqptpep5nfljmdkmtcf2l4wisa2mfa";
72
+
const LABEL = "test-label";
73
+
const COMMENT = "test comment";
86
-
const result = await checkAccountLabels("did:plc:test123", "window-reply");
75
+
it("should skip if claim fails (already claimed)", async () => {
76
+
vi.mocked(tryClaimPostLabel).mockResolvedValue(false);
88
-
expect(result).toBe(false);
78
+
await createPostLabel(URI, CID, LABEL, COMMENT, undefined);
91
-
it("should return false if labels property is undefined", async () => {
92
-
(agent.tools.ozone.moderation.getRepo as any).mockResolvedValueOnce({
80
+
expect(vi.mocked(tryClaimPostLabel)).toHaveBeenCalledWith(URI, LABEL);
81
+
expect(vi.mocked(agent.tools.ozone.moderation.getRecord)).not.toHaveBeenCalled();
82
+
expect(vi.mocked(agent.tools.ozone.moderation.emitEvent)).not.toHaveBeenCalled();
96
-
const result = await checkAccountLabels("did:plc:test123", "window-reply");
98
-
expect(result).toBe(false);
101
-
it("should handle API errors gracefully", async () => {
102
-
(agent.tools.ozone.moderation.getRepo as any).mockRejectedValueOnce(
103
-
new Error("API Error"),
106
-
const result = await checkAccountLabels("did:plc:test123", "window-reply");
85
+
it("should skip event if claimed but already labeled via API", async () => {
86
+
vi.mocked(tryClaimPostLabel).mockResolvedValue(true);
87
+
vi.mocked(agent.tools.ozone.moderation.getRecord).mockResolvedValue({
88
+
data: { labels: [{ val: LABEL, src: "did:plc:test", uri: URI, cts: "2024-01-01T00:00:00Z" }] },
108
-
expect(result).toBe(false);
109
-
expect(logger.error).toHaveBeenCalledWith(
111
-
process: "MODERATION",
112
-
did: "did:plc:test123",
113
-
error: expect.any(Error),
115
-
"Failed to check account labels",
91
+
await createPostLabel(URI, CID, LABEL, COMMENT, undefined);
119
-
it("should perform case-sensitive label matching", async () => {
120
-
(agent.tools.ozone.moderation.getRepo as any).mockResolvedValueOnce({
122
-
labels: [{ val: "window-reply" }],
93
+
expect(vi.mocked(tryClaimPostLabel)).toHaveBeenCalledWith(URI, LABEL);
94
+
expect(vi.mocked(agent.tools.ozone.moderation.getRecord)).toHaveBeenCalledWith(
98
+
expect(vi.mocked(agent.tools.ozone.moderation.emitEvent)).not.toHaveBeenCalled();
126
-
const resultLower = await checkAccountLabels(
130
-
expect(resultLower).toBe(true);
132
-
(agent.tools.ozone.moderation.getRepo as any).mockResolvedValueOnce({
134
-
labels: [{ val: "window-reply" }],
101
+
it("should emit event if claimed and not labeled anywhere", async () => {
102
+
vi.mocked(tryClaimPostLabel).mockResolvedValue(true);
103
+
vi.mocked(agent.tools.ozone.moderation.getRecord).mockResolvedValue({
104
+
data: { labels: [] },
106
+
vi.mocked(agent.tools.ozone.moderation.emitEvent).mockResolvedValue({ success: true } as any);
108
+
await createPostLabel(URI, CID, LABEL, COMMENT, undefined);
110
+
expect(vi.mocked(tryClaimPostLabel)).toHaveBeenCalledWith(URI, LABEL);
111
+
expect(vi.mocked(agent.tools.ozone.moderation.getRecord)).toHaveBeenCalledWith(
113
+
expect.any(Object),
115
+
expect(vi.mocked(agent.tools.ozone.moderation.emitEvent)).toHaveBeenCalled();
138
-
const resultUpper = await checkAccountLabels(
142
-
expect(resultUpper).toBe(false);