@remit/mailbox-service 0.0.108 → 0.0.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -7,20 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
import assert from "node:assert/strict";
|
|
9
9
|
import { describe, it } from "node:test";
|
|
10
|
+
import { MemoryCalendarStore } from "@remit/calendar-service/memory-store";
|
|
10
11
|
import type {
|
|
11
12
|
CalendarSuggestionItem,
|
|
12
13
|
FilterItem,
|
|
13
14
|
IAddressRepository,
|
|
14
|
-
ICalendarSuggestionRepository,
|
|
15
15
|
ICalendarUnitOfWork,
|
|
16
16
|
IEnvelopeRepository,
|
|
17
17
|
IFilterRepository,
|
|
18
18
|
IMessageRepository,
|
|
19
19
|
IThreadMessageRepository,
|
|
20
|
-
PutCalendarSuggestionInput,
|
|
21
|
-
ResultList,
|
|
22
20
|
} from "@remit/data-ports";
|
|
23
|
-
import { deriveCalendarSuggestionId } from "@remit/data-ports/id";
|
|
24
21
|
import {
|
|
25
22
|
CalendarInviteMethod,
|
|
26
23
|
CalendarSuggestionSource,
|
|
@@ -133,105 +130,9 @@ const PLAIN_EML = Buffer.from(
|
|
|
133
130
|
].join("\r\n"),
|
|
134
131
|
);
|
|
135
132
|
|
|
136
|
-
class MemorySuggestions implements ICalendarSuggestionRepository {
|
|
137
|
-
readonly rows = new Map<string, CalendarSuggestionItem>();
|
|
138
|
-
|
|
139
|
-
async put(
|
|
140
|
-
input: PutCalendarSuggestionInput,
|
|
141
|
-
): Promise<CalendarSuggestionItem> {
|
|
142
|
-
const suggestionId = deriveCalendarSuggestionId(
|
|
143
|
-
input.messageId,
|
|
144
|
-
input.bodyPartId,
|
|
145
|
-
input.icalUid,
|
|
146
|
-
);
|
|
147
|
-
const existing = this.rows.get(suggestionId);
|
|
148
|
-
const row: CalendarSuggestionItem = {
|
|
149
|
-
...input,
|
|
150
|
-
suggestionId,
|
|
151
|
-
state: existing?.state ?? CalendarSuggestionState.Pending,
|
|
152
|
-
acceptedCalendarObjectId: existing?.acceptedCalendarObjectId ?? "",
|
|
153
|
-
supersededByMessageId: existing?.supersededByMessageId ?? "",
|
|
154
|
-
createdAt: existing?.createdAt ?? 1,
|
|
155
|
-
updatedAt: 1,
|
|
156
|
-
};
|
|
157
|
-
this.rows.set(suggestionId, row);
|
|
158
|
-
return row;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
async get(
|
|
162
|
-
_accountConfigId: string,
|
|
163
|
-
suggestionId: string,
|
|
164
|
-
): Promise<CalendarSuggestionItem> {
|
|
165
|
-
const row = this.rows.get(suggestionId);
|
|
166
|
-
if (!row) throw new Error(`missing ${suggestionId}`);
|
|
167
|
-
return row;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async listByMessage(
|
|
171
|
-
_accountConfigId: string,
|
|
172
|
-
messageId: string,
|
|
173
|
-
): Promise<CalendarSuggestionItem[]> {
|
|
174
|
-
return [...this.rows.values()].filter((row) => row.messageId === messageId);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async listByState(
|
|
178
|
-
_accountConfigId: string,
|
|
179
|
-
state: CalendarSuggestionItem["state"],
|
|
180
|
-
): Promise<ResultList<CalendarSuggestionItem>> {
|
|
181
|
-
return {
|
|
182
|
-
items: [...this.rows.values()].filter((row) => row.state === state),
|
|
183
|
-
continuationToken: undefined,
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
async settle(
|
|
188
|
-
_accountConfigId: string,
|
|
189
|
-
suggestionId: string,
|
|
190
|
-
input: {
|
|
191
|
-
state: CalendarSuggestionItem["state"];
|
|
192
|
-
acceptedCalendarObjectId: string;
|
|
193
|
-
},
|
|
194
|
-
): Promise<CalendarSuggestionItem> {
|
|
195
|
-
const row = this.rows.get(suggestionId);
|
|
196
|
-
if (!row) throw new Error(`missing ${suggestionId}`);
|
|
197
|
-
const settled = { ...row, ...input };
|
|
198
|
-
this.rows.set(suggestionId, settled);
|
|
199
|
-
return settled;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
async supersedeIfPending(
|
|
203
|
-
_accountConfigId: string,
|
|
204
|
-
suggestionId: string,
|
|
205
|
-
supersededByMessageId: string,
|
|
206
|
-
): Promise<CalendarSuggestionItem | null> {
|
|
207
|
-
const row = this.rows.get(suggestionId);
|
|
208
|
-
if (!row || row.state !== CalendarSuggestionState.Pending) return null;
|
|
209
|
-
const retired = {
|
|
210
|
-
...row,
|
|
211
|
-
state: CalendarSuggestionState.Superseded,
|
|
212
|
-
acceptedCalendarObjectId: "",
|
|
213
|
-
supersededByMessageId,
|
|
214
|
-
};
|
|
215
|
-
this.rows.set(suggestionId, retired);
|
|
216
|
-
return retired;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
async repointSuperseded(
|
|
220
|
-
_accountConfigId: string,
|
|
221
|
-
suggestionId: string,
|
|
222
|
-
supersededByMessageId: string,
|
|
223
|
-
): Promise<CalendarSuggestionItem | null> {
|
|
224
|
-
const row = this.rows.get(suggestionId);
|
|
225
|
-
if (!row || row.state !== CalendarSuggestionState.Superseded) return null;
|
|
226
|
-
const repointed = { ...row, supersededByMessageId };
|
|
227
|
-
this.rows.set(suggestionId, repointed);
|
|
228
|
-
return repointed;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
133
|
interface Harness {
|
|
233
134
|
service: BodySyncService;
|
|
234
|
-
suggestions:
|
|
135
|
+
suggestions: Map<string, CalendarSuggestionItem>;
|
|
235
136
|
}
|
|
236
137
|
|
|
237
138
|
const buildHarness = ({
|
|
@@ -245,7 +146,8 @@ const buildHarness = ({
|
|
|
245
146
|
withCalendarConfig?: boolean;
|
|
246
147
|
mutedSenderFilters?: FilterItem[];
|
|
247
148
|
} = {}): Harness => {
|
|
248
|
-
const
|
|
149
|
+
const store = new MemoryCalendarStore();
|
|
150
|
+
const suggestions = store.calendarSuggestion;
|
|
249
151
|
|
|
250
152
|
const messageService = {
|
|
251
153
|
get: async (messageId: string) => ({
|
|
@@ -345,7 +247,7 @@ const buildHarness = ({
|
|
|
345
247
|
: undefined,
|
|
346
248
|
);
|
|
347
249
|
|
|
348
|
-
return { service, suggestions };
|
|
250
|
+
return { service, suggestions: store.suggestions };
|
|
349
251
|
};
|
|
350
252
|
|
|
351
253
|
const readBody = async (
|
|
@@ -372,7 +274,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
372
274
|
|
|
373
275
|
await readBody(harness.service, INVITATION_EML());
|
|
374
276
|
|
|
375
|
-
const rows = [...harness.suggestions.
|
|
277
|
+
const rows = [...harness.suggestions.values()];
|
|
376
278
|
assert.equal(rows.length, 1);
|
|
377
279
|
assert.equal(rows[0]?.state, CalendarSuggestionState.Pending);
|
|
378
280
|
assert.equal(rows[0]?.icalUid, UID);
|
|
@@ -387,7 +289,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
387
289
|
|
|
388
290
|
await readBody(harness.service, INVITATION_EML());
|
|
389
291
|
|
|
390
|
-
const row = [...harness.suggestions.
|
|
292
|
+
const row = [...harness.suggestions.values()][0];
|
|
391
293
|
assert.match(row?.icalData ?? "", /BEGIN:VCALENDAR/);
|
|
392
294
|
assert.match(row?.icalData ?? "", /UID:invite-4711@example\.test/);
|
|
393
295
|
});
|
|
@@ -400,7 +302,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
400
302
|
|
|
401
303
|
await readBody(harness.service, FLOATING_INVITATION_EML);
|
|
402
304
|
|
|
403
|
-
const row = [...harness.suggestions.
|
|
305
|
+
const row = [...harness.suggestions.values()][0];
|
|
404
306
|
assert.equal(row?.dtStart, "2026-09-01T10:00:00+02:00");
|
|
405
307
|
assert.equal(row?.zoneCertainty, "Local");
|
|
406
308
|
});
|
|
@@ -415,7 +317,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
415
317
|
|
|
416
318
|
await readBody(harness.service, INVITATION_EML());
|
|
417
319
|
|
|
418
|
-
assert.equal(harness.suggestions.
|
|
320
|
+
assert.equal(harness.suggestions.size, 0);
|
|
419
321
|
});
|
|
420
322
|
|
|
421
323
|
it("still offers a card when the rule names a different sender", async () => {
|
|
@@ -425,7 +327,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
425
327
|
|
|
426
328
|
await readBody(harness.service, INVITATION_EML());
|
|
427
329
|
|
|
428
|
-
assert.equal(harness.suggestions.
|
|
330
|
+
assert.equal(harness.suggestions.size, 1);
|
|
429
331
|
});
|
|
430
332
|
|
|
431
333
|
it("still offers a card when the rule about this sender does something", async () => {
|
|
@@ -442,7 +344,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
442
344
|
|
|
443
345
|
await readBody(harness.service, INVITATION_EML());
|
|
444
346
|
|
|
445
|
-
assert.equal(harness.suggestions.
|
|
347
|
+
assert.equal(harness.suggestions.size, 1);
|
|
446
348
|
});
|
|
447
349
|
|
|
448
350
|
it("offers nothing for a message carrying no calendar part", async () => {
|
|
@@ -450,7 +352,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
450
352
|
|
|
451
353
|
await readBody(harness.service, PLAIN_EML);
|
|
452
354
|
|
|
453
|
-
assert.equal(harness.suggestions.
|
|
355
|
+
assert.equal(harness.suggestions.size, 0);
|
|
454
356
|
});
|
|
455
357
|
|
|
456
358
|
it("offers nothing on a forced body re-sync", async () => {
|
|
@@ -465,7 +367,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
465
367
|
// The pass genuinely ran — the body was re-fetched and re-stored — and
|
|
466
368
|
// still offered nothing.
|
|
467
369
|
assert.equal(result.storedAt, "s3://bodies/m-1");
|
|
468
|
-
assert.equal(harness.suggestions.
|
|
370
|
+
assert.equal(harness.suggestions.size, 0);
|
|
469
371
|
});
|
|
470
372
|
|
|
471
373
|
it("supersedes the earlier revision when a higher SEQUENCE arrives", async () => {
|
|
@@ -474,7 +376,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
474
376
|
await readBody(harness.service, INVITATION_EML(0), "m-1");
|
|
475
377
|
await readBody(harness.service, INVITATION_EML(1), "m-2");
|
|
476
378
|
|
|
477
|
-
const rows = [...harness.suggestions.
|
|
379
|
+
const rows = [...harness.suggestions.values()];
|
|
478
380
|
assert.equal(rows.length, 2);
|
|
479
381
|
assert.deepEqual(
|
|
480
382
|
rows.map((row) => `${row.messageId}:${row.state}`).sort(),
|
|
@@ -487,7 +389,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
487
389
|
|
|
488
390
|
await readBody(harness.service, INVITATION_EML(1, "CANCEL"));
|
|
489
391
|
|
|
490
|
-
const row = [...harness.suggestions.
|
|
392
|
+
const row = [...harness.suggestions.values()][0];
|
|
491
393
|
assert.equal(row?.method, CalendarInviteMethod.Cancel);
|
|
492
394
|
assert.equal(row?.state, CalendarSuggestionState.Pending);
|
|
493
395
|
assert.equal(row?.acceptedCalendarObjectId, "");
|
|
@@ -518,7 +420,7 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
518
420
|
const result = await readBody(harness.service, broken);
|
|
519
421
|
|
|
520
422
|
assert.equal(result.storedAt, "newly-stored");
|
|
521
|
-
assert.equal(harness.suggestions.
|
|
423
|
+
assert.equal(harness.suggestions.size, 0);
|
|
522
424
|
});
|
|
523
425
|
|
|
524
426
|
it("is a no-op when body sync was built without a CalendarSuggestionConfig", async () => {
|
|
@@ -526,6 +428,6 @@ describe("mail-derived calendar suggestions (issue #1033)", () => {
|
|
|
526
428
|
|
|
527
429
|
await readBody(harness.service, INVITATION_EML());
|
|
528
430
|
|
|
529
|
-
assert.equal(harness.suggestions.
|
|
431
|
+
assert.equal(harness.suggestions.size, 0);
|
|
530
432
|
});
|
|
531
433
|
});
|