A tool for tailing a labelers' firehose, rehydrating, and storing records for future analysis of moderation decisions.
1import { describe, test, expect, beforeEach } from "bun:test";
2import { LabelFilter } from "../../src/firehose/filter.js";
3import { LabelEvent } from "../../src/firehose/decoder.js";
4
5describe("Label Filter", () => {
6 describe("with no filtering (capturing all labels)", () => {
7 let filter: LabelFilter;
8
9 beforeEach(() => {
10 filter = new LabelFilter([]);
11 });
12
13 test("should capture any label", () => {
14 const label: LabelEvent = {
15 src: "did:plc:labeler",
16 uri: "at://did:plc:user/app.bsky.feed.post/123",
17 val: "spam",
18 cts: "2025-01-15T12:00:00Z",
19 };
20
21 expect(filter.shouldCapture(label)).toBe(true);
22 });
23
24 test("should return null for filtered labels list", () => {
25 expect(filter.getFilteredLabels()).toBeNull();
26 });
27 });
28
29 describe("with label filtering enabled", () => {
30 let filter: LabelFilter;
31
32 beforeEach(() => {
33 filter = new LabelFilter(["spam", "hate-speech", "csam"]);
34 });
35
36 test("should capture allowed labels", () => {
37 const label: LabelEvent = {
38 src: "did:plc:labeler",
39 uri: "at://did:plc:user/app.bsky.feed.post/123",
40 val: "spam",
41 cts: "2025-01-15T12:00:00Z",
42 };
43
44 expect(filter.shouldCapture(label)).toBe(true);
45 });
46
47 test("should reject non-allowed labels", () => {
48 const label: LabelEvent = {
49 src: "did:plc:labeler",
50 uri: "at://did:plc:user/app.bsky.feed.post/123",
51 val: "misleading",
52 cts: "2025-01-15T12:00:00Z",
53 };
54
55 expect(filter.shouldCapture(label)).toBe(false);
56 });
57
58 test("should return list of filtered labels", () => {
59 const labels = filter.getFilteredLabels();
60
61 expect(labels).not.toBeNull();
62 expect(labels).toContain("spam");
63 expect(labels).toContain("hate-speech");
64 expect(labels).toContain("csam");
65 expect(labels?.length).toBe(3);
66 });
67 });
68});