MOW-105: regenerate home timeline after post

pull/114/head
Sven Sauleau 2023-01-16 19:05:45 +00:00
rodzic f87cd4ba31
commit fe547a7cb7
3 zmienionych plików z 55 dodań i 10 usunięć

Wyświetl plik

@ -20,6 +20,9 @@ import { MessageType } from 'wildebeest/backend/src/types/queue'
const userKEK = 'test_kek4' const userKEK = 'test_kek4'
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)) const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))
const domain = 'cloudflare.com' const domain = 'cloudflare.com'
const kv_cache: any = {
async put() {},
}
describe('Mastodon APIs', () => { describe('Mastodon APIs', () => {
describe('statuses', () => { describe('statuses', () => {
@ -35,7 +38,7 @@ describe('Mastodon APIs', () => {
}) })
const connectedActor: any = {} const connectedActor: any = {}
const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue) const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue, kv_cache)
assert.equal(res.status, 400) assert.equal(res.status, 400)
}) })
@ -55,7 +58,7 @@ describe('Mastodon APIs', () => {
}) })
const connectedActor = actor const connectedActor = actor
const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue) const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue, kv_cache)
assert.equal(res.status, 200) assert.equal(res.status, 200)
assertJSON(res) assertJSON(res)
@ -89,6 +92,41 @@ describe('Mastodon APIs', () => {
assert.equal(row.original_object_id, null) assert.equal(row.original_object_id, null)
}) })
test('create new status regenerates the timeline and contains post', async () => {
const db = await makeDB()
const queue = makeQueue()
const actor = await createPerson(domain, db, userKEK, 'sven@cloudflare.com')
let cache = null
const kv_cache: any = {
async put(key: string, value: any) {
assert.equal(key, actor.id + '/timeline/home')
cache = value
},
}
const body = {
status: 'my status',
visibility: 'public',
}
const req = new Request('https://example.com', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(body),
})
const res = await statuses.handleRequest(req, db, actor, userKEK, queue, kv_cache)
assert.equal(res.status, 200)
assertJSON(res)
const data = await res.json<any>()
assert(cache)
const timeline = JSON.parse(cache)
assert.equal(timeline.length, 1)
assert.equal(timeline[0].id, data.id)
})
test("create new status adds to Actor's outbox", async () => { test("create new status adds to Actor's outbox", async () => {
const db = await makeDB() const db = await makeDB()
const queue = makeQueue() const queue = makeQueue()
@ -105,7 +143,7 @@ describe('Mastodon APIs', () => {
}) })
const connectedActor = actor const connectedActor = actor
const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue) const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue, kv_cache)
assert.equal(res.status, 200) assert.equal(res.status, 200)
const row = await db.prepare(`SELECT count(*) as count FROM outbox_objects`).first() const row = await db.prepare(`SELECT count(*) as count FROM outbox_objects`).first()
@ -133,7 +171,7 @@ describe('Mastodon APIs', () => {
body: JSON.stringify(body), body: JSON.stringify(body),
}) })
const res = await statuses.handleRequest(req, db, actor, userKEK, queue) const res = await statuses.handleRequest(req, db, actor, userKEK, queue, kv_cache)
assert.equal(res.status, 200) assert.equal(res.status, 200)
assert.equal(queue.messages.length, 2) assert.equal(queue.messages.length, 2)
@ -212,7 +250,7 @@ describe('Mastodon APIs', () => {
}) })
const connectedActor = actor const connectedActor = actor
const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue) const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue, kv_cache)
assert.equal(res.status, 200) assert.equal(res.status, 200)
assert(deliveredNote) assert(deliveredNote)
@ -229,7 +267,7 @@ describe('Mastodon APIs', () => {
const queue = makeQueue() const queue = makeQueue()
const connectedActor = await createPerson(domain, db, userKEK, 'sven@cloudflare.com') const connectedActor = await createPerson(domain, db, userKEK, 'sven@cloudflare.com')
const properties = { url: 'foo' } const properties = { url: 'https://example.com/image.jpg' }
const image = await createImage(domain, db, connectedActor, properties) const image = await createImage(domain, db, connectedActor, properties)
const body = { const body = {
@ -243,7 +281,7 @@ describe('Mastodon APIs', () => {
body: JSON.stringify(body), body: JSON.stringify(body),
}) })
const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue) const res = await statuses.handleRequest(req, db, connectedActor, userKEK, queue, kv_cache)
assert.equal(res.status, 200) assert.equal(res.status, 200)
const data = await res.json<any>() const data = await res.json<any>()

Wyświetl plik

@ -9,6 +9,9 @@ const queue = {
async send() {}, async send() {},
async sendBatch() {}, async sendBatch() {},
} }
const kv_cache: any = {
async put() {},
}
/** /**
* Run helper commands to initialize the database with actors, statuses, etc. * Run helper commands to initialize the database with actors, statuses, etc.
*/ */
@ -43,7 +46,7 @@ async function createStatus(db: D1Database, actor: Person, status: string, visib
headers, headers,
body: JSON.stringify(body), body: JSON.stringify(body),
}) })
const resp = await statusesAPI.handleRequest(req, db, actor, kek, queue) const resp = await statusesAPI.handleRequest(req, db, actor, kek, queue, kv_cache)
return (await resp.json()) as MastodonStatus return (await resp.json()) as MastodonStatus
} }

Wyświetl plik

@ -1,4 +1,5 @@
// https://docs.joinmastodon.org/methods/statuses/#create // https://docs.joinmastodon.org/methods/statuses/#create
import * as timeline from 'wildebeest/backend/src/mastodon/timeline'
import type { Queue, DeliverMessageBody } from 'wildebeest/backend/src/types/queue' import type { Queue, DeliverMessageBody } from 'wildebeest/backend/src/types/queue'
import { loadLocalMastodonAccount } from 'wildebeest/backend/src/mastodon/account' import { loadLocalMastodonAccount } from 'wildebeest/backend/src/mastodon/account'
import { createPublicNote } from 'wildebeest/backend/src/activitypub/objects/note' import { createPublicNote } from 'wildebeest/backend/src/activitypub/objects/note'
@ -23,7 +24,7 @@ type StatusCreate = {
} }
export const onRequest: PagesFunction<Env, any, ContextData> = async ({ request, env, data }) => { export const onRequest: PagesFunction<Env, any, ContextData> = async ({ request, env, data }) => {
return handleRequest(request, env.DATABASE, data.connectedActor, env.userKEK, env.QUEUE) return handleRequest(request, env.DATABASE, data.connectedActor, env.userKEK, env.QUEUE, env.KV_CACHE)
} }
// FIXME: add tests for delivery to followers and mentions to a specific Actor. // FIXME: add tests for delivery to followers and mentions to a specific Actor.
@ -32,7 +33,8 @@ export async function handleRequest(
db: D1Database, db: D1Database,
connectedActor: Person, connectedActor: Person,
userKEK: string, userKEK: string,
queue: Queue<DeliverMessageBody> queue: Queue<DeliverMessageBody>,
cache: KVNamespace
): Promise<Response> { ): Promise<Response> {
// TODO: implement Idempotency-Key // TODO: implement Idempotency-Key
@ -89,6 +91,8 @@ export async function handleRequest(
} }
} }
await timeline.pregenerateTimelines(domain, db, cache, connectedActor)
const account = await loadLocalMastodonAccount(db, connectedActor) const account = await loadLocalMastodonAccount(db, connectedActor)
const res: any = { const res: any = {