167270bd7a
appview: fix takendown blocklist application on actor.getProfile
217 lines
6.2 KiB
TypeScript
217 lines
6.2 KiB
TypeScript
import { AtpAgent } from '@atproto/api'
|
|
import { TestNetwork, SeedClient, basicSeed, RecordRef } from '@atproto/dev-env'
|
|
import { ids } from '../../src/lexicon/lexicons'
|
|
|
|
describe('bsky takedown labels', () => {
|
|
let network: TestNetwork
|
|
let agent: AtpAgent
|
|
let pdsAgent: AtpAgent
|
|
let sc: SeedClient
|
|
|
|
let takendownSubjects: string[]
|
|
|
|
let aliceListRef: RecordRef
|
|
let carolListRef: RecordRef
|
|
let aliceGenRef: RecordRef
|
|
let bobGenRef: RecordRef
|
|
let carolGenRef: RecordRef
|
|
|
|
beforeAll(async () => {
|
|
network = await TestNetwork.create({
|
|
dbPostgresSchema: 'bsky_views_takedown_labels',
|
|
})
|
|
agent = network.bsky.getClient()
|
|
pdsAgent = network.pds.getClient()
|
|
sc = network.getSeedClient()
|
|
await basicSeed(sc)
|
|
|
|
aliceListRef = await sc.createList(sc.dids.alice, 'alice list', 'mod')
|
|
// carol blocks dan via alice's (takendown) list
|
|
await sc.addToList(sc.dids.alice, sc.dids.dan, aliceListRef)
|
|
await pdsAgent.app.bsky.graph.listblock.create(
|
|
{ repo: sc.dids.carol },
|
|
{
|
|
subject: aliceListRef.uriStr,
|
|
createdAt: new Date().toISOString(),
|
|
},
|
|
sc.getHeaders(sc.dids.carol),
|
|
)
|
|
carolListRef = await sc.createList(sc.dids.carol, 'carol list', 'mod')
|
|
aliceGenRef = await sc.createFeedGen(
|
|
sc.dids.alice,
|
|
'did:web:example.com',
|
|
'alice generator',
|
|
)
|
|
bobGenRef = await sc.createFeedGen(
|
|
sc.dids.bob,
|
|
'did:web:example.com',
|
|
'bob generator',
|
|
)
|
|
carolGenRef = await sc.createFeedGen(
|
|
sc.dids.carol,
|
|
'did:web:example.com',
|
|
'carol generator',
|
|
)
|
|
|
|
// labelers
|
|
await sc.createAccount('labeler1', {
|
|
email: 'lab1@test.com',
|
|
handle: 'lab1.test',
|
|
password: 'lab1',
|
|
})
|
|
await sc.agent.api.com.atproto.repo.createRecord(
|
|
{
|
|
repo: sc.dids.labeler1,
|
|
collection: ids.AppBskyLabelerService,
|
|
rkey: 'self',
|
|
record: {
|
|
policies: { labelValues: ['spam'] },
|
|
createdAt: new Date().toISOString(),
|
|
},
|
|
},
|
|
{
|
|
headers: sc.getHeaders(sc.dids.labeler1),
|
|
encoding: 'application/json',
|
|
},
|
|
)
|
|
await sc.createAccount('labeler2', {
|
|
email: 'lab2@test.com',
|
|
handle: 'lab2.test',
|
|
password: 'lab2',
|
|
})
|
|
await sc.agent.api.com.atproto.repo.createRecord(
|
|
{
|
|
repo: sc.dids.labeler2,
|
|
collection: ids.AppBskyLabelerService,
|
|
rkey: 'self',
|
|
record: {
|
|
policies: { labelValues: ['spam'] },
|
|
createdAt: new Date().toISOString(),
|
|
},
|
|
},
|
|
{
|
|
headers: sc.getHeaders(sc.dids.labeler2),
|
|
encoding: 'application/json',
|
|
},
|
|
)
|
|
|
|
await network.processAll()
|
|
|
|
takendownSubjects = [
|
|
sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
sc.dids.carol,
|
|
aliceListRef.uriStr,
|
|
aliceGenRef.uriStr,
|
|
sc.dids.labeler1,
|
|
]
|
|
const src = network.ozone.ctx.cfg.service.did
|
|
const cts = new Date().toISOString()
|
|
const labels = takendownSubjects.map((uri) => ({
|
|
src,
|
|
uri,
|
|
cid: '',
|
|
val: '!takedown',
|
|
neg: false,
|
|
cts,
|
|
}))
|
|
AtpAgent.configure({ appLabelers: [src] })
|
|
|
|
await network.bsky.db.db.insertInto('label').values(labels).execute()
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await network.close()
|
|
})
|
|
|
|
it('takesdown profiles', async () => {
|
|
const attempt = agent.api.app.bsky.actor.getProfile({
|
|
actor: sc.dids.carol,
|
|
})
|
|
await expect(attempt).rejects.toThrow('Account has been suspended')
|
|
const res = await agent.api.app.bsky.actor.getProfiles({
|
|
actors: [sc.dids.alice, sc.dids.bob, sc.dids.carol],
|
|
})
|
|
expect(res.data.profiles.length).toBe(2)
|
|
expect(res.data.profiles.some((p) => p.did === sc.dids.carol)).toBe(false)
|
|
})
|
|
|
|
it('takesdown posts', async () => {
|
|
const uris = [
|
|
sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
sc.posts[sc.dids.alice][1].ref.uriStr,
|
|
sc.posts[sc.dids.bob][0].ref.uriStr,
|
|
sc.posts[sc.dids.carol][0].ref.uriStr,
|
|
sc.posts[sc.dids.dan][1].ref.uriStr,
|
|
sc.replies[sc.dids.alice][0].ref.uriStr,
|
|
]
|
|
const res = await agent.api.app.bsky.feed.getPosts({ uris })
|
|
|
|
expect(res.data.posts.length).toBe(4)
|
|
expect(res.data.posts.some((p) => p.author.did === sc.dids.carol)).toBe(
|
|
false,
|
|
)
|
|
expect(
|
|
res.data.posts.some(
|
|
(p) => p.uri === sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
),
|
|
).toBe(false)
|
|
})
|
|
|
|
it('takesdown lists', async () => {
|
|
// record takedown
|
|
const attempt1 = agent.api.app.bsky.graph.getList({
|
|
list: aliceListRef.uriStr,
|
|
})
|
|
await expect(attempt1).rejects.toThrow('List not found')
|
|
|
|
// actor takedown
|
|
const attempt2 = agent.api.app.bsky.graph.getList({
|
|
list: carolListRef.uriStr,
|
|
})
|
|
await expect(attempt2).rejects.toThrow('List not found')
|
|
})
|
|
|
|
it('halts application of mod lists', async () => {
|
|
const { data: profile } = await agent.app.bsky.actor.getProfile(
|
|
{
|
|
actor: sc.dids.dan, // blocked via alice's takendown list
|
|
},
|
|
{
|
|
headers: await network.serviceHeaders(
|
|
sc.dids.carol,
|
|
ids.AppBskyActorGetProfile,
|
|
),
|
|
},
|
|
)
|
|
expect(profile.did).toBe(sc.dids.dan)
|
|
expect(profile.viewer).not.toBeUndefined()
|
|
expect(profile.viewer?.blockedBy).toBe(false)
|
|
expect(profile.viewer?.blocking).toBeUndefined()
|
|
expect(profile.viewer?.blockingByList).toBeUndefined()
|
|
})
|
|
|
|
it('takesdown feed generators', async () => {
|
|
const res = await agent.api.app.bsky.feed.getFeedGenerators({
|
|
feeds: [aliceGenRef.uriStr, bobGenRef.uriStr, carolGenRef.uriStr],
|
|
})
|
|
expect(res.data.feeds.length).toBe(1)
|
|
expect(res.data.feeds.at(0)?.uri).toEqual(bobGenRef.uriStr)
|
|
})
|
|
|
|
it('takesdown labelers', async () => {
|
|
const res = await agent.api.app.bsky.labeler.getServices({
|
|
dids: [sc.dids.labeler1, sc.dids.labeler2],
|
|
})
|
|
expect(res.data.views.length).toBe(1)
|
|
expect(res.data.views[0].creator?.['did']).toBe(sc.dids.labeler2)
|
|
})
|
|
|
|
it('only applies if the relevant labeler is configured', async () => {
|
|
AtpAgent.configure({ appLabelers: ['did:web:example.com'] })
|
|
const res = await agent.api.app.bsky.actor.getProfile({
|
|
actor: sc.dids.carol,
|
|
})
|
|
expect(res.data.did).toEqual(sc.dids.carol)
|
|
})
|
|
})
|