rafael 3303ff16a4
Remove author blocks from getLikes (#3012)
* Capture the issue in a test case

* Remove 3p blocks in getLikes

* fix test that captures the bug

* remove unnecessary hydration

* Remove `!viewer` check
2024-11-26 17:56:42 -05:00

188 lines
5.5 KiB
TypeScript

import { AtpAgent } from '@atproto/api'
import { TestNetwork, SeedClient, likesSeed } from '@atproto/dev-env'
import { constantDate, forSnapshot, paginateAll, stripViewer } from '../_util'
import { ids } from '../../src/lexicon/lexicons'
describe('pds like views', () => {
let network: TestNetwork
let agent: AtpAgent
let sc: SeedClient
// account dids, for convenience
let alice: string
let bob: string
let carol: string
let frankie: string
beforeAll(async () => {
network = await TestNetwork.create({
dbPostgresSchema: 'bsky_views_likes',
})
agent = network.bsky.getClient()
sc = network.getSeedClient()
await likesSeed(sc)
await sc.createAccount('frankie', {
handle: 'frankie.test',
email: 'frankie@frankie.com',
password: 'password',
})
await network.processAll()
alice = sc.dids.alice
bob = sc.dids.bob
carol = sc.dids.carol
frankie = sc.dids.frankie
})
afterAll(async () => {
await network.close()
})
const getCursors = (items: { createdAt?: string }[]) =>
items.map((item) => item.createdAt ?? constantDate)
const getSortedCursors = (items: { createdAt?: string }[]) =>
getCursors(items).sort((a, b) => tstamp(b) - tstamp(a))
const tstamp = (x: string) => new Date(x).getTime()
it('fetches post likes', async () => {
const alicePost = await agent.api.app.bsky.feed.getLikes(
{ uri: sc.posts[alice][1].ref.uriStr },
{ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
)
expect(forSnapshot(alicePost.data)).toMatchSnapshot()
expect(getCursors(alicePost.data.likes)).toEqual(
getSortedCursors(alicePost.data.likes),
)
})
it('fetches reply likes', async () => {
const bobReply = await agent.api.app.bsky.feed.getLikes(
{ uri: sc.replies[bob][0].ref.uriStr },
{ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
)
expect(forSnapshot(bobReply.data)).toMatchSnapshot()
expect(getCursors(bobReply.data.likes)).toEqual(
getSortedCursors(bobReply.data.likes),
)
})
it('paginates', async () => {
const results = (results) => results.flatMap((res) => res.likes)
const paginator = async (cursor?: string) => {
const res = await agent.api.app.bsky.feed.getLikes(
{
uri: sc.posts[alice][1].ref.uriStr,
cursor,
limit: 2,
},
{
headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes),
},
)
return res.data
}
const paginatedAll = await paginateAll(paginator)
paginatedAll.forEach((res) =>
expect(res.likes.length).toBeLessThanOrEqual(2),
)
const full = await agent.api.app.bsky.feed.getLikes(
{ uri: sc.posts[alice][1].ref.uriStr },
{ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
)
expect(full.data.likes.length).toEqual(4)
expect(results(paginatedAll)).toEqual(results([full.data]))
})
it('fetches post likes unauthed', async () => {
const { data: authed } = await agent.api.app.bsky.feed.getLikes(
{ uri: sc.posts[alice][1].ref.uriStr },
{ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
)
const { data: unauthed } = await agent.api.app.bsky.feed.getLikes({
uri: sc.posts[alice][1].ref.uriStr,
})
expect(unauthed.likes.length).toBeGreaterThan(0)
expect(unauthed.likes).toEqual(
authed.likes.map((like) => {
return {
...like,
actor: stripViewer(like.actor),
}
}),
)
})
it(`author viewer doesn't see likes by user the author blocked`, async () => {
await sc.like(frankie, sc.posts[alice][1].ref)
await network.processAll()
const beforeBlock = await agent.app.bsky.feed.getLikes(
{ uri: sc.posts[alice][1].ref.uriStr },
{ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
)
expect(beforeBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
sc.dids.frankie,
sc.dids.eve,
sc.dids.dan,
sc.dids.carol,
sc.dids.bob,
])
await sc.block(alice, frankie)
await network.processAll()
const afterBlock = await agent.app.bsky.feed.getLikes(
{ uri: sc.posts[alice][1].ref.uriStr },
{ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
)
expect(afterBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
sc.dids.eve,
sc.dids.dan,
sc.dids.carol,
sc.dids.bob,
])
})
it(`non-author viewer doesn't see likes by user the author blocked and by user the viewer blocked `, async () => {
await sc.unblock(alice, frankie)
await network.processAll()
const beforeBlock = await agent.app.bsky.feed.getLikes(
{ uri: sc.posts[alice][1].ref.uriStr },
{ headers: await network.serviceHeaders(bob, ids.AppBskyFeedGetLikes) },
)
expect(beforeBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
sc.dids.frankie,
sc.dids.eve,
sc.dids.dan,
sc.dids.carol,
sc.dids.bob,
])
await sc.block(alice, frankie)
await sc.block(bob, carol)
await network.processAll()
const afterBlock = await agent.app.bsky.feed.getLikes(
{ uri: sc.posts[alice][1].ref.uriStr },
{ headers: await network.serviceHeaders(bob, ids.AppBskyFeedGetLikes) },
)
expect(afterBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
sc.dids.eve,
sc.dids.dan,
sc.dids.bob,
])
})
})