@atproto/ozone 0.0.16 → 0.0.17-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/util.d.ts +10 -0
- package/dist/auth-verifier.d.ts +8 -12
- package/dist/communication-service/template.d.ts +2 -2
- package/dist/config/config.d.ts +6 -0
- package/dist/config/env.d.ts +3 -2
- package/dist/config/secrets.d.ts +0 -2
- package/dist/context.d.ts +6 -0
- package/dist/daemon/blob-diverter.d.ts +26 -0
- package/dist/daemon/event-pusher.d.ts +6 -0
- package/dist/daemon/index.d.ts +1 -0
- package/dist/db/index.js +21 -1
- package/dist/db/index.js.map +3 -3
- package/dist/db/migrations/20240228T003647759Z-add-label-sigs.d.ts +3 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/db/schema/index.d.ts +2 -1
- package/dist/db/schema/label.d.ts +4 -0
- package/dist/db/schema/moderation_event.d.ts +1 -1
- package/dist/db/schema/moderation_subject_status.d.ts +2 -2
- package/dist/db/schema/signing_key.d.ts +9 -0
- package/dist/index.js +10400 -10313
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +55 -27
- package/dist/lexicon/lexicons.d.ts +5046 -4757
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +23 -1
- package/dist/lexicon/types/app/bsky/embed/record.d.ts +2 -1
- package/dist/lexicon/types/app/bsky/feed/defs.d.ts +1 -0
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts +3 -0
- package/dist/lexicon/types/app/bsky/labeler/defs.d.ts +41 -0
- package/dist/lexicon/types/app/bsky/labeler/getServices.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/labeler/service.d.ts +14 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +0 -304
- package/dist/lexicon/types/com/atproto/label/defs.d.ts +23 -0
- package/dist/lexicon/types/{com/atproto/admin/createCommunicationTemplate.d.ts → tools/ozone/communication/createTemplate.d.ts} +2 -2
- package/dist/lexicon/types/tools/ozone/communication/defs.d.ts +14 -0
- package/dist/lexicon/types/{com/atproto/admin/listCommunicationTemplates.d.ts → tools/ozone/communication/listTemplates.d.ts} +2 -2
- package/dist/lexicon/types/{com/atproto/admin/updateCommunicationTemplate.d.ts → tools/ozone/communication/updateTemplate.d.ts} +2 -2
- package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts +269 -0
- package/dist/lexicon/types/{com/atproto/admin/emitModerationEvent.d.ts → tools/ozone/moderation/emitEvent.d.ts} +5 -4
- package/dist/lexicon/types/{com/atproto/admin/getModerationEvent.d.ts → tools/ozone/moderation/getEvent.d.ts} +2 -2
- package/dist/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRecord.d.ts +2 -2
- package/dist/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRepo.d.ts +2 -2
- package/dist/lexicon/types/{com/atproto/admin/queryModerationEvents.d.ts → tools/ozone/moderation/queryEvents.d.ts} +2 -2
- package/dist/lexicon/types/{com/atproto/admin/queryModerationStatuses.d.ts → tools/ozone/moderation/queryStatuses.d.ts} +2 -2
- package/dist/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/searchRepos.d.ts +2 -2
- package/dist/mod-service/index.d.ts +16 -15
- package/dist/mod-service/subject.d.ts +1 -1
- package/dist/mod-service/types.d.ts +2 -2
- package/dist/mod-service/util.d.ts +6 -0
- package/dist/mod-service/views.d.ts +9 -3
- package/dist/sequencer/sequencer.d.ts +6 -4
- package/dist/util.d.ts +2 -0
- package/package.json +9 -8
- package/src/api/{admin/createCommunicationTemplate.ts → communication/createTemplate.ts} +2 -2
- package/src/api/{admin/deleteCommunicationTemplate.ts → communication/deleteTemplate.ts} +2 -2
- package/src/api/{admin/listCommunicationTemplates.ts → communication/listTemplates.ts} +2 -2
- package/src/api/{admin/updateCommunicationTemplate.ts → communication/updateTemplate.ts} +2 -2
- package/src/api/index.ts +21 -21
- package/src/api/{temp → label}/fetchLabels.ts +5 -3
- package/src/api/label/queryLabels.ts +4 -2
- package/src/api/moderation/emitEvent.ts +218 -0
- package/src/api/{admin/getModerationEvent.ts → moderation/getEvent.ts} +2 -2
- package/src/api/{admin → moderation}/getRecord.ts +3 -3
- package/src/api/{admin → moderation}/getRepo.ts +3 -3
- package/src/api/{admin/queryModerationEvents.ts → moderation/queryEvents.ts} +3 -3
- package/src/api/{admin/queryModerationStatuses.ts → moderation/queryStatuses.ts} +3 -3
- package/src/api/{admin → moderation}/searchRepos.ts +2 -2
- package/src/api/proxied.ts +8 -8
- package/src/api/{moderation → report}/createReport.ts +2 -3
- package/src/api/util.ts +119 -0
- package/src/auth-verifier.ts +20 -30
- package/src/communication-service/template.ts +2 -2
- package/src/config/config.ts +24 -7
- package/src/config/env.ts +6 -4
- package/src/config/secrets.ts +0 -6
- package/src/context.ts +36 -12
- package/src/daemon/blob-diverter.ts +150 -0
- package/src/daemon/context.ts +11 -7
- package/src/daemon/event-pusher.ts +58 -15
- package/src/daemon/index.ts +1 -0
- package/src/db/migrations/20240228T003647759Z-add-label-sigs.ts +25 -0
- package/src/db/migrations/index.ts +1 -0
- package/src/db/schema/index.ts +2 -0
- package/src/db/schema/label.ts +3 -0
- package/src/db/schema/moderation_event.ts +11 -11
- package/src/db/schema/moderation_subject_status.ts +7 -2
- package/src/db/schema/signing_key.ts +10 -0
- package/src/lexicon/index.ts +200 -137
- package/src/lexicon/lexicons.ts +6310 -6012
- package/src/lexicon/types/app/bsky/actor/defs.ts +57 -1
- package/src/lexicon/types/app/bsky/embed/record.ts +2 -0
- package/src/lexicon/types/app/bsky/feed/defs.ts +1 -0
- package/src/lexicon/types/app/bsky/graph/defs.ts +3 -0
- package/src/lexicon/types/app/bsky/labeler/defs.ts +93 -0
- package/src/lexicon/types/app/bsky/labeler/getServices.ts +51 -0
- package/src/lexicon/types/app/bsky/labeler/service.ts +31 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +0 -694
- package/src/lexicon/types/com/atproto/label/defs.ts +78 -0
- package/src/lexicon/types/{com/atproto/admin/createCommunicationTemplate.ts → tools/ozone/communication/createTemplate.ts} +2 -2
- package/src/lexicon/types/tools/ozone/communication/defs.ts +35 -0
- package/src/lexicon/types/{com/atproto/admin/listCommunicationTemplates.ts → tools/ozone/communication/listTemplates.ts} +2 -2
- package/src/lexicon/types/{com/atproto/admin/updateCommunicationTemplate.ts → tools/ozone/communication/updateTemplate.ts} +2 -2
- package/src/lexicon/types/tools/ozone/moderation/defs.ts +641 -0
- package/src/lexicon/types/{com/atproto/admin/emitModerationEvent.ts → tools/ozone/moderation/emitEvent.ts} +15 -14
- package/src/lexicon/types/{com/atproto/admin/getModerationEvent.ts → tools/ozone/moderation/getEvent.ts} +2 -2
- package/src/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRecord.ts +2 -2
- package/src/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRepo.ts +2 -2
- package/src/lexicon/types/{com/atproto/admin/queryModerationEvents.ts → tools/ozone/moderation/queryEvents.ts} +3 -3
- package/src/lexicon/types/{com/atproto/admin/queryModerationStatuses.ts → tools/ozone/moderation/queryStatuses.ts} +2 -2
- package/src/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/searchRepos.ts +2 -2
- package/src/mod-service/index.ts +46 -50
- package/src/mod-service/lang.ts +1 -1
- package/src/mod-service/status.ts +60 -41
- package/src/mod-service/subject.ts +1 -1
- package/src/mod-service/types.ts +10 -10
- package/src/mod-service/util.ts +49 -5
- package/src/mod-service/views.ts +45 -18
- package/src/sequencer/sequencer.ts +12 -11
- package/src/util.ts +21 -0
- package/tests/__snapshots__/blob-divert.test.ts.snap +22 -0
- package/tests/__snapshots__/get-record.test.ts.snap +14 -6
- package/tests/__snapshots__/get-repo.test.ts.snap +7 -3
- package/tests/__snapshots__/moderation-events.test.ts.snap +8 -8
- package/tests/__snapshots__/moderation-statuses.test.ts.snap +6 -6
- package/tests/_util.ts +5 -0
- package/tests/blob-divert.test.ts +87 -0
- package/tests/communication-templates.test.ts +33 -37
- package/tests/db.test.ts +6 -6
- package/tests/get-record.test.ts +22 -12
- package/tests/get-repo.test.ts +33 -21
- package/tests/moderation-appeals.test.ts +39 -67
- package/tests/moderation-events.test.ts +99 -142
- package/tests/moderation-status-tags.test.ts +20 -37
- package/tests/moderation-statuses.test.ts +132 -65
- package/tests/moderation.test.ts +147 -301
- package/tests/query-labels.test.ts +86 -10
- package/tests/repo-search.test.ts +18 -11
- package/tests/sequencer.test.ts +6 -3
- package/dist/api/admin/util.d.ts +0 -5
- package/dist/api/moderation/util.d.ts +0 -4
- package/src/api/admin/emitModerationEvent.ts +0 -170
- package/src/api/admin/util.ts +0 -54
- package/src/api/moderation/util.ts +0 -67
- /package/dist/api/{admin/createCommunicationTemplate.d.ts → communication/createTemplate.d.ts} +0 -0
- /package/dist/api/{admin/deleteCommunicationTemplate.d.ts → communication/deleteTemplate.d.ts} +0 -0
- /package/dist/api/{admin/emitModerationEvent.d.ts → communication/listTemplates.d.ts} +0 -0
- /package/dist/api/{admin/getModerationEvent.d.ts → communication/updateTemplate.d.ts} +0 -0
- /package/dist/api/{temp → label}/fetchLabels.d.ts +0 -0
- /package/dist/api/{admin/getRecord.d.ts → moderation/emitEvent.d.ts} +0 -0
- /package/dist/api/{admin/getRepo.d.ts → moderation/getEvent.d.ts} +0 -0
- /package/dist/api/{admin/listCommunicationTemplates.d.ts → moderation/getRecord.d.ts} +0 -0
- /package/dist/api/{admin/queryModerationEvents.d.ts → moderation/getRepo.d.ts} +0 -0
- /package/dist/api/{admin/queryModerationStatuses.d.ts → moderation/queryEvents.d.ts} +0 -0
- /package/dist/api/{admin/searchRepos.d.ts → moderation/queryStatuses.d.ts} +0 -0
- /package/dist/api/{admin/updateCommunicationTemplate.d.ts → moderation/searchRepos.d.ts} +0 -0
- /package/dist/api/{moderation → report}/createReport.d.ts +0 -0
- /package/dist/lexicon/types/{com/atproto/admin/deleteCommunicationTemplate.d.ts → tools/ozone/communication/deleteTemplate.d.ts} +0 -0
- /package/src/lexicon/types/{com/atproto/admin/deleteCommunicationTemplate.ts → tools/ozone/communication/deleteTemplate.ts} +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
2
|
import EventEmitter, { once } from 'node:events'
|
|
3
|
+
import {
|
|
4
|
+
TestNetwork,
|
|
5
|
+
SeedClient,
|
|
6
|
+
basicSeed,
|
|
7
|
+
ModeratorClient,
|
|
8
|
+
} from '@atproto/dev-env'
|
|
9
|
+
import { ToolsOzoneModerationDefs } from '@atproto/api'
|
|
3
10
|
import Mail from 'nodemailer/lib/mailer'
|
|
4
|
-
import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
|
|
5
|
-
import AtpAgent, {
|
|
6
|
-
ComAtprotoAdminDefs,
|
|
7
|
-
ComAtprotoAdminEmitModerationEvent,
|
|
8
|
-
} from '@atproto/api'
|
|
9
11
|
import { forSnapshot } from './_util'
|
|
10
12
|
import {
|
|
11
13
|
REASONAPPEAL,
|
|
@@ -15,23 +17,8 @@ import {
|
|
|
15
17
|
|
|
16
18
|
describe('moderation-events', () => {
|
|
17
19
|
let network: TestNetwork
|
|
18
|
-
let agent: AtpAgent
|
|
19
|
-
let pdsAgent: AtpAgent
|
|
20
20
|
let sc: SeedClient
|
|
21
|
-
|
|
22
|
-
const emitModerationEvent = async (
|
|
23
|
-
eventData: ComAtprotoAdminEmitModerationEvent.InputSchema,
|
|
24
|
-
) => {
|
|
25
|
-
return pdsAgent.api.com.atproto.admin.emitModerationEvent(eventData, {
|
|
26
|
-
encoding: 'application/json',
|
|
27
|
-
headers: network.ozone.adminAuthHeaders('moderator'),
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const queryModerationEvents = (eventQuery) =>
|
|
32
|
-
agent.api.com.atproto.admin.queryModerationEvents(eventQuery, {
|
|
33
|
-
headers: network.ozone.adminAuthHeaders('moderator'),
|
|
34
|
-
})
|
|
21
|
+
let modClient: ModeratorClient
|
|
35
22
|
|
|
36
23
|
const seedEvents = async () => {
|
|
37
24
|
const bobsAccount = {
|
|
@@ -54,25 +41,19 @@ describe('moderation-events', () => {
|
|
|
54
41
|
}
|
|
55
42
|
|
|
56
43
|
for (let i = 0; i < 4; i++) {
|
|
57
|
-
await
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
reportType: i % 2 ? REASONSPAM : REASONMISLEADING,
|
|
61
|
-
comment: 'X',
|
|
62
|
-
},
|
|
44
|
+
await sc.createReport({
|
|
45
|
+
reasonType: i % 2 ? REASONSPAM : REASONMISLEADING,
|
|
46
|
+
reason: 'X',
|
|
63
47
|
// Report bob's account by alice and vice versa
|
|
64
48
|
subject: i % 2 ? bobsAccount : alicesAccount,
|
|
65
|
-
|
|
49
|
+
reportedBy: i % 2 ? sc.dids.alice : sc.dids.bob,
|
|
66
50
|
})
|
|
67
|
-
await
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
reportType: REASONSPAM,
|
|
71
|
-
comment: 'X',
|
|
72
|
-
},
|
|
51
|
+
await sc.createReport({
|
|
52
|
+
reasonType: REASONSPAM,
|
|
53
|
+
reason: 'X',
|
|
73
54
|
// Report bob's post by alice and vice versa
|
|
74
55
|
subject: i % 2 ? bobsPost : alicesPost,
|
|
75
|
-
|
|
56
|
+
reportedBy: i % 2 ? sc.dids.alice : sc.dids.bob,
|
|
76
57
|
})
|
|
77
58
|
}
|
|
78
59
|
}
|
|
@@ -81,9 +62,8 @@ describe('moderation-events', () => {
|
|
|
81
62
|
network = await TestNetwork.create({
|
|
82
63
|
dbPostgresSchema: 'ozone_moderation_events',
|
|
83
64
|
})
|
|
84
|
-
agent = network.ozone.getClient()
|
|
85
|
-
pdsAgent = network.pds.getClient()
|
|
86
65
|
sc = network.getSeedClient()
|
|
66
|
+
modClient = network.ozone.getModClient()
|
|
87
67
|
await basicSeed(sc)
|
|
88
68
|
await network.processAll()
|
|
89
69
|
await seedEvents()
|
|
@@ -96,16 +76,16 @@ describe('moderation-events', () => {
|
|
|
96
76
|
describe('query events', () => {
|
|
97
77
|
it('returns all events for record or repo', async () => {
|
|
98
78
|
const [bobsEvents, alicesPostEvents] = await Promise.all([
|
|
99
|
-
|
|
79
|
+
modClient.queryEvents({
|
|
100
80
|
subject: sc.dids.bob,
|
|
101
81
|
}),
|
|
102
|
-
|
|
82
|
+
modClient.queryEvents({
|
|
103
83
|
subject: sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
104
84
|
}),
|
|
105
85
|
])
|
|
106
86
|
|
|
107
|
-
expect(forSnapshot(bobsEvents.
|
|
108
|
-
expect(forSnapshot(alicesPostEvents.
|
|
87
|
+
expect(forSnapshot(bobsEvents.events)).toMatchSnapshot()
|
|
88
|
+
expect(forSnapshot(alicesPostEvents.events)).toMatchSnapshot()
|
|
109
89
|
})
|
|
110
90
|
|
|
111
91
|
it('filters events by types', async () => {
|
|
@@ -114,66 +94,64 @@ describe('moderation-events', () => {
|
|
|
114
94
|
did: sc.dids.alice,
|
|
115
95
|
}
|
|
116
96
|
await Promise.all([
|
|
117
|
-
|
|
97
|
+
modClient.emitEvent({
|
|
118
98
|
event: {
|
|
119
|
-
$type: '
|
|
99
|
+
$type: 'tools.ozone.moderation.defs#modEventComment',
|
|
120
100
|
comment: 'X',
|
|
121
101
|
},
|
|
122
102
|
subject: alicesAccount,
|
|
123
|
-
createdBy: 'did:plc:moderator',
|
|
124
103
|
}),
|
|
125
|
-
|
|
104
|
+
modClient.emitEvent({
|
|
126
105
|
event: {
|
|
127
|
-
$type: '
|
|
106
|
+
$type: 'tools.ozone.moderation.defs#modEventEscalate',
|
|
128
107
|
comment: 'X',
|
|
129
108
|
},
|
|
130
109
|
subject: alicesAccount,
|
|
131
|
-
createdBy: 'did:plc:moderator',
|
|
132
110
|
}),
|
|
133
111
|
])
|
|
134
112
|
const [allEvents, reportEvents] = await Promise.all([
|
|
135
|
-
|
|
113
|
+
modClient.queryEvents({
|
|
136
114
|
subject: sc.dids.alice,
|
|
137
115
|
}),
|
|
138
|
-
|
|
116
|
+
modClient.queryEvents({
|
|
139
117
|
subject: sc.dids.alice,
|
|
140
|
-
types: ['
|
|
118
|
+
types: ['tools.ozone.moderation.defs#modEventReport'],
|
|
141
119
|
}),
|
|
142
120
|
])
|
|
143
121
|
|
|
144
|
-
expect(allEvents.
|
|
145
|
-
reportEvents.
|
|
122
|
+
expect(allEvents.events.length).toBeGreaterThan(
|
|
123
|
+
reportEvents.events.length,
|
|
146
124
|
)
|
|
147
125
|
expect(
|
|
148
|
-
[...new Set(reportEvents.
|
|
126
|
+
[...new Set(reportEvents.events.map((e) => e.event.$type))].length,
|
|
149
127
|
).toEqual(1)
|
|
150
128
|
|
|
151
129
|
expect(
|
|
152
|
-
[...new Set(allEvents.
|
|
130
|
+
[...new Set(allEvents.events.map((e) => e.event.$type))].length,
|
|
153
131
|
).toEqual(4)
|
|
154
132
|
})
|
|
155
133
|
|
|
156
134
|
it('returns events for all content by user', async () => {
|
|
157
135
|
const [forAccount, forPost] = await Promise.all([
|
|
158
|
-
|
|
136
|
+
modClient.queryEvents({
|
|
159
137
|
subject: sc.dids.bob,
|
|
160
138
|
includeAllUserRecords: true,
|
|
161
139
|
}),
|
|
162
|
-
|
|
140
|
+
modClient.queryEvents({
|
|
163
141
|
subject: sc.posts[sc.dids.bob][0].ref.uriStr,
|
|
164
142
|
includeAllUserRecords: true,
|
|
165
143
|
}),
|
|
166
144
|
])
|
|
167
145
|
|
|
168
|
-
expect(forAccount.
|
|
146
|
+
expect(forAccount.events.length).toEqual(forPost.events.length)
|
|
169
147
|
// Save events are returned from both requests
|
|
170
|
-
expect(forPost.
|
|
171
|
-
forAccount.
|
|
148
|
+
expect(forPost.events.map(({ id }) => id).sort()).toEqual(
|
|
149
|
+
forAccount.events.map(({ id }) => id).sort(),
|
|
172
150
|
)
|
|
173
151
|
})
|
|
174
152
|
|
|
175
153
|
it('returns paginated list of events with cursor', async () => {
|
|
176
|
-
const allEvents = await
|
|
154
|
+
const allEvents = await modClient.queryEvents({
|
|
177
155
|
subject: sc.dids.bob,
|
|
178
156
|
includeAllUserRecords: true,
|
|
179
157
|
})
|
|
@@ -182,19 +160,19 @@ describe('moderation-events', () => {
|
|
|
182
160
|
sortDirection: 'asc' | 'desc' = 'desc',
|
|
183
161
|
) => {
|
|
184
162
|
let defaultCursor: undefined | string = undefined
|
|
185
|
-
const events:
|
|
163
|
+
const events: ToolsOzoneModerationDefs.ModEventView[] = []
|
|
186
164
|
let count = 0
|
|
187
165
|
do {
|
|
188
166
|
// get 1 event at a time and check we get all events
|
|
189
|
-
const
|
|
167
|
+
const res = await modClient.queryEvents({
|
|
190
168
|
limit: 1,
|
|
191
169
|
subject: sc.dids.bob,
|
|
192
170
|
includeAllUserRecords: true,
|
|
193
171
|
cursor: defaultCursor,
|
|
194
172
|
sortDirection,
|
|
195
173
|
})
|
|
196
|
-
events.push(...
|
|
197
|
-
defaultCursor =
|
|
174
|
+
events.push(...res.events)
|
|
175
|
+
defaultCursor = res.cursor
|
|
198
176
|
count++
|
|
199
177
|
// The count is a circuit breaker to prevent infinite loop in case of failing test
|
|
200
178
|
} while (defaultCursor && count < 10)
|
|
@@ -205,51 +183,53 @@ describe('moderation-events', () => {
|
|
|
205
183
|
const defaultEvents = await getPaginatedEvents()
|
|
206
184
|
const reversedEvents = await getPaginatedEvents('asc')
|
|
207
185
|
|
|
208
|
-
expect(allEvents.
|
|
209
|
-
expect(defaultEvents.length).toEqual(allEvents.
|
|
210
|
-
expect(reversedEvents.length).toEqual(allEvents.
|
|
186
|
+
expect(allEvents.events.length).toEqual(6)
|
|
187
|
+
expect(defaultEvents.length).toEqual(allEvents.events.length)
|
|
188
|
+
expect(reversedEvents.length).toEqual(allEvents.events.length)
|
|
211
189
|
// First event in the reversed list is the last item in the default list
|
|
212
|
-
expect(reversedEvents[0].id).toEqual(
|
|
190
|
+
expect(reversedEvents[0].id).toEqual(
|
|
191
|
+
defaultEvents[defaultEvents.length - 1].id,
|
|
192
|
+
)
|
|
213
193
|
})
|
|
214
194
|
|
|
215
195
|
it('returns report events matching reportType filters', async () => {
|
|
216
196
|
const [spamEvents, misleadingEvents] = await Promise.all([
|
|
217
|
-
|
|
197
|
+
modClient.queryEvents({
|
|
218
198
|
reportTypes: [REASONSPAM],
|
|
219
199
|
}),
|
|
220
|
-
|
|
200
|
+
modClient.queryEvents({
|
|
221
201
|
reportTypes: [REASONMISLEADING, REASONAPPEAL],
|
|
222
202
|
}),
|
|
223
203
|
])
|
|
224
204
|
|
|
225
|
-
expect(misleadingEvents.
|
|
226
|
-
expect(spamEvents.
|
|
205
|
+
expect(misleadingEvents.events.length).toEqual(2)
|
|
206
|
+
expect(spamEvents.events.length).toEqual(6)
|
|
227
207
|
})
|
|
228
208
|
|
|
229
209
|
it('returns events matching keyword in comment', async () => {
|
|
230
210
|
const [eventsWithX, eventsWithTest, eventsWithComment] =
|
|
231
211
|
await Promise.all([
|
|
232
|
-
|
|
212
|
+
modClient.queryEvents({
|
|
233
213
|
comment: 'X',
|
|
234
214
|
}),
|
|
235
|
-
|
|
215
|
+
modClient.queryEvents({
|
|
236
216
|
comment: 'test',
|
|
237
217
|
}),
|
|
238
|
-
|
|
218
|
+
modClient.queryEvents({
|
|
239
219
|
hasComment: true,
|
|
240
220
|
}),
|
|
241
221
|
])
|
|
242
222
|
|
|
243
|
-
expect(eventsWithX.
|
|
244
|
-
expect(eventsWithTest.
|
|
245
|
-
expect(eventsWithComment.
|
|
223
|
+
expect(eventsWithX.events.length).toEqual(10)
|
|
224
|
+
expect(eventsWithTest.events.length).toEqual(0)
|
|
225
|
+
expect(eventsWithComment.events.length).toEqual(10)
|
|
246
226
|
})
|
|
247
227
|
|
|
248
228
|
it('returns events matching filter params for labels', async () => {
|
|
249
229
|
const [negatedLabelEvent, createdLabelEvent] = await Promise.all([
|
|
250
|
-
|
|
230
|
+
modClient.emitEvent({
|
|
251
231
|
event: {
|
|
252
|
-
$type: '
|
|
232
|
+
$type: 'tools.ozone.moderation.defs#modEventLabel',
|
|
253
233
|
comment: 'X',
|
|
254
234
|
negateLabelVals: ['L1', 'L2'],
|
|
255
235
|
createLabelVals: [],
|
|
@@ -259,11 +239,10 @@ describe('moderation-events', () => {
|
|
|
259
239
|
$type: 'com.atproto.admin.defs#repoRef',
|
|
260
240
|
did: sc.dids.alice,
|
|
261
241
|
},
|
|
262
|
-
createdBy: sc.dids.bob,
|
|
263
242
|
}),
|
|
264
|
-
|
|
243
|
+
modClient.emitEvent({
|
|
265
244
|
event: {
|
|
266
|
-
$type: '
|
|
245
|
+
$type: 'tools.ozone.moderation.defs#modEventLabel',
|
|
267
246
|
comment: 'X',
|
|
268
247
|
createLabelVals: ['L1', 'L2'],
|
|
269
248
|
negateLabelVals: [],
|
|
@@ -273,36 +252,31 @@ describe('moderation-events', () => {
|
|
|
273
252
|
$type: 'com.atproto.admin.defs#repoRef',
|
|
274
253
|
did: sc.dids.bob,
|
|
275
254
|
},
|
|
276
|
-
createdBy: sc.dids.alice,
|
|
277
255
|
}),
|
|
278
256
|
])
|
|
279
257
|
const [withTwoLabels, withoutTwoLabels, withOneLabel, withoutOneLabel] =
|
|
280
258
|
await Promise.all([
|
|
281
|
-
|
|
259
|
+
modClient.queryEvents({
|
|
282
260
|
addedLabels: ['L1', 'L3'],
|
|
283
261
|
}),
|
|
284
|
-
|
|
262
|
+
modClient.queryEvents({
|
|
285
263
|
removedLabels: ['L1', 'L2'],
|
|
286
264
|
}),
|
|
287
|
-
|
|
265
|
+
modClient.queryEvents({
|
|
288
266
|
addedLabels: ['L1'],
|
|
289
267
|
}),
|
|
290
|
-
|
|
268
|
+
modClient.queryEvents({
|
|
291
269
|
removedLabels: ['L2'],
|
|
292
270
|
}),
|
|
293
271
|
])
|
|
294
272
|
|
|
295
273
|
// Verify that when querying for events where 2 different labels were added
|
|
296
274
|
// events where all of the labels from the list was added are returned
|
|
297
|
-
expect(withTwoLabels.
|
|
298
|
-
expect(negatedLabelEvent.
|
|
299
|
-
withoutTwoLabels.data.events[0].id,
|
|
300
|
-
)
|
|
275
|
+
expect(withTwoLabels.events.length).toEqual(0)
|
|
276
|
+
expect(negatedLabelEvent.id).toEqual(withoutTwoLabels.events[0].id)
|
|
301
277
|
|
|
302
|
-
expect(createdLabelEvent.
|
|
303
|
-
expect(negatedLabelEvent.
|
|
304
|
-
withoutOneLabel.data.events[0].id,
|
|
305
|
-
)
|
|
278
|
+
expect(createdLabelEvent.id).toEqual(withOneLabel.events[0].id)
|
|
279
|
+
expect(negatedLabelEvent.id).toEqual(withoutOneLabel.events[0].id)
|
|
306
280
|
})
|
|
307
281
|
it('returns events matching filter params for tags', async () => {
|
|
308
282
|
const tagEvent = async ({
|
|
@@ -312,9 +286,9 @@ describe('moderation-events', () => {
|
|
|
312
286
|
add: string[]
|
|
313
287
|
remove: string[]
|
|
314
288
|
}) =>
|
|
315
|
-
|
|
289
|
+
modClient.emitEvent({
|
|
316
290
|
event: {
|
|
317
|
-
$type: '
|
|
291
|
+
$type: 'tools.ozone.moderation.defs#modEventTag',
|
|
318
292
|
comment: 'X',
|
|
319
293
|
add,
|
|
320
294
|
remove,
|
|
@@ -323,43 +297,35 @@ describe('moderation-events', () => {
|
|
|
323
297
|
$type: 'com.atproto.admin.defs#repoRef',
|
|
324
298
|
did: sc.dids.carol,
|
|
325
299
|
},
|
|
326
|
-
createdBy: sc.dids.bob,
|
|
327
300
|
})
|
|
328
301
|
const addEvent = await tagEvent({ add: ['L1', 'L2'], remove: [] })
|
|
329
302
|
const addAndRemoveEvent = await tagEvent({ add: ['L3'], remove: ['L2'] })
|
|
330
303
|
const [addFinder, addAndRemoveFinder, _removeFinder] = await Promise.all([
|
|
331
|
-
|
|
304
|
+
modClient.queryEvents({
|
|
332
305
|
addedTags: ['L1'],
|
|
333
306
|
}),
|
|
334
|
-
|
|
307
|
+
modClient.queryEvents({
|
|
335
308
|
addedTags: ['L3'],
|
|
336
309
|
removedTags: ['L2'],
|
|
337
310
|
}),
|
|
338
|
-
|
|
311
|
+
modClient.queryEvents({
|
|
339
312
|
removedTags: ['L2'],
|
|
340
313
|
}),
|
|
341
314
|
])
|
|
342
315
|
|
|
343
|
-
expect(addFinder.
|
|
344
|
-
expect(addEvent.
|
|
316
|
+
expect(addFinder.events.length).toEqual(1)
|
|
317
|
+
expect(addEvent.id).toEqual(addFinder.events[0].id)
|
|
345
318
|
|
|
346
|
-
expect(addAndRemoveEvent.
|
|
347
|
-
|
|
348
|
-
)
|
|
349
|
-
expect(addAndRemoveEvent.
|
|
350
|
-
addAndRemoveFinder.data.events[0].id,
|
|
351
|
-
)
|
|
352
|
-
expect(addAndRemoveEvent.data.event.add).toEqual(['L3'])
|
|
353
|
-
expect(addAndRemoveEvent.data.event.remove).toEqual(['L2'])
|
|
319
|
+
expect(addAndRemoveEvent.id).toEqual(addAndRemoveFinder.events[0].id)
|
|
320
|
+
expect(addAndRemoveEvent.id).toEqual(addAndRemoveFinder.events[0].id)
|
|
321
|
+
expect(addAndRemoveEvent.event.add).toEqual(['L3'])
|
|
322
|
+
expect(addAndRemoveEvent.event.remove).toEqual(['L2'])
|
|
354
323
|
})
|
|
355
324
|
})
|
|
356
325
|
|
|
357
326
|
describe('get event', () => {
|
|
358
327
|
it('gets an event by specific id', async () => {
|
|
359
|
-
const
|
|
360
|
-
{ id: 1 },
|
|
361
|
-
{ headers: network.ozone.adminAuthHeaders('moderator') },
|
|
362
|
-
)
|
|
328
|
+
const data = await modClient.getEvent(1)
|
|
363
329
|
expect(forSnapshot(data)).toMatchSnapshot()
|
|
364
330
|
})
|
|
365
331
|
})
|
|
@@ -368,9 +334,9 @@ describe('moderation-events', () => {
|
|
|
368
334
|
it('are tracked on takedown event', async () => {
|
|
369
335
|
const post = sc.posts[sc.dids.carol][0]
|
|
370
336
|
assert(post.images.length > 1)
|
|
371
|
-
await
|
|
337
|
+
await modClient.emitEvent({
|
|
372
338
|
event: {
|
|
373
|
-
$type: '
|
|
339
|
+
$type: 'tools.ozone.moderation.defs#modEventTakedown',
|
|
374
340
|
},
|
|
375
341
|
subject: {
|
|
376
342
|
$type: 'com.atproto.repo.strongRef',
|
|
@@ -378,20 +344,15 @@ describe('moderation-events', () => {
|
|
|
378
344
|
cid: post.ref.cidStr,
|
|
379
345
|
},
|
|
380
346
|
subjectBlobCids: [post.images[0].image.ref.toString()],
|
|
381
|
-
createdBy: sc.dids.alice,
|
|
382
347
|
})
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
types: ['com.atproto.admin.defs#modEventTakedown'],
|
|
388
|
-
},
|
|
389
|
-
{ headers: network.ozone.adminAuthHeaders('moderator') },
|
|
390
|
-
)
|
|
348
|
+
const result = await modClient.queryEvents({
|
|
349
|
+
subject: post.ref.uriStr,
|
|
350
|
+
types: ['tools.ozone.moderation.defs#modEventTakedown'],
|
|
351
|
+
})
|
|
391
352
|
expect(result.events[0]).toMatchObject({
|
|
392
|
-
createdBy:
|
|
353
|
+
createdBy: network.ozone.moderatorAccnt.did,
|
|
393
354
|
event: {
|
|
394
|
-
$type: '
|
|
355
|
+
$type: 'tools.ozone.moderation.defs#modEventTakedown',
|
|
395
356
|
},
|
|
396
357
|
subjectBlobCids: [post.images[0].image.ref.toString()],
|
|
397
358
|
})
|
|
@@ -399,26 +360,23 @@ describe('moderation-events', () => {
|
|
|
399
360
|
|
|
400
361
|
it("are tracked on reverse-takedown event even if they aren't specified", async () => {
|
|
401
362
|
const post = sc.posts[sc.dids.carol][0]
|
|
402
|
-
await
|
|
363
|
+
await modClient.emitEvent({
|
|
403
364
|
event: {
|
|
404
|
-
$type: '
|
|
365
|
+
$type: 'tools.ozone.moderation.defs#modEventReverseTakedown',
|
|
405
366
|
},
|
|
406
367
|
subject: {
|
|
407
368
|
$type: 'com.atproto.repo.strongRef',
|
|
408
369
|
uri: post.ref.uriStr,
|
|
409
370
|
cid: post.ref.cidStr,
|
|
410
371
|
},
|
|
411
|
-
createdBy: sc.dids.alice,
|
|
412
372
|
})
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
{ headers: network.ozone.adminAuthHeaders('moderator') },
|
|
417
|
-
)
|
|
373
|
+
const result = await modClient.queryEvents({
|
|
374
|
+
subject: post.ref.uriStr,
|
|
375
|
+
})
|
|
418
376
|
expect(result.events[0]).toMatchObject({
|
|
419
|
-
createdBy:
|
|
377
|
+
createdBy: network.ozone.moderatorAccnt.did,
|
|
420
378
|
event: {
|
|
421
|
-
$type: '
|
|
379
|
+
$type: 'tools.ozone.moderation.defs#modEventReverseTakedown',
|
|
422
380
|
},
|
|
423
381
|
subjectBlobCids: [post.images[0].image.ref.toString()],
|
|
424
382
|
})
|
|
@@ -450,9 +408,9 @@ describe('moderation-events', () => {
|
|
|
450
408
|
|
|
451
409
|
it('sends email via pds.', async () => {
|
|
452
410
|
const mail = await getMailFrom(
|
|
453
|
-
|
|
411
|
+
modClient.emitEvent({
|
|
454
412
|
event: {
|
|
455
|
-
$type: '
|
|
413
|
+
$type: 'tools.ozone.moderation.defs#modEventEmail',
|
|
456
414
|
comment: 'Reaching out to Alice',
|
|
457
415
|
subjectLine: 'Hello',
|
|
458
416
|
content: 'Hey Alice, how are you?',
|
|
@@ -461,7 +419,6 @@ describe('moderation-events', () => {
|
|
|
461
419
|
$type: 'com.atproto.admin.defs#repoRef',
|
|
462
420
|
did: sc.dids.alice,
|
|
463
421
|
},
|
|
464
|
-
createdBy: sc.dids.bob,
|
|
465
422
|
}),
|
|
466
423
|
)
|
|
467
424
|
expect(mail).toEqual({
|
|
@@ -1,32 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
TestNetwork,
|
|
3
|
+
SeedClient,
|
|
4
|
+
basicSeed,
|
|
5
|
+
ModeratorClient,
|
|
6
|
+
} from '@atproto/dev-env'
|
|
3
7
|
import { REASONSPAM } from '../src/lexicon/types/com/atproto/moderation/defs'
|
|
4
8
|
|
|
5
9
|
describe('moderation-status-tags', () => {
|
|
6
10
|
let network: TestNetwork
|
|
7
|
-
let agent: AtpAgent
|
|
8
|
-
let pdsAgent: AtpAgent
|
|
9
11
|
let sc: SeedClient
|
|
10
|
-
|
|
11
|
-
const emitModerationEvent = async (eventData) => {
|
|
12
|
-
return pdsAgent.api.com.atproto.admin.emitModerationEvent(eventData, {
|
|
13
|
-
encoding: 'application/json',
|
|
14
|
-
headers: network.bsky.adminAuthHeaders('moderator'),
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const queryModerationStatuses = (statusQuery) =>
|
|
19
|
-
agent.api.com.atproto.admin.queryModerationStatuses(statusQuery, {
|
|
20
|
-
headers: network.bsky.adminAuthHeaders('moderator'),
|
|
21
|
-
})
|
|
12
|
+
let modClient: ModeratorClient
|
|
22
13
|
|
|
23
14
|
beforeAll(async () => {
|
|
24
15
|
network = await TestNetwork.create({
|
|
25
16
|
dbPostgresSchema: 'ozone_moderation_status_tags',
|
|
26
17
|
})
|
|
27
|
-
agent = network.ozone.getClient()
|
|
28
|
-
pdsAgent = network.pds.getClient()
|
|
29
18
|
sc = network.getSeedClient()
|
|
19
|
+
modClient = network.ozone.getModClient()
|
|
30
20
|
await basicSeed(sc)
|
|
31
21
|
await network.processAll()
|
|
32
22
|
})
|
|
@@ -41,43 +31,36 @@ describe('moderation-status-tags', () => {
|
|
|
41
31
|
$type: 'com.atproto.admin.defs#repoRef',
|
|
42
32
|
did: sc.dids.bob,
|
|
43
33
|
}
|
|
44
|
-
await
|
|
34
|
+
await sc.createReport({
|
|
35
|
+
reasonType: REASONSPAM,
|
|
36
|
+
reason: 'X',
|
|
45
37
|
subject: bobsAccount,
|
|
46
|
-
|
|
47
|
-
$type: 'com.atproto.admin.defs#modEventReport',
|
|
48
|
-
comment: 'X',
|
|
49
|
-
reportType: REASONSPAM,
|
|
50
|
-
},
|
|
51
|
-
createdBy: sc.dids.alice,
|
|
38
|
+
reportedBy: sc.dids.alice,
|
|
52
39
|
})
|
|
53
|
-
await
|
|
40
|
+
await modClient.emitEvent({
|
|
54
41
|
subject: bobsAccount,
|
|
55
42
|
event: {
|
|
56
|
-
$type: '
|
|
43
|
+
$type: 'tools.ozone.moderation.defs#modEventTag',
|
|
57
44
|
add: ['interaction-churn'],
|
|
58
45
|
remove: [],
|
|
59
46
|
},
|
|
60
|
-
createdBy: sc.dids.alice,
|
|
61
47
|
})
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
},
|
|
66
|
-
)
|
|
48
|
+
const statusAfterInteractionTag = await modClient.queryStatuses({
|
|
49
|
+
subject: bobsAccount.did,
|
|
50
|
+
})
|
|
67
51
|
expect(statusAfterInteractionTag.subjectStatuses[0].tags).toContain(
|
|
68
52
|
'interaction-churn',
|
|
69
53
|
)
|
|
70
54
|
|
|
71
|
-
await
|
|
55
|
+
await modClient.emitEvent({
|
|
72
56
|
subject: bobsAccount,
|
|
73
57
|
event: {
|
|
74
|
-
$type: '
|
|
58
|
+
$type: 'tools.ozone.moderation.defs#modEventTag',
|
|
75
59
|
remove: ['interaction-churn'],
|
|
76
60
|
add: ['follow-churn'],
|
|
77
61
|
},
|
|
78
|
-
createdBy: sc.dids.alice,
|
|
79
62
|
})
|
|
80
|
-
const
|
|
63
|
+
const statusAfterFollowTag = await modClient.queryStatuses({
|
|
81
64
|
subject: bobsAccount.did,
|
|
82
65
|
})
|
|
83
66
|
|