@marcoappio/marco-config 2.0.530 → 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.
- package/dist/zero/index.d.ts +11 -38
- package/dist/zero/index.d.ts.map +1 -1
- package/dist/zero/mutatorSchemas.d.ts +3 -30
- package/dist/zero/mutatorSchemas.d.ts.map +1 -1
- package/dist/zero/mutatorSchemas.js +1 -5
- package/dist/zero/mutators.d.ts +8 -8
- package/dist/zero/mutators.d.ts.map +1 -1
- package/dist/zero/mutators.js +3 -5
- package/dist/zero/mutators.test.js +343 -243
- package/package.json +1 -1
|
@@ -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: '
|
|
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: '
|
|
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({
|
|
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: '
|
|
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({
|
|
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({
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: {
|
|
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: '
|
|
273
|
-
fromName: '
|
|
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: {
|
|
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: '
|
|
288
|
-
fromName: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
367
|
+
tx.run = mock(() => Promise.resolve({ body: { bcc: [], cc: [], content: 'test-content', to: [] } }));
|
|
348
368
|
const args = {
|
|
349
|
-
id: 'draft-1',
|
|
350
|
-
patch: [{ index:
|
|
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: '
|
|
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: '
|
|
389
|
+
tx.run = mock(() => Promise.resolve({ body: { content: 'test-content' } }));
|
|
370
390
|
const args = {
|
|
371
|
-
envelope: {
|
|
372
|
-
|
|
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: {
|
|
378
|
-
|
|
379
|
-
|
|
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: '
|
|
390
|
-
fromName: '
|
|
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: '
|
|
399
|
-
fromName: '
|
|
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({
|
|
469
|
-
|
|
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 = {
|
|
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: '
|
|
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: '
|
|
552
|
-
.mockResolvedValueOnce([{ id: 'message-1' }])
|
|
553
|
-
.mockResolvedValueOnce([{ id: '
|
|
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({
|
|
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: '
|
|
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('
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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,78 +649,98 @@ 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: {
|
|
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: [
|
|
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: {
|
|
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: [
|
|
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: ['
|
|
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: ['
|
|
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: ['
|
|
649
|
-
{ aliasEmails: ['
|
|
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: ['
|
|
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: ['
|
|
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: ['
|
|
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
|
|
677
|
-
id: `view-${i}`,
|
|
678
|
-
name: `
|
|
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: ['
|
|
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();
|
|
@@ -689,22 +749,22 @@ describe('mutators', () => {
|
|
|
689
749
|
describe('deleteView', () => {
|
|
690
750
|
it('deletes a view', async () => {
|
|
691
751
|
tx.run = mock(() => Promise.resolve({
|
|
692
|
-
id: 'user-1',
|
|
752
|
+
id: 'test-user-id-1',
|
|
693
753
|
views: [
|
|
694
|
-
{ aliasEmails: ['
|
|
695
|
-
{ aliasEmails: ['
|
|
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' },
|
|
696
756
|
],
|
|
697
757
|
}));
|
|
698
|
-
const args = { id: 'user-1', viewId: 'view-1' };
|
|
758
|
+
const args = { id: 'test-user-id-1', viewId: 'test-view-id-1' };
|
|
699
759
|
await mutators.user.deleteView.fn({ args, ctx, tx: tx });
|
|
700
760
|
expect(tx.mutate.user.update).toHaveBeenCalledWith({
|
|
701
|
-
id: 'user-1',
|
|
702
|
-
views: [{ aliasEmails: ['
|
|
761
|
+
id: 'test-user-id-1',
|
|
762
|
+
views: [{ aliasEmails: ['test-email-2@example.com'], id: 'test-view-id-2', name: 'test-view-name-2' }],
|
|
703
763
|
});
|
|
704
764
|
});
|
|
705
765
|
it('does nothing if user not found', async () => {
|
|
706
766
|
tx.run = mock(() => Promise.resolve(null));
|
|
707
|
-
const args = { id: 'user-1', viewId: 'view-1' };
|
|
767
|
+
const args = { id: 'test-user-id-1', viewId: 'test-view-id-1' };
|
|
708
768
|
await mutators.user.deleteView.fn({ args, ctx, tx: tx });
|
|
709
769
|
expect(tx.mutate.user.update).not.toHaveBeenCalled();
|
|
710
770
|
});
|
|
@@ -712,95 +772,135 @@ describe('mutators', () => {
|
|
|
712
772
|
describe('updateView', () => {
|
|
713
773
|
it('updates view name', async () => {
|
|
714
774
|
tx.run = mock(() => Promise.resolve({
|
|
715
|
-
id: 'user-1',
|
|
716
|
-
views: [{ aliasEmails: ['
|
|
775
|
+
id: 'test-user-id-1',
|
|
776
|
+
views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
|
|
717
777
|
}));
|
|
718
|
-
const args = {
|
|
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
|
+
};
|
|
719
782
|
await mutators.user.updateView.fn({ args, ctx, tx: tx });
|
|
720
783
|
expect(tx.mutate.user.update).toHaveBeenCalledWith({
|
|
721
|
-
id: 'user-1',
|
|
722
|
-
views: [{ aliasEmails: ['
|
|
784
|
+
id: 'test-user-id-1',
|
|
785
|
+
views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-updated-name' }],
|
|
723
786
|
});
|
|
724
787
|
});
|
|
725
788
|
it('updates view aliasEmails', async () => {
|
|
726
789
|
tx.run = mock(() => Promise.resolve({
|
|
727
|
-
id: 'user-1',
|
|
728
|
-
views: [{ aliasEmails: ['
|
|
790
|
+
id: 'test-user-id-1',
|
|
791
|
+
views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
|
|
729
792
|
}));
|
|
730
|
-
const args = {
|
|
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
|
+
};
|
|
731
801
|
await mutators.user.updateView.fn({ args, ctx, tx: tx });
|
|
732
802
|
expect(tx.mutate.user.update).toHaveBeenCalledWith({
|
|
733
|
-
id: 'user-1',
|
|
734
|
-
views: [
|
|
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
|
+
],
|
|
735
811
|
});
|
|
736
812
|
});
|
|
737
813
|
it('deduplicates aliasEmails on update', async () => {
|
|
738
814
|
tx.run = mock(() => Promise.resolve({
|
|
739
|
-
id: 'user-1',
|
|
740
|
-
views: [{ aliasEmails: ['
|
|
815
|
+
id: 'test-user-id-1',
|
|
816
|
+
views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
|
|
741
817
|
}));
|
|
742
818
|
const args = {
|
|
743
|
-
id: 'user-1',
|
|
744
|
-
|
|
745
|
-
|
|
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
|
+
},
|
|
746
825
|
};
|
|
747
826
|
await mutators.user.updateView.fn({ args, ctx, tx: tx });
|
|
748
827
|
expect(tx.mutate.user.update).toHaveBeenCalledWith({
|
|
749
|
-
id: 'user-1',
|
|
750
|
-
views: [
|
|
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
|
+
],
|
|
751
836
|
});
|
|
752
837
|
});
|
|
753
838
|
it('updates both name and aliasEmails', async () => {
|
|
754
839
|
tx.run = mock(() => Promise.resolve({
|
|
755
|
-
id: 'user-1',
|
|
756
|
-
views: [{ aliasEmails: ['
|
|
840
|
+
id: 'test-user-id-1',
|
|
841
|
+
views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
|
|
757
842
|
}));
|
|
758
843
|
const args = {
|
|
759
|
-
id: 'user-1',
|
|
760
|
-
|
|
761
|
-
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' },
|
|
762
846
|
};
|
|
763
847
|
await mutators.user.updateView.fn({ args, ctx, tx: tx });
|
|
764
848
|
expect(tx.mutate.user.update).toHaveBeenCalledWith({
|
|
765
|
-
id: 'user-1',
|
|
766
|
-
views: [{ aliasEmails: ['
|
|
849
|
+
id: 'test-user-id-1',
|
|
850
|
+
views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-updated-name' }],
|
|
767
851
|
});
|
|
768
852
|
});
|
|
769
853
|
it('does nothing if user not found', async () => {
|
|
770
854
|
tx.run = mock(() => Promise.resolve(null));
|
|
771
|
-
const args = {
|
|
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
|
+
};
|
|
772
859
|
await mutators.user.updateView.fn({ args, ctx, tx: tx });
|
|
773
860
|
expect(tx.mutate.user.update).not.toHaveBeenCalled();
|
|
774
861
|
});
|
|
775
862
|
it('does nothing if view does not exist', async () => {
|
|
776
863
|
tx.run = mock(() => Promise.resolve({
|
|
777
|
-
id: 'user-1',
|
|
778
|
-
views: [{ aliasEmails: ['
|
|
864
|
+
id: 'test-user-id-1',
|
|
865
|
+
views: [{ aliasEmails: ['test-email-1@example.com'], id: 'test-view-id-1', name: 'test-view-name-1' }],
|
|
779
866
|
}));
|
|
780
|
-
const args = {
|
|
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
|
+
};
|
|
781
875
|
await mutators.user.updateView.fn({ args, ctx, tx: tx });
|
|
782
876
|
expect(tx.mutate.user.update).not.toHaveBeenCalled();
|
|
783
877
|
});
|
|
784
878
|
it('leaves non-matching views unchanged', async () => {
|
|
785
879
|
tx.run = mock(() => Promise.resolve({
|
|
786
|
-
id: 'user-1',
|
|
880
|
+
id: 'test-user-id-1',
|
|
787
881
|
views: [
|
|
788
|
-
{ aliasEmails: ['
|
|
789
|
-
{ aliasEmails: ['
|
|
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' },
|
|
790
884
|
],
|
|
791
885
|
}));
|
|
792
|
-
const args = {
|
|
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
|
+
};
|
|
793
890
|
await mutators.user.updateView.fn({ args, ctx, tx: tx });
|
|
794
891
|
expect(tx.mutate.user.update).toHaveBeenCalledWith({
|
|
795
|
-
id: 'user-1',
|
|
892
|
+
id: 'test-user-id-1',
|
|
796
893
|
views: [
|
|
797
|
-
{ aliasEmails: ['
|
|
798
|
-
{ aliasEmails: ['
|
|
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' },
|
|
799
896
|
],
|
|
800
897
|
});
|
|
801
898
|
});
|
|
802
899
|
it('schema rejects empty aliasEmails array', () => {
|
|
803
|
-
const args = {
|
|
900
|
+
const args = {
|
|
901
|
+
id: 'test-user-id-1',
|
|
902
|
+
view: { aliasEmails: [], id: 'test-view-id-1', name: 'test-view-name-1' },
|
|
903
|
+
};
|
|
804
904
|
const result = v.safeParse(mutatorSchemas.user.updateView, args);
|
|
805
905
|
expect(result.success).toBe(false);
|
|
806
906
|
});
|