@atproto/bsky 0.0.194 → 0.0.195
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 +10 -0
- package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.js +43 -12
- package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js +1 -2
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js +0 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/auth-verifier.d.ts +1 -0
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/auth-verifier.js +4 -0
- package/dist/auth-verifier.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -1
- package/dist/data-plane/server/routes/search.d.ts.map +1 -1
- package/dist/data-plane/server/routes/search.js +15 -1
- package/dist/data-plane/server/routes/search.js.map +1 -1
- package/dist/data-plane/server/util.d.ts +7 -0
- package/dist/data-plane/server/util.d.ts.map +1 -1
- package/dist/data-plane/server/util.js +38 -1
- package/dist/data-plane/server/util.js.map +1 -1
- package/dist/lexicon/index.d.ts +2 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +4 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +98 -28
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +52 -14
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +0 -2
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.d.ts +0 -2
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.d.ts +0 -2
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.d.ts +28 -0
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.d.ts.map +1 -0
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.js +7 -0
- package/dist/lexicon/types/com/atproto/lexicon/resolveLexicon.js.map +1 -0
- package/dist/views/index.d.ts +2 -4
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +8 -14
- package/dist/views/index.js.map +1 -1
- package/dist/views/threads-v2.d.ts +0 -1
- package/dist/views/threads-v2.d.ts.map +1 -1
- package/dist/views/threads-v2.js +2 -4
- package/dist/views/threads-v2.js.map +1 -1
- package/package.json +5 -5
- package/src/api/app/bsky/feed/searchPosts.ts +51 -10
- package/src/api/app/bsky/unspecced/getPostThreadOtherV2.ts +1 -2
- package/src/api/app/bsky/unspecced/getPostThreadV2.ts +0 -1
- package/src/auth-verifier.ts +5 -0
- package/src/config.ts +8 -0
- package/src/data-plane/server/routes/search.ts +18 -1
- package/src/data-plane/server/util.ts +51 -0
- package/src/lexicon/index.ts +13 -0
- package/src/lexicon/lexicons.ts +52 -16
- package/src/lexicon/types/app/bsky/actor/defs.ts +0 -2
- package/src/lexicon/types/app/bsky/unspecced/getPostThreadOtherV2.ts +0 -2
- package/src/lexicon/types/app/bsky/unspecced/getPostThreadV2.ts +0 -2
- package/src/lexicon/types/com/atproto/lexicon/resolveLexicon.ts +46 -0
- package/src/views/index.ts +3 -23
- package/src/views/threads-v2.ts +2 -12
- package/tests/utils.test.ts +45 -0
- package/tests/views/post-search.test.ts +221 -0
- package/tests/views/thread-v2.test.ts +2 -109
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tests.tsbuildinfo +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
import type * as ComAtprotoLexiconSchema from './schema.js'
|
|
13
|
+
|
|
14
|
+
const is$typed = _is$typed,
|
|
15
|
+
validate = _validate
|
|
16
|
+
const id = 'com.atproto.lexicon.resolveLexicon'
|
|
17
|
+
|
|
18
|
+
export type QueryParams = {
|
|
19
|
+
/** The lexicon NSID to resolve. */
|
|
20
|
+
nsid: string
|
|
21
|
+
}
|
|
22
|
+
export type InputSchema = undefined
|
|
23
|
+
|
|
24
|
+
export interface OutputSchema {
|
|
25
|
+
/** The CID of the lexicon schema record. */
|
|
26
|
+
cid: string
|
|
27
|
+
schema: ComAtprotoLexiconSchema.Main
|
|
28
|
+
/** The AT-URI of the lexicon schema record. */
|
|
29
|
+
uri: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type HandlerInput = void
|
|
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
|
+
error?: 'LexiconNotFound'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type HandlerOutput = HandlerError | HandlerSuccess
|
package/src/views/index.ts
CHANGED
|
@@ -1246,13 +1246,11 @@ export class Views {
|
|
|
1246
1246
|
above,
|
|
1247
1247
|
below,
|
|
1248
1248
|
branchingFactor,
|
|
1249
|
-
prioritizeFollowedUsers,
|
|
1250
1249
|
sort,
|
|
1251
1250
|
}: {
|
|
1252
1251
|
above: number
|
|
1253
1252
|
below: number
|
|
1254
1253
|
branchingFactor: number
|
|
1255
|
-
prioritizeFollowedUsers: boolean
|
|
1256
1254
|
sort: GetPostThreadV2QueryParams['sort']
|
|
1257
1255
|
},
|
|
1258
1256
|
): { hasOtherReplies: boolean; thread: ThreadItem[] } {
|
|
@@ -1347,7 +1345,6 @@ export class Views {
|
|
|
1347
1345
|
below,
|
|
1348
1346
|
depth: 1,
|
|
1349
1347
|
branchingFactor,
|
|
1350
|
-
prioritizeFollowedUsers,
|
|
1351
1348
|
},
|
|
1352
1349
|
state,
|
|
1353
1350
|
)
|
|
@@ -1374,7 +1371,6 @@ export class Views {
|
|
|
1374
1371
|
opDid,
|
|
1375
1372
|
branchingFactor,
|
|
1376
1373
|
sort,
|
|
1377
|
-
prioritizeFollowedUsers,
|
|
1378
1374
|
viewer: state.ctx?.viewer ?? null,
|
|
1379
1375
|
threadTagsBumpDown: this.threadTagsBumpDown,
|
|
1380
1376
|
threadTagsHide: this.threadTagsHide,
|
|
@@ -1513,7 +1509,6 @@ export class Views {
|
|
|
1513
1509
|
below,
|
|
1514
1510
|
depth,
|
|
1515
1511
|
branchingFactor,
|
|
1516
|
-
prioritizeFollowedUsers,
|
|
1517
1512
|
}: {
|
|
1518
1513
|
parentUri: string
|
|
1519
1514
|
isOPThread: boolean
|
|
@@ -1523,7 +1518,6 @@ export class Views {
|
|
|
1523
1518
|
below: number
|
|
1524
1519
|
depth: number
|
|
1525
1520
|
branchingFactor: number
|
|
1526
|
-
prioritizeFollowedUsers: boolean
|
|
1527
1521
|
},
|
|
1528
1522
|
state: HydrationState,
|
|
1529
1523
|
): { replies: ThreadTreeVisible[] | undefined; hasOtherReplies: boolean } {
|
|
@@ -1547,7 +1541,7 @@ export class Views {
|
|
|
1547
1541
|
|
|
1548
1542
|
// Hidden.
|
|
1549
1543
|
const { isOther } = this.isOtherThreadPost(
|
|
1550
|
-
{ post, postView,
|
|
1544
|
+
{ post, postView, rootUri, uri },
|
|
1551
1545
|
state,
|
|
1552
1546
|
)
|
|
1553
1547
|
if (isOther) {
|
|
@@ -1570,7 +1564,6 @@ export class Views {
|
|
|
1570
1564
|
below,
|
|
1571
1565
|
depth: depth + 1,
|
|
1572
1566
|
branchingFactor,
|
|
1573
|
-
prioritizeFollowedUsers,
|
|
1574
1567
|
},
|
|
1575
1568
|
state,
|
|
1576
1569
|
)
|
|
@@ -1699,11 +1692,9 @@ export class Views {
|
|
|
1699
1692
|
{
|
|
1700
1693
|
below,
|
|
1701
1694
|
branchingFactor,
|
|
1702
|
-
prioritizeFollowedUsers,
|
|
1703
1695
|
}: {
|
|
1704
1696
|
below: number
|
|
1705
1697
|
branchingFactor: number
|
|
1706
|
-
prioritizeFollowedUsers: boolean
|
|
1707
1698
|
},
|
|
1708
1699
|
): ThreadOtherItem[] {
|
|
1709
1700
|
const { anchor: anchorUri, uris } = skeleton
|
|
@@ -1738,7 +1729,6 @@ export class Views {
|
|
|
1738
1729
|
childrenByParentUri,
|
|
1739
1730
|
below,
|
|
1740
1731
|
depth: 1,
|
|
1741
|
-
prioritizeFollowedUsers,
|
|
1742
1732
|
},
|
|
1743
1733
|
state,
|
|
1744
1734
|
),
|
|
@@ -1747,7 +1737,6 @@ export class Views {
|
|
|
1747
1737
|
return sortTrimFlattenThreadTree(anchorTree, {
|
|
1748
1738
|
opDid,
|
|
1749
1739
|
branchingFactor,
|
|
1750
|
-
prioritizeFollowedUsers: false,
|
|
1751
1740
|
viewer: state.ctx?.viewer ?? null,
|
|
1752
1741
|
threadTagsBumpDown: this.threadTagsBumpDown,
|
|
1753
1742
|
threadTagsHide: this.threadTagsHide,
|
|
@@ -1761,14 +1750,12 @@ export class Views {
|
|
|
1761
1750
|
childrenByParentUri,
|
|
1762
1751
|
below,
|
|
1763
1752
|
depth,
|
|
1764
|
-
prioritizeFollowedUsers,
|
|
1765
1753
|
}: {
|
|
1766
1754
|
parentUri: string
|
|
1767
1755
|
rootUri: string
|
|
1768
1756
|
childrenByParentUri: Record<string, string[]>
|
|
1769
1757
|
below: number
|
|
1770
1758
|
depth: number
|
|
1771
|
-
prioritizeFollowedUsers: boolean
|
|
1772
1759
|
},
|
|
1773
1760
|
state: HydrationState,
|
|
1774
1761
|
): ThreadOtherPostNode[] | undefined {
|
|
@@ -1791,10 +1778,7 @@ export class Views {
|
|
|
1791
1778
|
|
|
1792
1779
|
// Other posts to pull out
|
|
1793
1780
|
const { isOther, hiddenByThreadgate, mutedByViewer } =
|
|
1794
|
-
this.isOtherThreadPost(
|
|
1795
|
-
{ post, postView, rootUri, prioritizeFollowedUsers, uri },
|
|
1796
|
-
state,
|
|
1797
|
-
)
|
|
1781
|
+
this.isOtherThreadPost({ post, postView, rootUri, uri }, state)
|
|
1798
1782
|
if (isOther) {
|
|
1799
1783
|
// Only show hidden anchor replies, not all hidden.
|
|
1800
1784
|
if (depth > 1) {
|
|
@@ -1813,7 +1797,6 @@ export class Views {
|
|
|
1813
1797
|
childrenByParentUri,
|
|
1814
1798
|
below,
|
|
1815
1799
|
depth: depth + 1,
|
|
1816
|
-
prioritizeFollowedUsers,
|
|
1817
1800
|
},
|
|
1818
1801
|
state,
|
|
1819
1802
|
)
|
|
@@ -1932,13 +1915,11 @@ export class Views {
|
|
|
1932
1915
|
{
|
|
1933
1916
|
post,
|
|
1934
1917
|
postView,
|
|
1935
|
-
prioritizeFollowedUsers,
|
|
1936
1918
|
rootUri,
|
|
1937
1919
|
uri,
|
|
1938
1920
|
}: {
|
|
1939
1921
|
post: Post
|
|
1940
1922
|
postView: PostView
|
|
1941
|
-
prioritizeFollowedUsers: boolean
|
|
1942
1923
|
rootUri: string
|
|
1943
1924
|
uri: string
|
|
1944
1925
|
},
|
|
@@ -1952,8 +1933,7 @@ export class Views {
|
|
|
1952
1933
|
const opDid = creatorFromUri(rootUri)
|
|
1953
1934
|
const authorDid = creatorFromUri(uri)
|
|
1954
1935
|
|
|
1955
|
-
const showBecauseFollowing =
|
|
1956
|
-
prioritizeFollowedUsers && !!postView.author.viewer?.following
|
|
1936
|
+
const showBecauseFollowing = !!postView.author.viewer?.following
|
|
1957
1937
|
const hiddenByTag =
|
|
1958
1938
|
authorDid !== opDid &&
|
|
1959
1939
|
authorDid !== state.ctx?.viewer &&
|
package/src/views/threads-v2.ts
CHANGED
|
@@ -119,7 +119,6 @@ export function sortTrimFlattenThreadTree(
|
|
|
119
119
|
type SortTrimFlattenOptions = {
|
|
120
120
|
branchingFactor: GetPostThreadV2QueryParams['branchingFactor']
|
|
121
121
|
opDid: string
|
|
122
|
-
prioritizeFollowedUsers: boolean
|
|
123
122
|
sort?: GetPostThreadV2QueryParams['sort']
|
|
124
123
|
viewer: HydrateCtx['viewer']
|
|
125
124
|
threadTagsBumpDown: readonly string[]
|
|
@@ -182,13 +181,7 @@ function applyBumping(
|
|
|
182
181
|
return null
|
|
183
182
|
}
|
|
184
183
|
|
|
185
|
-
const {
|
|
186
|
-
opDid,
|
|
187
|
-
prioritizeFollowedUsers,
|
|
188
|
-
viewer,
|
|
189
|
-
threadTagsBumpDown,
|
|
190
|
-
threadTagsHide,
|
|
191
|
-
} = opts
|
|
184
|
+
const { opDid, viewer, threadTagsBumpDown, threadTagsHide } = opts
|
|
192
185
|
|
|
193
186
|
type BumpDirection = 'up' | 'down'
|
|
194
187
|
type BumpPredicateFn = (i: ThreadMaybeOtherPostNode) => boolean
|
|
@@ -227,10 +220,7 @@ function applyBumping(
|
|
|
227
220
|
// Followers posts.
|
|
228
221
|
[
|
|
229
222
|
'up',
|
|
230
|
-
(i) =>
|
|
231
|
-
i.type === 'post' &&
|
|
232
|
-
prioritizeFollowedUsers &&
|
|
233
|
-
!!i.item.value.post.author.viewer?.following,
|
|
223
|
+
(i) => i.type === 'post' && !!i.item.value.post.author.viewer?.following,
|
|
234
224
|
],
|
|
235
225
|
// Bump-down tags.
|
|
236
226
|
[
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PostSearchQuery,
|
|
3
|
+
parsePostSearchQuery,
|
|
4
|
+
} from '../src/data-plane/server/util'
|
|
5
|
+
|
|
6
|
+
describe('parsePostSearchQuery', () => {
|
|
7
|
+
type TestCase = {
|
|
8
|
+
input: string
|
|
9
|
+
output: PostSearchQuery
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const tests: TestCase[] = [
|
|
13
|
+
{
|
|
14
|
+
input: `bluesky `,
|
|
15
|
+
output: { q: `bluesky`, author: undefined },
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
input: ` bluesky from:esb.lol`,
|
|
19
|
+
output: { q: `bluesky`, author: `esb.lol` },
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
input: `bluesky "from:esb.lol"`,
|
|
23
|
+
output: { q: `bluesky "from:esb.lol"`, author: undefined },
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
input: `bluesky mentions:@esb.lol `,
|
|
27
|
+
output: { q: `bluesky mentions:@esb.lol`, author: undefined },
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
input: `bluesky lang:"en"`,
|
|
31
|
+
output: { q: `bluesky lang:"en"`, author: undefined },
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
input: `bluesky "literal" "from:invalid" did:test:123 `,
|
|
35
|
+
output: {
|
|
36
|
+
q: `bluesky "literal" "from:invalid"`,
|
|
37
|
+
author: `did:test:123`,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
it.each(tests)(`'$input' -> '$output'`, ({ input, output }) => {
|
|
43
|
+
expect(parsePostSearchQuery(input)).toEqual(output)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { AtpAgent } from '@atproto/api'
|
|
2
|
+
import { QueryParams as SearchPostsQueryParams } from '@atproto/api/src/client/types/app/bsky/feed/searchPosts'
|
|
3
|
+
import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
|
4
|
+
import { DatabaseSchema } from '../../src'
|
|
5
|
+
import { ids } from '../../src/lexicon/lexicons'
|
|
6
|
+
|
|
7
|
+
const TAG_HIDE = 'hide'
|
|
8
|
+
|
|
9
|
+
describe('appview search', () => {
|
|
10
|
+
let network: TestNetwork
|
|
11
|
+
let agent: AtpAgent
|
|
12
|
+
let ozoneAgent: AtpAgent
|
|
13
|
+
let sc: SeedClient
|
|
14
|
+
let post0: Awaited<ReturnType<SeedClient['post']>>
|
|
15
|
+
let post1: Awaited<ReturnType<SeedClient['post']>>
|
|
16
|
+
let post2: Awaited<ReturnType<SeedClient['post']>>
|
|
17
|
+
let allResults: string[]
|
|
18
|
+
let nonTaggedResults: string[]
|
|
19
|
+
|
|
20
|
+
// account dids, for convenience
|
|
21
|
+
let alice: string
|
|
22
|
+
let bob: string
|
|
23
|
+
let carol: string
|
|
24
|
+
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
network = await TestNetwork.create({
|
|
27
|
+
dbPostgresSchema: 'bsky_views_search',
|
|
28
|
+
bsky: {
|
|
29
|
+
searchTagsHide: new Set([TAG_HIDE]),
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
agent = network.bsky.getClient()
|
|
33
|
+
sc = network.getSeedClient()
|
|
34
|
+
ozoneAgent = network.ozone.getClient()
|
|
35
|
+
await basicSeed(sc)
|
|
36
|
+
|
|
37
|
+
alice = sc.dids.alice
|
|
38
|
+
bob = sc.dids.bob
|
|
39
|
+
carol = sc.dids.carol
|
|
40
|
+
|
|
41
|
+
post0 = await sc.post(alice, 'good doggo')
|
|
42
|
+
post1 = await sc.post(alice, 'bad doggo')
|
|
43
|
+
post2 = await sc.post(alice, 'cute doggo')
|
|
44
|
+
await network.processAll()
|
|
45
|
+
|
|
46
|
+
await createTag(network.bsky.db.db, {
|
|
47
|
+
uri: post1.ref.uriStr,
|
|
48
|
+
val: TAG_HIDE,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
allResults = [post2.ref.uriStr, post1.ref.uriStr, post0.ref.uriStr]
|
|
52
|
+
nonTaggedResults = [post2.ref.uriStr, post0.ref.uriStr]
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
afterAll(async () => {
|
|
56
|
+
await deleteTags(network.bsky.db.db, {
|
|
57
|
+
uri: post1.ref.uriStr,
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
await network.close()
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe(`post search with 'top' sort`, () => {
|
|
64
|
+
type TestCase = {
|
|
65
|
+
name: string
|
|
66
|
+
viewer: () => string
|
|
67
|
+
queryParams: () => SearchPostsQueryParams
|
|
68
|
+
expectedPostUris: () => string[]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const tests: TestCase[] = [
|
|
72
|
+
// 'top' cases
|
|
73
|
+
{
|
|
74
|
+
name: `with 'top' sort, finds only non-tagged posts`,
|
|
75
|
+
viewer: () => carol,
|
|
76
|
+
queryParams: () => ({ q: 'doggo', sort: 'top' }),
|
|
77
|
+
expectedPostUris: () => nonTaggedResults,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: `with 'top' sort, includes tagged posts from the viewer`,
|
|
81
|
+
viewer: () => alice,
|
|
82
|
+
queryParams: () => ({ q: 'doggo', sort: 'top' }),
|
|
83
|
+
expectedPostUris: () => allResults,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: `with 'top' sort, finds only non-tagged posts, even specifying author`,
|
|
87
|
+
viewer: () => carol,
|
|
88
|
+
queryParams: () => ({ q: `doggo`, author: alice, sort: 'top' }),
|
|
89
|
+
expectedPostUris: () => nonTaggedResults,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: `with 'top' sort, finds only non-tagged posts, even specifying from:`,
|
|
93
|
+
viewer: () => carol,
|
|
94
|
+
queryParams: () => ({
|
|
95
|
+
q: `doggo from:${sc.accounts[alice].handle}`,
|
|
96
|
+
sort: 'top',
|
|
97
|
+
}),
|
|
98
|
+
expectedPostUris: () => nonTaggedResults,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: `with 'top' sort, finds only non-tagged posts, even specifying DID`,
|
|
102
|
+
viewer: () => carol,
|
|
103
|
+
queryParams: () => ({ q: `doggo ${alice}`, sort: 'top' }),
|
|
104
|
+
expectedPostUris: () => nonTaggedResults,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: `with 'top' sort, finds no posts if specifying user who didn't post the term`,
|
|
108
|
+
viewer: () => carol,
|
|
109
|
+
queryParams: () => ({ q: `doggo ${bob}`, sort: 'top' }),
|
|
110
|
+
expectedPostUris: () => [],
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
// 'latest' cases
|
|
114
|
+
{
|
|
115
|
+
name: `with 'latest' sort, finds only non-tagged posts`,
|
|
116
|
+
viewer: () => carol,
|
|
117
|
+
queryParams: () => ({ q: 'doggo', sort: 'latest' }),
|
|
118
|
+
expectedPostUris: () => nonTaggedResults,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: `with 'latest' sort, includes tagged posts from the viewer`,
|
|
122
|
+
viewer: () => alice,
|
|
123
|
+
queryParams: () => ({ q: 'doggo', sort: 'latest' }),
|
|
124
|
+
expectedPostUris: () => allResults,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: `with 'latest' sort, finds all posts if specifying author`,
|
|
128
|
+
viewer: () => carol,
|
|
129
|
+
queryParams: () => ({
|
|
130
|
+
q: `doggo`,
|
|
131
|
+
author: alice,
|
|
132
|
+
sort: 'latest',
|
|
133
|
+
}),
|
|
134
|
+
expectedPostUris: () => allResults,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: `with 'latest' sort, finds all posts if specifying from:`,
|
|
138
|
+
viewer: () => carol,
|
|
139
|
+
queryParams: () => ({
|
|
140
|
+
q: `doggo from:${sc.accounts[alice].handle}`,
|
|
141
|
+
sort: 'latest',
|
|
142
|
+
}),
|
|
143
|
+
expectedPostUris: () => allResults,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: `with 'latest' sort, finds all posts if specifying DID`,
|
|
147
|
+
viewer: () => carol,
|
|
148
|
+
queryParams: () => ({ q: `doggo ${alice}`, sort: 'latest' }),
|
|
149
|
+
expectedPostUris: () => allResults,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: `with 'latest' sort, finds no posts if specifying user who didn't post the term`,
|
|
153
|
+
viewer: () => carol,
|
|
154
|
+
queryParams: () => ({ q: `doggo ${bob}`, sort: 'latest' }),
|
|
155
|
+
expectedPostUris: () => [],
|
|
156
|
+
},
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
it.each(tests)(
|
|
160
|
+
'$name',
|
|
161
|
+
async ({ viewer, queryParams, expectedPostUris }) => {
|
|
162
|
+
const res = await agent.app.bsky.feed.searchPosts(queryParams(), {
|
|
163
|
+
headers: await network.serviceHeaders(
|
|
164
|
+
viewer(),
|
|
165
|
+
ids.AppBskyFeedSearchPosts,
|
|
166
|
+
),
|
|
167
|
+
})
|
|
168
|
+
expect(res.data.posts.map((p) => p.uri)).toStrictEqual(
|
|
169
|
+
expectedPostUris(),
|
|
170
|
+
)
|
|
171
|
+
},
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
it('mod service finds even tagged posts', async () => {
|
|
175
|
+
const resTop = await ozoneAgent.app.bsky.feed.searchPosts(
|
|
176
|
+
{ q: 'doggo', sort: 'top' },
|
|
177
|
+
{ headers: await network.ozone.modHeaders(ids.AppBskyFeedSearchPosts) },
|
|
178
|
+
)
|
|
179
|
+
const resLatest = await ozoneAgent.app.bsky.feed.searchPosts(
|
|
180
|
+
{ q: 'doggo', sort: 'latest' },
|
|
181
|
+
{ headers: await network.ozone.modHeaders(ids.AppBskyFeedSearchPosts) },
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
expect(resTop.data.posts.map((p) => p.uri)).toStrictEqual(allResults)
|
|
185
|
+
expect(resLatest.data.posts.map((p) => p.uri)).toStrictEqual(allResults)
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
const createTag = async (
|
|
191
|
+
db: DatabaseSchema,
|
|
192
|
+
opts: {
|
|
193
|
+
uri: string
|
|
194
|
+
val: string
|
|
195
|
+
},
|
|
196
|
+
) => {
|
|
197
|
+
await db
|
|
198
|
+
.updateTable('record')
|
|
199
|
+
.set({
|
|
200
|
+
tags: JSON.stringify([opts.val]),
|
|
201
|
+
})
|
|
202
|
+
.where('uri', '=', opts.uri)
|
|
203
|
+
.returningAll()
|
|
204
|
+
.execute()
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const deleteTags = async (
|
|
208
|
+
db: DatabaseSchema,
|
|
209
|
+
opts: {
|
|
210
|
+
uri: string
|
|
211
|
+
},
|
|
212
|
+
) => {
|
|
213
|
+
await db
|
|
214
|
+
.updateTable('record')
|
|
215
|
+
.set({
|
|
216
|
+
tags: JSON.stringify([]),
|
|
217
|
+
})
|
|
218
|
+
.where('uri', '=', opts.uri)
|
|
219
|
+
.returningAll()
|
|
220
|
+
.execute()
|
|
221
|
+
}
|
|
@@ -1108,16 +1108,11 @@ describe('appview thread views v2', () => {
|
|
|
1108
1108
|
await network.processAll()
|
|
1109
1109
|
})
|
|
1110
1110
|
|
|
1111
|
-
const threadForPostAndViewer = async (
|
|
1112
|
-
post: string,
|
|
1113
|
-
viewer: string,
|
|
1114
|
-
prioritizeFollowedUsers: boolean = false,
|
|
1115
|
-
) => {
|
|
1111
|
+
const threadForPostAndViewer = async (post: string, viewer: string) => {
|
|
1116
1112
|
const { data } = await agent.app.bsky.unspecced.getPostThreadV2(
|
|
1117
1113
|
{
|
|
1118
1114
|
anchor: post,
|
|
1119
1115
|
sort: 'newest',
|
|
1120
|
-
prioritizeFollowedUsers,
|
|
1121
1116
|
},
|
|
1122
1117
|
{
|
|
1123
1118
|
headers: await network.serviceHeaders(
|
|
@@ -1133,13 +1128,10 @@ describe('appview thread views v2', () => {
|
|
|
1133
1128
|
return t
|
|
1134
1129
|
}
|
|
1135
1130
|
|
|
1136
|
-
it('bumps up followed users
|
|
1137
|
-
const prioritizeFollowedUsers = true
|
|
1138
|
-
|
|
1131
|
+
it('bumps up followed users', async () => {
|
|
1139
1132
|
const t1 = await threadForPostAndViewer(
|
|
1140
1133
|
seed.root.ref.uriStr,
|
|
1141
1134
|
seed.users.viewerF.did,
|
|
1142
|
-
prioritizeFollowedUsers,
|
|
1143
1135
|
)
|
|
1144
1136
|
expect(t1).toEqual([
|
|
1145
1137
|
expect.objectContaining({ uri: seed.root.ref.uriStr }), // root
|
|
@@ -1154,7 +1146,6 @@ describe('appview thread views v2', () => {
|
|
|
1154
1146
|
const t2 = await threadForPostAndViewer(
|
|
1155
1147
|
seed.root.ref.uriStr,
|
|
1156
1148
|
seed.users.viewerNoF.did,
|
|
1157
|
-
prioritizeFollowedUsers,
|
|
1158
1149
|
)
|
|
1159
1150
|
expect(t2).toEqual([
|
|
1160
1151
|
expect.objectContaining({ uri: seed.root.ref.uriStr }), // root
|
|
@@ -1167,36 +1158,6 @@ describe('appview thread views v2', () => {
|
|
|
1167
1158
|
expect.objectContaining({ uri: seed.r['0'].ref.uriStr }),
|
|
1168
1159
|
])
|
|
1169
1160
|
})
|
|
1170
|
-
|
|
1171
|
-
it('does not prioritize followed users if option is not set', async () => {
|
|
1172
|
-
const t1 = await threadForPostAndViewer(
|
|
1173
|
-
seed.root.ref.uriStr,
|
|
1174
|
-
seed.users.viewerF.did,
|
|
1175
|
-
)
|
|
1176
|
-
expect(t1).toHaveLength(7)
|
|
1177
|
-
expect(t1[0].uri).toBe(seed.root.ref.uriStr) // root
|
|
1178
|
-
expect(t1[1].uri).toBe(seed.r['3'].ref.uriStr) // op reply
|
|
1179
|
-
expect(t1[2].uri).toBe(seed.r['4'].ref.uriStr) // viewer reply
|
|
1180
|
-
// newest to oldest
|
|
1181
|
-
expect(t1[3].uri).toBe(seed.r['5'].ref.uriStr)
|
|
1182
|
-
expect(t1[4].uri).toBe(seed.r['2'].ref.uriStr)
|
|
1183
|
-
expect(t1[5].uri).toBe(seed.r['1'].ref.uriStr)
|
|
1184
|
-
expect(t1[6].uri).toBe(seed.r['0'].ref.uriStr)
|
|
1185
|
-
|
|
1186
|
-
const t2 = await threadForPostAndViewer(
|
|
1187
|
-
seed.root.ref.uriStr,
|
|
1188
|
-
seed.users.viewerNoF.did,
|
|
1189
|
-
)
|
|
1190
|
-
expect(t2).toHaveLength(7)
|
|
1191
|
-
expect(t2[0].uri).toBe(seed.root.ref.uriStr) // root
|
|
1192
|
-
expect(t2[1].uri).toBe(seed.r['3'].ref.uriStr) // op reply
|
|
1193
|
-
expect(t2[2].uri).toBe(seed.r['5'].ref.uriStr) // viewer reply
|
|
1194
|
-
// newest to oldest
|
|
1195
|
-
expect(t2[3].uri).toBe(seed.r['4'].ref.uriStr)
|
|
1196
|
-
expect(t2[4].uri).toBe(seed.r['2'].ref.uriStr)
|
|
1197
|
-
expect(t2[5].uri).toBe(seed.r['1'].ref.uriStr)
|
|
1198
|
-
expect(t2[6].uri).toBe(seed.r['0'].ref.uriStr)
|
|
1199
|
-
})
|
|
1200
1161
|
})
|
|
1201
1162
|
})
|
|
1202
1163
|
})
|
|
@@ -1960,14 +1921,11 @@ describe('appview thread views v2', () => {
|
|
|
1960
1921
|
})
|
|
1961
1922
|
|
|
1962
1923
|
describe('when prioritizing followed users', () => {
|
|
1963
|
-
const prioritizeFollowedUsers = true
|
|
1964
|
-
|
|
1965
1924
|
it('considers tags for bumping down and hiding', async () => {
|
|
1966
1925
|
const { data } = await agent.app.bsky.unspecced.getPostThreadV2(
|
|
1967
1926
|
{
|
|
1968
1927
|
anchor: seed.root.ref.uriStr,
|
|
1969
1928
|
sort: 'newest',
|
|
1970
|
-
prioritizeFollowedUsers,
|
|
1971
1929
|
},
|
|
1972
1930
|
{
|
|
1973
1931
|
headers: await network.serviceHeaders(
|
|
@@ -2003,7 +1961,6 @@ describe('appview thread views v2', () => {
|
|
|
2003
1961
|
const { data } = await agent.app.bsky.unspecced.getPostThreadOtherV2(
|
|
2004
1962
|
{
|
|
2005
1963
|
anchor: seed.root.ref.uriStr,
|
|
2006
|
-
prioritizeFollowedUsers,
|
|
2007
1964
|
},
|
|
2008
1965
|
{
|
|
2009
1966
|
headers: await network.serviceHeaders(
|
|
@@ -2021,70 +1978,6 @@ describe('appview thread views v2', () => {
|
|
|
2021
1978
|
])
|
|
2022
1979
|
})
|
|
2023
1980
|
})
|
|
2024
|
-
|
|
2025
|
-
describe('when not prioritizing followed users', () => {
|
|
2026
|
-
const prioritizeFollowedUsers = false
|
|
2027
|
-
|
|
2028
|
-
it('considers tags for bumping down and hiding', async () => {
|
|
2029
|
-
const { data } = await agent.app.bsky.unspecced.getPostThreadV2(
|
|
2030
|
-
{
|
|
2031
|
-
anchor: seed.root.ref.uriStr,
|
|
2032
|
-
sort: 'newest',
|
|
2033
|
-
prioritizeFollowedUsers,
|
|
2034
|
-
},
|
|
2035
|
-
{
|
|
2036
|
-
headers: await network.serviceHeaders(
|
|
2037
|
-
seed.users.viewer.did,
|
|
2038
|
-
ids.AppBskyUnspeccedGetPostThreadV2,
|
|
2039
|
-
),
|
|
2040
|
-
},
|
|
2041
|
-
)
|
|
2042
|
-
const { thread: t, hasOtherReplies } = data
|
|
2043
|
-
|
|
2044
|
-
expect(hasOtherReplies).toBe(true)
|
|
2045
|
-
assertPosts(t)
|
|
2046
|
-
expect(t).toEqual([
|
|
2047
|
-
expect.objectContaining({ uri: seed.root.ref.uriStr }),
|
|
2048
|
-
// OP (down overridden).
|
|
2049
|
-
expect.objectContaining({ uri: seed.r['3'].ref.uriStr }),
|
|
2050
|
-
// Viewer (hide overriden).
|
|
2051
|
-
expect.objectContaining({ uri: seed.r['4'].ref.uriStr }),
|
|
2052
|
-
// Following was hidden because not prioritizing.
|
|
2053
|
-
// Not following.
|
|
2054
|
-
expect.objectContaining({ uri: seed.r['0'].ref.uriStr }),
|
|
2055
|
-
expect.objectContaining({ uri: seed.r['0.0'].ref.uriStr }),
|
|
2056
|
-
expect.objectContaining({ uri: seed.r['0.1'].ref.uriStr }),
|
|
2057
|
-
// Down.
|
|
2058
|
-
expect.objectContaining({ uri: seed.r['1'].ref.uriStr }),
|
|
2059
|
-
expect.objectContaining({ uri: seed.r['1.0'].ref.uriStr }),
|
|
2060
|
-
expect.objectContaining({ uri: seed.r['1.1'].ref.uriStr }),
|
|
2061
|
-
])
|
|
2062
|
-
})
|
|
2063
|
-
|
|
2064
|
-
it('finds the hidden by tag', async () => {
|
|
2065
|
-
const { data } = await agent.app.bsky.unspecced.getPostThreadOtherV2(
|
|
2066
|
-
{
|
|
2067
|
-
anchor: seed.root.ref.uriStr,
|
|
2068
|
-
prioritizeFollowedUsers,
|
|
2069
|
-
},
|
|
2070
|
-
{
|
|
2071
|
-
headers: await network.serviceHeaders(
|
|
2072
|
-
seed.users.viewer.did,
|
|
2073
|
-
ids.AppBskyUnspeccedGetPostThreadOtherV2,
|
|
2074
|
-
),
|
|
2075
|
-
},
|
|
2076
|
-
)
|
|
2077
|
-
const { thread: t } = data
|
|
2078
|
-
|
|
2079
|
-
assertHiddenPosts(t)
|
|
2080
|
-
expect(t).toEqual([
|
|
2081
|
-
// Following (hide).
|
|
2082
|
-
expect.objectContaining({ uri: seed.r['5'].ref.uriStr }),
|
|
2083
|
-
// Hide.
|
|
2084
|
-
expect.objectContaining({ uri: seed.r['2'].ref.uriStr }),
|
|
2085
|
-
])
|
|
2086
|
-
})
|
|
2087
|
-
})
|
|
2088
1981
|
})
|
|
2089
1982
|
})
|
|
2090
1983
|
|