@atproto/bsky 0.0.96 → 0.0.98

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/api/app/bsky/actor/getProfile.js +3 -1
  3. package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
  4. package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
  5. package/dist/api/app/bsky/actor/getProfiles.js +6 -2
  6. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  7. package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
  8. package/dist/api/app/bsky/feed/getLikes.js +14 -7
  9. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  10. package/dist/api/app/bsky/notification/listNotifications.js +45 -3
  11. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  12. package/dist/auth-verifier.d.ts.map +1 -1
  13. package/dist/auth-verifier.js.map +1 -1
  14. package/dist/hydration/hydrator.d.ts +6 -1
  15. package/dist/hydration/hydrator.d.ts.map +1 -1
  16. package/dist/hydration/hydrator.js +28 -4
  17. package/dist/hydration/hydrator.js.map +1 -1
  18. package/dist/lexicon/lexicons.d.ts +17795 -7841
  19. package/dist/lexicon/lexicons.d.ts.map +1 -1
  20. package/dist/lexicon/lexicons.js +8 -0
  21. package/dist/lexicon/lexicons.js.map +1 -1
  22. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +2 -0
  23. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts.map +1 -1
  24. package/dist/lexicon/types/app/bsky/notification/listNotifications.js.map +1 -1
  25. package/package.json +11 -11
  26. package/src/api/app/bsky/actor/getProfile.ts +3 -1
  27. package/src/api/app/bsky/actor/getProfiles.ts +6 -2
  28. package/src/api/app/bsky/feed/getLikes.ts +24 -12
  29. package/src/api/app/bsky/notification/listNotifications.ts +57 -3
  30. package/src/auth-verifier.ts +1 -8
  31. package/src/hydration/hydrator.ts +33 -4
  32. package/src/lexicon/lexicons.ts +12 -2
  33. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +2 -0
  34. package/tests/views/__snapshots__/notifications.test.ts.snap +257 -0
  35. package/tests/views/labels-takedown.test.ts +31 -0
  36. package/tests/views/likes.test.ts +76 -0
  37. package/tests/views/notifications.test.ts +78 -0
@@ -5,6 +5,7 @@ import { ids } from '../../src/lexicon/lexicons'
5
5
  describe('bsky takedown labels', () => {
6
6
  let network: TestNetwork
7
7
  let agent: AtpAgent
8
+ let pdsAgent: AtpAgent
8
9
  let sc: SeedClient
9
10
 
10
11
  let takendownSubjects: string[]
@@ -20,10 +21,21 @@ describe('bsky takedown labels', () => {
20
21
  dbPostgresSchema: 'bsky_views_takedown_labels',
21
22
  })
22
23
  agent = network.bsky.getClient()
24
+ pdsAgent = network.pds.getClient()
23
25
  sc = network.getSeedClient()
24
26
  await basicSeed(sc)
25
27
 
26
28
  aliceListRef = await sc.createList(sc.dids.alice, 'alice list', 'mod')
29
+ // carol blocks dan via alice's (takendown) list
30
+ await sc.addToList(sc.dids.alice, sc.dids.dan, aliceListRef)
31
+ await pdsAgent.app.bsky.graph.listblock.create(
32
+ { repo: sc.dids.carol },
33
+ {
34
+ subject: aliceListRef.uriStr,
35
+ createdAt: new Date().toISOString(),
36
+ },
37
+ sc.getHeaders(sc.dids.carol),
38
+ )
27
39
  carolListRef = await sc.createList(sc.dids.carol, 'carol list', 'mod')
28
40
  aliceGenRef = await sc.createFeedGen(
29
41
  sc.dids.alice,
@@ -159,6 +171,25 @@ describe('bsky takedown labels', () => {
159
171
  await expect(attempt2).rejects.toThrow('List not found')
160
172
  })
161
173
 
174
+ it('halts application of mod lists', async () => {
175
+ const { data: profile } = await agent.app.bsky.actor.getProfile(
176
+ {
177
+ actor: sc.dids.dan, // blocked via alice's takendown list
178
+ },
179
+ {
180
+ headers: await network.serviceHeaders(
181
+ sc.dids.carol,
182
+ ids.AppBskyActorGetProfile,
183
+ ),
184
+ },
185
+ )
186
+ expect(profile.did).toBe(sc.dids.dan)
187
+ expect(profile.viewer).not.toBeUndefined()
188
+ expect(profile.viewer?.blockedBy).toBe(false)
189
+ expect(profile.viewer?.blocking).toBeUndefined()
190
+ expect(profile.viewer?.blockingByList).toBeUndefined()
191
+ })
192
+
162
193
  it('takesdown feed generators', async () => {
163
194
  const res = await agent.api.app.bsky.feed.getFeedGenerators({
164
195
  feeds: [aliceGenRef.uriStr, bobGenRef.uriStr, carolGenRef.uriStr],
@@ -11,6 +11,8 @@ describe('pds like views', () => {
11
11
  // account dids, for convenience
12
12
  let alice: string
13
13
  let bob: string
14
+ let carol: string
15
+ let frankie: string
14
16
 
15
17
  beforeAll(async () => {
16
18
  network = await TestNetwork.create({
@@ -19,9 +21,17 @@ describe('pds like views', () => {
19
21
  agent = network.bsky.getClient()
20
22
  sc = network.getSeedClient()
21
23
  await likesSeed(sc)
24
+ await sc.createAccount('frankie', {
25
+ handle: 'frankie.test',
26
+ email: 'frankie@frankie.com',
27
+ password: 'password',
28
+ })
22
29
  await network.processAll()
30
+
23
31
  alice = sc.dids.alice
24
32
  bob = sc.dids.bob
33
+ carol = sc.dids.carol
34
+ frankie = sc.dids.frankie
25
35
  })
26
36
 
27
37
  afterAll(async () => {
@@ -108,4 +118,70 @@ describe('pds like views', () => {
108
118
  }),
109
119
  )
110
120
  })
121
+
122
+ it(`author viewer doesn't see likes by user the author blocked`, async () => {
123
+ await sc.like(frankie, sc.posts[alice][1].ref)
124
+ await network.processAll()
125
+
126
+ const beforeBlock = await agent.app.bsky.feed.getLikes(
127
+ { uri: sc.posts[alice][1].ref.uriStr },
128
+ { headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
129
+ )
130
+
131
+ expect(beforeBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
132
+ sc.dids.frankie,
133
+ sc.dids.eve,
134
+ sc.dids.dan,
135
+ sc.dids.carol,
136
+ sc.dids.bob,
137
+ ])
138
+
139
+ await sc.block(alice, frankie)
140
+ await network.processAll()
141
+
142
+ const afterBlock = await agent.app.bsky.feed.getLikes(
143
+ { uri: sc.posts[alice][1].ref.uriStr },
144
+ { headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetLikes) },
145
+ )
146
+
147
+ expect(afterBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
148
+ sc.dids.eve,
149
+ sc.dids.dan,
150
+ sc.dids.carol,
151
+ sc.dids.bob,
152
+ ])
153
+ })
154
+
155
+ it(`non-author viewer doesn't see likes by user the author blocked and by user the viewer blocked `, async () => {
156
+ await sc.unblock(alice, frankie)
157
+ await network.processAll()
158
+
159
+ const beforeBlock = await agent.app.bsky.feed.getLikes(
160
+ { uri: sc.posts[alice][1].ref.uriStr },
161
+ { headers: await network.serviceHeaders(bob, ids.AppBskyFeedGetLikes) },
162
+ )
163
+
164
+ expect(beforeBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
165
+ sc.dids.frankie,
166
+ sc.dids.eve,
167
+ sc.dids.dan,
168
+ sc.dids.carol,
169
+ sc.dids.bob,
170
+ ])
171
+
172
+ await sc.block(alice, frankie)
173
+ await sc.block(bob, carol)
174
+ await network.processAll()
175
+
176
+ const afterBlock = await agent.app.bsky.feed.getLikes(
177
+ { uri: sc.posts[alice][1].ref.uriStr },
178
+ { headers: await network.serviceHeaders(bob, ids.AppBskyFeedGetLikes) },
179
+ )
180
+
181
+ expect(afterBlock.data.likes.map((like) => like.actor.did)).toStrictEqual([
182
+ sc.dids.eve,
183
+ sc.dids.dan,
184
+ sc.dids.bob,
185
+ ])
186
+ })
111
187
  })
@@ -417,6 +417,84 @@ describe('notification views', () => {
417
417
  ),
418
418
  ).toBe(true)
419
419
  expect(forSnapshot(notifs.data)).toMatchSnapshot()
420
+ await agent.api.app.bsky.notification.putPreferences(
421
+ { priority: false },
422
+ {
423
+ encoding: 'application/json',
424
+ headers: await network.serviceHeaders(
425
+ sc.dids.carol,
426
+ ids.AppBskyNotificationPutPreferences,
427
+ ),
428
+ },
429
+ )
430
+ await network.processAll()
431
+ })
432
+
433
+ it('filters notifications by reason', async () => {
434
+ const res = await agent.app.bsky.notification.listNotifications(
435
+ {
436
+ reasons: ['mention'],
437
+ },
438
+ {
439
+ headers: await network.serviceHeaders(
440
+ sc.dids.alice,
441
+ ids.AppBskyNotificationListNotifications,
442
+ ),
443
+ },
444
+ )
445
+ expect(res.data.notifications.length).toBe(1)
446
+ expect(forSnapshot(res.data)).toMatchSnapshot()
447
+ })
448
+
449
+ it('filters notifications by multiple reasons', async () => {
450
+ const res = await agent.app.bsky.notification.listNotifications(
451
+ {
452
+ reasons: ['mention', 'reply'],
453
+ },
454
+ {
455
+ headers: await network.serviceHeaders(
456
+ sc.dids.alice,
457
+ ids.AppBskyNotificationListNotifications,
458
+ ),
459
+ },
460
+ )
461
+ expect(res.data.notifications.length).toBe(4)
462
+ expect(forSnapshot(res.data)).toMatchSnapshot()
463
+ })
464
+
465
+ it('paginates filtered notifications', async () => {
466
+ const results = (results) =>
467
+ sort(results.flatMap((res) => res.notifications))
468
+ const paginator = async (cursor?: string) => {
469
+ const res = await agent.app.bsky.notification.listNotifications(
470
+ { reasons: ['mention', 'reply'], cursor, limit: 2 },
471
+ {
472
+ headers: await network.serviceHeaders(
473
+ alice,
474
+ ids.AppBskyNotificationListNotifications,
475
+ ),
476
+ },
477
+ )
478
+ return res.data
479
+ }
480
+
481
+ const paginatedAll = await paginateAll(paginator)
482
+ paginatedAll.forEach((res) =>
483
+ expect(res.notifications.length).toBeLessThanOrEqual(2),
484
+ )
485
+
486
+ const full = await agent.app.bsky.notification.listNotifications(
487
+ { reasons: ['mention', 'reply'] },
488
+ {
489
+ headers: await network.serviceHeaders(
490
+ alice,
491
+ ids.AppBskyNotificationListNotifications,
492
+ ),
493
+ },
494
+ )
495
+
496
+ expect(full.data.notifications.length).toBe(4)
497
+ expect(results(paginatedAll)).toEqual(results([full.data]))
420
498
  })
421
499
 
422
500
  it('fails open on clearly bad cursor.', async () => {