From 1dd50e2e63452121a02bd00f7e5ca74ee0a4b234 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 15 Mar 2025 14:38:19 -0500 Subject: [PATCH] Add tests for pleromaStatusesRoute --- .../ditto/routes/pleromaStatusesRoute.test.ts | 56 +++++++++++++++++++ packages/ditto/routes/pleromaStatusesRoute.ts | 9 +-- packages/mastoapi/test/TestApp.ts | 12 +++- 3 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 packages/ditto/routes/pleromaStatusesRoute.test.ts diff --git a/packages/ditto/routes/pleromaStatusesRoute.test.ts b/packages/ditto/routes/pleromaStatusesRoute.test.ts new file mode 100644 index 00000000..09217e88 --- /dev/null +++ b/packages/ditto/routes/pleromaStatusesRoute.test.ts @@ -0,0 +1,56 @@ +import { DittoConf } from '@ditto/conf'; +import { DittoPolyPg } from '@ditto/db'; +import { TestApp } from '@ditto/mastoapi/test'; +import { genEvent, MockRelay } from '@nostrify/nostrify/test'; +import { assertEquals } from '@std/assert'; + +import { DittoPgStore } from '@/storages/DittoPgStore.ts'; +import { DittoRelayStore } from '@/storages/DittoRelayStore.ts'; + +import route from './pleromaStatusesRoute.ts'; + +Deno.test('Emoji reactions', async (t) => { + await using test = createTestApp(); + const { relay } = test.var; + + test.user(); + + const note = genEvent({ kind: 1 }); + await relay.event(note); + + await t.step('PUT /:id/reactions/:emoji', async () => { + const response = await test.api.put(`/${note.id}/reactions/🚀`); + const json = await response.json(); + + assertEquals(response.status, 200); + assertEquals(json.pleroma.emoji_reactions, [{ name: '🚀', me: true, count: 1 }]); + }); + + await t.step('GET /:id/reactions', async () => { + const response = await test.api.get(`/${note.id}/reactions`); + const json = await response.json(); + const [{ accounts }] = json; + + assertEquals(response.status, 200); + assertEquals(json, [{ name: '🚀', me: true, count: 1, accounts }]); + }); + + await t.step('DELETE /:id/reactions/:emoji', async () => { + const response = await test.api.delete(`/${note.id}/reactions/🚀`); + const json = await response.json(); + + assertEquals(response.status, 200); + assertEquals(json.pleroma.emoji_reactions, []); + }); +}); + +// TODO: modify `TestApp` itself to avoid this boilerplate. +function createTestApp(): TestApp { + const conf = new DittoConf(Deno.env); + const db = new DittoPolyPg(conf.databaseUrl); + const pool = new MockRelay(); + const store = new DittoPgStore({ conf, db }); + const relay = new DittoRelayStore({ conf, db, pool, relay: store }); + + return new TestApp(route, { conf, db, relay }); +} diff --git a/packages/ditto/routes/pleromaStatusesRoute.ts b/packages/ditto/routes/pleromaStatusesRoute.ts index 0daa497c..d3a5d6a4 100644 --- a/packages/ditto/routes/pleromaStatusesRoute.ts +++ b/packages/ditto/routes/pleromaStatusesRoute.ts @@ -60,7 +60,7 @@ route.put('/:id{[0-9a-f]{64}}/reactions/:emoji', userMiddleware(), async (c) => */ route.delete('/:id{[0-9a-f]{64}}/reactions/:emoji', userMiddleware(), async (c) => { const { id, emoji } = c.req.param(); - const { relay, user } = c.var; + const { relay, user, signal } = c.var; const pubkey = await user.signer.getPublicKey(); @@ -68,9 +68,7 @@ route.delete('/:id{[0-9a-f]{64}}/reactions/:emoji', userMiddleware(), async (c) return c.json({ error: 'Invalid emoji' }, 400); } - const [event] = await relay.query([ - { kinds: [1, 20], ids: [id], limit: 1 }, - ]); + const [event] = await relay.query([{ ids: [id] }], { signal }); if (!event) { return c.json({ error: 'Status not found' }, 404); @@ -91,8 +89,7 @@ route.delete('/:id{[0-9a-f]{64}}/reactions/:emoji', userMiddleware(), async (c) tags, }, c); - const status = renderStatus(relay, event, { viewerPubkey: pubkey }); - + const status = await renderStatus(relay, event, { viewerPubkey: pubkey }); return c.json(status); }); diff --git a/packages/mastoapi/test/TestApp.ts b/packages/mastoapi/test/TestApp.ts index a12f48a4..14b8e802 100644 --- a/packages/mastoapi/test/TestApp.ts +++ b/packages/mastoapi/test/TestApp.ts @@ -110,9 +110,19 @@ export class TestApp extends DittoApp implements AsyncDisposable { return await this.request(path, { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(body), + body: body ? JSON.stringify(body) : undefined, }); }, + put: async (path: string, body?: unknown): Promise => { + return await this.request(path, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: body ? JSON.stringify(body) : undefined, + }); + }, + delete: async (path: string): Promise => { + return await this.request(path, { method: 'DELETE' }); + }, }; async [Symbol.asyncDispose](): Promise {