[READ-ONLY] Mirror of https://github.com/flo-bit/atproto-notify.
1.7 kB
41 lines
1import type { Did } from '@atcute/lexicons';
2import { env } from 'cloudflare:test';
3import { expect, it } from 'vitest';
4
5import { channelLimit, withinChannelLimits } from '../src/delivery/limits';
6
7it('email is capped; push/telegram/dm/webhook are not', () => {
8 const email = channelLimit(env, 'email');
9 expect(email?.perRecipientPerDay).toBeGreaterThan(0);
10 expect(email?.globalPerDay).toBeGreaterThan(0);
11 for (const c of ['push', 'telegram', 'dm', 'webhook'] as const) {
12 expect(channelLimit(env, c)).toBeUndefined();
13 }
14});
15
16it('uncapped channels always pass and never limit', async () => {
17 const did: Did = 'did:plc:limits-push';
18 for (let i = 0; i < 50; i++) {
19 expect(await withinChannelLimits(env, 'push', did)).toBe(true);
20 }
21});
22
23it('email caps per recipient per day, independently per recipient', async () => {
24 const a: Did = 'did:plc:limits-emailA';
25 const b: Did = 'did:plc:limits-emailB';
26 const perRecipient = channelLimit(env, 'email')!.perRecipientPerDay!;
27 // Isolate the per-recipient cap from the relay-global cap: raise the global so
28 // A exhausting its own budget can't also drain the shared global budget (which
29 // would block B for the wrong reason). Tests the per-recipient dimension only.
30 env.EMAIL_DAILY_GLOBAL = String(perRecipient * 100);
31
32 // A can receive up to the per-recipient cap…
33 for (let i = 0; i < perRecipient; i++) {
34 expect(await withinChannelLimits(env, 'email', a)).toBe(true);
35 }
36 // …the next email to A is blocked.
37 expect(await withinChannelLimits(env, 'email', a)).toBe(false);
38
39 // B has its own budget — unaffected by A hitting the cap.
40 expect(await withinChannelLimits(env, 'email', b)).toBe(true);
41});