Merge branch 'main' of github.com:bluesky-social/social-app into main
commit
8d32f3de37
|
@ -34,6 +34,9 @@ async function main() {
|
||||||
displayName: 'Carla',
|
displayName: 'Carla',
|
||||||
description: 'Test user 3',
|
description: 'Test user 3',
|
||||||
}))
|
}))
|
||||||
|
if (inviteRequired) {
|
||||||
|
await server.mocker.createInvite(server.mocker.users.alice.did)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ('follows' in url.query) {
|
if ('follows' in url.query) {
|
||||||
console.log('Generating mock follows')
|
console.log('Generating mock follows')
|
||||||
|
|
122
jest/test-pds.ts
122
jest/test-pds.ts
|
@ -1,20 +1,9 @@
|
||||||
import {AddressInfo} from 'net'
|
|
||||||
import os from 'os'
|
|
||||||
import net from 'net'
|
import net from 'net'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import * as crypto from '@atproto/crypto'
|
import {TestPds as DevEnvTestPDS, TestNetworkNoAppView} from '@atproto/dev-env'
|
||||||
import {PDS, ServerConfig, Database, MemoryBlobStore} from '@atproto/pds'
|
|
||||||
import * as plc from '@did-plc/lib'
|
|
||||||
import {PlcServer, Database as PlcDatabase} from '@did-plc/server'
|
|
||||||
import {BskyAgent} from '@atproto/api'
|
import {BskyAgent} from '@atproto/api'
|
||||||
|
|
||||||
const ADMIN_PASSWORD = 'admin-pass'
|
|
||||||
const SECOND = 1000
|
|
||||||
const MINUTE = SECOND * 60
|
|
||||||
const HOUR = MINUTE * 60
|
|
||||||
const DAY = HOUR * 24
|
|
||||||
|
|
||||||
export interface TestUser {
|
export interface TestUser {
|
||||||
email: string
|
email: string
|
||||||
did: string
|
did: string
|
||||||
|
@ -32,81 +21,13 @@ export interface TestPDS {
|
||||||
export async function createServer(
|
export async function createServer(
|
||||||
{inviteRequired}: {inviteRequired: boolean} = {inviteRequired: false},
|
{inviteRequired}: {inviteRequired: boolean} = {inviteRequired: false},
|
||||||
): Promise<TestPDS> {
|
): Promise<TestPDS> {
|
||||||
const repoSigningKey = await crypto.Secp256k1Keypair.create()
|
|
||||||
const plcRotationKey = await crypto.Secp256k1Keypair.create()
|
|
||||||
const port = await getPort()
|
const port = await getPort()
|
||||||
|
const port2 = await getPort(port + 1)
|
||||||
const plcDb = PlcDatabase.mock()
|
|
||||||
|
|
||||||
const plcServer = PlcServer.create({db: plcDb})
|
|
||||||
const plcListener = await plcServer.start()
|
|
||||||
const plcPort = (plcListener.address() as AddressInfo).port
|
|
||||||
const plcUrl = `http://localhost:${plcPort}`
|
|
||||||
|
|
||||||
const recoveryKey = (await crypto.Secp256k1Keypair.create()).did()
|
|
||||||
|
|
||||||
const plcClient = new plc.Client(plcUrl)
|
|
||||||
const serverDid = await plcClient.createDid({
|
|
||||||
signingKey: repoSigningKey.did(),
|
|
||||||
rotationKeys: [recoveryKey, plcRotationKey.did()],
|
|
||||||
handle: 'localhost',
|
|
||||||
pds: `http://localhost:${port}`,
|
|
||||||
signer: plcRotationKey,
|
|
||||||
})
|
|
||||||
|
|
||||||
const blobstoreLoc = path.join(os.tmpdir(), crypto.randomStr(5, 'base32'))
|
|
||||||
|
|
||||||
const cfg = new ServerConfig({
|
|
||||||
debugMode: true,
|
|
||||||
version: '0.0.0',
|
|
||||||
scheme: 'http',
|
|
||||||
hostname: 'localhost',
|
|
||||||
port,
|
|
||||||
serverDid,
|
|
||||||
recoveryKey,
|
|
||||||
adminPassword: ADMIN_PASSWORD,
|
|
||||||
inviteRequired,
|
|
||||||
didPlcUrl: plcUrl,
|
|
||||||
didCacheMaxTTL: DAY,
|
|
||||||
didCacheStaleTTL: HOUR,
|
|
||||||
jwtSecret: 'jwt-secret',
|
|
||||||
availableUserDomains: ['.test'],
|
|
||||||
appUrlPasswordReset: 'app://forgot-password',
|
|
||||||
emailNoReplyAddress: 'noreply@blueskyweb.xyz',
|
|
||||||
publicUrl: `http://localhost:${port}`,
|
|
||||||
imgUriSalt: '9dd04221f5755bce5f55f47464c27e1e',
|
|
||||||
imgUriKey:
|
|
||||||
'f23ecd142835025f42c3db2cf25dd813956c178392760256211f9d315f8ab4d8',
|
|
||||||
dbPostgresUrl: process.env.DB_POSTGRES_URL,
|
|
||||||
blobstoreLocation: `${blobstoreLoc}/blobs`,
|
|
||||||
blobstoreTmp: `${blobstoreLoc}/tmp`,
|
|
||||||
maxSubscriptionBuffer: 200,
|
|
||||||
repoBackfillLimitMs: HOUR,
|
|
||||||
userInviteInterval: 1,
|
|
||||||
labelerDid: 'did:example:labeler',
|
|
||||||
labelerKeywords: {},
|
|
||||||
})
|
|
||||||
|
|
||||||
const db =
|
|
||||||
cfg.dbPostgresUrl !== undefined
|
|
||||||
? Database.postgres({
|
|
||||||
url: cfg.dbPostgresUrl,
|
|
||||||
schema: cfg.dbPostgresSchema,
|
|
||||||
})
|
|
||||||
: Database.memory()
|
|
||||||
await db.migrateToLatestOrThrow()
|
|
||||||
|
|
||||||
const blobstore = new MemoryBlobStore()
|
|
||||||
|
|
||||||
const pds = PDS.create({
|
|
||||||
db,
|
|
||||||
blobstore,
|
|
||||||
repoSigningKey,
|
|
||||||
plcRotationKey,
|
|
||||||
config: cfg,
|
|
||||||
})
|
|
||||||
await pds.start()
|
|
||||||
const pdsUrl = `http://localhost:${port}`
|
const pdsUrl = `http://localhost:${port}`
|
||||||
|
const {pds, plc} = await TestNetworkNoAppView.create({
|
||||||
|
pds: {port, publicUrl: pdsUrl, inviteRequired},
|
||||||
|
plc: {port: port2},
|
||||||
|
})
|
||||||
|
|
||||||
const profilePic = fs.readFileSync(
|
const profilePic = fs.readFileSync(
|
||||||
path.join(__dirname, '..', 'assets', 'default-avatar.jpg'),
|
path.join(__dirname, '..', 'assets', 'default-avatar.jpg'),
|
||||||
|
@ -116,8 +37,8 @@ export async function createServer(
|
||||||
pdsUrl,
|
pdsUrl,
|
||||||
mocker: new Mocker(pds, pdsUrl, profilePic),
|
mocker: new Mocker(pds, pdsUrl, profilePic),
|
||||||
async close() {
|
async close() {
|
||||||
await pds.destroy()
|
await pds.server.destroy()
|
||||||
await plcServer.destroy()
|
await plc.server.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +48,7 @@ class Mocker {
|
||||||
users: Record<string, TestUser> = {}
|
users: Record<string, TestUser> = {}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public pds: PDS,
|
public pds: DevEnvTestPDS,
|
||||||
public service: string,
|
public service: string,
|
||||||
public profilePic: Uint8Array,
|
public profilePic: Uint8Array,
|
||||||
) {
|
) {
|
||||||
|
@ -152,7 +73,11 @@ class Mocker {
|
||||||
const inviteRes = await agent.api.com.atproto.server.createInviteCode(
|
const inviteRes = await agent.api.com.atproto.server.createInviteCode(
|
||||||
{useCount: 1},
|
{useCount: 1},
|
||||||
{
|
{
|
||||||
headers: {authorization: `Basic ${btoa(`admin:${ADMIN_PASSWORD}`)}`},
|
headers: {
|
||||||
|
authorization: `Basic ${btoa(
|
||||||
|
`admin:${this.pds.ctx.cfg.adminPassword}`,
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
encoding: 'application/json',
|
encoding: 'application/json',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -265,6 +190,21 @@ class Mocker {
|
||||||
return await agent.like(uri, cid)
|
return await agent.like(uri, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async createInvite(forAccount: string) {
|
||||||
|
const agent = new BskyAgent({service: this.agent.service})
|
||||||
|
await agent.api.com.atproto.server.createInviteCode(
|
||||||
|
{useCount: 1, forAccount},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
authorization: `Basic ${btoa(
|
||||||
|
`admin:${this.pds.ctx.cfg.adminPassword}`,
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
encoding: 'application/json',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async labelAccount(label: string, user: string) {
|
async labelAccount(label: string, user: string) {
|
||||||
const did = this.users[user]?.did
|
const did = this.users[user]?.did
|
||||||
if (!did) {
|
if (!did) {
|
||||||
|
@ -380,8 +320,8 @@ const checkAvailablePort = (port: number) =>
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
async function getPort() {
|
async function getPort(start = 3000) {
|
||||||
for (let i = 3000; i < 65000; i++) {
|
for (let i = start; i < 65000; i++) {
|
||||||
if (await checkAvailablePort(i)) {
|
if (await checkAvailablePort(i)) {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,8 @@
|
||||||
"zod": "^3.20.2"
|
"zod": "^3.20.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@atproto/pds": "^0.1.10",
|
"@atproto/dev-env": "^0.2.2",
|
||||||
|
"@atproto/pds": "^0.2.0-beta.2",
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
"@babel/preset-env": "^7.20.0",
|
"@babel/preset-env": "^7.20.0",
|
||||||
"@babel/runtime": "^7.20.0",
|
"@babel/runtime": "^7.20.0",
|
||||||
|
|
|
@ -25,7 +25,8 @@ export const ListActions = ({
|
||||||
|
|
||||||
let buttons = [
|
let buttons = [
|
||||||
<Button
|
<Button
|
||||||
key="subscribeButton"
|
key="subscribeListBtn"
|
||||||
|
testID={muted ? 'unsubscribeListBtn' : 'subscribeListBtn'}
|
||||||
type={muted ? 'inverted' : 'primary'}
|
type={muted ? 'inverted' : 'primary'}
|
||||||
label={muted ? 'Unsubscribe' : 'Subscribe & Mute'}
|
label={muted ? 'Unsubscribe' : 'Subscribe & Mute'}
|
||||||
accessibilityLabel={muted ? 'Unsubscribe' : 'Subscribe and mute'}
|
accessibilityLabel={muted ? 'Unsubscribe' : 'Subscribe and mute'}
|
||||||
|
@ -34,7 +35,8 @@ export const ListActions = ({
|
||||||
/>,
|
/>,
|
||||||
isOwner && (
|
isOwner && (
|
||||||
<Button
|
<Button
|
||||||
key="editListButton"
|
key="editListBtn"
|
||||||
|
testID="editListBtn"
|
||||||
type="default"
|
type="default"
|
||||||
label="Edit List"
|
label="Edit List"
|
||||||
accessibilityLabel="Edit list"
|
accessibilityLabel="Edit list"
|
||||||
|
@ -44,9 +46,9 @@ export const ListActions = ({
|
||||||
),
|
),
|
||||||
isOwner && (
|
isOwner && (
|
||||||
<Button
|
<Button
|
||||||
key="deleteListButton"
|
key="deleteListBtn"
|
||||||
type="default"
|
|
||||||
testID="deleteListBtn"
|
testID="deleteListBtn"
|
||||||
|
type="default"
|
||||||
accessibilityLabel="Delete list"
|
accessibilityLabel="Delete list"
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
onPress={onPressDeleteList}>
|
onPress={onPressDeleteList}>
|
||||||
|
@ -54,9 +56,9 @@ export const ListActions = ({
|
||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
<Button
|
<Button
|
||||||
key="shareListButton"
|
key="shareListBtn"
|
||||||
type="default"
|
|
||||||
testID="shareListBtn"
|
testID="shareListBtn"
|
||||||
|
type="default"
|
||||||
accessibilityLabel="Share list"
|
accessibilityLabel="Share list"
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
onPress={onPressShareList}>
|
onPress={onPressShareList}>
|
||||||
|
|
Loading…
Reference in New Issue