1
1
import {
2
2
DEFAULT_WORKFLOW_PREFERENCES ,
3
3
PreferencesTypeEnum ,
4
+ WorkflowPreferences ,
4
5
} from '@novu/shared' ;
5
6
import { describe , expect , it } from 'vitest' ;
6
7
import { MergePreferencesCommand } from './merge-preferences.command' ;
7
8
import { MergePreferences } from './merge-preferences.usecase' ;
8
- import { PreferenceSet } from '../.. ' ;
9
+ import { PreferenceSet } from '../get-preferences/get-preferences.usecase ' ;
9
10
10
- const DEFAULT_WORKFLOW_PREFERENCES_WITH_EMAIL_DISABLED = {
11
+ /**
12
+ * This test spec is used to test the merge preferences usecase.
13
+ * It covers all the possible combinations of preferences types and readOnly flag.
14
+ */
15
+
16
+ const MOCK_SUBSCRIBER_GLOBAL_PREFERENCE = {
11
17
...DEFAULT_WORKFLOW_PREFERENCES ,
12
18
channels : {
13
19
...DEFAULT_WORKFLOW_PREFERENCES . channels ,
14
20
email : { enabled : false } ,
21
+ in_app : { enabled : true } ,
22
+ } ,
23
+ } ;
24
+
25
+ const MOCK_SUBSCRIBER_WORKFLOW_PREFERENCE = {
26
+ ...DEFAULT_WORKFLOW_PREFERENCES ,
27
+ channels : {
28
+ ...DEFAULT_WORKFLOW_PREFERENCES . channels ,
29
+ email : { enabled : true } ,
30
+ in_app : { enabled : true } ,
15
31
} ,
16
32
} ;
17
33
@@ -20,7 +36,6 @@ type TestCase = {
20
36
types : PreferencesTypeEnum [ ] ;
21
37
expectedType : PreferencesTypeEnum ;
22
38
readOnly : boolean ;
23
- subscriberOverrides ?: boolean ;
24
39
} ;
25
40
26
41
const testCases : TestCase [ ] = [
@@ -144,7 +159,6 @@ const testCases: TestCase[] = [
144
159
] ,
145
160
expectedType : PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ,
146
161
readOnly : false ,
147
- subscriberOverrides : true ,
148
162
} ,
149
163
{
150
164
comment : 'Subscriber global overrides workflow resource' ,
@@ -154,7 +168,6 @@ const testCases: TestCase[] = [
154
168
] ,
155
169
expectedType : PreferencesTypeEnum . SUBSCRIBER_GLOBAL ,
156
170
readOnly : false ,
157
- subscriberOverrides : true ,
158
171
} ,
159
172
{
160
173
comment : 'Subscriber workflow overrides user workflow' ,
@@ -165,7 +178,6 @@ const testCases: TestCase[] = [
165
178
] ,
166
179
expectedType : PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ,
167
180
readOnly : false ,
168
- subscriberOverrides : true ,
169
181
} ,
170
182
{
171
183
comment : 'Subscriber global overrides user workflow' ,
@@ -176,7 +188,17 @@ const testCases: TestCase[] = [
176
188
] ,
177
189
expectedType : PreferencesTypeEnum . SUBSCRIBER_GLOBAL ,
178
190
readOnly : false ,
179
- subscriberOverrides : true ,
191
+ } ,
192
+ {
193
+ comment : 'Subscriber workflow overrides subscriber global' ,
194
+ types : [
195
+ PreferencesTypeEnum . WORKFLOW_RESOURCE ,
196
+ PreferencesTypeEnum . USER_WORKFLOW ,
197
+ PreferencesTypeEnum . SUBSCRIBER_GLOBAL ,
198
+ PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ,
199
+ ] ,
200
+ expectedType : PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ,
201
+ readOnly : false ,
180
202
} ,
181
203
// Subscriber overrides with readOnly true behavior
182
204
{
@@ -188,7 +210,6 @@ const testCases: TestCase[] = [
188
210
] ,
189
211
expectedType : PreferencesTypeEnum . WORKFLOW_RESOURCE ,
190
212
readOnly : true ,
191
- subscriberOverrides : true ,
192
213
} ,
193
214
{
194
215
comment :
@@ -199,7 +220,6 @@ const testCases: TestCase[] = [
199
220
] ,
200
221
expectedType : PreferencesTypeEnum . WORKFLOW_RESOURCE ,
201
222
readOnly : true ,
202
- subscriberOverrides : true ,
203
223
} ,
204
224
{
205
225
comment :
@@ -211,7 +231,6 @@ const testCases: TestCase[] = [
211
231
] ,
212
232
expectedType : PreferencesTypeEnum . USER_WORKFLOW ,
213
233
readOnly : true ,
214
- subscriberOverrides : true ,
215
234
} ,
216
235
{
217
236
comment :
@@ -223,97 +242,111 @@ const testCases: TestCase[] = [
223
242
] ,
224
243
expectedType : PreferencesTypeEnum . USER_WORKFLOW ,
225
244
readOnly : true ,
226
- subscriberOverrides : true ,
245
+ } ,
246
+ {
247
+ comment :
248
+ 'Subscriber global+workflow cannot override user workflow when readOnly is true' ,
249
+ types : [
250
+ PreferencesTypeEnum . WORKFLOW_RESOURCE ,
251
+ PreferencesTypeEnum . USER_WORKFLOW ,
252
+ PreferencesTypeEnum . SUBSCRIBER_GLOBAL ,
253
+ PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ,
254
+ ] ,
255
+ expectedType : PreferencesTypeEnum . USER_WORKFLOW ,
256
+ readOnly : true ,
227
257
} ,
228
258
] ;
229
259
230
260
describe ( 'MergePreferences' , ( ) => {
231
261
describe ( 'merging readOnly and subscriberOverrides' , ( ) => {
232
- testCases . forEach (
233
- ( {
234
- types,
235
- expectedType,
236
- readOnly,
237
- subscriberOverrides = false ,
238
- comment = '' ,
239
- } ) => {
240
- it ( `should merge preferences for types: ${ types . join ( ', ' ) } with readOnly: ${ readOnly } ${ comment ? ` (${ comment } )` : '' } ` , ( ) => {
241
- const preferenceSet = types . reduce ( ( acc , type , index ) => {
242
- const preference = {
243
- _id : `${ index + 1 } ` ,
244
- _organizationId : '1' ,
245
- _environmentId : '1' ,
246
- type,
247
- preferences : {
248
- // default
249
- ...DEFAULT_WORKFLOW_PREFERENCES ,
250
- // readOnly
251
- all : { ...DEFAULT_WORKFLOW_PREFERENCES . all , readOnly } ,
252
- // subscriber overrides
253
- ...( [
254
- PreferencesTypeEnum . SUBSCRIBER_GLOBAL ,
255
- PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ,
256
- ] . includes ( type ) &&
257
- subscriberOverrides &&
258
- // only apply subscriber overrides if readOnly is false
259
- ! readOnly
260
- ? DEFAULT_WORKFLOW_PREFERENCES_WITH_EMAIL_DISABLED
261
- : { } ) ,
262
- } ,
263
- } ;
262
+ testCases . forEach ( ( { types, expectedType, readOnly, comment = '' } ) => {
263
+ it ( `should merge preferences for types: ${ types . join ( ', ' ) } with readOnly: ${ readOnly } ${ comment ? ` (${ comment } )` : '' } ` , ( ) => {
264
+ const preferenceSet = types . reduce ( ( acc , type , index ) => {
265
+ const preference = {
266
+ _id : `${ index + 1 } ` ,
267
+ _organizationId : '1' ,
268
+ _environmentId : '1' ,
269
+ type,
270
+ preferences : {
271
+ // default
272
+ ...DEFAULT_WORKFLOW_PREFERENCES ,
273
+ // readOnly
274
+ all : { ...DEFAULT_WORKFLOW_PREFERENCES . all , readOnly } ,
275
+ // subscriber overrides
276
+ ...( PreferencesTypeEnum . SUBSCRIBER_GLOBAL === type
277
+ ? MOCK_SUBSCRIBER_GLOBAL_PREFERENCE
278
+ : { } ) ,
279
+ ...( PreferencesTypeEnum . SUBSCRIBER_WORKFLOW === type
280
+ ? MOCK_SUBSCRIBER_WORKFLOW_PREFERENCE
281
+ : { } ) ,
282
+ } ,
283
+ } ;
264
284
265
- switch ( type ) {
266
- case PreferencesTypeEnum . WORKFLOW_RESOURCE :
267
- acc . workflowResourcePreference = preference ;
268
- break ;
269
- case PreferencesTypeEnum . USER_WORKFLOW :
270
- acc . workflowUserPreference = preference ;
271
- break ;
272
- case PreferencesTypeEnum . SUBSCRIBER_GLOBAL :
273
- acc . subscriberGlobalPreference = preference ;
274
- break ;
275
- case PreferencesTypeEnum . SUBSCRIBER_WORKFLOW :
276
- acc . subscriberWorkflowPreference = preference ;
277
- break ;
278
- default :
279
- throw new Error ( `Unknown preference type: ${ type } ` ) ;
280
- }
285
+ switch ( type ) {
286
+ case PreferencesTypeEnum . WORKFLOW_RESOURCE :
287
+ acc . workflowResourcePreference = preference ;
288
+ break ;
289
+ case PreferencesTypeEnum . USER_WORKFLOW :
290
+ acc . workflowUserPreference = preference ;
291
+ break ;
292
+ case PreferencesTypeEnum . SUBSCRIBER_GLOBAL :
293
+ acc . subscriberGlobalPreference = preference ;
294
+ break ;
295
+ case PreferencesTypeEnum . SUBSCRIBER_WORKFLOW :
296
+ acc . subscriberWorkflowPreference = preference ;
297
+ break ;
298
+ default :
299
+ throw new Error ( `Unknown preference type: ${ type } ` ) ;
300
+ }
281
301
282
- return acc ;
283
- } , { } as PreferenceSet ) ;
302
+ return acc ;
303
+ } , { } as PreferenceSet ) ;
284
304
285
- const command = MergePreferencesCommand . create ( preferenceSet ) ;
305
+ const command = MergePreferencesCommand . create ( preferenceSet ) ;
286
306
287
- const result = MergePreferences . execute ( command ) ;
307
+ const result = MergePreferences . execute ( command ) ;
288
308
289
- const expectedPreferences =
290
- subscriberOverrides && ! readOnly
291
- ? DEFAULT_WORKFLOW_PREFERENCES_WITH_EMAIL_DISABLED
292
- : {
293
- ...DEFAULT_WORKFLOW_PREFERENCES ,
294
- all : { ...DEFAULT_WORKFLOW_PREFERENCES . all , readOnly } ,
295
- } ;
309
+ const hasSubscriberGlobalPreference =
310
+ ! ! preferenceSet . subscriberGlobalPreference ;
311
+ const hasSubscriberWorkflowPreference =
312
+ ! ! preferenceSet . subscriberWorkflowPreference ;
296
313
297
- expect ( result ) . toEqual ( {
298
- preferences : expectedPreferences ,
299
- type : expectedType ,
300
- source : {
301
- [ PreferencesTypeEnum . WORKFLOW_RESOURCE ] : null ,
302
- [ PreferencesTypeEnum . USER_WORKFLOW ] : null ,
303
- [ PreferencesTypeEnum . SUBSCRIBER_GLOBAL ] : null ,
304
- [ PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ] : null ,
305
- ...Object . entries ( preferenceSet ) . reduce ( ( acc , [ key , pref ] ) => {
306
- if ( pref ) {
307
- acc [ pref . type ] = pref . preferences ;
308
- }
314
+ let expectedPreferences : WorkflowPreferences ;
309
315
310
- return acc ;
311
- } , { } ) ,
312
- } ,
313
- } ) ;
316
+ if ( ! readOnly ) {
317
+ if ( hasSubscriberWorkflowPreference ) {
318
+ expectedPreferences = MOCK_SUBSCRIBER_WORKFLOW_PREFERENCE ;
319
+ } else if ( hasSubscriberGlobalPreference ) {
320
+ expectedPreferences = MOCK_SUBSCRIBER_GLOBAL_PREFERENCE ;
321
+ } else {
322
+ expectedPreferences = DEFAULT_WORKFLOW_PREFERENCES ;
323
+ }
324
+ } else {
325
+ expectedPreferences = {
326
+ ...DEFAULT_WORKFLOW_PREFERENCES ,
327
+ all : { ...DEFAULT_WORKFLOW_PREFERENCES . all , readOnly } ,
328
+ } ;
329
+ }
330
+
331
+ expect ( result ) . toEqual ( {
332
+ preferences : expectedPreferences ,
333
+ type : expectedType ,
334
+ source : {
335
+ [ PreferencesTypeEnum . WORKFLOW_RESOURCE ] : null ,
336
+ [ PreferencesTypeEnum . USER_WORKFLOW ] : null ,
337
+ [ PreferencesTypeEnum . SUBSCRIBER_GLOBAL ] : null ,
338
+ [ PreferencesTypeEnum . SUBSCRIBER_WORKFLOW ] : null ,
339
+ ...Object . entries ( preferenceSet ) . reduce ( ( acc , [ key , pref ] ) => {
340
+ if ( pref ) {
341
+ acc [ pref . type ] = pref . preferences ;
342
+ }
343
+
344
+ return acc ;
345
+ } , { } ) ,
346
+ } ,
314
347
} ) ;
315
- } ,
316
- ) ;
348
+ } ) ;
349
+ } ) ;
317
350
} ) ;
318
351
319
352
it ( 'should have test cases for all combinations of PreferencesTypeEnum' , ( ) => {
@@ -344,7 +377,10 @@ describe('MergePreferences', () => {
344
377
345
378
allCombinations . forEach ( ( combination ) => {
346
379
const combinationKey = combination . sort ( ) . join ( ',' ) ;
347
- expect ( coveredCombinations ) . toContain ( combinationKey ) ;
380
+ expect (
381
+ coveredCombinations ,
382
+ `Combination ${ combinationKey } is not covered` ,
383
+ ) . toContain ( combinationKey ) ;
348
384
} ) ;
349
385
} ) ;
350
386
} ) ;
0 commit comments