@atproto/bsky 0.0.142 → 0.0.144

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 (47) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/data-plane/server/indexing/plugins/verification.d.ts.map +1 -1
  3. package/dist/data-plane/server/indexing/plugins/verification.js +27 -4
  4. package/dist/data-plane/server/indexing/plugins/verification.js.map +1 -1
  5. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  6. package/dist/data-plane/server/routes/records.js +1 -0
  7. package/dist/data-plane/server/routes/records.js.map +1 -1
  8. package/dist/hydration/graph.d.ts +4 -0
  9. package/dist/hydration/graph.d.ts.map +1 -1
  10. package/dist/hydration/graph.js +9 -0
  11. package/dist/hydration/graph.js.map +1 -1
  12. package/dist/hydration/hydrator.d.ts +2 -1
  13. package/dist/hydration/hydrator.d.ts.map +1 -1
  14. package/dist/hydration/hydrator.js +5 -1
  15. package/dist/hydration/hydrator.js.map +1 -1
  16. package/dist/lexicon/lexicons.d.ts +50 -6
  17. package/dist/lexicon/lexicons.d.ts.map +1 -1
  18. package/dist/lexicon/lexicons.js +27 -1
  19. package/dist/lexicon/lexicons.js.map +1 -1
  20. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +9 -1
  21. package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
  22. package/dist/lexicon/types/app/bsky/actor/defs.js +9 -0
  23. package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
  24. package/dist/lexicon/types/app/bsky/notification/defs.d.ts +10 -0
  25. package/dist/lexicon/types/app/bsky/notification/defs.d.ts.map +1 -0
  26. package/dist/lexicon/types/app/bsky/notification/defs.js +16 -0
  27. package/dist/lexicon/types/app/bsky/notification/defs.js.map +1 -0
  28. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +2 -2
  29. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts.map +1 -1
  30. package/dist/lexicon/types/app/bsky/notification/listNotifications.js.map +1 -1
  31. package/dist/views/index.d.ts +3 -1
  32. package/dist/views/index.d.ts.map +1 -1
  33. package/dist/views/index.js +13 -0
  34. package/dist/views/index.js.map +1 -1
  35. package/package.json +6 -6
  36. package/src/data-plane/server/indexing/plugins/verification.ts +27 -4
  37. package/src/data-plane/server/routes/records.ts +1 -0
  38. package/src/hydration/graph.ts +19 -0
  39. package/src/hydration/hydrator.ts +22 -9
  40. package/src/lexicon/lexicons.ts +28 -1
  41. package/src/lexicon/types/app/bsky/actor/defs.ts +18 -0
  42. package/src/lexicon/types/app/bsky/notification/defs.ts +29 -0
  43. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +3 -1
  44. package/src/views/index.ts +22 -1
  45. package/tests/views/__snapshots__/notifications.test.ts.snap +140 -0
  46. package/tests/views/notifications.test.ts +38 -0
  47. package/tsconfig.build.tsbuildinfo +1 -1
@@ -4,6 +4,7 @@ import { Record as FollowRecord } from '../lexicon/types/app/bsky/graph/follow'
4
4
  import { Record as ListRecord } from '../lexicon/types/app/bsky/graph/list'
5
5
  import { Record as ListItemRecord } from '../lexicon/types/app/bsky/graph/listitem'
6
6
  import { Record as StarterPackRecord } from '../lexicon/types/app/bsky/graph/starterpack'
7
+ import { Record as VerificationRecord } from '../lexicon/types/app/bsky/graph/verification'
7
8
  import { FollowInfo } from '../proto/bsky_pb'
8
9
  import { HydrationMap, ItemRef, RecordInfo, parseRecord } from './util'
9
10
 
@@ -29,6 +30,9 @@ export type Block = RecordInfo<BlockRecord>
29
30
  export type StarterPack = RecordInfo<StarterPackRecord>
30
31
  export type StarterPacks = HydrationMap<StarterPack>
31
32
 
33
+ export type Verification = RecordInfo<VerificationRecord>
34
+ export type Verifications = HydrationMap<Verification>
35
+
32
36
  export type StarterPackAgg = {
33
37
  joinedWeek: number
34
38
  joinedAllTime: number
@@ -176,6 +180,21 @@ export class GraphHydrator {
176
180
  }, new HydrationMap<Follow>())
177
181
  }
178
182
 
183
+ async getVerifications(
184
+ uris: string[],
185
+ includeTakedowns = false,
186
+ ): Promise<Verifications> {
187
+ if (!uris.length) return new HydrationMap<Verification>()
188
+ const res = await this.dataplane.getVerificationRecords({ uris })
189
+ return uris.reduce((acc, uri, i) => {
190
+ const record = parseRecord<VerificationRecord>(
191
+ res.records[i],
192
+ includeTakedowns,
193
+ )
194
+ return acc.set(uri, record ?? null)
195
+ }, new HydrationMap<Verification>())
196
+ }
197
+
179
198
  async getBlocks(
180
199
  uris: string[],
181
200
  includeTakedowns = false,
@@ -46,6 +46,7 @@ import {
46
46
  RelationshipPair,
47
47
  StarterPackAggs,
48
48
  StarterPacks,
49
+ Verifications,
49
50
  } from './graph'
50
51
  import {
51
52
  LabelHydrator,
@@ -121,6 +122,7 @@ export type HydrationState = {
121
122
  labelerAggs?: LabelerAggs
122
123
  knownFollowers?: KnownFollowers
123
124
  bidirectionalBlocks?: BidirectionalBlocks
125
+ verifications?: Verifications
124
126
  }
125
127
 
126
128
  export type PostBlock = { embed: boolean; parent: boolean; root: boolean }
@@ -876,15 +878,24 @@ export class Hydrator {
876
878
  const likeUris = collections.get(ids.AppBskyFeedLike) ?? []
877
879
  const repostUris = collections.get(ids.AppBskyFeedRepost) ?? []
878
880
  const followUris = collections.get(ids.AppBskyGraphFollow) ?? []
879
- const [posts, likes, reposts, follows, labels, profileState] =
880
- await Promise.all([
881
- this.feed.getPosts(postUris), // reason: mention, reply, quote
882
- this.feed.getLikes(likeUris), // reason: like
883
- this.feed.getReposts(repostUris), // reason: repost
884
- this.graph.getFollows(followUris), // reason: follow
885
- this.label.getLabelsForSubjects(uris, ctx.labelers),
886
- this.hydrateProfiles(uris.map(didFromUri), ctx),
887
- ])
881
+ const verificationUris = collections.get(ids.AppBskyGraphVerification) ?? []
882
+ const [
883
+ posts,
884
+ likes,
885
+ reposts,
886
+ follows,
887
+ verifications,
888
+ labels,
889
+ profileState,
890
+ ] = await Promise.all([
891
+ this.feed.getPosts(postUris), // reason: mention, reply, quote
892
+ this.feed.getLikes(likeUris), // reason: like
893
+ this.feed.getReposts(repostUris), // reason: repost
894
+ this.graph.getFollows(followUris), // reason: follow
895
+ this.graph.getVerifications(verificationUris), // reason: verified
896
+ this.label.getLabelsForSubjects(uris, ctx.labelers),
897
+ this.hydrateProfiles(uris.map(didFromUri), ctx),
898
+ ])
888
899
  const viewerRootPostUris = new Set<string>()
889
900
  for (const notif of notifs) {
890
901
  if (notif.reason === 'reply') {
@@ -906,6 +917,7 @@ export class Hydrator {
906
917
  likes,
907
918
  reposts,
908
919
  follows,
920
+ verifications,
909
921
  labels,
910
922
  threadgates,
911
923
  ctx,
@@ -1297,6 +1309,7 @@ export const mergeStates = (
1297
1309
  stateA.bidirectionalBlocks,
1298
1310
  stateB.bidirectionalBlocks,
1299
1311
  ),
1312
+ verifications: mergeMaps(stateA.verifications, stateB.verifications),
1300
1313
  }
1301
1314
  }
1302
1315
 
@@ -4860,6 +4860,7 @@ export const schemaDict = {
4860
4860
  'lex:app.bsky.actor.defs#bskyAppStatePref',
4861
4861
  'lex:app.bsky.actor.defs#labelersPref',
4862
4862
  'lex:app.bsky.actor.defs#postInteractionSettingsPref',
4863
+ 'lex:app.bsky.actor.defs#verificationPrefs',
4863
4864
  ],
4864
4865
  },
4865
4866
  },
@@ -5193,6 +5194,19 @@ export const schemaDict = {
5193
5194
  },
5194
5195
  },
5195
5196
  },
5197
+ verificationPrefs: {
5198
+ type: 'object',
5199
+ description: 'Preferences for how verified accounts appear in the app.',
5200
+ required: [],
5201
+ properties: {
5202
+ hideBadges: {
5203
+ description:
5204
+ 'Hide the blue check badges for verified accounts and trusted verifiers.',
5205
+ type: 'boolean',
5206
+ default: false,
5207
+ },
5208
+ },
5209
+ },
5196
5210
  postInteractionSettingsPref: {
5197
5211
  type: 'object',
5198
5212
  description:
@@ -9592,6 +9606,16 @@ export const schemaDict = {
9592
9606
  },
9593
9607
  },
9594
9608
  },
9609
+ AppBskyNotificationDefs: {
9610
+ lexicon: 1,
9611
+ id: 'app.bsky.notification.defs',
9612
+ defs: {
9613
+ recordDeleted: {
9614
+ type: 'object',
9615
+ properties: {},
9616
+ },
9617
+ },
9618
+ },
9595
9619
  AppBskyNotificationGetUnreadCount: {
9596
9620
  lexicon: 1,
9597
9621
  id: 'app.bsky.notification.getUnreadCount',
@@ -9719,7 +9743,7 @@ export const schemaDict = {
9719
9743
  reason: {
9720
9744
  type: 'string',
9721
9745
  description:
9722
- "Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', and 'starterpack-joined'.",
9746
+ "Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', 'starterpack-joined', 'verified', and 'unverified'.",
9723
9747
  knownValues: [
9724
9748
  'like',
9725
9749
  'repost',
@@ -9728,6 +9752,8 @@ export const schemaDict = {
9728
9752
  'reply',
9729
9753
  'quote',
9730
9754
  'starterpack-joined',
9755
+ 'verified',
9756
+ 'unverified',
9731
9757
  ],
9732
9758
  },
9733
9759
  reasonSubject: {
@@ -12535,6 +12561,7 @@ export const ids = {
12535
12561
  AppBskyLabelerDefs: 'app.bsky.labeler.defs',
12536
12562
  AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
12537
12563
  AppBskyLabelerService: 'app.bsky.labeler.service',
12564
+ AppBskyNotificationDefs: 'app.bsky.notification.defs',
12538
12565
  AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
12539
12566
  AppBskyNotificationListNotifications:
12540
12567
  'app.bsky.notification.listNotifications',
@@ -230,6 +230,7 @@ export type Preferences = (
230
230
  | $Typed<BskyAppStatePref>
231
231
  | $Typed<LabelersPref>
232
232
  | $Typed<PostInteractionSettingsPref>
233
+ | $Typed<VerificationPrefs>
233
234
  | { $type: string }
234
235
  )[]
235
236
 
@@ -543,6 +544,23 @@ export function validateNux<V>(v: V) {
543
544
  return validate<Nux & V>(v, id, hashNux)
544
545
  }
545
546
 
547
+ /** Preferences for how verified accounts appear in the app. */
548
+ export interface VerificationPrefs {
549
+ $type?: 'app.bsky.actor.defs#verificationPrefs'
550
+ /** Hide the blue check badges for verified accounts and trusted verifiers. */
551
+ hideBadges: boolean
552
+ }
553
+
554
+ const hashVerificationPrefs = 'verificationPrefs'
555
+
556
+ export function isVerificationPrefs<V>(v: V) {
557
+ return is$typed(v, id, hashVerificationPrefs)
558
+ }
559
+
560
+ export function validateVerificationPrefs<V>(v: V) {
561
+ return validate<VerificationPrefs & V>(v, id, hashVerificationPrefs)
562
+ }
563
+
546
564
  /** Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly. */
547
565
  export interface PostInteractionSettingsPref {
548
566
  $type?: 'app.bsky.actor.defs#postInteractionSettingsPref'
@@ -0,0 +1,29 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+ import { CID } from 'multiformats/cid'
6
+ import { validate as _validate } from '../../../../lexicons'
7
+ import {
8
+ type $Typed,
9
+ is$typed as _is$typed,
10
+ type OmitKey,
11
+ } from '../../../../util'
12
+
13
+ const is$typed = _is$typed,
14
+ validate = _validate
15
+ const id = 'app.bsky.notification.defs'
16
+
17
+ export interface RecordDeleted {
18
+ $type?: 'app.bsky.notification.defs#recordDeleted'
19
+ }
20
+
21
+ const hashRecordDeleted = 'recordDeleted'
22
+
23
+ export function isRecordDeleted<V>(v: V) {
24
+ return is$typed(v, id, hashRecordDeleted)
25
+ }
26
+
27
+ export function validateRecordDeleted<V>(v: V) {
28
+ return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
29
+ }
@@ -67,7 +67,7 @@ export interface Notification {
67
67
  uri: string
68
68
  cid: string
69
69
  author: AppBskyActorDefs.ProfileView
70
- /** Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', and 'starterpack-joined'. */
70
+ /** Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', 'starterpack-joined', 'verified', and 'unverified'. */
71
71
  reason:
72
72
  | 'like'
73
73
  | 'repost'
@@ -76,6 +76,8 @@ export interface Notification {
76
76
  | 'reply'
77
77
  | 'quote'
78
78
  | 'starterpack-joined'
79
+ | 'verified'
80
+ | 'unverified'
79
81
  | (string & {})
80
82
  reasonSubject?: string
81
83
  record: { [_ in string]: unknown }
@@ -2,7 +2,7 @@ import { mapDefined } from '@atproto/common'
2
2
  import { AtUri, INVALID_HANDLE, normalizeDatetimeAlways } from '@atproto/syntax'
3
3
  import { ProfileViewerState } from '../hydration/actor'
4
4
  import { FeedItem, Like, Post, Repost } from '../hydration/feed'
5
- import { Follow } from '../hydration/graph'
5
+ import { Follow, Verification } from '../hydration/graph'
6
6
  import { HydrationState } from '../hydration/hydrator'
7
7
  import { Label } from '../hydration/label'
8
8
  import { RecordInfo } from '../hydration/util'
@@ -48,6 +48,7 @@ import {
48
48
  StarterPackViewBasic,
49
49
  } from '../lexicon/types/app/bsky/graph/defs'
50
50
  import { Record as FollowRecord } from '../lexicon/types/app/bsky/graph/follow'
51
+ import { Record as VerificationRecord } from '../lexicon/types/app/bsky/graph/verification'
51
52
  import {
52
53
  LabelerView,
53
54
  LabelerViewDetailed,
@@ -56,6 +57,7 @@ import {
56
57
  Record as LabelerRecord,
57
58
  isRecord as isLabelerRecord,
58
59
  } from '../lexicon/types/app/bsky/labeler/service'
60
+ import { RecordDeleted as NotificationRecordDeleted } from '../lexicon/types/app/bsky/notification/defs'
59
61
  import { isSelfLabels } from '../lexicon/types/com/atproto/label/defs'
60
62
  import { $Typed, Un$Typed } from '../lexicon/util'
61
63
  import { Notification } from '../proto/bsky_pb'
@@ -99,6 +101,14 @@ import {
99
101
  parseThreadGate,
100
102
  } from './util'
101
103
 
104
+ const notificationDeletedRecord = {
105
+ $type: 'app.bsky.notification.defs#recordDeleted' as const,
106
+ }
107
+
108
+ // Pre-computed CID for the `notificationDeletedRecord`.
109
+ const notificationDeletedRecordCid =
110
+ 'bafyreidad6nyekfa4a67yfb573ptxiv6s7kyxyg2ra6qbbemcruadvtuim'
111
+
102
112
  export class Views {
103
113
  public imgUriBuilder: ImageUriBuilder = this.opts.imgUriBuilder
104
114
  public videoUriBuilder: VideoUriBuilder = this.opts.videoUriBuilder
@@ -582,6 +592,8 @@ export class Views {
582
592
  | FollowRecord
583
593
  | ProfileRecord
584
594
  | LabelerRecord
595
+ | VerificationRecord
596
+ | NotificationRecordDeleted
585
597
  }): Label[] {
586
598
  if (!uri || !cid || !record) return []
587
599
 
@@ -1415,6 +1427,8 @@ export class Views {
1415
1427
  | Repost
1416
1428
  | Follow
1417
1429
  | RecordInfo<ProfileRecord>
1430
+ | Verification
1431
+ | Pick<RecordInfo<Required<NotificationRecordDeleted>>, 'cid' | 'record'>
1418
1432
  | undefined
1419
1433
  | null
1420
1434
 
@@ -1426,6 +1440,13 @@ export class Views {
1426
1440
  recordInfo = state.reposts?.get(notif.uri)
1427
1441
  } else if (uri.collection === ids.AppBskyGraphFollow) {
1428
1442
  recordInfo = state.follows?.get(notif.uri)
1443
+ } else if (uri.collection === ids.AppBskyGraphVerification) {
1444
+ // When a verification record is removed, the record won't be found,
1445
+ // both for the `verified` and `unverified` notifications.
1446
+ recordInfo = state.verifications?.get(notif.uri) ?? {
1447
+ record: notificationDeletedRecord,
1448
+ cid: notificationDeletedRecordCid,
1449
+ }
1429
1450
  } else if (uri.collection === ids.AppBskyActorProfile) {
1430
1451
  const actor = state.actors?.get(authorDid)
1431
1452
  recordInfo =
@@ -1652,3 +1652,143 @@ Array [
1652
1652
  },
1653
1653
  ]
1654
1654
  `;
1655
+
1656
+ exports[`notification views generates notifications for verification created and removed 1`] = `
1657
+ Array [
1658
+ Object {
1659
+ "author": Object {
1660
+ "avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
1661
+ "createdAt": "1970-01-01T00:00:00.000Z",
1662
+ "description": "its me!",
1663
+ "did": "user(0)",
1664
+ "displayName": "ali",
1665
+ "handle": "alice.test",
1666
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1667
+ "labels": Array [
1668
+ Object {
1669
+ "cid": "cids(2)",
1670
+ "cts": "1970-01-01T00:00:00.000Z",
1671
+ "src": "user(0)",
1672
+ "uri": "record(3)",
1673
+ "val": "self-label-a",
1674
+ },
1675
+ Object {
1676
+ "cid": "cids(2)",
1677
+ "cts": "1970-01-01T00:00:00.000Z",
1678
+ "src": "user(0)",
1679
+ "uri": "record(3)",
1680
+ "val": "self-label-b",
1681
+ },
1682
+ ],
1683
+ "viewer": Object {
1684
+ "blockedBy": false,
1685
+ "followedBy": "record(2)",
1686
+ "following": "record(1)",
1687
+ "muted": false,
1688
+ },
1689
+ },
1690
+ "cid": "cids(0)",
1691
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1692
+ "isRead": false,
1693
+ "labels": Array [],
1694
+ "reason": "verified",
1695
+ "record": Object {
1696
+ "$type": "app.bsky.graph.verification",
1697
+ "createdAt": "1970-01-01T00:00:00.000Z",
1698
+ "displayName": "bobby",
1699
+ "handle": "bob.test",
1700
+ "subject": "user(2)",
1701
+ },
1702
+ "uri": "record(0)",
1703
+ },
1704
+ ]
1705
+ `;
1706
+
1707
+ exports[`notification views generates notifications for verification created and removed 2`] = `
1708
+ Array [
1709
+ Object {
1710
+ "author": Object {
1711
+ "avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
1712
+ "createdAt": "1970-01-01T00:00:00.000Z",
1713
+ "description": "its me!",
1714
+ "did": "user(0)",
1715
+ "displayName": "ali",
1716
+ "handle": "alice.test",
1717
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1718
+ "labels": Array [
1719
+ Object {
1720
+ "cid": "cids(2)",
1721
+ "cts": "1970-01-01T00:00:00.000Z",
1722
+ "src": "user(0)",
1723
+ "uri": "record(3)",
1724
+ "val": "self-label-a",
1725
+ },
1726
+ Object {
1727
+ "cid": "cids(2)",
1728
+ "cts": "1970-01-01T00:00:00.000Z",
1729
+ "src": "user(0)",
1730
+ "uri": "record(3)",
1731
+ "val": "self-label-b",
1732
+ },
1733
+ ],
1734
+ "viewer": Object {
1735
+ "blockedBy": false,
1736
+ "followedBy": "record(2)",
1737
+ "following": "record(1)",
1738
+ "muted": false,
1739
+ },
1740
+ },
1741
+ "cid": "cids(0)",
1742
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1743
+ "isRead": false,
1744
+ "labels": Array [],
1745
+ "reason": "unverified",
1746
+ "record": Object {
1747
+ "$type": "app.bsky.notification.defs#recordDeleted",
1748
+ },
1749
+ "uri": "record(0)",
1750
+ },
1751
+ Object {
1752
+ "author": Object {
1753
+ "avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
1754
+ "createdAt": "1970-01-01T00:00:00.000Z",
1755
+ "description": "its me!",
1756
+ "did": "user(0)",
1757
+ "displayName": "ali",
1758
+ "handle": "alice.test",
1759
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1760
+ "labels": Array [
1761
+ Object {
1762
+ "cid": "cids(2)",
1763
+ "cts": "1970-01-01T00:00:00.000Z",
1764
+ "src": "user(0)",
1765
+ "uri": "record(3)",
1766
+ "val": "self-label-a",
1767
+ },
1768
+ Object {
1769
+ "cid": "cids(2)",
1770
+ "cts": "1970-01-01T00:00:00.000Z",
1771
+ "src": "user(0)",
1772
+ "uri": "record(3)",
1773
+ "val": "self-label-b",
1774
+ },
1775
+ ],
1776
+ "viewer": Object {
1777
+ "blockedBy": false,
1778
+ "followedBy": "record(2)",
1779
+ "following": "record(1)",
1780
+ "muted": false,
1781
+ },
1782
+ },
1783
+ "cid": "cids(0)",
1784
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1785
+ "isRead": true,
1786
+ "labels": Array [],
1787
+ "reason": "verified",
1788
+ "record": Object {
1789
+ "$type": "app.bsky.notification.defs#recordDeleted",
1790
+ },
1791
+ "uri": "record(0)",
1792
+ },
1793
+ ]
1794
+ `;
@@ -20,6 +20,11 @@ describe('notification views', () => {
20
20
  agent = network.bsky.getClient()
21
21
  sc = network.getSeedClient()
22
22
  await basicSeed(sc)
23
+ await network.bsky.db.db
24
+ .updateTable('actor')
25
+ .set({ trustedVerifier: true })
26
+ .where('did', '=', alice)
27
+ .execute()
23
28
  await network.processAll()
24
29
  alice = sc.dids.alice
25
30
  })
@@ -151,6 +156,39 @@ describe('notification views', () => {
151
156
  expect(forSnapshot(sort(notifsDan.data.notifications))).toMatchSnapshot()
152
157
  })
153
158
 
159
+ it('generates notifications for verification created and removed', async () => {
160
+ await sc.verify(
161
+ sc.dids.alice,
162
+ sc.dids.bob,
163
+ sc.accounts[sc.dids.bob].handle,
164
+ sc.profiles[sc.dids.bob].displayName,
165
+ )
166
+ await network.processAll()
167
+ const notifsBob1 = await agent.app.bsky.notification.listNotifications(
168
+ { reasons: ['verified', 'unverified'] },
169
+ {
170
+ headers: await network.serviceHeaders(
171
+ sc.dids.bob,
172
+ ids.AppBskyNotificationListNotifications,
173
+ ),
174
+ },
175
+ )
176
+ expect(forSnapshot(sort(notifsBob1.data.notifications))).toMatchSnapshot()
177
+
178
+ await sc.unverify(sc.dids.alice, sc.dids.bob)
179
+ await network.processAll()
180
+ const notifsBob2 = await agent.app.bsky.notification.listNotifications(
181
+ { reasons: ['verified', 'unverified'] },
182
+ {
183
+ headers: await network.serviceHeaders(
184
+ sc.dids.bob,
185
+ ids.AppBskyNotificationListNotifications,
186
+ ),
187
+ },
188
+ )
189
+ expect(forSnapshot(sort(notifsBob2.data.notifications))).toMatchSnapshot()
190
+ })
191
+
154
192
  it('fetches notifications without a last-seen', async () => {
155
193
  const notifRes = await agent.api.app.bsky.notification.listNotifications(
156
194
  {},