atproto/packages/ozone/tests/mod-tool.test.ts
Foysal Ahamed 3156ddf615
Add batchId filter for queryEvents (#4109)
*  Add batchId filter for queryEvents

* 📝 Add changeset
2025-08-20 21:39:24 +02:00

269 lines
7.4 KiB
TypeScript

import {
ModeratorClient,
SeedClient,
TestNetwork,
basicSeed,
} from '@atproto/dev-env'
describe('mod-tool tracking', () => {
let network: TestNetwork
let sc: SeedClient
let modClient: ModeratorClient
beforeAll(async () => {
network = await TestNetwork.create({
dbPostgresSchema: 'ozone_mod_tool_test',
})
sc = network.getSeedClient()
modClient = network.ozone.getModClient()
await basicSeed(sc)
await network.processAll()
})
afterAll(async () => {
await network.close()
})
it('stores and returns modTool with name and meta metadata', async () => {
const subject = {
$type: 'com.atproto.repo.strongRef' as const,
uri: sc.posts[sc.dids.bob][0].ref.uriStr,
cid: sc.posts[sc.dids.bob][0].ref.cidStr,
}
const modTool = {
name: 'automod/1.1.3',
meta: {
confidence: 85,
rules: ['high_risk_country', 'spam_detection'],
version: '1.1.3',
environment: 'production',
},
}
const emittedEvent = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['spam'],
negateLabelVals: [],
},
subject,
modTool,
})
expect(emittedEvent.modTool).toEqual(modTool)
expect(emittedEvent.modTool?.name).toBe('automod/1.1.3')
expect(emittedEvent.modTool?.meta).toEqual({
confidence: 85,
rules: ['high_risk_country', 'spam_detection'],
version: '1.1.3',
environment: 'production',
})
const queryResult = await modClient.queryEvents({
subject: subject.uri,
})
const foundEvent = queryResult.events.find((e) => e.id === emittedEvent.id)
expect(foundEvent?.modTool).toEqual(modTool)
})
it('filters events by modTool name', async () => {
const subject = {
$type: 'com.atproto.repo.strongRef' as const,
uri: sc.posts[sc.dids.alice][0].ref.uriStr,
cid: sc.posts[sc.dids.alice][0].ref.cidStr,
}
const event1 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['test1'],
negateLabelVals: [],
},
subject,
modTool: { name: 'automod/1.1.3' },
})
const event2 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['test2'],
negateLabelVals: [],
},
subject,
modTool: { name: 'ozone-web/1.0.0' },
})
const event3 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['test3'],
negateLabelVals: [],
},
subject,
modTool: { name: 'mobile-app/2.1.0' },
})
const automodResults = await modClient.queryEvents({
subject: subject.uri,
modTool: ['automod/1.1.3'],
})
expect(automodResults.events).toHaveLength(1)
expect(automodResults.events[0].id).toBe(event1.id)
expect(automodResults.events[0].modTool?.name).toBe('automod/1.1.3')
const multipleResults = await modClient.queryEvents({
subject: subject.uri,
modTool: ['automod/1.1.3', 'ozone-web/1.0.0'],
})
expect(multipleResults.events).toHaveLength(2)
const eventIds = multipleResults.events.map((e) => e.id)
expect(eventIds).toContain(event1.id)
expect(eventIds).toContain(event2.id)
expect(eventIds).not.toContain(event3.id)
})
it('filters events by batchId and supports pagination', async () => {
const subject = {
$type: 'com.atproto.repo.strongRef',
uri: sc.posts[sc.dids.carol][0].ref.uriStr,
cid: sc.posts[sc.dids.carol][0].ref.cidStr,
}
const batchId1 = 'batch-123'
const batchId2 = 'batch-456'
// Create events with first batchId
const event1 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['batch1-event1'],
negateLabelVals: [],
},
subject,
modTool: {
name: 'automod/1.1.3',
meta: { batchId: batchId1 },
},
})
const event2 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['batch1-event2'],
negateLabelVals: [],
},
subject,
modTool: {
name: 'automod/1.1.3',
meta: { batchId: batchId1 },
},
})
const event3 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['batch1-event3'],
negateLabelVals: [],
},
subject,
modTool: {
name: 'ozone-ui/workspace',
meta: { batchId: batchId1 },
},
})
// Create events with second batchId
const event4 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['batch2-event1'],
negateLabelVals: [],
},
subject,
modTool: {
name: 'ozone-ui/workspace',
meta: { batchId: batchId2 },
},
})
// Create event without batchId
const event5 = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals: ['no-batch'],
negateLabelVals: [],
},
subject,
})
// Test filtering by first batchId
const batch1Results = await modClient.queryEvents({
subject: subject.uri,
batchId: batchId1,
})
expect(batch1Results.events).toHaveLength(3)
const batch1EventIds = batch1Results.events.map((e) => e.id)
expect(batch1EventIds).toContain(event1.id)
expect(batch1EventIds).toContain(event2.id)
expect(batch1EventIds).toContain(event3.id)
expect(batch1EventIds).not.toContain(event4.id)
expect(batch1EventIds).not.toContain(event5.id)
// Verify all events have the correct batchId
batch1Results.events.forEach((event) => {
expect(event.modTool?.meta?.batchId).toBe(batchId1)
})
// Test filtering by second batchId
const batch2Results = await modClient.queryEvents({
subject: subject.uri,
batchId: batchId2,
})
expect(batch2Results.events).toHaveLength(1)
expect(batch2Results.events[0].id).toBe(event4.id)
expect(batch2Results.events[0].modTool?.meta?.batchId).toBe(batchId2)
// Test pagination with batchId filter
const paginatedResults = await modClient.queryEvents({
subject: subject.uri,
batchId: batchId1,
limit: 2,
})
expect(paginatedResults.events).toHaveLength(2)
expect(paginatedResults.cursor).toBeTruthy()
// Get next page
const nextPageResults = await modClient.queryEvents({
subject: subject.uri,
batchId: batchId1,
limit: 2,
cursor: paginatedResults.cursor,
})
expect(nextPageResults.events).toHaveLength(1)
// Verify all paginated results have correct batchId
const allPaginatedEvents = paginatedResults.events.concat(
nextPageResults.events,
)
allPaginatedEvents.forEach((event) => {
expect(event.modTool?.meta?.batchId).toBe(batchId1)
})
// Verify we got all 3 events across pages
const allPaginatedIds = paginatedResults.events
.map((e) => e.id)
.concat(nextPageResults.events.map((e) => e.id))
expect(allPaginatedIds).toContain(event1.id)
expect(allPaginatedIds).toContain(event2.id)
expect(allPaginatedIds).toContain(event3.id)
})
})