@remit/backend 0.0.115 → 0.0.116
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
|
@@ -467,6 +467,7 @@ describe("executeUnifiedThreadListing", () => {
|
|
|
467
467
|
: [
|
|
468
468
|
mailbox("m2-inbox", "a2", "INBOX"),
|
|
469
469
|
mailbox("m2-archive", "a2", "Archive"),
|
|
470
|
+
mailbox("m2-trash", "a2", "Trash", ["Trash"]),
|
|
470
471
|
],
|
|
471
472
|
},
|
|
472
473
|
accountSetting: { listByAccountConfig: async () => [] },
|
|
@@ -730,4 +731,52 @@ describe("executeUnifiedThreadListing", () => {
|
|
|
730
731
|
assert.deepEqual(response.items, []);
|
|
731
732
|
assert.equal(response.count, 0);
|
|
732
733
|
});
|
|
734
|
+
|
|
735
|
+
// #313: the Spam offer stated the junk share of the page the client had
|
|
736
|
+
// loaded, offered as a folder total. A count of one folder under the search's
|
|
737
|
+
// own criteria is what makes that number the folder's.
|
|
738
|
+
test("a folder scope narrows the search and the count to that folder", async () => {
|
|
739
|
+
const calls: Call[] = [];
|
|
740
|
+
const response = await executeUnifiedThreadListing(
|
|
741
|
+
buildListingClient(calls, 12),
|
|
742
|
+
CONFIG_ID,
|
|
743
|
+
{ ...params({ mailboxId: "m2-archive", count: true }), searchText: "x" },
|
|
744
|
+
);
|
|
745
|
+
|
|
746
|
+
const searching = calls.find((call) => call.mode === "searchByDate");
|
|
747
|
+
const counting = calls.find((call) => call.mode === "count");
|
|
748
|
+
assert.deepEqual([...(searching?.mailboxIds ?? [])], ["m2-archive"]);
|
|
749
|
+
assert.deepEqual([...(counting?.mailboxIds ?? [])], ["m2-archive"]);
|
|
750
|
+
assert.equal(response.count, 12);
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
test("a folder scope intersects the account scope rather than replacing it", async () => {
|
|
754
|
+
const calls: Call[] = [];
|
|
755
|
+
const response = await executeUnifiedThreadListing(
|
|
756
|
+
buildListingClient(calls, 99),
|
|
757
|
+
CONFIG_ID,
|
|
758
|
+
{
|
|
759
|
+
...params({ accountId: "a1", mailboxId: "m2-archive", count: true }),
|
|
760
|
+
searchText: "x",
|
|
761
|
+
},
|
|
762
|
+
);
|
|
763
|
+
|
|
764
|
+
assert.deepEqual(calls, []);
|
|
765
|
+
assert.equal(response.count, 0);
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
// Trash is the one folder the unscoped search never reaches, so a caller
|
|
769
|
+
// asking what it holds of a search is asking about mail the search does not
|
|
770
|
+
// see. Answering with the folder's own contents would widen the scope.
|
|
771
|
+
test("a folder the search scope excludes matches nothing", async () => {
|
|
772
|
+
const calls: Call[] = [];
|
|
773
|
+
const response = await executeUnifiedThreadListing(
|
|
774
|
+
buildListingClient(calls, 99),
|
|
775
|
+
CONFIG_ID,
|
|
776
|
+
{ ...params({ mailboxId: "m2-trash", count: true }), searchText: "x" },
|
|
777
|
+
);
|
|
778
|
+
|
|
779
|
+
assert.deepEqual(calls, []);
|
|
780
|
+
assert.equal(response.count, 0);
|
|
781
|
+
});
|
|
733
782
|
});
|
|
@@ -391,6 +391,29 @@ export const scopeToAccount = (
|
|
|
391
391
|
);
|
|
392
392
|
};
|
|
393
393
|
|
|
394
|
+
/**
|
|
395
|
+
* Narrow a mailbox scope to one folder.
|
|
396
|
+
*
|
|
397
|
+
* Intersects rather than replaces: a folder the mode's own scope does not hold —
|
|
398
|
+
* Trash, a muted folder, one of a muted account, one of another account when
|
|
399
|
+
* `accountId` narrowed first — leaves the empty set and matches nothing. A
|
|
400
|
+
* caller asking what one folder holds of a search must not be handed a folder
|
|
401
|
+
* the search itself does not reach.
|
|
402
|
+
*
|
|
403
|
+
* This is what makes a per-folder count of a cross-account search exact. The
|
|
404
|
+
* spam offer states how much of the search sits in a junk folder; before the
|
|
405
|
+
* parameter existed the only number available was the junk share of the page
|
|
406
|
+
* the client had loaded, which is a page length presented as a folder total
|
|
407
|
+
* (#313).
|
|
408
|
+
*/
|
|
409
|
+
export const scopeToMailbox = (
|
|
410
|
+
mailboxIds: Set<string>,
|
|
411
|
+
mailboxId: string | undefined,
|
|
412
|
+
): Set<string> => {
|
|
413
|
+
if (mailboxId === undefined) return mailboxIds;
|
|
414
|
+
return new Set(mailboxIds.has(mailboxId) ? [mailboxId] : []);
|
|
415
|
+
};
|
|
416
|
+
|
|
394
417
|
/**
|
|
395
418
|
* Minimal client surface `executeUnifiedThreadListing` needs, declared
|
|
396
419
|
* structurally (like `ThreadSearchClient`) so the mode selection, the row
|
|
@@ -428,6 +451,7 @@ export type UnifiedThreadParams = {
|
|
|
428
451
|
from?: string;
|
|
429
452
|
subject?: string;
|
|
430
453
|
accountId?: string;
|
|
454
|
+
mailboxId?: string;
|
|
431
455
|
category?: MessageCategory[];
|
|
432
456
|
unread?: boolean;
|
|
433
457
|
attachments?: boolean;
|
|
@@ -462,10 +486,15 @@ export const executeUnifiedThreadListing = async (
|
|
|
462
486
|
virtualCopyMailboxIds,
|
|
463
487
|
} = await buildInboxMailboxMap(accountConfigId, client);
|
|
464
488
|
|
|
465
|
-
// The account
|
|
466
|
-
// search and the count all narrow by the same rule.
|
|
489
|
+
// The account and folder scopes apply before the mode picks a set, so the
|
|
490
|
+
// listing, the search and the count all narrow by the same rule. Account
|
|
491
|
+
// first, folder second: the folder intersects what the account left, so a
|
|
492
|
+
// folder of another account narrows to nothing rather than reinstating one.
|
|
467
493
|
const narrow = (mailboxIds: Set<string>): Set<string> =>
|
|
468
|
-
|
|
494
|
+
scopeToMailbox(
|
|
495
|
+
scopeToAccount(mailboxIds, mailboxIdToAccountId, params.accountId),
|
|
496
|
+
params.mailboxId,
|
|
497
|
+
);
|
|
469
498
|
const inboxMailboxIds = narrow(everyInboxMailboxId);
|
|
470
499
|
const starredMailboxIds = narrow(everyStarredMailboxId);
|
|
471
500
|
const searchMailboxIds = narrow(everySearchMailboxId);
|
|
@@ -581,6 +610,7 @@ export const UnifiedThreadOperations: Record<
|
|
|
581
610
|
from,
|
|
582
611
|
subject,
|
|
583
612
|
accountId,
|
|
613
|
+
mailboxId,
|
|
584
614
|
category,
|
|
585
615
|
unread,
|
|
586
616
|
attachments,
|
|
@@ -596,6 +626,7 @@ export const UnifiedThreadOperations: Record<
|
|
|
596
626
|
from?: string;
|
|
597
627
|
subject?: string;
|
|
598
628
|
accountId?: string;
|
|
629
|
+
mailboxId?: string;
|
|
599
630
|
category?: MessageCategory | MessageCategory[];
|
|
600
631
|
unread?: boolean | string;
|
|
601
632
|
attachments?: boolean | string;
|
|
@@ -624,6 +655,7 @@ export const UnifiedThreadOperations: Record<
|
|
|
624
655
|
from: fromText || undefined,
|
|
625
656
|
subject: subjectText || undefined,
|
|
626
657
|
accountId: accountId || undefined,
|
|
658
|
+
mailboxId: mailboxId || undefined,
|
|
627
659
|
category: toArray(category),
|
|
628
660
|
unread: toBoolean(unread),
|
|
629
661
|
attachments: toBoolean(attachments),
|