task-loop-rrule-validator.test.mjs
74 lines 2.2 KB
Raw
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor ⚠ breaking 10 days ago
1 /**
2 * Tier 1 — UNIT: RRULE subset validator accept/reject matrix.
3 */
4 import { describe, it } from 'node:test';
5 import assert from 'node:assert/strict';
6 import { TASK_LOOP_RRULE_ENABLED, validateTaskLoopRrule } from '../lib/task/task-loop-rrule.mjs';
7
8 const SERIES_TZ = 'America/Los_Angeles';
9
10 const VALID_WEEKLY = {
11 kind: 'rrule',
12 rrule: 'FREQ=WEEKLY;BYDAY=MO',
13 dtstart: '2026-06-02T16:00:00Z',
14 anchor_tz: SERIES_TZ,
15 };
16
17 describe('Task loop RRULE — posture', () => {
18 it('TASK_LOOP_RRULE_ENABLED is true after Tier 3 BUNDLED_2G_LIVE 2026-06-25', () => {
19 assert.equal(TASK_LOOP_RRULE_ENABLED, true);
20 });
21 });
22
23 describe('Task loop RRULE — validator accept matrix', () => {
24 it('accepts school-trip weekly RRULE fixture', () => {
25 const result = validateTaskLoopRrule(VALID_WEEKLY, SERIES_TZ);
26 assert.equal(result.ok, true);
27 if (result.ok) {
28 assert.equal(result.recurrence.kind, 'rrule');
29 }
30 });
31
32 it('accepts optional exdates when unique and ISO8601', () => {
33 const result = validateTaskLoopRrule(
34 {
35 ...VALID_WEEKLY,
36 exdates: ['2026-06-09T16:00:00Z'],
37 },
38 SERIES_TZ,
39 );
40 assert.equal(result.ok, true);
41 });
42 });
43
44 describe('Task loop RRULE — validator reject matrix', () => {
45 it('requires DTSTART', () => {
46 const result = validateTaskLoopRrule({ ...VALID_WEEKLY, dtstart: '' }, SERIES_TZ);
47 assert.equal(result.ok, false);
48 if (!result.ok) assert.equal(result.detail, 'dtstart');
49 });
50
51 it('rejects timezone mismatch', () => {
52 const result = validateTaskLoopRrule(VALID_WEEKLY, 'UTC');
53 assert.equal(result.ok, false);
54 if (!result.ok) assert.equal(result.detail, 'timezone_mismatch');
55 });
56
57 it('rejects unsupported FREQ token', () => {
58 const result = validateTaskLoopRrule(
59 { ...VALID_WEEKLY, rrule: 'FREQ=HOURLY' },
60 SERIES_TZ,
61 );
62 assert.equal(result.ok, false);
63 if (!result.ok) assert.equal(result.detail, 'FREQ');
64 });
65
66 it('rejects BYSETPOS in v0 subset', () => {
67 const result = validateTaskLoopRrule(
68 { ...VALID_WEEKLY, rrule: 'FREQ=WEEKLY;BYDAY=MO;BYSETPOS=1' },
69 SERIES_TZ,
70 );
71 assert.equal(result.ok, false);
72 if (!result.ok) assert.equal(result.detail, 'BYSETPOS');
73 });
74 });
File History 1 commit
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor 10 days ago