@marcoappio/marco-config 2.0.529 → 2.0.531

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.
@@ -39,26 +39,26 @@ describe('mutators', () => {
39
39
  describe('createAccount', () => {
40
40
  it('creates an account and primary alias', async () => {
41
41
  const args = {
42
- aliasId: 'alias-1',
42
+ aliasId: 'test-alias-id-1',
43
43
  color: '#ff0000',
44
44
  emailAddress: 'test@example.com',
45
- id: 'account-1',
45
+ id: 'test-account-id-1',
46
46
  };
47
47
  await mutators.account.createAccount.fn({ args, ctx, tx: tx });
48
48
  expect(tx.mutate.account.insert).toHaveBeenCalledWith({
49
49
  color: '#ff0000',
50
50
  displayName: null,
51
- id: 'account-1',
51
+ id: 'test-account-id-1',
52
52
  imapConnectionStatus: 'AWAITING_CONNECTION',
53
53
  mailProcessedCount: 0,
54
54
  mailTotalCount: 0,
55
- primaryAliasId: 'alias-1',
55
+ primaryAliasId: 'test-alias-id-1',
56
56
  userId: 'test-user-id',
57
57
  });
58
58
  expect(tx.mutate.accountAlias.insert).toHaveBeenCalledWith({
59
- accountId: 'account-1',
59
+ accountId: 'test-account-id-1',
60
60
  emailAddress: 'test@example.com',
61
- id: 'alias-1',
61
+ id: 'test-alias-id-1',
62
62
  isPrimary: true,
63
63
  name: null,
64
64
  });
@@ -67,36 +67,36 @@ describe('mutators', () => {
67
67
  describe('createAlias', () => {
68
68
  it('creates a non-primary alias', async () => {
69
69
  const args = {
70
- accountId: 'account-1',
70
+ accountId: 'test-account-id-1',
71
71
  alias: {
72
72
  emailAddress: 'alias@example.com',
73
- id: 'alias-2',
74
- name: 'My Alias',
73
+ id: 'test-alias-id-2',
74
+ name: 'test-alias-name',
75
75
  },
76
76
  };
77
77
  await mutators.account.createAlias.fn({ args, ctx, tx: tx });
78
78
  expect(tx.mutate.accountAlias.insert).toHaveBeenCalledWith({
79
- accountId: 'account-1',
79
+ accountId: 'test-account-id-1',
80
80
  emailAddress: 'alias@example.com',
81
- id: 'alias-2',
81
+ id: 'test-alias-id-2',
82
82
  isPrimary: false,
83
- name: 'My Alias',
83
+ name: 'test-alias-name',
84
84
  });
85
85
  });
86
86
  it('creates an alias with null name', async () => {
87
87
  const args = {
88
- accountId: 'account-1',
88
+ accountId: 'test-account-id-1',
89
89
  alias: {
90
90
  emailAddress: 'alias@example.com',
91
- id: 'alias-2',
91
+ id: 'test-alias-id-2',
92
92
  name: null,
93
93
  },
94
94
  };
95
95
  await mutators.account.createAlias.fn({ args, ctx, tx: tx });
96
96
  expect(tx.mutate.accountAlias.insert).toHaveBeenCalledWith({
97
- accountId: 'account-1',
97
+ accountId: 'test-account-id-1',
98
98
  emailAddress: 'alias@example.com',
99
- id: 'alias-2',
99
+ id: 'test-alias-id-2',
100
100
  isPrimary: false,
101
101
  name: null,
102
102
  });
@@ -104,51 +104,60 @@ describe('mutators', () => {
104
104
  });
105
105
  describe('deleteAccount', () => {
106
106
  it('deletes an account', async () => {
107
- const args = { id: 'account-1' };
107
+ const args = { id: 'test-account-id-1' };
108
108
  await mutators.account.deleteAccount.fn({ args, ctx, tx: tx });
109
- expect(tx.mutate.account.delete).toHaveBeenCalledWith({ id: 'account-1' });
109
+ expect(tx.mutate.account.delete).toHaveBeenCalledWith({ id: 'test-account-id-1' });
110
110
  });
111
111
  });
112
112
  describe('deleteAlias', () => {
113
113
  it('deletes a non-primary alias', async () => {
114
114
  tx.run = mock(() => Promise.resolve({ isPrimary: false }));
115
- const args = { accountId: 'account-1', aliasId: 'alias-2' };
115
+ const args = { accountId: 'test-account-id-1', aliasId: 'test-alias-id-2' };
116
116
  await mutators.account.deleteAlias.fn({ args, ctx, tx: tx });
117
- expect(tx.mutate.accountAlias.delete).toHaveBeenCalledWith({ id: 'alias-2' });
117
+ expect(tx.mutate.accountAlias.delete).toHaveBeenCalledWith({ id: 'test-alias-id-2' });
118
118
  expect(tx.mutate.accountAlias.update).not.toHaveBeenCalled();
119
119
  });
120
120
  it('promotes another alias when deleting primary', async () => {
121
121
  tx.run = mock()
122
122
  .mockResolvedValueOnce({ isPrimary: true })
123
- .mockResolvedValueOnce([{ id: 'alias-3' }]);
124
- const args = { accountId: 'account-1', aliasId: 'alias-1' };
123
+ .mockResolvedValueOnce([{ id: 'test-alias-id-3' }]);
124
+ const args = { accountId: 'test-account-id-1', aliasId: 'test-alias-id-1' };
125
125
  await mutators.account.deleteAlias.fn({ args, ctx, tx: tx });
126
- expect(tx.mutate.accountAlias.delete).toHaveBeenCalledWith({ id: 'alias-1' });
127
- expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({ id: 'alias-3', isPrimary: true });
128
- expect(tx.mutate.account.update).toHaveBeenCalledWith({ id: 'account-1', primaryAliasId: 'alias-3' });
126
+ expect(tx.mutate.accountAlias.delete).toHaveBeenCalledWith({ id: 'test-alias-id-1' });
127
+ expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({ id: 'test-alias-id-3', isPrimary: true });
128
+ expect(tx.mutate.account.update).toHaveBeenCalledWith({
129
+ id: 'test-account-id-1',
130
+ primaryAliasId: 'test-alias-id-3',
131
+ });
129
132
  });
130
133
  it('sets primaryAliasId to null when no remaining aliases', async () => {
131
134
  tx.run = mock().mockResolvedValueOnce({ isPrimary: true }).mockResolvedValueOnce([]);
132
- const args = { accountId: 'account-1', aliasId: 'alias-1' };
135
+ const args = { accountId: 'test-account-id-1', aliasId: 'test-alias-id-1' };
133
136
  await mutators.account.deleteAlias.fn({ args, ctx, tx: tx });
134
- expect(tx.mutate.account.update).toHaveBeenCalledWith({ id: 'account-1', primaryAliasId: null });
137
+ expect(tx.mutate.account.update).toHaveBeenCalledWith({ id: 'test-account-id-1', primaryAliasId: null });
135
138
  });
136
139
  });
137
140
  describe('setAliasName', () => {
138
141
  it('updates alias name', async () => {
139
- const args = { accountId: 'account-1', aliasId: 'alias-1', displayName: 'New Name' };
142
+ const args = { accountId: 'test-account-id-1', aliasId: 'test-alias-id-1', displayName: 'test-alias-new-name' };
140
143
  await mutators.account.setAliasName.fn({ args, ctx, tx: tx });
141
- expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({ id: 'alias-1', name: 'New Name' });
144
+ expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({
145
+ id: 'test-alias-id-1',
146
+ name: 'test-alias-new-name',
147
+ });
142
148
  });
143
149
  });
144
150
  describe('setAliasPrimary', () => {
145
151
  it('sets a new primary alias', async () => {
146
- tx.run = mock(() => Promise.resolve([{ id: 'alias-1' }, { id: 'alias-2' }]));
147
- const args = { accountId: 'account-1', aliasId: 'alias-2' };
152
+ tx.run = mock(() => Promise.resolve([{ id: 'test-alias-id-1' }, { id: 'test-alias-id-2' }]));
153
+ const args = { accountId: 'test-account-id-1', aliasId: 'test-alias-id-2' };
148
154
  await mutators.account.setAliasPrimary.fn({ args, ctx, tx: tx });
149
- expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({ id: 'alias-1', isPrimary: false });
150
- expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({ id: 'alias-2', isPrimary: true });
151
- expect(tx.mutate.account.update).toHaveBeenCalledWith({ id: 'account-1', primaryAliasId: 'alias-2' });
155
+ expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({ id: 'test-alias-id-1', isPrimary: false });
156
+ expect(tx.mutate.accountAlias.update).toHaveBeenCalledWith({ id: 'test-alias-id-2', isPrimary: true });
157
+ expect(tx.mutate.account.update).toHaveBeenCalledWith({
158
+ id: 'test-account-id-1',
159
+ primaryAliasId: 'test-alias-id-2',
160
+ });
152
161
  });
153
162
  });
154
163
  describe('setConnectionConfigImapRaw', () => {
@@ -156,21 +165,21 @@ describe('mutators', () => {
156
165
  const args = {
157
166
  connectionConfig: {
158
167
  imapHost: 'imap.example.com',
159
- imapPassword: 'pass',
168
+ imapPassword: 'test-imap-password',
160
169
  imapPort: 993,
161
170
  imapSocketType: 'SSL',
162
- imapUser: 'user',
171
+ imapUser: 'test-imap-user',
163
172
  smtpHost: 'smtp.example.com',
164
- smtpPassword: 'pass',
173
+ smtpPassword: 'test-smtp-password',
165
174
  smtpPort: 465,
166
175
  smtpSocketType: 'SSL',
167
- smtpUser: 'user',
176
+ smtpUser: 'test-smtp-user',
168
177
  },
169
- id: 'account-1',
178
+ id: 'test-account-id-1',
170
179
  };
171
180
  await mutators.account.setConnectionConfigImapRaw.fn({ args, ctx, tx: tx });
172
181
  expect(tx.mutate.account.update).toHaveBeenCalledWith({
173
- id: 'account-1',
182
+ id: 'test-account-id-1',
174
183
  imapConnectionStatus: 'AWAITING_CONNECTION',
175
184
  });
176
185
  });
@@ -178,24 +187,24 @@ describe('mutators', () => {
178
187
  describe('setConnectionConfigOauth', () => {
179
188
  it('updates connection status for oauth', async () => {
180
189
  const args = {
181
- connectionConfig: { code: 'auth-code', provider: 'GOOGLE', user: 'user@example.com' },
182
- id: 'account-1',
190
+ connectionConfig: { code: 'test-auth-code', provider: 'GOOGLE', user: 'test-user@example.com' },
191
+ id: 'test-account-id-1',
183
192
  };
184
193
  await mutators.account.setConnectionConfigOauth.fn({ args, ctx, tx: tx });
185
194
  expect(tx.mutate.account.update).toHaveBeenCalledWith({
186
- id: 'account-1',
195
+ id: 'test-account-id-1',
187
196
  imapConnectionStatus: 'AWAITING_CONNECTION',
188
197
  });
189
198
  });
190
199
  });
191
200
  describe('setSettings', () => {
192
201
  it('updates account settings', async () => {
193
- const args = { color: '#00ff00', displayName: 'Work', id: 'account-1' };
202
+ const args = { color: '#00ff00', displayName: 'test-account-display-name', id: 'test-account-id-1' };
194
203
  await mutators.account.setSettings.fn({ args, ctx, tx: tx });
195
204
  expect(tx.mutate.account.update).toHaveBeenCalledWith({
196
205
  color: '#00ff00',
197
- displayName: 'Work',
198
- id: 'account-1',
206
+ displayName: 'test-account-display-name',
207
+ id: 'test-account-id-1',
199
208
  });
200
209
  });
201
210
  });
@@ -204,10 +213,10 @@ describe('mutators', () => {
204
213
  describe('cancelSend', () => {
205
214
  it('cancels a scheduled send', async () => {
206
215
  tx.run = mock(() => Promise.resolve({ status: 'SEND_REQUESTED' }));
207
- const args = { id: 'draft-1', updatedAt: 1234567890 };
216
+ const args = { id: 'test-draft-id-1', updatedAt: 1234567890 };
208
217
  await mutators.draft.cancelSend.fn({ args, ctx, tx: tx });
209
218
  expect(tx.mutate.draft.update).toHaveBeenCalledWith({
210
- id: 'draft-1',
219
+ id: 'test-draft-id-1',
211
220
  scheduledFor: null,
212
221
  status: 'DRAFT',
213
222
  updatedAt: 1234567890,
@@ -215,13 +224,13 @@ describe('mutators', () => {
215
224
  });
216
225
  it('does nothing if draft not found', async () => {
217
226
  tx.run = mock(() => Promise.resolve(null));
218
- const args = { id: 'draft-1', updatedAt: 1234567890 };
227
+ const args = { id: 'test-draft-id-1', updatedAt: 1234567890 };
219
228
  await mutators.draft.cancelSend.fn({ args, ctx, tx: tx });
220
229
  expect(tx.mutate.draft.update).not.toHaveBeenCalled();
221
230
  });
222
231
  it('does nothing if already confirmed', async () => {
223
232
  tx.run = mock(() => Promise.resolve({ status: 'SEND_CONFIRMED' }));
224
- const args = { id: 'draft-1', updatedAt: 1234567890 };
233
+ const args = { id: 'test-draft-id-1', updatedAt: 1234567890 };
225
234
  await mutators.draft.cancelSend.fn({ args, ctx, tx: tx });
226
235
  expect(tx.mutate.draft.update).not.toHaveBeenCalled();
227
236
  });
@@ -231,25 +240,25 @@ describe('mutators', () => {
231
240
  const args = {
232
241
  attachment: {
233
242
  fileName: 'file.pdf',
234
- id: 'attachment-1',
243
+ id: 'test-attachment-id-1',
235
244
  mimeType: 'application/pdf',
236
245
  status: 'PENDING',
237
246
  totalSize: 1024,
238
247
  },
239
- id: 'draft-1',
248
+ id: 'test-draft-id-1',
240
249
  updatedAt: 1234567890,
241
250
  };
242
251
  await mutators.draft.createAttachment.fn({ args, ctx, tx: tx });
243
252
  expect(tx.mutate.draftAttachment.insert).toHaveBeenCalledWith({
244
- draftId: 'draft-1',
253
+ draftId: 'test-draft-id-1',
245
254
  fileName: 'file.pdf',
246
- id: 'attachment-1',
255
+ id: 'test-attachment-id-1',
247
256
  mimeType: 'application/pdf',
248
257
  status: 'PENDING',
249
258
  totalSize: 1024,
250
259
  });
251
260
  expect(tx.mutate.draft.update).toHaveBeenCalledWith({
252
- id: 'draft-1',
261
+ id: 'test-draft-id-1',
253
262
  updatedAt: 1234567890,
254
263
  });
255
264
  });
@@ -257,21 +266,27 @@ describe('mutators', () => {
257
266
  describe('createDraft', () => {
258
267
  it('creates a draft with attachments', async () => {
259
268
  const args = {
260
- accountId: 'account-1',
269
+ accountId: 'test-account-id-1',
261
270
  attachments: [
262
271
  {
263
- fileName: 'file.pdf',
264
- id: 'att-1',
272
+ fileName: 'test-file-name.pdf',
273
+ id: 'test-attachment-id-1',
265
274
  mimeType: 'application/pdf',
266
275
  status: 'COMPLETE',
267
276
  totalSize: 1024,
268
277
  },
269
278
  ],
270
- body: { bcc: [], cc: ['cc@example.com'], content: 'Hello', subject: 'Test', to: ['to@example.com'] },
279
+ body: {
280
+ bcc: [],
281
+ cc: ['test-email-1@example.com'],
282
+ content: 'test-content',
283
+ subject: 'test-subject',
284
+ to: ['test-email-2@example.com'],
285
+ },
271
286
  error: null,
272
- from: 'from@example.com',
273
- fromName: 'Sender',
274
- id: 'draft-1',
287
+ from: 'test-email-3@example.com',
288
+ fromName: 'test-sender-name',
289
+ id: 'test-draft-id-1',
275
290
  referencedMessageId: null,
276
291
  scheduledFor: null,
277
292
  status: 'DRAFT',
@@ -280,25 +295,30 @@ describe('mutators', () => {
280
295
  };
281
296
  await mutators.draft.createDraft.fn({ args, ctx, tx: tx });
282
297
  expect(tx.mutate.draft.insert).toHaveBeenCalledWith({
283
- accountId: 'account-1',
284
- body: { bcc: [], cc: ['cc@example.com'], content: 'Hello', to: ['to@example.com'] },
298
+ accountId: 'test-account-id-1',
299
+ body: {
300
+ bcc: [],
301
+ cc: ['test-email-1@example.com'],
302
+ content: 'test-content',
303
+ to: ['test-email-2@example.com'],
304
+ },
285
305
  error: null,
286
306
  fromAliasId: null,
287
- fromEmail: 'from@example.com',
288
- fromName: 'Sender',
289
- id: 'draft-1',
307
+ fromEmail: 'test-email-3@example.com',
308
+ fromName: 'test-sender-name',
309
+ id: 'test-draft-id-1',
290
310
  referencedMessageId: null,
291
311
  scheduledFor: null,
292
312
  status: 'DRAFT',
293
- subject: 'Test',
313
+ subject: 'test-subject',
294
314
  type: 'NEW',
295
315
  updatedAt: 1234567890,
296
316
  userId: 'test-user-id',
297
317
  });
298
318
  expect(tx.mutate.draftAttachment.insert).toHaveBeenCalledWith({
299
- draftId: 'draft-1',
300
- fileName: 'file.pdf',
301
- id: 'att-1',
319
+ draftId: 'test-draft-id-1',
320
+ fileName: 'test-file-name.pdf',
321
+ id: 'test-attachment-id-1',
302
322
  mimeType: 'application/pdf',
303
323
  status: 'COMPLETE',
304
324
  totalSize: 1024,
@@ -307,35 +327,35 @@ describe('mutators', () => {
307
327
  });
308
328
  describe('deleteAttachment', () => {
309
329
  it('deletes an attachment and updates draft', async () => {
310
- const args = { attachmentId: 'att-1', id: 'draft-1', updatedAt: 1234567890 };
330
+ const args = { attachmentId: 'test-attachment-id-1', id: 'test-draft-id-1', updatedAt: 1234567890 };
311
331
  await mutators.draft.deleteAttachment.fn({ args, ctx, tx: tx });
312
- expect(tx.mutate.draftAttachment.delete).toHaveBeenCalledWith({ id: 'att-1' });
313
- expect(tx.mutate.draft.update).toHaveBeenCalledWith({ id: 'draft-1', updatedAt: 1234567890 });
332
+ expect(tx.mutate.draftAttachment.delete).toHaveBeenCalledWith({ id: 'test-attachment-id-1' });
333
+ expect(tx.mutate.draft.update).toHaveBeenCalledWith({ id: 'test-draft-id-1', updatedAt: 1234567890 });
314
334
  });
315
335
  });
316
336
  describe('deleteDraft', () => {
317
337
  it('deletes a draft', async () => {
318
- const args = { id: 'draft-1' };
338
+ const args = { id: 'test-draft-id-1' };
319
339
  await mutators.draft.deleteDraft.fn({ args, ctx, tx: tx });
320
- expect(tx.mutate.draft.delete).toHaveBeenCalledWith({ id: 'draft-1' });
340
+ expect(tx.mutate.draft.delete).toHaveBeenCalledWith({ id: 'test-draft-id-1' });
321
341
  });
322
342
  });
323
343
  describe('scheduleSend', () => {
324
344
  it('schedules an immediate send with undo delay', async () => {
325
- const args = { id: 'draft-1', kind: 'IMMEDIATE', undoMs: 5000, updatedAt: 1000000 };
345
+ const args = { id: 'test-draft-id-1', kind: 'IMMEDIATE', undoMs: 5000, updatedAt: 1000000 };
326
346
  await mutators.draft.scheduleSend.fn({ args, ctx, tx: tx });
327
347
  expect(tx.mutate.draft.update).toHaveBeenCalledWith({
328
- id: 'draft-1',
348
+ id: 'test-draft-id-1',
329
349
  scheduledFor: 1005000,
330
350
  status: 'SEND_REQUESTED',
331
351
  updatedAt: 1000000,
332
352
  });
333
353
  });
334
354
  it('schedules a future send', async () => {
335
- const args = { id: 'draft-1', kind: 'SCHEDULED', scheduledFor: 2000000, updatedAt: 1000000 };
355
+ const args = { id: 'test-draft-id-1', kind: 'SCHEDULED', scheduledFor: 2000000, updatedAt: 1000000 };
336
356
  await mutators.draft.scheduleSend.fn({ args, ctx, tx: tx });
337
357
  expect(tx.mutate.draft.update).toHaveBeenCalledWith({
338
- id: 'draft-1',
358
+ id: 'test-draft-id-1',
339
359
  scheduledFor: 2000000,
340
360
  status: 'SEND_REQUESTED',
341
361
  updatedAt: 1000000,
@@ -344,39 +364,49 @@ describe('mutators', () => {
344
364
  });
345
365
  describe('setContent', () => {
346
366
  it('applies a content patch', async () => {
347
- tx.run = mock(() => Promise.resolve({ body: { bcc: [], cc: [], content: 'Hello', to: [] } }));
367
+ tx.run = mock(() => Promise.resolve({ body: { bcc: [], cc: [], content: 'test-content', to: [] } }));
348
368
  const args = {
349
- id: 'draft-1',
350
- patch: [{ index: 5, type: 'INSERTION', value: ' World' }],
369
+ id: 'test-draft-id-1',
370
+ patch: [{ index: 12, type: 'INSERTION', value: ' test-value' }],
351
371
  updatedAt: 1234567890,
352
372
  };
353
373
  await mutators.draft.setContent.fn({ args, ctx, tx: tx });
354
374
  expect(tx.mutate.draft.update).toHaveBeenCalledWith({
355
- body: { bcc: [], cc: [], content: 'Hello World', to: [] },
356
- id: 'draft-1',
375
+ body: { bcc: [], cc: [], content: 'test-content test-value', to: [] },
376
+ id: 'test-draft-id-1',
357
377
  updatedAt: 1234567890,
358
378
  });
359
379
  });
360
380
  it('does nothing if draft not found', async () => {
361
381
  tx.run = mock(() => Promise.resolve(null));
362
- const args = { id: 'draft-1', patch: [], updatedAt: 1234567890 };
382
+ const args = { id: 'test-draft-id-1', patch: [], updatedAt: 1234567890 };
363
383
  await mutators.draft.setContent.fn({ args, ctx, tx: tx });
364
384
  expect(tx.mutate.draft.update).not.toHaveBeenCalled();
365
385
  });
366
386
  });
367
387
  describe('setEnvelope', () => {
368
388
  it('updates envelope fields', async () => {
369
- tx.run = mock(() => Promise.resolve({ body: { content: 'Hello' } }));
389
+ tx.run = mock(() => Promise.resolve({ body: { content: 'test-content' } }));
370
390
  const args = {
371
- envelope: { bcc: ['bcc@example.com'], cc: [], subject: 'New Subject', to: ['to@example.com'] },
372
- id: 'draft-1',
391
+ envelope: {
392
+ bcc: ['test-email-1@example.com'],
393
+ cc: [],
394
+ subject: 'test-subject',
395
+ to: ['test-email-2@example.com'],
396
+ },
397
+ id: 'test-draft-id-1',
373
398
  updatedAt: 1234567890,
374
399
  };
375
400
  await mutators.draft.setEnvelope.fn({ args, ctx, tx: tx });
376
401
  expect(tx.mutate.draft.update).toHaveBeenCalledWith({
377
- body: { bcc: ['bcc@example.com'], cc: [], content: 'Hello', to: ['to@example.com'] },
378
- id: 'draft-1',
379
- subject: 'New Subject',
402
+ body: {
403
+ bcc: ['test-email-1@example.com'],
404
+ cc: [],
405
+ content: 'test-content',
406
+ to: ['test-email-2@example.com'],
407
+ },
408
+ id: 'test-draft-id-1',
409
+ subject: 'test-subject',
380
410
  updatedAt: 1234567890,
381
411
  });
382
412
  });
@@ -384,20 +414,20 @@ describe('mutators', () => {
384
414
  describe('setFrom', () => {
385
415
  it('updates from fields', async () => {
386
416
  const args = {
387
- accountId: 'account-2',
388
- aliasId: 'alias-2',
389
- from: 'new@example.com',
390
- fromName: 'New Name',
391
- id: 'draft-1',
417
+ accountId: 'test-account-id-2',
418
+ aliasId: 'test-alias-id-2',
419
+ from: 'test-email-3@example.com',
420
+ fromName: 'test-alias-new-name',
421
+ id: 'test-draft-id-1',
392
422
  updatedAt: 1234567890,
393
423
  };
394
424
  await mutators.draft.setFrom.fn({ args, ctx, tx: tx });
395
425
  expect(tx.mutate.draft.update).toHaveBeenCalledWith({
396
- accountId: 'account-2',
397
- fromAliasId: 'alias-2',
398
- fromEmail: 'new@example.com',
399
- fromName: 'New Name',
400
- id: 'draft-1',
426
+ accountId: 'test-account-id-2',
427
+ fromAliasId: 'test-alias-id-2',
428
+ fromEmail: 'test-email-3@example.com',
429
+ fromName: 'test-alias-new-name',
430
+ id: 'test-draft-id-1',
401
431
  updatedAt: 1234567890,
402
432
  });
403
433
  });
@@ -407,35 +437,35 @@ describe('mutators', () => {
407
437
  describe('addLabel', () => {
408
438
  it('adds a label to threads', async () => {
409
439
  tx.run = mock()
410
- .mockResolvedValueOnce({ id: 'label-1', uidValidity: 1, unreadCount: 0 })
440
+ .mockResolvedValueOnce({ id: 'test-label-id-1', uidValidity: 1, unreadCount: 0 })
411
441
  .mockResolvedValueOnce({
412
- id: 'thread-1',
413
- labelIdList: ' label-2 ',
442
+ id: 'test-thread-id-1',
443
+ labelIdList: ' test-label-id-2 ',
414
444
  latestMessageDate: 1234567890,
415
445
  seen: true,
416
446
  })
417
- .mockResolvedValueOnce([{ id: 'message-1' }])
447
+ .mockResolvedValueOnce([{ id: 'test-message-id-1' }])
418
448
  .mockResolvedValueOnce(null);
419
449
  const args = {
420
- accounts: { 'account-1': { threadIds: ['thread-1'] } },
450
+ accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } },
421
451
  labelPath: 'INBOX',
422
452
  };
423
453
  await mutators.thread.addLabel.fn({ args, ctx, tx: tx });
424
454
  expect(tx.mutate.threadByLabel.insert).toHaveBeenCalledWith({
425
- labelId: 'label-1',
455
+ labelId: 'test-label-id-1',
426
456
  latestMessageDate: 1234567890,
427
- threadId: 'thread-1',
457
+ threadId: 'test-thread-id-1',
428
458
  });
429
459
  expect(tx.mutate.threadLabel.insert).toHaveBeenCalled();
430
460
  expect(tx.mutate.thread.update).toHaveBeenCalledWith({
431
- id: 'thread-1',
432
- labelIdList: expect.stringContaining('label-1'),
461
+ id: 'test-thread-id-1',
462
+ labelIdList: expect.stringContaining('test-label-id-1'),
433
463
  });
434
464
  });
435
465
  it('does nothing if label not found', async () => {
436
466
  tx.run = mock(() => Promise.resolve(null));
437
467
  const args = {
438
- accounts: { 'account-1': { threadIds: ['thread-1'] } },
468
+ accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } },
439
469
  labelPath: 'NONEXISTENT',
440
470
  };
441
471
  await mutators.thread.addLabel.fn({ args, ctx, tx: tx });
@@ -446,50 +476,54 @@ describe('mutators', () => {
446
476
  describe('delete', () => {
447
477
  it('deletes threads and updates unread counts', async () => {
448
478
  tx.run = mock()
449
- .mockResolvedValueOnce({ id: 'thread-1', labelIdList: ' label-1 ', seen: false })
450
- .mockResolvedValueOnce([{ id: 'label-1', unreadCount: 5 }]);
451
- const args = { accounts: { 'account-1': { threadIds: ['thread-1'] } } };
479
+ .mockResolvedValueOnce({ id: 'test-thread-id-1', labelIdList: ' test-label-id-1 ', seen: false })
480
+ .mockResolvedValueOnce([{ id: 'test-label-id-1', unreadCount: 5 }]);
481
+ const args = { accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } } };
452
482
  await mutators.thread.delete.fn({ args, ctx, tx: tx });
453
- expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'label-1', unreadCount: 4 });
454
- expect(tx.mutate.thread.delete).toHaveBeenCalledWith({ id: 'thread-1' });
483
+ expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'test-label-id-1', unreadCount: 4 });
484
+ expect(tx.mutate.thread.delete).toHaveBeenCalledWith({ id: 'test-thread-id-1' });
455
485
  });
456
486
  it('skips unread count update for seen threads', async () => {
457
- tx.run = mock(() => Promise.resolve({ id: 'thread-1', labelIdList: '', seen: true }));
458
- const args = { accounts: { 'account-1': { threadIds: ['thread-1'] } } };
487
+ tx.run = mock(() => Promise.resolve({ id: 'test-thread-id-1', labelIdList: '', seen: true }));
488
+ const args = { accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } } };
459
489
  await mutators.thread.delete.fn({ args, ctx, tx: tx });
460
490
  expect(tx.mutate.accountLabel.update).not.toHaveBeenCalled();
461
- expect(tx.mutate.thread.delete).toHaveBeenCalledWith({ id: 'thread-1' });
491
+ expect(tx.mutate.thread.delete).toHaveBeenCalledWith({ id: 'test-thread-id-1' });
462
492
  });
463
493
  });
464
494
  describe('removeLabel', () => {
465
495
  it('removes a label from threads', async () => {
466
496
  tx.run = mock()
467
- .mockResolvedValueOnce({ id: 'label-1', unreadCount: 5 })
468
- .mockResolvedValueOnce({ id: 'thread-1', labelIdList: ' label-1 label-2 ', seen: false })
469
- .mockResolvedValueOnce([{ id: 'message-1' }]);
497
+ .mockResolvedValueOnce({ id: 'test-label-id-1', unreadCount: 5 })
498
+ .mockResolvedValueOnce({
499
+ id: 'test-thread-id-1',
500
+ labelIdList: ' test-label-id-1 test-label-id-2 ',
501
+ seen: false,
502
+ })
503
+ .mockResolvedValueOnce([{ id: 'test-message-id-1' }]);
470
504
  const args = {
471
- accounts: { 'account-1': { threadIds: ['thread-1'] } },
505
+ accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } },
472
506
  labelPath: 'INBOX',
473
507
  };
474
508
  await mutators.thread.removeLabel.fn({ args, ctx, tx: tx });
475
509
  expect(tx.mutate.threadLabel.delete).toHaveBeenCalledWith({
476
- accountId: 'account-1',
477
- labelId: 'label-1',
478
- threadMessageId: 'message-1',
510
+ accountId: 'test-account-id-1',
511
+ labelId: 'test-label-id-1',
512
+ threadMessageId: 'test-message-id-1',
479
513
  });
480
514
  expect(tx.mutate.threadByLabel.delete).toHaveBeenCalledWith({
481
- labelId: 'label-1',
482
- threadId: 'thread-1',
515
+ labelId: 'test-label-id-1',
516
+ threadId: 'test-thread-id-1',
483
517
  });
484
- expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'label-1', unreadCount: 4 });
518
+ expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'test-label-id-1', unreadCount: 4 });
485
519
  });
486
520
  it('does nothing if thread does not have label', async () => {
487
521
  tx.run = mock()
488
- .mockResolvedValueOnce({ id: 'label-1' })
489
- .mockResolvedValueOnce({ id: 'thread-1', labelIdList: ' label-2 ' })
522
+ .mockResolvedValueOnce({ id: 'test-label-id-1' })
523
+ .mockResolvedValueOnce({ id: 'test-thread-id-1', labelIdList: ' test-label-id-2 ' })
490
524
  .mockResolvedValueOnce([]);
491
525
  const args = {
492
- accounts: { 'account-1': { threadIds: ['thread-1'] } },
526
+ accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } },
493
527
  labelPath: 'INBOX',
494
528
  };
495
529
  await mutators.thread.removeLabel.fn({ args, ctx, tx: tx });
@@ -499,34 +533,37 @@ describe('mutators', () => {
499
533
  });
500
534
  describe('setFlagged', () => {
501
535
  it('sets flagged status', async () => {
502
- const args = { accounts: { 'account-1': { threadIds: ['thread-1', 'thread-2'] } }, flagged: true };
536
+ const args = {
537
+ accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1', 'test-thread-id-2'] } },
538
+ flagged: true,
539
+ };
503
540
  await mutators.thread.setFlagged.fn({ args, ctx, tx: tx });
504
- expect(tx.mutate.thread.update).toHaveBeenCalledWith({ flagged: true, id: 'thread-1' });
505
- expect(tx.mutate.thread.update).toHaveBeenCalledWith({ flagged: true, id: 'thread-2' });
541
+ expect(tx.mutate.thread.update).toHaveBeenCalledWith({ flagged: true, id: 'test-thread-id-1' });
542
+ expect(tx.mutate.thread.update).toHaveBeenCalledWith({ flagged: true, id: 'test-thread-id-2' });
506
543
  });
507
544
  });
508
545
  describe('setSeen', () => {
509
546
  it('marks threads as seen and updates label counts', async () => {
510
547
  tx.run = mock()
511
- .mockResolvedValueOnce([{ id: 'thread-1', labelIdList: ' label-1 ', seen: false }])
512
- .mockResolvedValueOnce([{ id: 'label-1', unreadCount: 5 }]);
513
- const args = { accounts: { 'account-1': { threadIds: ['thread-1'] } }, seen: true };
548
+ .mockResolvedValueOnce([{ id: 'test-thread-id-1', labelIdList: ' test-label-id-1 ', seen: false }])
549
+ .mockResolvedValueOnce([{ id: 'test-label-id-1', unreadCount: 5 }]);
550
+ const args = { accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } }, seen: true };
514
551
  await mutators.thread.setSeen.fn({ args, ctx, tx: tx });
515
- expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'label-1', unreadCount: 4 });
516
- expect(tx.mutate.thread.update).toHaveBeenCalledWith({ id: 'thread-1', seen: true });
552
+ expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'test-label-id-1', unreadCount: 4 });
553
+ expect(tx.mutate.thread.update).toHaveBeenCalledWith({ id: 'test-thread-id-1', seen: true });
517
554
  });
518
555
  it('marks threads as unseen and increments label counts', async () => {
519
556
  tx.run = mock()
520
- .mockResolvedValueOnce([{ id: 'thread-1', labelIdList: ' label-1 ', seen: true }])
521
- .mockResolvedValueOnce([{ id: 'label-1', unreadCount: 5 }]);
522
- const args = { accounts: { 'account-1': { threadIds: ['thread-1'] } }, seen: false };
557
+ .mockResolvedValueOnce([{ id: 'test-thread-id-1', labelIdList: ' test-label-id-1 ', seen: true }])
558
+ .mockResolvedValueOnce([{ id: 'test-label-id-1', unreadCount: 5 }]);
559
+ const args = { accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } }, seen: false };
523
560
  await mutators.thread.setSeen.fn({ args, ctx, tx: tx });
524
- expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'label-1', unreadCount: 6 });
525
- expect(tx.mutate.thread.update).toHaveBeenCalledWith({ id: 'thread-1', seen: false });
561
+ expect(tx.mutate.accountLabel.update).toHaveBeenCalledWith({ id: 'test-label-id-1', unreadCount: 6 });
562
+ expect(tx.mutate.thread.update).toHaveBeenCalledWith({ id: 'test-thread-id-1', seen: false });
526
563
  });
527
564
  it('skips label update when thread seen status unchanged', async () => {
528
- tx.run = mock(() => Promise.resolve([{ id: 'thread-1', labelIdList: ' label-1 ', seen: true }]));
529
- const args = { accounts: { 'account-1': { threadIds: ['thread-1'] } }, seen: true };
565
+ tx.run = mock(() => Promise.resolve([{ id: 'test-thread-id-1', labelIdList: ' test-label-id-1 ', seen: true }]));
566
+ const args = { accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } }, seen: true };
530
567
  await mutators.thread.setSeen.fn({ args, ctx, tx: tx });
531
568
  expect(tx.mutate.accountLabel.update).not.toHaveBeenCalled();
532
569
  });
@@ -542,26 +579,29 @@ describe('mutators', () => {
542
579
  it(`moves thread to ${specialUse} label`, async () => {
543
580
  tx.run = mock()
544
581
  .mockResolvedValueOnce({
545
- accountId: 'account-1',
546
- id: 'thread-1',
547
- labelIdList: ' old-label ',
582
+ accountId: 'test-account-id-1',
583
+ id: 'test-thread-id-1',
584
+ labelIdList: ' test-label-id-1 ',
548
585
  latestMessageDate: 1234567890,
549
586
  seen: true,
550
587
  })
551
- .mockResolvedValueOnce({ id: 'new-label', uidValidity: 1 })
552
- .mockResolvedValueOnce([{ id: 'message-1' }])
553
- .mockResolvedValueOnce([{ id: 'old-label', unreadCount: 0 }]);
554
- const args = { accounts: { 'account-1': { threadIds: ['thread-1'] } } };
588
+ .mockResolvedValueOnce({ id: 'test-label-id-2', uidValidity: 1 })
589
+ .mockResolvedValueOnce([{ id: 'test-message-id-1' }])
590
+ .mockResolvedValueOnce([{ id: 'test-label-id-1', unreadCount: 0 }]);
591
+ const args = { accounts: { 'test-account-id-1': { threadIds: ['test-thread-id-1'] } } };
555
592
  await mutators.thread[mutatorName].fn({ args, ctx, tx: tx });
556
- expect(tx.mutate.threadByLabel.delete).toHaveBeenCalledWith({ labelId: 'old-label', threadId: 'thread-1' });
593
+ expect(tx.mutate.threadByLabel.delete).toHaveBeenCalledWith({
594
+ labelId: 'test-label-id-1',
595
+ threadId: 'test-thread-id-1',
596
+ });
557
597
  expect(tx.mutate.threadByLabel.insert).toHaveBeenCalledWith({
558
- labelId: 'new-label',
598
+ labelId: 'test-label-id-2',
559
599
  latestMessageDate: 1234567890,
560
- threadId: 'thread-1',
600
+ threadId: 'test-thread-id-1',
561
601
  });
562
602
  expect(tx.mutate.thread.update).toHaveBeenCalledWith({
563
- id: 'thread-1',
564
- labelIdList: expect.stringContaining('new-label'),
603
+ id: 'test-thread-id-1',
604
+ labelIdList: expect.stringContaining('test-label-id-2'),
565
605
  });
566
606
  });
567
607
  });
@@ -570,38 +610,38 @@ describe('mutators', () => {
570
610
  describe('user', () => {
571
611
  describe('deleteSettingsPushNotificationToken', () => {
572
612
  it('deletes a push notification token', async () => {
573
- const args = { id: 'token-1', token: 'abc123' };
613
+ const args = { id: 'test-token-id-1', token: 'test-token-1' };
574
614
  await mutators.user.deleteSettingsPushNotificationToken.fn({ args, ctx, tx: tx });
575
- expect(tx.mutate.userPushNotificationToken.delete).toHaveBeenCalledWith({ id: 'token-1' });
615
+ expect(tx.mutate.userPushNotificationToken.delete).toHaveBeenCalledWith({ id: 'test-token-id-1' });
576
616
  });
577
617
  });
578
618
  describe('setSettingsName', () => {
579
619
  it('updates user name', async () => {
580
- const args = { id: 'user-1', name: 'New Name' };
620
+ const args = { id: 'test-user-id-1', name: 'test-user-new-name' };
581
621
  await mutators.user.setSettingsName.fn({ args, ctx, tx: tx });
582
- expect(tx.mutate.user.update).toHaveBeenCalledWith({ id: 'user-1', name: 'New Name' });
622
+ expect(tx.mutate.user.update).toHaveBeenCalledWith({ id: 'test-user-id-1', name: 'test-user-new-name' });
583
623
  });
584
624
  });
585
625
  describe('setSettingsPushNotificationToken', () => {
586
626
  it('inserts a new push notification token', async () => {
587
627
  tx.run = mock(() => Promise.resolve(null));
588
628
  const args = {
589
- id: 'user-1',
590
- pushNotificationToken: { createdAt: 1234567890, id: 'token-1', token: 'abc123' },
629
+ id: 'test-user-id-1',
630
+ pushNotificationToken: { createdAt: 1234567890, id: 'test-token-id-1', token: 'test-token-1' },
591
631
  };
592
632
  await mutators.user.setSettingsPushNotificationToken.fn({ args, ctx, tx: tx });
593
633
  expect(tx.mutate.userPushNotificationToken.insert).toHaveBeenCalledWith({
594
634
  createdAt: 1234567890,
595
- id: 'token-1',
596
- token: 'abc123',
597
- userId: 'user-1',
635
+ id: 'test-token-id-1',
636
+ token: 'test-token-1',
637
+ userId: 'test-user-id-1',
598
638
  });
599
639
  });
600
640
  it('skips insert if token already exists', async () => {
601
641
  tx.run = mock(() => Promise.resolve({ id: 'existing-token' }));
602
642
  const args = {
603
- id: 'user-1',
604
- pushNotificationToken: { createdAt: 1234567890, id: 'token-1', token: 'abc123' },
643
+ id: 'test-user-id-1',
644
+ pushNotificationToken: { createdAt: 1234567890, id: 'test-token-id-1', token: 'test-token-1' },
605
645
  };
606
646
  await mutators.user.setSettingsPushNotificationToken.fn({ args, ctx, tx: tx });
607
647
  expect(tx.mutate.userPushNotificationToken.insert).not.toHaveBeenCalled();
@@ -609,219 +649,258 @@ describe('mutators', () => {
609
649
  });
610
650
  describe('createView', () => {
611
651
  it('creates a new view', async () => {
612
- tx.run = mock(() => Promise.resolve({ id: 'user-1', views: [] }));
652
+ tx.run = mock(() => Promise.resolve({ id: 'test-user-id-1', views: [] }));
613
653
  const args = {
614
- id: 'user-1',
615
- view: { aliasEmails: ['a@example.com', 'b@example.com'], id: 'view-1', name: 'Work' },
654
+ id: 'test-user-id-1',
655
+ view: {
656
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com'],
657
+ id: 'test-view-id-1',
658
+ name: 'test-view-name-1',
659
+ },
616
660
  };
617
661
  await mutators.user.createView.fn({ args, ctx, tx: tx });
618
662
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
619
- id: 'user-1',
620
- views: [{ aliasEmails: ['a@example.com', 'b@example.com'], id: 'view-1', name: 'Work' }],
663
+ id: 'test-user-id-1',
664
+ views: [
665
+ {
666
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com'],
667
+ id: 'test-view-id-1',
668
+ name: 'test-view-name-1',
669
+ },
670
+ ],
621
671
  });
622
672
  });
623
673
  it('deduplicates aliasEmails', async () => {
624
- tx.run = mock(() => Promise.resolve({ id: 'user-1', views: [] }));
674
+ tx.run = mock(() => Promise.resolve({ id: 'test-user-id-1', views: [] }));
625
675
  const args = {
626
- id: 'user-1',
627
- view: { aliasEmails: ['a@example.com', 'b@example.com', 'a@example.com'], id: 'view-1', name: 'Work' },
676
+ id: 'test-user-id-1',
677
+ view: {
678
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com', 'test-email-1@example.com'],
679
+ id: 'test-view-id-1',
680
+ name: 'test-view-name-1',
681
+ },
628
682
  };
629
683
  await mutators.user.createView.fn({ args, ctx, tx: tx });
630
684
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
631
- id: 'user-1',
632
- views: [{ aliasEmails: ['a@example.com', 'b@example.com'], id: 'view-1', name: 'Work' }],
685
+ id: 'test-user-id-1',
686
+ views: [
687
+ {
688
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com'],
689
+ id: 'test-view-id-1',
690
+ name: 'test-view-name-1',
691
+ },
692
+ ],
633
693
  });
634
694
  });
635
695
  it('appends to existing views', async () => {
636
696
  tx.run = mock(() => Promise.resolve({
637
- id: 'user-1',
638
- views: [{ aliasEmails: ['x@example.com'], id: 'view-0', name: 'Personal' }],
697
+ id: 'test-user-id-1',
698
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
639
699
  }));
640
700
  const args = {
641
- id: 'user-1',
642
- view: { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' },
701
+ id: 'test-user-id-1',
702
+ view: { aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-2', name: 'test-view-name-2' },
643
703
  };
644
704
  await mutators.user.createView.fn({ args, ctx, tx: tx });
645
705
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
646
- id: 'user-1',
706
+ id: 'test-user-id-1',
647
707
  views: [
648
- { aliasEmails: ['x@example.com'], id: 'view-0', name: 'Personal' },
649
- { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' },
708
+ { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' },
709
+ { aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-2', name: 'test-view-name-2' },
650
710
  ],
651
711
  });
652
712
  });
653
713
  it('does nothing if user not found', async () => {
654
714
  tx.run = mock(() => Promise.resolve(null));
655
715
  const args = {
656
- id: 'user-1',
657
- view: { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' },
716
+ id: 'test-user-id-1',
717
+ view: { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' },
658
718
  };
659
719
  await mutators.user.createView.fn({ args, ctx, tx: tx });
660
720
  expect(tx.mutate.user.update).not.toHaveBeenCalled();
661
721
  });
662
722
  it('does nothing if view with same id already exists', async () => {
663
723
  tx.run = mock(() => Promise.resolve({
664
- id: 'user-1',
665
- views: [{ aliasEmails: ['x@example.com'], id: 'view-1', name: 'Existing' }],
724
+ id: 'test-user-id-1',
725
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
666
726
  }));
667
727
  const args = {
668
- id: 'user-1',
669
- view: { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' },
728
+ id: 'test-user-id-1',
729
+ view: { aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-1', name: 'test-view-name-2' },
670
730
  };
671
731
  await mutators.user.createView.fn({ args, ctx, tx: tx });
672
732
  expect(tx.mutate.user.update).not.toHaveBeenCalled();
673
733
  });
674
734
  it('does nothing if max views limit reached', async () => {
675
735
  const existingViews = Array.from({ length: 25 }, (_, i) => ({
676
- aliasEmails: [`email${i}@example.com`],
677
- id: `view-${i}`,
678
- name: `View ${i}`,
736
+ aliasEmails: [`test-email-${i}@example.com`],
737
+ id: `test-view-id-${i}`,
738
+ name: `test-view-name-${i}`,
679
739
  }));
680
- tx.run = mock(() => Promise.resolve({ id: 'user-1', views: existingViews }));
740
+ tx.run = mock(() => Promise.resolve({ id: 'test-user-id-1', views: existingViews }));
681
741
  const args = {
682
- id: 'user-1',
683
- view: { aliasEmails: ['new@example.com'], id: 'view-new', name: 'New View' },
742
+ id: 'test-user-id-1',
743
+ view: { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' },
684
744
  };
685
745
  await mutators.user.createView.fn({ args, ctx, tx: tx });
686
746
  expect(tx.mutate.user.update).not.toHaveBeenCalled();
687
747
  });
688
- it('handles null views array', async () => {
689
- tx.run = mock(() => Promise.resolve({ id: 'user-1', views: null }));
690
- const args = {
691
- id: 'user-1',
692
- view: { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' },
693
- };
694
- await mutators.user.createView.fn({ args, ctx, tx: tx });
695
- expect(tx.mutate.user.update).toHaveBeenCalledWith({
696
- id: 'user-1',
697
- views: [{ aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' }],
698
- });
699
- });
700
748
  });
701
749
  describe('deleteView', () => {
702
750
  it('deletes a view', async () => {
703
751
  tx.run = mock(() => Promise.resolve({
704
- id: 'user-1',
752
+ id: 'test-user-id-1',
705
753
  views: [
706
- { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' },
707
- { aliasEmails: ['b@example.com'], id: 'view-2', name: 'Personal' },
754
+ { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' },
755
+ { aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-2', name: 'test-view-name-2' },
708
756
  ],
709
757
  }));
710
- const args = { id: 'user-1', viewId: 'view-1' };
758
+ const args = { id: 'test-user-id-1', viewId: 'test-view-id-1' };
711
759
  await mutators.user.deleteView.fn({ args, ctx, tx: tx });
712
760
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
713
- id: 'user-1',
714
- views: [{ aliasEmails: ['b@example.com'], id: 'view-2', name: 'Personal' }],
761
+ id: 'test-user-id-1',
762
+ views: [{ aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-2', name: 'test-view-name-2' }],
715
763
  });
716
764
  });
717
765
  it('does nothing if user not found', async () => {
718
766
  tx.run = mock(() => Promise.resolve(null));
719
- const args = { id: 'user-1', viewId: 'view-1' };
767
+ const args = { id: 'test-user-id-1', viewId: 'test-view-id-1' };
720
768
  await mutators.user.deleteView.fn({ args, ctx, tx: tx });
721
769
  expect(tx.mutate.user.update).not.toHaveBeenCalled();
722
770
  });
723
- it('handles null views array', async () => {
724
- tx.run = mock(() => Promise.resolve({ id: 'user-1', views: null }));
725
- const args = { id: 'user-1', viewId: 'view-1' };
726
- await mutators.user.deleteView.fn({ args, ctx, tx: tx });
727
- expect(tx.mutate.user.update).toHaveBeenCalledWith({
728
- id: 'user-1',
729
- views: [],
730
- });
731
- });
732
771
  });
733
772
  describe('updateView', () => {
734
773
  it('updates view name', async () => {
735
774
  tx.run = mock(() => Promise.resolve({
736
- id: 'user-1',
737
- views: [{ aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' }],
775
+ id: 'test-user-id-1',
776
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
738
777
  }));
739
- const args = { id: 'user-1', updates: { name: 'Updated Work' }, viewId: 'view-1' };
778
+ const args = {
779
+ id: 'test-user-id-1',
780
+ view: { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-updated-name' },
781
+ };
740
782
  await mutators.user.updateView.fn({ args, ctx, tx: tx });
741
783
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
742
- id: 'user-1',
743
- views: [{ aliasEmails: ['a@example.com'], id: 'view-1', name: 'Updated Work' }],
784
+ id: 'test-user-id-1',
785
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-updated-name' }],
744
786
  });
745
787
  });
746
788
  it('updates view aliasEmails', async () => {
747
789
  tx.run = mock(() => Promise.resolve({
748
- id: 'user-1',
749
- views: [{ aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' }],
790
+ id: 'test-user-id-1',
791
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
750
792
  }));
751
- const args = { id: 'user-1', updates: { aliasEmails: ['x@example.com', 'y@example.com'] }, viewId: 'view-1' };
793
+ const args = {
794
+ id: 'test-user-id-1',
795
+ view: {
796
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com'],
797
+ id: 'test-view-id-1',
798
+ name: 'test-view-name-1',
799
+ },
800
+ };
752
801
  await mutators.user.updateView.fn({ args, ctx, tx: tx });
753
802
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
754
- id: 'user-1',
755
- views: [{ aliasEmails: ['x@example.com', 'y@example.com'], id: 'view-1', name: 'Work' }],
803
+ id: 'test-user-id-1',
804
+ views: [
805
+ {
806
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com'],
807
+ id: 'test-view-id-1',
808
+ name: 'test-view-name-1',
809
+ },
810
+ ],
756
811
  });
757
812
  });
758
813
  it('deduplicates aliasEmails on update', async () => {
759
814
  tx.run = mock(() => Promise.resolve({
760
- id: 'user-1',
761
- views: [{ aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' }],
815
+ id: 'test-user-id-1',
816
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
762
817
  }));
763
818
  const args = {
764
- id: 'user-1',
765
- updates: { aliasEmails: ['x@example.com', 'y@example.com', 'x@example.com'] },
766
- viewId: 'view-1',
819
+ id: 'test-user-id-1',
820
+ view: {
821
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com', 'test-email-1@example.com'],
822
+ id: 'test-view-id-1',
823
+ name: 'test-view-name-1',
824
+ },
767
825
  };
768
826
  await mutators.user.updateView.fn({ args, ctx, tx: tx });
769
827
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
770
- id: 'user-1',
771
- views: [{ aliasEmails: ['x@example.com', 'y@example.com'], id: 'view-1', name: 'Work' }],
828
+ id: 'test-user-id-1',
829
+ views: [
830
+ {
831
+ aliasEmails: ['test-email-1@example.com', 'test-email-2@example.com'],
832
+ id: 'test-view-id-1',
833
+ name: 'test-view-name-1',
834
+ },
835
+ ],
772
836
  });
773
837
  });
774
838
  it('updates both name and aliasEmails', async () => {
775
839
  tx.run = mock(() => Promise.resolve({
776
- id: 'user-1',
777
- views: [{ aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' }],
840
+ id: 'test-user-id-1',
841
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
778
842
  }));
779
843
  const args = {
780
- id: 'user-1',
781
- updates: { aliasEmails: ['x@example.com'], name: 'New Name' },
782
- viewId: 'view-1',
844
+ id: 'test-user-id-1',
845
+ view: { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-updated-name' },
783
846
  };
784
847
  await mutators.user.updateView.fn({ args, ctx, tx: tx });
785
848
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
786
- id: 'user-1',
787
- views: [{ aliasEmails: ['x@example.com'], id: 'view-1', name: 'New Name' }],
849
+ id: 'test-user-id-1',
850
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-updated-name' }],
788
851
  });
789
852
  });
790
853
  it('does nothing if user not found', async () => {
791
854
  tx.run = mock(() => Promise.resolve(null));
792
- const args = { id: 'user-1', updates: { name: 'Updated' }, viewId: 'view-1' };
855
+ const args = {
856
+ id: 'test-user-id-1',
857
+ view: { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-updated-name' },
858
+ };
793
859
  await mutators.user.updateView.fn({ args, ctx, tx: tx });
794
860
  expect(tx.mutate.user.update).not.toHaveBeenCalled();
795
861
  });
796
862
  it('does nothing if view does not exist', async () => {
797
863
  tx.run = mock(() => Promise.resolve({
798
- id: 'user-1',
799
- views: [{ aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' }],
864
+ id: 'test-user-id-1',
865
+ views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
800
866
  }));
801
- const args = { id: 'user-1', updates: { name: 'Updated' }, viewId: 'non-existent-view' };
867
+ const args = {
868
+ id: 'test-user-id-1',
869
+ view: {
870
+ aliasEmails: ['test-email-1@example.com'],
871
+ id: 'test-view-id-nonexistent',
872
+ name: 'test-updated-name',
873
+ },
874
+ };
802
875
  await mutators.user.updateView.fn({ args, ctx, tx: tx });
803
876
  expect(tx.mutate.user.update).not.toHaveBeenCalled();
804
877
  });
805
878
  it('leaves non-matching views unchanged', async () => {
806
879
  tx.run = mock(() => Promise.resolve({
807
- id: 'user-1',
880
+ id: 'test-user-id-1',
808
881
  views: [
809
- { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Work' },
810
- { aliasEmails: ['b@example.com'], id: 'view-2', name: 'Personal' },
882
+ { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' },
883
+ { aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-2', name: 'test-view-name-2' },
811
884
  ],
812
885
  }));
813
- const args = { id: 'user-1', updates: { name: 'Updated Work' }, viewId: 'view-1' };
886
+ const args = {
887
+ id: 'test-user-id-1',
888
+ view: { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-updated-name' },
889
+ };
814
890
  await mutators.user.updateView.fn({ args, ctx, tx: tx });
815
891
  expect(tx.mutate.user.update).toHaveBeenCalledWith({
816
- id: 'user-1',
892
+ id: 'test-user-id-1',
817
893
  views: [
818
- { aliasEmails: ['a@example.com'], id: 'view-1', name: 'Updated Work' },
819
- { aliasEmails: ['b@example.com'], id: 'view-2', name: 'Personal' },
894
+ { aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-updated-name' },
895
+ { aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-2', name: 'test-view-name-2' },
820
896
  ],
821
897
  });
822
898
  });
823
899
  it('schema rejects empty aliasEmails array', () => {
824
- const args = { id: 'user-1', updates: { aliasEmails: [] }, viewId: 'view-1' };
900
+ const args = {
901
+ id: 'test-user-id-1',
902
+ view: { aliasEmails: [], id: 'test-view-id-1', name: 'test-view-name-1' },
903
+ };
825
904
  const result = v.safeParse(mutatorSchemas.user.updateView, args);
826
905
  expect(result.success).toBe(false);
827
906
  });