@atproto/bsky 0.0.133 → 0.0.134
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 +17 -0
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +101 -0
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -0
- package/dist/api/app/bsky/unspecced/getTrends.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getTrends.js +96 -0
- package/dist/api/app/bsky/unspecced/getTrends.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/lexicon/index.d.ts +10 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +20 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +516 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +277 -0
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts +27 -0
- package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/defs.js +18 -0
- package/dist/lexicon/types/app/bsky/unspecced/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacks.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacks.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.d.ts +37 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrends.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrends.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrends.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrends.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrendsSkeleton.d.ts +38 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrendsSkeleton.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrendsSkeleton.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrendsSkeleton.js.map +1 -0
- package/dist/lexicon/types/com/atproto/admin/updateAccountSigningKey.d.ts +31 -0
- package/dist/lexicon/types/com/atproto/admin/updateAccountSigningKey.d.ts.map +1 -0
- package/dist/lexicon/types/com/atproto/admin/updateAccountSigningKey.js +7 -0
- package/dist/lexicon/types/com/atproto/admin/updateAccountSigningKey.js.map +1 -0
- package/package.json +9 -9
- package/src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts +150 -0
- package/src/api/app/bsky/unspecced/getTrends.ts +144 -0
- package/src/api/index.ts +4 -0
- package/src/lexicon/index.ts +62 -0
- package/src/lexicon/lexicons.ts +285 -0
- package/src/lexicon/types/app/bsky/unspecced/defs.ts +45 -0
- package/src/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacks.ts +54 -0
- package/src/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.ts +55 -0
- package/src/lexicon/types/app/bsky/unspecced/getTrends.ts +54 -0
- package/src/lexicon/types/app/bsky/unspecced/getTrendsSkeleton.ts +56 -0
- package/src/lexicon/types/com/atproto/admin/updateAccountSigningKey.ts +48 -0
- package/tests/seed/get-suggested-starter-packs.ts +63 -0
- package/tests/seed/get-trends.ts +70 -0
- package/tests/views/get-suggested-starter-packs.test.ts +128 -0
- package/tests/views/get-trends.test.ts +133 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tests.tsbuildinfo +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { CID } from 'multiformats/cid'
|
|
7
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
8
|
+
import {
|
|
9
|
+
type $Typed,
|
|
10
|
+
is$typed as _is$typed,
|
|
11
|
+
type OmitKey,
|
|
12
|
+
} from '../../../../util'
|
|
13
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
14
|
+
|
|
15
|
+
const is$typed = _is$typed,
|
|
16
|
+
validate = _validate
|
|
17
|
+
const id = 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton'
|
|
18
|
+
|
|
19
|
+
export interface QueryParams {
|
|
20
|
+
/** DID of the account making the request (not included for public/unauthenticated queries). */
|
|
21
|
+
viewer?: string
|
|
22
|
+
limit: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type InputSchema = undefined
|
|
26
|
+
|
|
27
|
+
export interface OutputSchema {
|
|
28
|
+
starterPacks: string[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type HandlerInput = undefined
|
|
32
|
+
|
|
33
|
+
export interface HandlerSuccess {
|
|
34
|
+
encoding: 'application/json'
|
|
35
|
+
body: OutputSchema
|
|
36
|
+
headers?: { [key: string]: string }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface HandlerError {
|
|
40
|
+
status: number
|
|
41
|
+
message?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
45
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
46
|
+
auth: HA
|
|
47
|
+
params: QueryParams
|
|
48
|
+
input: HandlerInput
|
|
49
|
+
req: express.Request
|
|
50
|
+
res: express.Response
|
|
51
|
+
resetRouteRateLimits: () => Promise<void>
|
|
52
|
+
}
|
|
53
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
54
|
+
ctx: HandlerReqCtx<HA>,
|
|
55
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { CID } from 'multiformats/cid'
|
|
7
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
8
|
+
import {
|
|
9
|
+
type $Typed,
|
|
10
|
+
is$typed as _is$typed,
|
|
11
|
+
type OmitKey,
|
|
12
|
+
} from '../../../../util'
|
|
13
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
14
|
+
import type * as AppBskyUnspeccedDefs from './defs.js'
|
|
15
|
+
|
|
16
|
+
const is$typed = _is$typed,
|
|
17
|
+
validate = _validate
|
|
18
|
+
const id = 'app.bsky.unspecced.getTrends'
|
|
19
|
+
|
|
20
|
+
export interface QueryParams {
|
|
21
|
+
limit: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type InputSchema = undefined
|
|
25
|
+
|
|
26
|
+
export interface OutputSchema {
|
|
27
|
+
trends: AppBskyUnspeccedDefs.TrendView[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type HandlerInput = undefined
|
|
31
|
+
|
|
32
|
+
export interface HandlerSuccess {
|
|
33
|
+
encoding: 'application/json'
|
|
34
|
+
body: OutputSchema
|
|
35
|
+
headers?: { [key: string]: string }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface HandlerError {
|
|
39
|
+
status: number
|
|
40
|
+
message?: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
44
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
45
|
+
auth: HA
|
|
46
|
+
params: QueryParams
|
|
47
|
+
input: HandlerInput
|
|
48
|
+
req: express.Request
|
|
49
|
+
res: express.Response
|
|
50
|
+
resetRouteRateLimits: () => Promise<void>
|
|
51
|
+
}
|
|
52
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
53
|
+
ctx: HandlerReqCtx<HA>,
|
|
54
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { CID } from 'multiformats/cid'
|
|
7
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
8
|
+
import {
|
|
9
|
+
type $Typed,
|
|
10
|
+
is$typed as _is$typed,
|
|
11
|
+
type OmitKey,
|
|
12
|
+
} from '../../../../util'
|
|
13
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
14
|
+
import type * as AppBskyUnspeccedDefs from './defs.js'
|
|
15
|
+
|
|
16
|
+
const is$typed = _is$typed,
|
|
17
|
+
validate = _validate
|
|
18
|
+
const id = 'app.bsky.unspecced.getTrendsSkeleton'
|
|
19
|
+
|
|
20
|
+
export interface QueryParams {
|
|
21
|
+
/** DID of the account making the request (not included for public/unauthenticated queries). */
|
|
22
|
+
viewer?: string
|
|
23
|
+
limit: number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type InputSchema = undefined
|
|
27
|
+
|
|
28
|
+
export interface OutputSchema {
|
|
29
|
+
trends: AppBskyUnspeccedDefs.SkeletonTrend[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type HandlerInput = undefined
|
|
33
|
+
|
|
34
|
+
export interface HandlerSuccess {
|
|
35
|
+
encoding: 'application/json'
|
|
36
|
+
body: OutputSchema
|
|
37
|
+
headers?: { [key: string]: string }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface HandlerError {
|
|
41
|
+
status: number
|
|
42
|
+
message?: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
46
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
47
|
+
auth: HA
|
|
48
|
+
params: QueryParams
|
|
49
|
+
input: HandlerInput
|
|
50
|
+
req: express.Request
|
|
51
|
+
res: express.Response
|
|
52
|
+
resetRouteRateLimits: () => Promise<void>
|
|
53
|
+
}
|
|
54
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
55
|
+
ctx: HandlerReqCtx<HA>,
|
|
56
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { CID } from 'multiformats/cid'
|
|
7
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
8
|
+
import {
|
|
9
|
+
type $Typed,
|
|
10
|
+
is$typed as _is$typed,
|
|
11
|
+
type OmitKey,
|
|
12
|
+
} from '../../../../util'
|
|
13
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
14
|
+
|
|
15
|
+
const is$typed = _is$typed,
|
|
16
|
+
validate = _validate
|
|
17
|
+
const id = 'com.atproto.admin.updateAccountSigningKey'
|
|
18
|
+
|
|
19
|
+
export interface QueryParams {}
|
|
20
|
+
|
|
21
|
+
export interface InputSchema {
|
|
22
|
+
did: string
|
|
23
|
+
/** Did-key formatted public key */
|
|
24
|
+
signingKey: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface HandlerInput {
|
|
28
|
+
encoding: 'application/json'
|
|
29
|
+
body: InputSchema
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface HandlerError {
|
|
33
|
+
status: number
|
|
34
|
+
message?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type HandlerOutput = HandlerError | void
|
|
38
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
39
|
+
auth: HA
|
|
40
|
+
params: QueryParams
|
|
41
|
+
input: HandlerInput
|
|
42
|
+
req: express.Request
|
|
43
|
+
res: express.Response
|
|
44
|
+
resetRouteRateLimits: () => Promise<void>
|
|
45
|
+
}
|
|
46
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
47
|
+
ctx: HandlerReqCtx<HA>,
|
|
48
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { SeedClient, TestNetwork, TestNetworkNoAppView } from '@atproto/dev-env'
|
|
2
|
+
|
|
3
|
+
export type User = {
|
|
4
|
+
id: string
|
|
5
|
+
did: string
|
|
6
|
+
email: string
|
|
7
|
+
handle: string
|
|
8
|
+
password: string
|
|
9
|
+
displayName: string
|
|
10
|
+
description: string
|
|
11
|
+
selfLabels: undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function createUser(name: string): User {
|
|
15
|
+
return {
|
|
16
|
+
id: name,
|
|
17
|
+
// @ts-ignore overwritten below
|
|
18
|
+
did: undefined,
|
|
19
|
+
email: `${name}@test.com`,
|
|
20
|
+
handle: `${name}.test`,
|
|
21
|
+
password: `${name}-pass`,
|
|
22
|
+
displayName: name,
|
|
23
|
+
description: `hi im ${name} label_me`,
|
|
24
|
+
selfLabels: undefined,
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const users = {
|
|
29
|
+
creator: createUser('creator'),
|
|
30
|
+
poster: createUser('poster'),
|
|
31
|
+
|
|
32
|
+
viewer: createUser('viewer'),
|
|
33
|
+
viewerBlocker: createUser('viewerBlocker'),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type Users = typeof users
|
|
37
|
+
export type StarterPacks = SeedClient['starterpacks']
|
|
38
|
+
|
|
39
|
+
export async function trendsSeed(
|
|
40
|
+
sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
|
|
41
|
+
) {
|
|
42
|
+
const u = structuredClone(users)
|
|
43
|
+
|
|
44
|
+
await sc.createAccount('creator', u.creator)
|
|
45
|
+
await sc.createAccount('poster', u.poster)
|
|
46
|
+
await sc.createAccount('viewer', u.viewer)
|
|
47
|
+
await sc.createAccount('viewerBlocker', u.viewerBlocker)
|
|
48
|
+
|
|
49
|
+
Object.values(u).forEach((user) => {
|
|
50
|
+
u[user.id].did = sc.dids[user.id]
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
await sc.createStarterPack(u.creator.did, 'test', [u.poster.did])
|
|
54
|
+
await sc.block(u.viewerBlocker.did, u.creator.did)
|
|
55
|
+
|
|
56
|
+
await sc.network.processAll()
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
users: u,
|
|
60
|
+
starterpacks: sc.starterpacks,
|
|
61
|
+
seedClient: sc,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { SeedClient, TestNetwork, TestNetworkNoAppView } from '@atproto/dev-env'
|
|
2
|
+
|
|
3
|
+
export type User = {
|
|
4
|
+
id: string
|
|
5
|
+
did: string
|
|
6
|
+
email: string
|
|
7
|
+
handle: string
|
|
8
|
+
password: string
|
|
9
|
+
displayName: string
|
|
10
|
+
description: string
|
|
11
|
+
selfLabels: undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function createUser(name: string): User {
|
|
15
|
+
return {
|
|
16
|
+
id: name,
|
|
17
|
+
// @ts-ignore overwritten below
|
|
18
|
+
did: undefined,
|
|
19
|
+
email: `${name}@test.com`,
|
|
20
|
+
handle: `${name}.test`,
|
|
21
|
+
password: `${name}-pass`,
|
|
22
|
+
displayName: name,
|
|
23
|
+
description: `hi im ${name} label_me`,
|
|
24
|
+
selfLabels: undefined,
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const users = {
|
|
29
|
+
trender: createUser('trender'),
|
|
30
|
+
|
|
31
|
+
posterA: createUser('posterA'),
|
|
32
|
+
posterB: createUser('posterB'),
|
|
33
|
+
posterC: createUser('posterC'),
|
|
34
|
+
posterD: createUser('posterD'),
|
|
35
|
+
|
|
36
|
+
viewer: createUser('viewer'),
|
|
37
|
+
viewerBlocker: createUser('viewerBlocker'),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type Users = typeof users
|
|
41
|
+
export type Feeds = SeedClient['feedgens']
|
|
42
|
+
|
|
43
|
+
export async function trendsSeed(
|
|
44
|
+
sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
|
|
45
|
+
) {
|
|
46
|
+
const u = structuredClone(users)
|
|
47
|
+
|
|
48
|
+
await sc.createAccount('trender', u.trender)
|
|
49
|
+
await sc.createAccount('posterA', u.posterA)
|
|
50
|
+
await sc.createAccount('posterB', u.posterB)
|
|
51
|
+
await sc.createAccount('posterC', u.posterC)
|
|
52
|
+
await sc.createAccount('posterD', u.posterD)
|
|
53
|
+
await sc.createAccount('viewer', u.viewer)
|
|
54
|
+
await sc.createAccount('viewerBlocker', u.viewerBlocker)
|
|
55
|
+
|
|
56
|
+
Object.values(u).forEach((user) => {
|
|
57
|
+
u[user.id].did = sc.dids[user.id]
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
await sc.createFeedGen(u.trender.did, 'did:web:example.com', 'trendA')
|
|
61
|
+
await sc.block(u.viewerBlocker.did, u.posterC.did)
|
|
62
|
+
|
|
63
|
+
await sc.network.processAll()
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
users: u,
|
|
67
|
+
feeds: sc.feedgens,
|
|
68
|
+
seedClient: sc,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { once } from 'node:events'
|
|
2
|
+
import { Server, createServer } from 'node:http'
|
|
3
|
+
import { AddressInfo } from 'node:net'
|
|
4
|
+
import express, { Application } from 'express'
|
|
5
|
+
import AtpAgent from '@atproto/api'
|
|
6
|
+
import { SeedClient, TestNetwork } from '@atproto/dev-env'
|
|
7
|
+
import { ids } from '../../src/lexicon/lexicons'
|
|
8
|
+
import { OutputSchema } from '../../src/lexicon/types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton'
|
|
9
|
+
import {
|
|
10
|
+
StarterPacks,
|
|
11
|
+
Users,
|
|
12
|
+
trendsSeed,
|
|
13
|
+
} from '../seed/get-suggested-starter-packs'
|
|
14
|
+
|
|
15
|
+
describe('getSuggestedStarterPacks', () => {
|
|
16
|
+
let network: TestNetwork
|
|
17
|
+
let agent: AtpAgent
|
|
18
|
+
let sc: SeedClient
|
|
19
|
+
let users: Users
|
|
20
|
+
let mockServer: MockServer
|
|
21
|
+
let starterpacks: StarterPacks
|
|
22
|
+
|
|
23
|
+
beforeAll(async () => {
|
|
24
|
+
mockServer = new MockServer()
|
|
25
|
+
await mockServer.listen()
|
|
26
|
+
|
|
27
|
+
network = await TestNetwork.create({
|
|
28
|
+
dbPostgresSchema: 'bsky_tests_get_suggested_starter_packs',
|
|
29
|
+
bsky: {
|
|
30
|
+
topicsUrl: mockServer.url,
|
|
31
|
+
topicsApiKey: 'test',
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
agent = network.bsky.getClient()
|
|
35
|
+
sc = network.getSeedClient()
|
|
36
|
+
|
|
37
|
+
const result = await trendsSeed(sc)
|
|
38
|
+
users = result.users
|
|
39
|
+
starterpacks = result.starterpacks
|
|
40
|
+
|
|
41
|
+
await network.processAll()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
afterAll(async () => {
|
|
45
|
+
await network.close()
|
|
46
|
+
await mockServer.stop()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe(`basic handling`, () => {
|
|
50
|
+
beforeAll(() => {
|
|
51
|
+
const pack = Object.values(starterpacks[users.creator.did])[0]
|
|
52
|
+
mockServer.mockedStarterPackUris.set('a', pack.ref.uriStr)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
afterAll(() => {
|
|
56
|
+
mockServer.mockedStarterPackUris.delete('a')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it(`returns pack for non-blocking user`, async () => {
|
|
60
|
+
const { data } = await agent.app.bsky.unspecced.getSuggestedStarterPacks(
|
|
61
|
+
undefined,
|
|
62
|
+
{
|
|
63
|
+
headers: await network.serviceHeaders(
|
|
64
|
+
users.viewer.did,
|
|
65
|
+
ids.AppBskyUnspeccedGetSuggestedStarterPacks,
|
|
66
|
+
),
|
|
67
|
+
},
|
|
68
|
+
)
|
|
69
|
+
const sp = data.starterPacks[0]
|
|
70
|
+
expect(sp).toBeDefined()
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it(`does not return pack if creator blocked by viewer`, async () => {
|
|
74
|
+
const { data } = await agent.app.bsky.unspecced.getSuggestedStarterPacks(
|
|
75
|
+
undefined,
|
|
76
|
+
{
|
|
77
|
+
headers: await network.serviceHeaders(
|
|
78
|
+
users.viewerBlocker.did,
|
|
79
|
+
ids.AppBskyUnspeccedGetSuggestedStarterPacks,
|
|
80
|
+
),
|
|
81
|
+
},
|
|
82
|
+
)
|
|
83
|
+
const sp = data.starterPacks[0]
|
|
84
|
+
expect(sp).not.toBeDefined()
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
class MockServer {
|
|
90
|
+
app: Application
|
|
91
|
+
server: Server
|
|
92
|
+
|
|
93
|
+
mockedStarterPackUris = new Map<string, OutputSchema['starterPacks'][0]>()
|
|
94
|
+
|
|
95
|
+
constructor() {
|
|
96
|
+
this.app = this.createApp()
|
|
97
|
+
this.server = createServer(this.app)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async listen(port?: number) {
|
|
101
|
+
this.server.listen(port)
|
|
102
|
+
await once(this.server, 'listening')
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async stop() {
|
|
106
|
+
this.server.close()
|
|
107
|
+
await once(this.server, 'close')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get url() {
|
|
111
|
+
const address = this.server.address() as AddressInfo
|
|
112
|
+
return `http://localhost:${address.port}`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private createApp() {
|
|
116
|
+
const app = express()
|
|
117
|
+
app.get(
|
|
118
|
+
'/xrpc/app.bsky.unspecced.getSuggestedStarterPacksSkeleton',
|
|
119
|
+
(req, res) => {
|
|
120
|
+
const skeleton: OutputSchema = {
|
|
121
|
+
starterPacks: Array.from(this.mockedStarterPackUris.values()),
|
|
122
|
+
}
|
|
123
|
+
return res.json(skeleton)
|
|
124
|
+
},
|
|
125
|
+
)
|
|
126
|
+
return app
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { once } from 'node:events'
|
|
3
|
+
import { Server, createServer } from 'node:http'
|
|
4
|
+
import { AddressInfo } from 'node:net'
|
|
5
|
+
import express, { Application } from 'express'
|
|
6
|
+
import AtpAgent from '@atproto/api'
|
|
7
|
+
import { SeedClient, TestNetwork } from '@atproto/dev-env'
|
|
8
|
+
import { ids } from '../../src/lexicon/lexicons'
|
|
9
|
+
import { OutputSchema } from '../../src/lexicon/types/app/bsky/unspecced/getTrendsSkeleton'
|
|
10
|
+
import { Users, trendsSeed } from '../seed/get-trends'
|
|
11
|
+
|
|
12
|
+
describe('getTrends', () => {
|
|
13
|
+
let network: TestNetwork
|
|
14
|
+
let agent: AtpAgent
|
|
15
|
+
let sc: SeedClient
|
|
16
|
+
let users: Users
|
|
17
|
+
let mockTrendServer: MockTrendsServer
|
|
18
|
+
|
|
19
|
+
beforeAll(async () => {
|
|
20
|
+
mockTrendServer = new MockTrendsServer()
|
|
21
|
+
await mockTrendServer.listen()
|
|
22
|
+
|
|
23
|
+
network = await TestNetwork.create({
|
|
24
|
+
dbPostgresSchema: 'bsky_tests_get_trends_test_b',
|
|
25
|
+
bsky: {
|
|
26
|
+
topicsUrl: mockTrendServer.url,
|
|
27
|
+
topicsApiKey: 'test',
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
agent = network.bsky.getClient()
|
|
31
|
+
sc = network.getSeedClient()
|
|
32
|
+
|
|
33
|
+
const result = await trendsSeed(sc)
|
|
34
|
+
users = result.users
|
|
35
|
+
|
|
36
|
+
await network.processAll()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
afterAll(async () => {
|
|
40
|
+
await network.close()
|
|
41
|
+
await mockTrendServer.stop()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe(`basic handling`, () => {
|
|
45
|
+
beforeAll(() => {
|
|
46
|
+
mockTrendServer.mockedTrendSkeletons.set('a', {
|
|
47
|
+
topic: 'a',
|
|
48
|
+
displayName: 'A',
|
|
49
|
+
link: '/test',
|
|
50
|
+
startedAt: new Date().toISOString(),
|
|
51
|
+
postCount: 3,
|
|
52
|
+
dids: [users.posterA.did, users.posterB.did, users.posterC.did],
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
afterAll(() => {
|
|
57
|
+
mockTrendServer.mockedTrendSkeletons.delete('a')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it(`returns all users for non-blocked user`, async () => {
|
|
61
|
+
const { data } = await agent.app.bsky.unspecced.getTrends(undefined, {
|
|
62
|
+
headers: await network.serviceHeaders(
|
|
63
|
+
users.viewer.did,
|
|
64
|
+
ids.AppBskyUnspeccedGetTrends,
|
|
65
|
+
),
|
|
66
|
+
})
|
|
67
|
+
const trendA = data.trends.find((t) => t.topic === 'a')
|
|
68
|
+
|
|
69
|
+
assert(trendA)
|
|
70
|
+
|
|
71
|
+
expect(trendA.actors.map((a) => a.did)).toEqual([
|
|
72
|
+
users.posterA.did,
|
|
73
|
+
users.posterB.did,
|
|
74
|
+
users.posterC.did,
|
|
75
|
+
])
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it(`does not return user blocked by viewer`, async () => {
|
|
79
|
+
const { data } = await agent.app.bsky.unspecced.getTrends(undefined, {
|
|
80
|
+
headers: await network.serviceHeaders(
|
|
81
|
+
users.viewerBlocker.did,
|
|
82
|
+
ids.AppBskyUnspeccedGetTrends,
|
|
83
|
+
),
|
|
84
|
+
})
|
|
85
|
+
const trendA = data.trends.find((t) => t.topic === 'a')
|
|
86
|
+
|
|
87
|
+
assert(trendA)
|
|
88
|
+
|
|
89
|
+
expect(trendA.actors.map((a) => a.did)).toEqual([
|
|
90
|
+
users.posterA.did,
|
|
91
|
+
users.posterB.did,
|
|
92
|
+
])
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
class MockTrendsServer {
|
|
98
|
+
app: Application
|
|
99
|
+
server: Server
|
|
100
|
+
|
|
101
|
+
mockedTrendSkeletons = new Map<string, OutputSchema['trends'][0]>()
|
|
102
|
+
|
|
103
|
+
constructor() {
|
|
104
|
+
this.app = this.createApp()
|
|
105
|
+
this.server = createServer(this.app)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async listen(port?: number) {
|
|
109
|
+
this.server.listen(port)
|
|
110
|
+
await once(this.server, 'listening')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async stop() {
|
|
114
|
+
this.server.close()
|
|
115
|
+
await once(this.server, 'close')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get url() {
|
|
119
|
+
const address = this.server.address() as AddressInfo
|
|
120
|
+
return `http://localhost:${address.port}`
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private createApp() {
|
|
124
|
+
const app = express()
|
|
125
|
+
app.get('/xrpc/app.bsky.unspecced.getTrendsSkeleton', (req, res) => {
|
|
126
|
+
const skeleton: OutputSchema = {
|
|
127
|
+
trends: Array.from(this.mockedTrendSkeletons.values()),
|
|
128
|
+
}
|
|
129
|
+
return res.json(skeleton)
|
|
130
|
+
})
|
|
131
|
+
return app
|
|
132
|
+
}
|
|
133
|
+
}
|