atproto/packages/bsky/tests/views/suggested-follows.test.ts
Daniel Holmgren 50c0ec176c
Service auth method binding (lxm) (#2663)
* add scopes to service auth impl

* add error to getServiceAuth

* send scoped tokens from pds

* clean up privileged access scopes & allow simple service auth tokens for app passwords

* integration into ozone

* fix up bsky tests

* cleanup xrpc-server tests

* fix up tests & types

* one more test

* fix read after write tests

* fix mod auth test

* convert scopes to be a single method name

* add scope check callback for auth verifier

* pds changes only

* fix feed generation tests

* use scope for ozone service profile

* dont verify scopes on pds yet

* tidy

* tidy imports

* changeset

* add tests

* tidy

* another changeset

* scope -> lxm

* tidy

* clean up scope references

* update nonce size

* pr feedback

* trim trailing slash

* nonce -> jti

* fix xrpc-server test

* allow service auth on uploadBlob

* fix build error

* changeset

* build, tidy

* xrpc-server: update lxm claim check error

* appview: temporarily permit labeler service calls to omit lxm claim

* xrpc-server: fix test

* changeset

* fix merged tests

---------

Co-authored-by: Devin Ivy <devinivy@gmail.com>
2024-08-18 15:46:07 -04:00

170 lines
4.9 KiB
TypeScript

import { AtpAgent, AtUri } from '@atproto/api'
import { TestNetwork, SeedClient, likesSeed } from '@atproto/dev-env'
import { ids } from '../../src/lexicon/lexicons'
describe('suggested follows', () => {
let network: TestNetwork
let agent: AtpAgent
let pdsAgent: AtpAgent
let sc: SeedClient
beforeAll(async () => {
network = await TestNetwork.create({
dbPostgresSchema: 'bsky_views_suggested_follows',
})
agent = network.bsky.getClient()
pdsAgent = network.pds.getClient()
sc = network.getSeedClient()
await likesSeed(sc)
await network.processAll()
const suggestions = [
{ did: sc.dids.alice, order: 1 },
{ did: sc.dids.bob, order: 2 },
{ did: sc.dids.carol, order: 3 },
{ did: sc.dids.dan, order: 4 },
{ did: sc.dids.fred, order: 5 },
{ did: sc.dids.gina, order: 6 },
]
await network.bsky.db.db
.insertInto('suggested_follow')
.values(suggestions)
.execute()
})
afterAll(async () => {
await network.close()
})
it('returns sorted suggested follows for carol', async () => {
const result = await agent.api.app.bsky.graph.getSuggestedFollowsByActor(
{
actor: sc.dids.alice,
},
{
headers: await network.serviceHeaders(
sc.dids.carol,
ids.AppBskyGraphGetSuggestedFollowsByActor,
),
},
)
expect(result.data.suggestions.length).toBe(4) // backfilled with 2 NPCs
expect(
result.data.suggestions.find((sug) => {
return [sc.dids.alice, sc.dids.carol].includes(sug.did)
}),
).toBeFalsy() // not actor or viewer
})
it('returns sorted suggested follows for fred', async () => {
const result = await agent.api.app.bsky.graph.getSuggestedFollowsByActor(
{
actor: sc.dids.alice,
},
{
headers: await network.serviceHeaders(
sc.dids.fred,
ids.AppBskyGraphGetSuggestedFollowsByActor,
),
},
)
expect(result.data.suggestions.length).toBe(4) // backfilled with 2 NPCs
expect(
result.data.suggestions.find((sug) => {
return [sc.dids.fred, sc.dids.alice].includes(sug.did)
}),
).toBeFalsy() // not actor or viewer or followed
})
it('exludes users muted by viewer', async () => {
await pdsAgent.api.app.bsky.graph.muteActor(
{ actor: sc.dids.bob },
{ headers: sc.getHeaders(sc.dids.carol), encoding: 'application/json' },
)
const result = await agent.api.app.bsky.graph.getSuggestedFollowsByActor(
{
actor: sc.dids.alice,
},
{
headers: await network.serviceHeaders(
sc.dids.carol,
ids.AppBskyGraphGetSuggestedFollowsByActor,
),
},
)
expect(
result.data.suggestions.find((sug) => {
return [sc.dids.alice, sc.dids.carol, sc.dids.bob].includes(sug.did)
}),
).toBeFalsy() // not actor or viewer or muted
await pdsAgent.api.app.bsky.graph.muteActor(
{ actor: sc.dids.bob },
{ headers: sc.getHeaders(sc.dids.carol), encoding: 'application/json' },
)
})
it('exludes users blocked by viewer', async () => {
const carolBlocksBob = await pdsAgent.api.app.bsky.graph.block.create(
{ repo: sc.dids.carol },
{ createdAt: new Date().toISOString(), subject: sc.dids.bob },
sc.getHeaders(sc.dids.carol),
)
const result = await agent.api.app.bsky.graph.getSuggestedFollowsByActor(
{
actor: sc.dids.alice,
},
{
headers: await network.serviceHeaders(
sc.dids.carol,
ids.AppBskyGraphGetSuggestedFollowsByActor,
),
},
)
expect(
result.data.suggestions.find((sug) => {
return [sc.dids.alice, sc.dids.carol, sc.dids.bob].includes(sug.did)
}),
).toBeFalsy() // not actor or viewer or muted
await pdsAgent.api.app.bsky.graph.block.delete(
{ repo: sc.dids.carol, rkey: new AtUri(carolBlocksBob.uri).rkey },
sc.getHeaders(sc.dids.carol),
)
})
it('exludes users blocking viewer', async () => {
const bobBlocksCarol = await pdsAgent.api.app.bsky.graph.block.create(
{ repo: sc.dids.bob },
{ createdAt: new Date().toISOString(), subject: sc.dids.carol },
sc.getHeaders(sc.dids.bob),
)
const result = await agent.api.app.bsky.graph.getSuggestedFollowsByActor(
{
actor: sc.dids.alice,
},
{
headers: await network.serviceHeaders(
sc.dids.carol,
ids.AppBskyGraphGetSuggestedFollowsByActor,
),
},
)
expect(
result.data.suggestions.find((sug) => {
return [sc.dids.alice, sc.dids.carol, sc.dids.bob].includes(sug.did)
}),
).toBeFalsy() // not actor or viewer or muted
await pdsAgent.api.app.bsky.graph.block.delete(
{ repo: sc.dids.bob, rkey: new AtUri(bobBlocksCarol.uri).rkey },
sc.getHeaders(sc.dids.bob),
)
})
})