@atproto/bsky 0.0.175 → 0.0.177
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.
- package/CHANGELOG.md +19 -0
- package/dist/api/app/bsky/graph/getList.js +1 -6
- package/dist/api/app/bsky/graph/getList.js.map +1 -1
- package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getLists.js +16 -4
- package/dist/api/app/bsky/graph/getLists.js.map +1 -1
- package/dist/api/app/bsky/graph/getListsWithMembership.d.ts +4 -0
- package/dist/api/app/bsky/graph/getListsWithMembership.d.ts.map +1 -0
- package/dist/api/app/bsky/graph/getListsWithMembership.js +88 -0
- package/dist/api/app/bsky/graph/getListsWithMembership.js.map +1 -0
- package/dist/api/app/bsky/graph/getStarterPacksWithMembership.d.ts +4 -0
- package/dist/api/app/bsky/graph/getStarterPacksWithMembership.d.ts.map +1 -0
- package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js +72 -0
- package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -1
- package/dist/hydration/graph.d.ts +4 -0
- package/dist/hydration/graph.d.ts.map +1 -1
- package/dist/hydration/graph.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +3 -1
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +27 -0
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/lexicon/index.d.ts +4 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +8 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +288 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +146 -0
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/graph/getLists.d.ts +2 -0
- package/dist/lexicon/types/app/bsky/graph/getLists.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/graph/getListsWithMembership.d.ts +40 -0
- package/dist/lexicon/types/app/bsky/graph/getListsWithMembership.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/graph/getListsWithMembership.js +16 -0
- package/dist/lexicon/types/app/bsky/graph/getListsWithMembership.js.map +1 -0
- package/dist/lexicon/types/app/bsky/graph/getStarterPacksWithMembership.d.ts +38 -0
- package/dist/lexicon/types/app/bsky/graph/getStarterPacksWithMembership.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/graph/getStarterPacksWithMembership.js +16 -0
- package/dist/lexicon/types/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -0
- package/dist/views/index.d.ts +2 -1
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +7 -0
- package/dist/views/index.js.map +1 -1
- package/package.json +8 -8
- package/src/api/app/bsky/graph/getList.ts +3 -5
- package/src/api/app/bsky/graph/getLists.ts +18 -5
- package/src/api/app/bsky/graph/getListsWithMembership.ts +139 -0
- package/src/api/app/bsky/graph/getStarterPacksWithMembership.ts +135 -0
- package/src/api/index.ts +4 -0
- package/src/hydration/graph.ts +8 -0
- package/src/hydration/hydrator.ts +43 -0
- package/src/lexicon/index.ts +26 -0
- package/src/lexicon/lexicons.ts +153 -0
- package/src/lexicon/types/app/bsky/graph/getLists.ts +2 -0
- package/src/lexicon/types/app/bsky/graph/getListsWithMembership.ts +63 -0
- package/src/lexicon/types/app/bsky/graph/getStarterPacksWithMembership.ts +65 -0
- package/src/views/index.ts +12 -0
- package/tests/__snapshots__/feed-generation.test.ts.snap +115 -12
- package/tests/feed-generation.test.ts +47 -8
- package/tests/views/__snapshots__/lists.test.ts.snap +160 -8
- package/tests/views/lists.test.ts +270 -36
- package/tests/views/starter-packs.test.ts +132 -3
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import { AtpAgent } from '@atproto/api'
|
|
2
2
|
import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
|
3
3
|
import { ids } from '../../src/lexicon/lexicons'
|
|
4
|
-
import {
|
|
4
|
+
import { OutputSchema as GetListsOutputSchema } from '../../src/lexicon/types/app/bsky/graph/getLists'
|
|
5
|
+
import {
|
|
6
|
+
ListWithMembership,
|
|
7
|
+
OutputSchema as GetListsWithMembershipOutputSchema,
|
|
8
|
+
} from '../../src/lexicon/types/app/bsky/graph/getListsWithMembership'
|
|
9
|
+
import { forSnapshot, paginateAll } from '../_util'
|
|
5
10
|
|
|
6
11
|
describe('bsky actor likes feed views', () => {
|
|
7
12
|
let network: TestNetwork
|
|
8
13
|
let agent: AtpAgent
|
|
9
14
|
let sc: SeedClient
|
|
10
15
|
|
|
16
|
+
let blockList: string
|
|
11
17
|
let curateList: string
|
|
12
18
|
let referenceList: string
|
|
19
|
+
let eveListItemCur: string
|
|
20
|
+
let frankieListItemCur: string
|
|
21
|
+
let frankieListItemMod: string
|
|
22
|
+
let gretaListItemMod: string
|
|
23
|
+
|
|
13
24
|
let alice: string
|
|
14
25
|
let eve: string
|
|
15
26
|
let frankie: string
|
|
@@ -38,30 +49,53 @@ describe('bsky actor likes feed views', () => {
|
|
|
38
49
|
password: 'hunter4real',
|
|
39
50
|
})
|
|
40
51
|
|
|
41
|
-
const newRefList = await sc.createList(
|
|
52
|
+
const newRefList = await sc.createList(sc.dids.eve, 'ref0', 'reference')
|
|
53
|
+
await sc.addToList(sc.dids.eve, sc.dids.eve, newRefList)
|
|
54
|
+
await sc.addToList(sc.dids.eve, sc.dids.bob, newRefList)
|
|
55
|
+
await sc.addToList(sc.dids.eve, sc.dids.frankie, newRefList)
|
|
56
|
+
|
|
57
|
+
const newCurList = await sc.createList(sc.dids.eve, 'cur0', 'curate')
|
|
58
|
+
await sc.createList(sc.dids.eve, 'cur1', 'curate')
|
|
59
|
+
await sc.createList(sc.dids.eve, 'cur2', 'curate')
|
|
60
|
+
const newEveListItemCur = await sc.addToList(
|
|
61
|
+
sc.dids.eve,
|
|
42
62
|
sc.dids.eve,
|
|
43
|
-
|
|
44
|
-
'reference',
|
|
63
|
+
newCurList,
|
|
45
64
|
)
|
|
46
|
-
|
|
65
|
+
await sc.addToList(sc.dids.eve, sc.dids.bob, newCurList)
|
|
66
|
+
const newFrankieListItemCur = await sc.addToList(
|
|
47
67
|
sc.dids.eve,
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
sc.dids.frankie,
|
|
69
|
+
newCurList,
|
|
50
70
|
)
|
|
51
71
|
|
|
52
|
-
await sc.
|
|
53
|
-
await sc.
|
|
54
|
-
await sc.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
72
|
+
const newBlockList = await sc.createList(sc.dids.eve, 'mod0', 'mod')
|
|
73
|
+
await sc.createList(sc.dids.eve, 'mod1', 'mod')
|
|
74
|
+
await sc.createList(sc.dids.eve, 'mod2', 'mod')
|
|
75
|
+
const newFrankieListItemMod = await sc.addToList(
|
|
76
|
+
sc.dids.eve,
|
|
77
|
+
sc.dids.frankie,
|
|
78
|
+
newBlockList,
|
|
79
|
+
)
|
|
80
|
+
const newGretaListItemMod = await sc.addToList(
|
|
81
|
+
sc.dids.eve,
|
|
82
|
+
sc.dids.greta,
|
|
83
|
+
newBlockList,
|
|
84
|
+
)
|
|
59
85
|
|
|
86
|
+
await sc.block(sc.dids.frankie, sc.dids.greta)
|
|
60
87
|
await sc.block(sc.dids.frankie, sc.dids.eve)
|
|
61
88
|
|
|
62
89
|
await network.processAll()
|
|
63
|
-
|
|
90
|
+
blockList = newBlockList.uriStr
|
|
91
|
+
curateList = newCurList.uriStr
|
|
64
92
|
referenceList = newRefList.uriStr
|
|
93
|
+
|
|
94
|
+
eveListItemCur = newEveListItemCur.uriStr
|
|
95
|
+
frankieListItemCur = newFrankieListItemCur.uriStr
|
|
96
|
+
frankieListItemMod = newFrankieListItemMod.uriStr
|
|
97
|
+
gretaListItemMod = newGretaListItemMod.uriStr
|
|
98
|
+
|
|
65
99
|
alice = sc.dids.alice
|
|
66
100
|
eve = sc.dids.eve
|
|
67
101
|
frankie = sc.dids.frankie
|
|
@@ -73,12 +107,10 @@ describe('bsky actor likes feed views', () => {
|
|
|
73
107
|
})
|
|
74
108
|
|
|
75
109
|
it('does not include reference lists in getActorLists', async () => {
|
|
76
|
-
await
|
|
77
|
-
await network.processAll()
|
|
78
|
-
const view = await agent.api.app.bsky.graph.getLists({
|
|
110
|
+
const view = await agent.app.bsky.graph.getLists({
|
|
79
111
|
actor: eve,
|
|
80
112
|
})
|
|
81
|
-
expect(view.data.lists.length).toBe(
|
|
113
|
+
expect(view.data.lists.length).toBe(6)
|
|
82
114
|
expect(forSnapshot(view.data.lists)).toMatchSnapshot()
|
|
83
115
|
})
|
|
84
116
|
|
|
@@ -86,12 +118,79 @@ describe('bsky actor likes feed views', () => {
|
|
|
86
118
|
const view = await agent.app.bsky.graph.getLists({
|
|
87
119
|
actor: 'eve.test',
|
|
88
120
|
})
|
|
89
|
-
expect(view.data.lists.length).toBe(
|
|
121
|
+
expect(view.data.lists.length).toBe(6)
|
|
90
122
|
expect(forSnapshot(view.data.lists)).toMatchSnapshot()
|
|
91
123
|
})
|
|
92
124
|
|
|
125
|
+
it('allows filtering by list purpose', async () => {
|
|
126
|
+
const viewCurate = await agent.app.bsky.graph.getLists({
|
|
127
|
+
actor: eve,
|
|
128
|
+
purposes: ['curatelist'],
|
|
129
|
+
})
|
|
130
|
+
expect(viewCurate.data.lists.length).toBe(3)
|
|
131
|
+
|
|
132
|
+
const viewMod = await agent.app.bsky.graph.getLists({
|
|
133
|
+
actor: eve,
|
|
134
|
+
purposes: ['modlist'],
|
|
135
|
+
})
|
|
136
|
+
expect(viewMod.data.lists.length).toBe(3)
|
|
137
|
+
|
|
138
|
+
const viewAll = await agent.app.bsky.graph.getLists({
|
|
139
|
+
actor: eve,
|
|
140
|
+
purposes: ['curatelist', 'modlist'],
|
|
141
|
+
})
|
|
142
|
+
expect(viewAll.data.lists.length).toBe(6)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it.each([
|
|
146
|
+
{ expected: 6, purposes: [] },
|
|
147
|
+
{ expected: 6, purposes: ['curatelist', 'modlist'] },
|
|
148
|
+
{ expected: 3, purposes: ['curatelist'] },
|
|
149
|
+
{ expected: 3, purposes: ['modlist'] },
|
|
150
|
+
{ expected: 0, purposes: ['referencelist'] }, // not supported on getLists.
|
|
151
|
+
])(
|
|
152
|
+
'paginates for purposes filter: $purposes',
|
|
153
|
+
async ({ expected, purposes }) => {
|
|
154
|
+
const results = (out: GetListsOutputSchema[]) =>
|
|
155
|
+
out.flatMap((res) => res.lists)
|
|
156
|
+
const paginator = async (cursor?: string) => {
|
|
157
|
+
const res = await agent.app.bsky.graph.getLists(
|
|
158
|
+
{ actor: eve, purposes, limit: 2, cursor },
|
|
159
|
+
{
|
|
160
|
+
headers: await network.serviceHeaders(
|
|
161
|
+
eve,
|
|
162
|
+
ids.AppBskyGraphGetLists,
|
|
163
|
+
),
|
|
164
|
+
},
|
|
165
|
+
)
|
|
166
|
+
return res.data
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const paginatedAll = await paginateAll(paginator)
|
|
170
|
+
paginatedAll.forEach((res) =>
|
|
171
|
+
expect(res.lists.length).toBeLessThanOrEqual(2),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
const full = await agent.app.bsky.graph.getLists(
|
|
175
|
+
{ actor: eve, purposes },
|
|
176
|
+
{
|
|
177
|
+
headers: await network.serviceHeaders(eve, ids.AppBskyGraphGetLists),
|
|
178
|
+
},
|
|
179
|
+
)
|
|
180
|
+
expect(full.data.lists.length).toBe(expected)
|
|
181
|
+
|
|
182
|
+
const sortedFull = results([full.data]).sort((a, b) =>
|
|
183
|
+
a.uri > b.uri ? 1 : -1,
|
|
184
|
+
)
|
|
185
|
+
const sortedPaginated = results(paginatedAll).sort((a, b) =>
|
|
186
|
+
a.uri > b.uri ? 1 : -1,
|
|
187
|
+
)
|
|
188
|
+
expect(sortedPaginated).toEqual(sortedFull)
|
|
189
|
+
},
|
|
190
|
+
)
|
|
191
|
+
|
|
93
192
|
it('does not include users with creator block relationship in reference lists for non-creator, in-list viewers', async () => {
|
|
94
|
-
const curView = await agent.
|
|
193
|
+
const curView = await agent.app.bsky.graph.getList(
|
|
95
194
|
{
|
|
96
195
|
list: curateList,
|
|
97
196
|
},
|
|
@@ -102,7 +201,7 @@ describe('bsky actor likes feed views', () => {
|
|
|
102
201
|
expect(curView.data.items.length).toBe(2)
|
|
103
202
|
expect(forSnapshot(curView.data.items)).toMatchSnapshot()
|
|
104
203
|
|
|
105
|
-
const refView = await agent.
|
|
204
|
+
const refView = await agent.app.bsky.graph.getList(
|
|
106
205
|
{ list: referenceList },
|
|
107
206
|
{
|
|
108
207
|
headers: await network.serviceHeaders(frankie, ids.AppBskyGraphGetList),
|
|
@@ -113,7 +212,7 @@ describe('bsky actor likes feed views', () => {
|
|
|
113
212
|
})
|
|
114
213
|
|
|
115
214
|
it('does not include users with creator block relationship in reference lists for non-creator, not-in-list viewers', async () => {
|
|
116
|
-
const curView = await agent.
|
|
215
|
+
const curView = await agent.app.bsky.graph.getList(
|
|
117
216
|
{
|
|
118
217
|
list: curateList,
|
|
119
218
|
},
|
|
@@ -122,7 +221,7 @@ describe('bsky actor likes feed views', () => {
|
|
|
122
221
|
expect(curView.data.items.length).toBe(2)
|
|
123
222
|
expect(forSnapshot(curView.data.items)).toMatchSnapshot()
|
|
124
223
|
|
|
125
|
-
const refView = await agent.
|
|
224
|
+
const refView = await agent.app.bsky.graph.getList(
|
|
126
225
|
{ list: referenceList },
|
|
127
226
|
{ headers: await network.serviceHeaders(greta, ids.AppBskyGraphGetList) },
|
|
128
227
|
)
|
|
@@ -131,13 +230,13 @@ describe('bsky actor likes feed views', () => {
|
|
|
131
230
|
})
|
|
132
231
|
|
|
133
232
|
it('does not include users with creator block relationship in reference and curate lists for signed-out viewers', async () => {
|
|
134
|
-
const curView = await agent.
|
|
233
|
+
const curView = await agent.app.bsky.graph.getList({
|
|
135
234
|
list: curateList,
|
|
136
235
|
})
|
|
137
236
|
expect(curView.data.items.length).toBe(2)
|
|
138
237
|
expect(forSnapshot(curView.data.items)).toMatchSnapshot()
|
|
139
238
|
|
|
140
|
-
const refView = await agent.
|
|
239
|
+
const refView = await agent.app.bsky.graph.getList({
|
|
141
240
|
list: referenceList,
|
|
142
241
|
})
|
|
143
242
|
expect(refView.data.items.length).toBe(2)
|
|
@@ -145,14 +244,14 @@ describe('bsky actor likes feed views', () => {
|
|
|
145
244
|
})
|
|
146
245
|
|
|
147
246
|
it('does include users with creator block relationship in reference lists for creator', async () => {
|
|
148
|
-
const curView = await agent.
|
|
247
|
+
const curView = await agent.app.bsky.graph.getList(
|
|
149
248
|
{ list: curateList },
|
|
150
249
|
{ headers: await network.serviceHeaders(eve, ids.AppBskyGraphGetList) },
|
|
151
250
|
)
|
|
152
251
|
expect(curView.data.items.length).toBe(3)
|
|
153
252
|
expect(forSnapshot(curView.data.items)).toMatchSnapshot()
|
|
154
253
|
|
|
155
|
-
const refView = await agent.
|
|
254
|
+
const refView = await agent.app.bsky.graph.getList(
|
|
156
255
|
{ list: referenceList },
|
|
157
256
|
{ headers: await network.serviceHeaders(eve, ids.AppBskyGraphGetList) },
|
|
158
257
|
)
|
|
@@ -161,17 +260,152 @@ describe('bsky actor likes feed views', () => {
|
|
|
161
260
|
})
|
|
162
261
|
|
|
163
262
|
it('does return all users regardless of creator block relationship in moderation lists', async () => {
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
await sc.addToList(eve, greta, blockList)
|
|
167
|
-
await sc.block(frankie, greta)
|
|
168
|
-
await network.processAll()
|
|
169
|
-
|
|
170
|
-
const view = await agent.api.app.bsky.graph.getList(
|
|
171
|
-
{ list: blockList.uriStr },
|
|
263
|
+
const view = await agent.app.bsky.graph.getList(
|
|
264
|
+
{ list: blockList },
|
|
172
265
|
{ headers: await network.serviceHeaders(alice, ids.AppBskyGraphGetList) },
|
|
173
266
|
)
|
|
174
267
|
expect(view.data.items.length).toBe(2)
|
|
175
268
|
expect(forSnapshot(view.data.items)).toMatchSnapshot()
|
|
176
269
|
})
|
|
270
|
+
|
|
271
|
+
describe('list membership', () => {
|
|
272
|
+
const uriSort = (a: string, b: string) => (a > b ? 1 : -1)
|
|
273
|
+
const membershipsUris = (lwms: ListWithMembership[]): string[] =>
|
|
274
|
+
lwms
|
|
275
|
+
.map((lwm) => lwm.listItem?.uri)
|
|
276
|
+
.filter((li): li is string => typeof li === 'string')
|
|
277
|
+
.sort(uriSort)
|
|
278
|
+
|
|
279
|
+
it('returns all lists by the user', async () => {
|
|
280
|
+
const view = await agent.app.bsky.graph.getListsWithMembership(
|
|
281
|
+
{ actor: frankie },
|
|
282
|
+
{
|
|
283
|
+
headers: await network.serviceHeaders(
|
|
284
|
+
eve,
|
|
285
|
+
ids.AppBskyGraphGetListsWithMembership,
|
|
286
|
+
),
|
|
287
|
+
},
|
|
288
|
+
)
|
|
289
|
+
expect(view.data.listsWithMembership.length).toBe(6)
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
it('finds self membership', async () => {
|
|
293
|
+
const view = await agent.app.bsky.graph.getListsWithMembership(
|
|
294
|
+
{ actor: eve },
|
|
295
|
+
{
|
|
296
|
+
headers: await network.serviceHeaders(
|
|
297
|
+
eve,
|
|
298
|
+
ids.AppBskyGraphGetListsWithMembership,
|
|
299
|
+
),
|
|
300
|
+
},
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
expect(view.data.listsWithMembership.length).toBe(6)
|
|
304
|
+
const memberships = membershipsUris(view.data.listsWithMembership)
|
|
305
|
+
const expectedMemberships = [eveListItemCur].sort(uriSort)
|
|
306
|
+
expect(memberships).toEqual(expectedMemberships)
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
it('finds membership in curatelist and modlist if actor is in both and purpose filter includes both', async () => {
|
|
310
|
+
const view = await agent.app.bsky.graph.getListsWithMembership(
|
|
311
|
+
{ actor: frankie },
|
|
312
|
+
{
|
|
313
|
+
headers: await network.serviceHeaders(
|
|
314
|
+
eve,
|
|
315
|
+
ids.AppBskyGraphGetListsWithMembership,
|
|
316
|
+
),
|
|
317
|
+
},
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
expect(view.data.listsWithMembership.length).toBe(6)
|
|
321
|
+
const memberships = membershipsUris(view.data.listsWithMembership)
|
|
322
|
+
const expectedMemberships = [frankieListItemCur, frankieListItemMod].sort(
|
|
323
|
+
uriSort,
|
|
324
|
+
)
|
|
325
|
+
expect(memberships).toEqual(expectedMemberships)
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
it('finds modlist membership filtering by modlist', async () => {
|
|
329
|
+
const view = await agent.app.bsky.graph.getListsWithMembership(
|
|
330
|
+
{ actor: greta, purposes: ['modlist'] },
|
|
331
|
+
{
|
|
332
|
+
headers: await network.serviceHeaders(
|
|
333
|
+
eve,
|
|
334
|
+
ids.AppBskyGraphGetListsWithMembership,
|
|
335
|
+
),
|
|
336
|
+
},
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
expect(view.data.listsWithMembership.length).toBe(3)
|
|
340
|
+
const memberships = membershipsUris(view.data.listsWithMembership)
|
|
341
|
+
const expectedMemberships = [gretaListItemMod].sort(uriSort)
|
|
342
|
+
expect(memberships).toEqual(expectedMemberships)
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
it('does not find modlist membership filtering by curatelist', async () => {
|
|
346
|
+
const view = await agent.app.bsky.graph.getListsWithMembership(
|
|
347
|
+
{ actor: greta, purposes: ['curatelist'] },
|
|
348
|
+
{
|
|
349
|
+
headers: await network.serviceHeaders(
|
|
350
|
+
eve,
|
|
351
|
+
ids.AppBskyGraphGetListsWithMembership,
|
|
352
|
+
),
|
|
353
|
+
},
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
expect(view.data.listsWithMembership.length).toBe(3)
|
|
357
|
+
const memberships = membershipsUris(view.data.listsWithMembership)
|
|
358
|
+
expect(memberships.length).toBe(0)
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
it.each([
|
|
362
|
+
{ expected: 6, purposes: [] },
|
|
363
|
+
{ expected: 6, purposes: ['curatelist', 'modlist'] },
|
|
364
|
+
{ expected: 3, purposes: ['curatelist'] },
|
|
365
|
+
{ expected: 3, purposes: ['modlist'] },
|
|
366
|
+
{ expected: 0, purposes: ['referencelist'] }, // not supported on getLists.
|
|
367
|
+
])(
|
|
368
|
+
'paginates for purposes filter: $purposes',
|
|
369
|
+
async ({ expected, purposes }) => {
|
|
370
|
+
const results = (out: GetListsWithMembershipOutputSchema[]) =>
|
|
371
|
+
out.flatMap((res) => res.listsWithMembership)
|
|
372
|
+
const paginator = async (cursor?: string) => {
|
|
373
|
+
const res = await agent.app.bsky.graph.getListsWithMembership(
|
|
374
|
+
{ actor: eve, purposes, limit: 2, cursor },
|
|
375
|
+
{
|
|
376
|
+
headers: await network.serviceHeaders(
|
|
377
|
+
eve,
|
|
378
|
+
ids.AppBskyGraphGetListsWithMembership,
|
|
379
|
+
),
|
|
380
|
+
},
|
|
381
|
+
)
|
|
382
|
+
return res.data
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const paginatedAll = await paginateAll(paginator)
|
|
386
|
+
paginatedAll.forEach((res) =>
|
|
387
|
+
expect(res.listsWithMembership.length).toBeLessThanOrEqual(2),
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
const full = await agent.app.bsky.graph.getListsWithMembership(
|
|
391
|
+
{ actor: eve, purposes },
|
|
392
|
+
{
|
|
393
|
+
headers: await network.serviceHeaders(
|
|
394
|
+
eve,
|
|
395
|
+
ids.AppBskyGraphGetListsWithMembership,
|
|
396
|
+
),
|
|
397
|
+
},
|
|
398
|
+
)
|
|
399
|
+
expect(full.data.listsWithMembership.length).toBe(expected)
|
|
400
|
+
|
|
401
|
+
const sortedFull = results([full.data]).sort((a, b) =>
|
|
402
|
+
a.list.uri > b.list.uri ? 1 : -1,
|
|
403
|
+
)
|
|
404
|
+
const sortedPaginated = results(paginatedAll).sort((a, b) =>
|
|
405
|
+
a.list.uri > b.list.uri ? 1 : -1,
|
|
406
|
+
)
|
|
407
|
+
expect(sortedPaginated).toEqual(sortedFull)
|
|
408
|
+
},
|
|
409
|
+
)
|
|
410
|
+
})
|
|
177
411
|
})
|
|
@@ -3,7 +3,11 @@ import { AtpAgent, asPredicate } from '@atproto/api'
|
|
|
3
3
|
import { RecordRef, SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
|
4
4
|
import { ids } from '../../src/lexicon/lexicons'
|
|
5
5
|
import { validateRecord as validateProfileRecord } from '../../src/lexicon/types/app/bsky/actor/profile'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
OutputSchema as GetStarterPacksWithMembershipOutputSchema,
|
|
8
|
+
StarterPackWithMembership,
|
|
9
|
+
} from '../../src/lexicon/types/app/bsky/graph/getStarterPacksWithMembership'
|
|
10
|
+
import { forSnapshot, paginateAll } from '../_util'
|
|
7
11
|
|
|
8
12
|
const isValidProfile = asPredicate(validateProfileRecord)
|
|
9
13
|
|
|
@@ -24,9 +28,7 @@ describe('starter packs', () => {
|
|
|
24
28
|
sc = network.getSeedClient()
|
|
25
29
|
await basicSeed(sc)
|
|
26
30
|
await network.processAll()
|
|
27
|
-
})
|
|
28
31
|
|
|
29
|
-
beforeAll(async () => {
|
|
30
32
|
const feedgen = await sc.createFeedGen(
|
|
31
33
|
sc.dids.alice,
|
|
32
34
|
'did:web:example.com',
|
|
@@ -262,4 +264,131 @@ describe('starter packs', () => {
|
|
|
262
264
|
])
|
|
263
265
|
})
|
|
264
266
|
})
|
|
267
|
+
|
|
268
|
+
describe('starter pack membership', () => {
|
|
269
|
+
const membershipsUris = (lwms: StarterPackWithMembership[]): string[] =>
|
|
270
|
+
lwms
|
|
271
|
+
.map((spwm) => spwm.listItem?.uri)
|
|
272
|
+
.filter((li): li is string => typeof li === 'string')
|
|
273
|
+
|
|
274
|
+
it('returns all SPs by the user', async () => {
|
|
275
|
+
const view = await agent.app.bsky.graph.getStarterPacksWithMembership(
|
|
276
|
+
{ actor: sc.dids.bob },
|
|
277
|
+
{
|
|
278
|
+
headers: await network.serviceHeaders(
|
|
279
|
+
sc.dids.alice,
|
|
280
|
+
ids.AppBskyGraphGetStarterPacksWithMembership,
|
|
281
|
+
),
|
|
282
|
+
},
|
|
283
|
+
)
|
|
284
|
+
expect(view.data.starterPacksWithMembership.length).toBe(3)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
it('finds self membership', async () => {
|
|
288
|
+
const view = await agent.app.bsky.graph.getStarterPacksWithMembership(
|
|
289
|
+
{ actor: sc.dids.alice },
|
|
290
|
+
{
|
|
291
|
+
headers: await network.serviceHeaders(
|
|
292
|
+
sc.dids.alice,
|
|
293
|
+
ids.AppBskyGraphGetStarterPacksWithMembership,
|
|
294
|
+
),
|
|
295
|
+
},
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
expect(view.data.starterPacksWithMembership.length).toBe(3)
|
|
299
|
+
const memberships = membershipsUris(view.data.starterPacksWithMembership)
|
|
300
|
+
expect(memberships.length).toBe(1)
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
it(`finds other user's membership`, async () => {
|
|
304
|
+
const view = await agent.app.bsky.graph.getStarterPacksWithMembership(
|
|
305
|
+
{ actor: sc.dids.bob },
|
|
306
|
+
{
|
|
307
|
+
headers: await network.serviceHeaders(
|
|
308
|
+
sc.dids.alice,
|
|
309
|
+
ids.AppBskyGraphGetStarterPacksWithMembership,
|
|
310
|
+
),
|
|
311
|
+
},
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
expect(view.data.starterPacksWithMembership.length).toBe(3)
|
|
315
|
+
const memberships = membershipsUris(view.data.starterPacksWithMembership)
|
|
316
|
+
expect(memberships.length).toBe(1)
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
it('finds that user has no memberships', async () => {
|
|
320
|
+
// @NOTE: dan is not in bob's SP.
|
|
321
|
+
const view = await agent.app.bsky.graph.getStarterPacksWithMembership(
|
|
322
|
+
{ actor: sc.dids.dan },
|
|
323
|
+
{
|
|
324
|
+
headers: await network.serviceHeaders(
|
|
325
|
+
sc.dids.bob,
|
|
326
|
+
ids.AppBskyGraphGetStarterPacksWithMembership,
|
|
327
|
+
),
|
|
328
|
+
},
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
expect(view.data.starterPacksWithMembership.length).toBe(1)
|
|
332
|
+
const memberships = membershipsUris(view.data.starterPacksWithMembership)
|
|
333
|
+
expect(memberships.length).toBe(0)
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
it('finds empty list of SPs if user has none', async () => {
|
|
337
|
+
const view = await agent.app.bsky.graph.getStarterPacksWithMembership(
|
|
338
|
+
{ actor: sc.dids.bob },
|
|
339
|
+
{
|
|
340
|
+
headers: await network.serviceHeaders(
|
|
341
|
+
sc.dids.carol,
|
|
342
|
+
ids.AppBskyGraphGetStarterPacksWithMembership,
|
|
343
|
+
),
|
|
344
|
+
},
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
expect(view.data.starterPacksWithMembership.length).toBe(0)
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
it('paginates SPs with memberships', async () => {
|
|
351
|
+
const viewer = sc.dids.alice
|
|
352
|
+
const actor = sc.dids.bob
|
|
353
|
+
|
|
354
|
+
const results = (out: GetStarterPacksWithMembershipOutputSchema[]) =>
|
|
355
|
+
out.flatMap((res) => res.starterPacksWithMembership)
|
|
356
|
+
const paginator = async (cursor?: string) => {
|
|
357
|
+
const res = await agent.app.bsky.graph.getStarterPacksWithMembership(
|
|
358
|
+
{ actor, limit: 2, cursor },
|
|
359
|
+
{
|
|
360
|
+
headers: await network.serviceHeaders(
|
|
361
|
+
viewer,
|
|
362
|
+
ids.AppBskyGraphGetStarterPacksWithMembership,
|
|
363
|
+
),
|
|
364
|
+
},
|
|
365
|
+
)
|
|
366
|
+
return res.data
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const paginatedAll = await paginateAll(paginator)
|
|
370
|
+
paginatedAll.forEach((res) =>
|
|
371
|
+
expect(res.starterPacksWithMembership.length).toBeLessThanOrEqual(2),
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
const full = await agent.app.bsky.graph.getStarterPacksWithMembership(
|
|
375
|
+
{ actor },
|
|
376
|
+
{
|
|
377
|
+
headers: await network.serviceHeaders(
|
|
378
|
+
viewer,
|
|
379
|
+
ids.AppBskyGraphGetStarterPacksWithMembership,
|
|
380
|
+
),
|
|
381
|
+
},
|
|
382
|
+
)
|
|
383
|
+
expect(full.data.starterPacksWithMembership.length).toBe(3)
|
|
384
|
+
|
|
385
|
+
const sortedFull = results([full.data]).sort((a, b) =>
|
|
386
|
+
a.starterPack.uri > b.starterPack.uri ? 1 : -1,
|
|
387
|
+
)
|
|
388
|
+
const sortedPaginated = results(paginatedAll).sort((a, b) =>
|
|
389
|
+
a.starterPack.uri > b.starterPack.uri ? 1 : -1,
|
|
390
|
+
)
|
|
391
|
+
expect(sortedPaginated).toEqual(sortedFull)
|
|
392
|
+
})
|
|
393
|
+
})
|
|
265
394
|
})
|