@remit/imap-worker 0.0.88 → 0.0.89

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.
@@ -5,17 +5,23 @@ import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
  import {
7
7
  _resetForTest,
8
- getClient,
9
8
  type RemitClient,
10
9
  setClient,
11
10
  } from "@remit/backend/client";
11
+ import { composeSqliteClient } from "@remit/backend/compose-sqlite";
12
+ import { buildSharedDeps } from "@remit/backend/shared-deps";
12
13
  import type {
13
14
  AccountItem,
14
15
  MailboxItem,
15
16
  MailboxSpecialUseValue,
16
17
  MessageItem,
17
18
  OutboxMessageItem,
19
+ QueueProducer,
18
20
  } from "@remit/data-ports";
21
+ import {
22
+ type RecordingQueue,
23
+ recordingQueue,
24
+ } from "@remit/data-ports/recording-queue";
19
25
  import {
20
26
  AccountAuthType,
21
27
  ConnectionState,
@@ -28,13 +34,10 @@ import {
28
34
  eml,
29
35
  FakeImapServer,
30
36
  } from "@remit/mailbox-service/test-helpers/fake-imap";
31
- import {
32
- captureQueue,
33
- type QueueCapture,
34
- } from "@remit/mailbox-service/test-helpers/test-queue";
35
37
  import { serializeEncryptedPayload } from "@remit/secrets-service";
36
38
  import type { createConnectionScopeWithCredentials } from "../connection-scope.js";
37
39
  import { syncMessages } from "../handlers/sync-messages.js";
40
+ import { setWorkerQueues } from "../queues.js";
38
41
 
39
42
  export interface LogLine {
40
43
  level: string;
@@ -93,6 +96,7 @@ export interface SeededMessage {
93
96
  */
94
97
  export const openStore = async (): Promise<{
95
98
  client: RemitClient;
99
+ bindWorkerQueues: () => void;
96
100
  world: (accountConfigId?: string) => Promise<World>;
97
101
  close: () => void;
98
102
  }> => {
@@ -103,12 +107,38 @@ export const openStore = async (): Promise<{
103
107
  process.env.BETTER_AUTH_URL = "https://mail.example.com";
104
108
  process.env.BETTER_AUTH_SECRET = "a-signing-secret-of-at-least-32-characters";
105
109
  _resetForTest();
106
- const client = await getClient();
110
+ let current = recordingQueue();
111
+ const queue: QueueProducer<unknown> = {
112
+ send: (message) => current.send(message),
113
+ sendBatch: (messages) => current.sendBatch(messages),
114
+ };
115
+ const client = await composeSqliteClient(
116
+ buildSharedDeps({
117
+ sync: queue,
118
+ accountFanout: queue,
119
+ smtp: queue,
120
+ messageManagement: queue,
121
+ body: queue,
122
+ }),
123
+ );
107
124
  setClient(client);
125
+ const bindWorkerQueues = (): void =>
126
+ setWorkerQueues({
127
+ mailboxes: queue,
128
+ messages: queue,
129
+ flags: queue,
130
+ body: queue,
131
+ mailboxManagement: queue,
132
+ messageManagement: queue,
133
+ });
134
+ bindWorkerQueues();
108
135
  return {
109
136
  client,
110
- world: (accountConfigId = `cfg-${randomUUID()}`) =>
111
- createWorld(client, accountConfigId),
137
+ bindWorkerQueues,
138
+ world: (accountConfigId = `cfg-${randomUUID()}`) => {
139
+ current = recordingQueue();
140
+ return createWorld(client, current, accountConfigId);
141
+ },
112
142
  close: () => {
113
143
  _resetForTest();
114
144
  rmSync(directory, { recursive: true, force: true });
@@ -135,7 +165,7 @@ export interface World {
135
165
  ) => Promise<Array<{ mailboxId: string; uid?: number; isDeleted: boolean }>>;
136
166
  queued: () => Array<Record<string, unknown>>;
137
167
  refuseSends: (error: Error | undefined) => void;
138
- queue: QueueCapture;
168
+ queue: RecordingQueue;
139
169
  draft: (
140
170
  attachment?: Buffer,
141
171
  ) => Promise<{ outbox: OutboxMessageItem; attachmentId?: string }>;
@@ -145,10 +175,9 @@ export interface World {
145
175
 
146
176
  const createWorld = async (
147
177
  client: RemitClient,
178
+ queue: RecordingQueue,
148
179
  accountConfigId: string,
149
180
  ): Promise<World> => {
150
- const queue = captureQueue();
151
-
152
181
  const imap = new FakeImapServer();
153
182
  const logs: LogLine[] = [];
154
183
  const password = await client.secrets.encrypt("app-password");
@@ -1,58 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { describe, it } from "node:test";
3
- import type { Logger } from "@remit/logger";
4
- import type { ImapWorkerStopEvent } from "./events.js";
5
- import { processEvent } from "./processor.js";
6
-
7
- interface CapturedLogEntry {
8
- args: unknown[];
9
- }
10
-
11
- const createCapturingLogger = (): {
12
- log: Logger;
13
- infoCalls: CapturedLogEntry[];
14
- } => {
15
- const infoCalls: CapturedLogEntry[] = [];
16
- const noop = () => {};
17
- const log = {
18
- info: (...args: unknown[]) => infoCalls.push({ args }),
19
- warn: noop,
20
- error: noop,
21
- debug: noop,
22
- fatal: noop,
23
- trace: noop,
24
- child: () => log,
25
- } as unknown as Logger;
26
- return { log, infoCalls };
27
- };
28
-
29
- describe("processEvent — IMAP_WORKER_STOP", () => {
30
- it("returns undefined and logs the stop signal — tombstone fence on the account row already halts work", async () => {
31
- const event: ImapWorkerStopEvent = {
32
- type: "IMAP_WORKER_STOP",
33
- accountConfigId: "acfg_alice_replay_safe_test_id",
34
- accountId: "acct_alice_replay_safe_test_id",
35
- };
36
- const { log, infoCalls } = createCapturingLogger();
37
-
38
- const result = await processEvent(event, log);
39
-
40
- assert.equal(result, undefined);
41
- const matched = infoCalls.find((c) => {
42
- const [meta, msg] = c.args;
43
- return (
44
- typeof msg === "string" &&
45
- msg === "Imap worker stop signal received" &&
46
- typeof meta === "object" &&
47
- meta !== null &&
48
- (meta as { accountConfigId?: string }).accountConfigId ===
49
- event.accountConfigId &&
50
- (meta as { accountId?: string }).accountId === event.accountId
51
- );
52
- });
53
- assert.ok(
54
- matched,
55
- "processor must log the cascade-contract stop signal with both ids",
56
- );
57
- });
58
- });