A tool for parsing traffic on the jetstream and applying a moderation workstream based on regexp based rules
at main 4.2 kB view raw
1import { beforeEach, describe, expect, it, vi } from "vitest"; 2// --- Imports Second --- 3import { checkAccountLabels } from "../accountModeration.js"; 4import { agent } from "../agent.js"; 5import { createPostLabel } from "../moderation.js"; 6import { tryClaimPostLabel } from "../redis.js"; 7 8// --- Mocks First --- 9 10vi.mock("../agent.js", () => ({ 11 agent: { 12 tools: { 13 ozone: { 14 moderation: { 15 getRepo: vi.fn(), 16 getRecord: vi.fn(), 17 emitEvent: vi.fn(), 18 }, 19 }, 20 }, 21 }, 22 isLoggedIn: Promise.resolve(true), 23})); 24 25vi.mock("../redis.js", () => ({ 26 tryClaimPostLabel: vi.fn(), 27 tryClaimAccountLabel: vi.fn(), 28})); 29 30vi.mock("../logger.js", () => ({ 31 logger: { 32 info: vi.fn(), 33 debug: vi.fn(), 34 warn: vi.fn(), 35 error: vi.fn(), 36 }, 37})); 38 39vi.mock("../config.js", () => ({ 40 MOD_DID: "did:plc:moderator123", 41})); 42 43vi.mock("../limits.js", () => ({ 44 limit: vi.fn((fn) => fn()), 45})); 46 47describe("Moderation Logic", () => { 48 beforeEach(() => { 49 vi.clearAllMocks(); 50 }); 51 52 describe("checkAccountLabels", () => { 53 it("should return true if label exists on account", async () => { 54 vi.mocked(agent.tools.ozone.moderation.getRepo).mockResolvedValueOnce({ 55 data: { 56 labels: [ 57 { 58 val: "spam", 59 src: "did:plc:test", 60 uri: "at://test", 61 cts: "2024-01-01T00:00:00Z", 62 }, 63 { 64 val: "window-reply", 65 src: "did:plc:test", 66 uri: "at://test", 67 cts: "2024-01-01T00:00:00Z", 68 }, 69 ], 70 }, 71 } as any); 72 const result = await checkAccountLabels( 73 "did:plc:test123", 74 "window-reply", 75 ); 76 expect(result).toBe(true); 77 }); 78 }); 79 80 describe("createPostLabel with Caching", () => { 81 const URI = "at://did:plc:test/app.bsky.feed.post/123"; 82 const CID = "bafybeig6xv5nwph5j7grrlp3pdeolqptpep5nfljmdkmtcf2l4wisa2mfa"; 83 const LABEL = "test-label"; 84 const COMMENT = "test comment"; 85 86 it("should skip if claim fails (already claimed)", async () => { 87 vi.mocked(tryClaimPostLabel).mockResolvedValue(false); 88 89 await createPostLabel(URI, CID, LABEL, COMMENT, undefined); 90 91 expect(vi.mocked(tryClaimPostLabel)).toHaveBeenCalledWith(URI, LABEL); 92 expect( 93 vi.mocked(agent.tools.ozone.moderation.getRecord), 94 ).not.toHaveBeenCalled(); 95 expect( 96 vi.mocked(agent.tools.ozone.moderation.emitEvent), 97 ).not.toHaveBeenCalled(); 98 }); 99 100 it("should skip event if claimed but already labeled via API", async () => { 101 vi.mocked(tryClaimPostLabel).mockResolvedValue(true); 102 vi.mocked(agent.tools.ozone.moderation.getRecord).mockResolvedValue({ 103 data: { 104 labels: [ 105 { 106 val: LABEL, 107 src: "did:plc:test", 108 uri: URI, 109 cts: "2024-01-01T00:00:00Z", 110 }, 111 ], 112 }, 113 } as any); 114 115 await createPostLabel(URI, CID, LABEL, COMMENT, undefined); 116 117 expect(vi.mocked(tryClaimPostLabel)).toHaveBeenCalledWith(URI, LABEL); 118 expect( 119 vi.mocked(agent.tools.ozone.moderation.getRecord), 120 ).toHaveBeenCalledWith({ uri: URI }, expect.any(Object)); 121 expect( 122 vi.mocked(agent.tools.ozone.moderation.emitEvent), 123 ).not.toHaveBeenCalled(); 124 }); 125 126 it("should emit event if claimed and not labeled anywhere", async () => { 127 vi.mocked(tryClaimPostLabel).mockResolvedValue(true); 128 vi.mocked(agent.tools.ozone.moderation.getRecord).mockResolvedValue({ 129 data: { labels: [] }, 130 } as any); 131 vi.mocked(agent.tools.ozone.moderation.emitEvent).mockResolvedValue({ 132 success: true, 133 } as any); 134 135 await createPostLabel(URI, CID, LABEL, COMMENT, undefined); 136 137 expect(vi.mocked(tryClaimPostLabel)).toHaveBeenCalledWith(URI, LABEL); 138 expect( 139 vi.mocked(agent.tools.ozone.moderation.getRecord), 140 ).toHaveBeenCalledWith({ uri: URI }, expect.any(Object)); 141 expect( 142 vi.mocked(agent.tools.ozone.moderation.emitEvent), 143 ).toHaveBeenCalled(); 144 }); 145 }); 146});