[READ-ONLY] Mirror of https://github.com/flo-bit/atproto-notify.
2.9 kB
93 lines
1import type { Did } from '@atcute/lexicons';
2import { createExecutionContext, env, waitOnExecutionContext } from 'cloudflare:test';
3import { beforeAll, expect, it } from 'vitest';
4
5import * as q from '../src/db/queries';
6import worker from '../src/index';
7
8import { installFetchMock, makeIdentity, makeJwt, mockPlc, mockTelegramOk, xrpcPost } from './helpers';
9
10beforeAll(() => {
11 installFetchMock();
12 mockTelegramOk();
13});
14
15const SEND = 'tools.atmo.notifs.send';
16const RECIPIENT: Did = 'did:plc:sendrecipient';
17
18async function call(req: Request): Promise<Response> {
19 const ctx = createExecutionContext();
20 const res = await worker.fetch(req, env, ctx);
21 await waitOnExecutionContext(ctx);
22 return res;
23}
24
25function send(jwt: string): Request {
26 return xrpcPost(SEND, jwt, { recipient: RECIPIENT, title: 'Hello', body: 'World' });
27}
28
29it('returns 403 when no grant exists', async () => {
30 const sender = await makeIdentity('did:plc:sendnogrant');
31 mockPlc(sender);
32 const jwt = await makeJwt(sender, { lxm: SEND });
33
34 const res = await call(send(jwt));
35
36 expect(res.status).toBe(403);
37});
38
39it('accepts but delivers to nobody when there is a grant but no channel', async () => {
40 const sender = await makeIdentity('did:plc:sendnochannel');
41 mockPlc(sender);
42 await q.upsertGrant(env.DB, RECIPIENT, sender.did, Date.now());
43 const jwt = await makeJwt(sender, { lxm: SEND });
44
45 const res = await call(send(jwt));
46
47 expect(res.status).toBe(200);
48 expect(await res.json()).toMatchObject({ delivered: 0 });
49});
50
51it('enqueues and reports delivered=1 with a linked channel', async () => {
52 const sender = await makeIdentity('did:plc:sendchannel');
53 mockPlc(sender);
54 await q.upsertGrant(env.DB, RECIPIENT, sender.did, Date.now());
55 await q.upsertChannel(env.DB, {
56 did: RECIPIENT,
57 platform: 'telegram',
58 platformUserId: '12345',
59 displayName: null,
60 linkedAt: Date.now(),
61 });
62 const jwt = await makeJwt(sender, { lxm: SEND });
63
64 const res = await call(send(jwt));
65
66 expect(res.status).toBe(200);
67 expect(await res.json()).toMatchObject({ delivered: 1 });
68
69 const log = await env.DB.prepare('SELECT delivered_count FROM delivery_log WHERE recipient_did = ?')
70 .bind(RECIPIENT)
71 .first<{ delivered_count: number }>();
72 expect(log?.delivered_count).toBe(1);
73});
74
75it('accepts silently with delivered=0 when the grant is muted', async () => {
76 const sender = await makeIdentity('did:plc:sendmuted');
77 mockPlc(sender);
78 await q.upsertGrant(env.DB, RECIPIENT, sender.did, Date.now());
79 await q.setGrantMuted(env.DB, RECIPIENT, sender.did, true);
80 await q.upsertChannel(env.DB, {
81 did: RECIPIENT,
82 platform: 'telegram',
83 platformUserId: '54321',
84 displayName: null,
85 linkedAt: Date.now(),
86 });
87 const jwt = await makeJwt(sender, { lxm: SEND });
88
89 const res = await call(send(jwt));
90
91 expect(res.status).toBe(200);
92 expect(await res.json()).toMatchObject({ delivered: 0 });
93});