@remit/backend 0.0.139 → 0.0.140

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/backend",
3
- "version": "0.0.139",
3
+ "version": "0.0.140",
4
4
  "description": "Remit Mail Inspector API backend",
5
5
  "license": "MIT",
6
6
  "author": "",
@@ -22,6 +22,7 @@ import {
22
22
  CalendarSuggestionState,
23
23
  FilterState,
24
24
  RecurrenceScope,
25
+ ZoneCertainty,
25
26
  } from "@remit/domain-enums";
26
27
  import type { APIGatewayProxyEvent } from "aws-lambda";
27
28
  import type { Context } from "openapi-backend";
@@ -65,6 +66,7 @@ const suggestion = (
65
66
  summary: "Quarterly review",
66
67
  dtStart: "2026-09-01T10:00:00+02:00",
67
68
  dtEnd: "2026-09-01T11:00:00+02:00",
69
+ endsAtUtc: "2026-09-01T09:00:00Z",
68
70
  allDay: false,
69
71
  location: "Room 4",
70
72
  organizer: "organizer@example.test",
@@ -335,6 +337,7 @@ interface Card {
335
337
  state: string;
336
338
  supersededByMessageId: string;
337
339
  supersededByThreadId: string;
340
+ summary: string;
338
341
  }
339
342
 
340
343
  const fileInThread = async (
@@ -397,10 +400,22 @@ const INVITATION = [
397
400
  "",
398
401
  ].join("\r\n");
399
402
 
403
+ const futureStart = new Date(Date.now() + 86400000).toISOString();
404
+ const futureEnd = new Date(Date.now() + 172800000).toISOString();
405
+
400
406
  const putSuggestion = (
401
407
  accountConfigId: string,
402
408
  messageId: string,
403
409
  method: CalendarSuggestionItem["method"] = CalendarInviteMethod.Request,
410
+ times: Pick<
411
+ PutCalendarSuggestionInput,
412
+ "dtStart" | "dtEnd" | "endsAtUtc" | "icalData"
413
+ > = {
414
+ dtStart: futureStart,
415
+ dtEnd: futureEnd,
416
+ endsAtUtc: futureEnd,
417
+ icalData: INVITATION,
418
+ },
404
419
  ): Promise<CalendarSuggestionItem> =>
405
420
  client.calendarSuggestion.put({
406
421
  accountConfigId,
@@ -411,14 +426,12 @@ const putSuggestion = (
411
426
  method,
412
427
  source: CalendarSuggestionSource.IcalendarPart,
413
428
  summary: "Quarterly review",
414
- dtStart: "2026-09-01T10:00:00+02:00",
415
- dtEnd: "2026-09-01T11:00:00+02:00",
416
429
  allDay: false,
417
430
  location: "Room 4",
418
431
  organizer: "organizer@example.test",
419
- zoneCertainty: "Explicit",
420
- icalData: INVITATION,
421
- } as PutCalendarSuggestionInput);
432
+ zoneCertainty: ZoneCertainty.Explicit,
433
+ ...times,
434
+ });
422
435
 
423
436
  /** A message with a From address, which is all muting a sender reads. */
424
437
  const seedMessageFrom = async (
@@ -954,8 +967,9 @@ describe("POST /calendar-suggestions/{suggestionId}/reopen, against what else ho
954
967
  method: CalendarInviteMethod.Request,
955
968
  source: CalendarSuggestionSource.IcalendarPart,
956
969
  summary: "Quarterly review",
957
- dtStart: "2026-09-01T10:00:00+02:00",
958
- dtEnd: "2026-09-01T11:00:00+02:00",
970
+ dtStart: futureStart,
971
+ dtEnd: futureEnd,
972
+ endsAtUtc: futureEnd,
959
973
  allDay: false,
960
974
  location: "Room 4",
961
975
  organizer: "organizer@example.test",
@@ -1160,3 +1174,96 @@ describe("POST /calendar-suggestions/{suggestionId}/reopen, against what else ho
1160
1174
  );
1161
1175
  });
1162
1176
  });
1177
+
1178
+ describe("GET /calendar-suggestions leaves out events that are over", () => {
1179
+ const hoursFromNow = (hours: number): string =>
1180
+ new Date(Date.now() + hours * 3600000).toISOString();
1181
+
1182
+ const past = {
1183
+ dtStart: hoursFromNow(-48),
1184
+ dtEnd: hoursFromNow(-47),
1185
+ endsAtUtc: hoursFromNow(-47),
1186
+ icalData: INVITATION,
1187
+ };
1188
+
1189
+ const listState = async (
1190
+ event: APIGatewayProxyEvent,
1191
+ state: CalendarSuggestionItem["state"],
1192
+ ): Promise<Card[]> =>
1193
+ (
1194
+ (await listSuggestions(
1195
+ contextOf({ query: { state } }),
1196
+ event,
1197
+ )) as unknown as { items: Card[] }
1198
+ ).items;
1199
+
1200
+ test("omits a Pending suggestion that ended and keeps one still ahead", async () => {
1201
+ const { accountConfigId, event } = anAccount();
1202
+ await putSuggestion(
1203
+ accountConfigId,
1204
+ "msg-past",
1205
+ CalendarInviteMethod.Request,
1206
+ past,
1207
+ );
1208
+ const ahead = await putSuggestion(accountConfigId, "msg-ahead");
1209
+
1210
+ const pending = await listState(event, CalendarSuggestionState.Pending);
1211
+
1212
+ assert.deepEqual(
1213
+ pending.map((card) => card.suggestionId),
1214
+ [ahead.suggestionId],
1215
+ );
1216
+ });
1217
+
1218
+ test("keeps a weekly series that began two years ago and has no end", async () => {
1219
+ const { accountConfigId, event } = anAccount();
1220
+ const twoYearsAgo = hoursFromNow(-2 * 365 * 24);
1221
+ const stamp = twoYearsAgo.replace(/[-:]/g, "").slice(0, 15).concat("Z");
1222
+ const series = await putSuggestion(
1223
+ accountConfigId,
1224
+ "msg-series",
1225
+ CalendarInviteMethod.Request,
1226
+ {
1227
+ dtStart: twoYearsAgo,
1228
+ dtEnd: twoYearsAgo,
1229
+ endsAtUtc: "9999-12-31T23:59:59Z",
1230
+ icalData: INVITATION.replace(
1231
+ /DTSTART[^\r\n]*/,
1232
+ `DTSTART:${stamp}`,
1233
+ ).replace(/DTEND[^\r\n]*/, `DTEND:${stamp}\r\nRRULE:FREQ=WEEKLY`),
1234
+ },
1235
+ );
1236
+
1237
+ const pending = await listState(event, CalendarSuggestionState.Pending);
1238
+
1239
+ assert.deepEqual(
1240
+ pending.map((card) => card.suggestionId),
1241
+ [series.suggestionId],
1242
+ );
1243
+ });
1244
+
1245
+ test("still returns an Accepted suggestion whose event is over", async () => {
1246
+ const { accountConfigId, event } = anAccount();
1247
+ const stored = await putSuggestion(
1248
+ accountConfigId,
1249
+ "msg-accepted",
1250
+ CalendarInviteMethod.Request,
1251
+ past,
1252
+ );
1253
+ await client.calendarSuggestion.settle(
1254
+ accountConfigId,
1255
+ stored.suggestionId,
1256
+ {
1257
+ state: CalendarSuggestionState.Accepted,
1258
+ acceptedCalendarObjectId: "",
1259
+ },
1260
+ );
1261
+
1262
+ const accepted = await listState(event, CalendarSuggestionState.Accepted);
1263
+
1264
+ assert.deepEqual(
1265
+ accepted.map((card) => card.suggestionId),
1266
+ [stored.suggestionId],
1267
+ );
1268
+ });
1269
+ });
@@ -219,7 +219,13 @@ export const CalendarSuggestionOperations: Record<
219
219
  const page = await client.calendarSuggestion.listByState(
220
220
  accountConfigId,
221
221
  state,
222
- { continuationToken },
222
+ {
223
+ continuationToken,
224
+ endsAfter:
225
+ state === CalendarSuggestionState.Pending
226
+ ? new Date().toISOString()
227
+ : new Date(0).toISOString(),
228
+ },
223
229
  );
224
230
 
225
231
  return {