musora-content-services 1.0.104 → 1.0.107

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.
@@ -1,4 +1,5 @@
1
1
  import {initializeService} from '../src/services/config.js';
2
+ import {log} from './log.js';
2
3
 
3
4
  const {
4
5
  fetchSongById,
@@ -8,33 +9,34 @@ const {
8
9
  fetchAllSongs,
9
10
  fetchSongFilterOptions,
10
11
  fetchSongCount,
11
- fetchWorkouts,
12
12
  fetchNewReleases,
13
13
  fetchUpcomingEvents,
14
14
  fetchByRailContentId,
15
15
  fetchByRailContentIds,
16
16
  fetchAll,
17
17
  fetchAllFilterOptions,
18
- fetchMethodNextLesson,
19
- fetchMethodChildrenIds,
20
- fetchNextPreviousLesson,
18
+ fetchFoundation,
19
+ fetchMethods,
20
+ fetchMethod,
21
21
  fetchRelatedLessons,
22
+ fetchAllPacks,
22
23
  fetchPackAll,
23
- fetchPackChildren,
24
24
  fetchLessonContent,
25
- getSortOrder,
26
- fetchParentByRailContentId,
25
+ fetchCourseOverview,
27
26
  fetchChildren,
28
- fetchMethod,
29
- fetchMethods,
30
- fetchFoundation,
31
- fetchAllPacks,
32
- fetchPacksAll,
27
+ fetchParentByRailContentId,
28
+ fetchLiveEvent,
29
+ fetchChallengeOverview,
33
30
  fetchCoachLessons,
34
31
  fetchByReference,
35
- fetchScheduledReleases
32
+ fetchScheduledReleases,
33
+ getSortOrder,
36
34
  } = require('../src/services/sanity.js');
37
35
 
36
+ const {
37
+ FilterBuilder,
38
+ } = require('../src/filterBuilder.js');
39
+
38
40
  describe('Sanity Queries', function () {
39
41
  beforeEach(() => {
40
42
  const config = {
@@ -66,13 +68,20 @@ describe('Sanity Queries', function () {
66
68
 
67
69
  test('fetchSongArtistCount', async () => {
68
70
  const response = await fetchSongArtistCount('drumeo');
69
- // console.log(response);
71
+ log(response);
70
72
  expect(response).toBeGreaterThan(1000);
71
73
  });
72
74
 
73
75
  test('fetchByRailContentId', async () => {
74
76
  const id = 380094;
75
- const response = await fetchByRailContentId(id);
77
+ const response = await fetchByRailContentId(id, "song");
78
+ expect(response.id).toBe(id);
79
+ });
80
+
81
+ test('fetchChallengeOverview', async () => {
82
+ const id = 402197;
83
+ const response = await fetchChallengeOverview(id);
84
+ expect(response.lessons).toBeDefined();
76
85
  expect(response.id).toBe(id);
77
86
  });
78
87
 
@@ -87,20 +96,51 @@ describe('Sanity Queries', function () {
87
96
 
88
97
  });
89
98
 
99
+ test('fetchUpcomingEvents', async () => {
100
+ const response = await fetchUpcomingEvents('drumeo', {});
101
+ expect(response.length).toBeGreaterThan(0);
102
+ });
103
+
104
+ test('fetchUpcomingNewReleases', async () => {
105
+ const response = await fetchNewReleases('drumeo');
106
+ expect(response.length).toBeGreaterThan(0);
107
+ });
108
+
109
+
90
110
  test('fetchLessonContent', async () => {
91
111
  const id = 380094;
92
112
  const response = await fetchLessonContent(id);
93
113
  expect(response.id).toBe(id);
94
114
  });
95
115
 
116
+
117
+ test('fetchCourseOverview', async () => {
118
+ const id = 310414;
119
+ const response = await fetchCourseOverview(id);
120
+ expect(response.id).toBe(id);
121
+ expect(response.type).toBe('course');
122
+ });
123
+
124
+ test('fetchSongCount', async () => {
125
+ const response = await fetchSongCount('drumeo');
126
+ expect(response).toBeGreaterThan(1000);
127
+ });
128
+
96
129
  test('fetchAllSongs', async () => {
97
130
  const response = await fetchAllSongs('drumeo', {});
98
- // console.log(response);
131
+ log(response);
99
132
  expect(response.entity[0].soundslice).toBeDefined();
100
133
  expect(response.entity[0].artist_name).toBeDefined();
101
134
  expect(response.entity[0].instrumentless).toBeDefined();
102
135
  });
103
136
 
137
+ test('fetchSongFilterOptions', async () => {
138
+ const response = await fetchSongFilterOptions('drumeo', {});
139
+ log(response);
140
+ expect(response.genre).toBeDefined();
141
+ expect(response.difficulty).toBeDefined();
142
+ });
143
+
104
144
  test('fetchAllSongsGroupByArtist', async () => {
105
145
  const response = await fetchAllSongs('drumeo', {groupBy:"artist"});
106
146
  expect(response.entity[0].lessons[0].soundslice).toBeDefined();
@@ -109,22 +149,28 @@ describe('Sanity Queries', function () {
109
149
  }, 100000);
110
150
 
111
151
 
152
+ test('fetchNewReleases', async () => {
153
+ const response = await fetchNewReleases('drumeo');
154
+ log(response);
155
+ expect(response[0].id).toBeDefined();
156
+ });
157
+
112
158
  test('fetchAllWorkouts', async () => {
113
159
  const response = await fetchAll('drumeo', 'workout',{});
114
- // console.log(response);
160
+ log(response);
115
161
  expect(response.entity[0].id).toBeDefined();
116
162
  });
117
163
 
118
164
  test('fetchAllInstructorField', async () => {
119
165
  const response = await fetchAll('drumeo', 'quick-tips',{searchTerm: 'Domino Santantonio'});
120
- // console.log(response);
166
+ log(response);
121
167
  expect(response.entity[0].id).toBeDefined();
122
168
  expect(response.entity[0].instructors).toBeTruthy();
123
169
  });
124
170
 
125
171
  test('fetchAllSortField', async () => {
126
172
  const response = await fetchAll('drumeo', 'rhythmic-adventures-of-captain-carson',{});
127
- // console.log(response);
173
+ log(response);
128
174
  expect(response.entity[0].id).toBeDefined();
129
175
  expect(response.entity[0].sort).toBeDefined();
130
176
  });
@@ -132,7 +178,7 @@ describe('Sanity Queries', function () {
132
178
 
133
179
  test('fetchAllChallenges', async () => {
134
180
  const response = await fetchAll('drumeo', 'challenge',{});
135
- // console.log(response);
181
+ log(response);
136
182
  expect(response.entity[0].registration_url).toBeDefined();
137
183
  expect(response.entity[0].enrollment_start_time).toBeDefined();
138
184
  expect(response.entity[0].enrollment_end_time).toBeDefined();
@@ -146,22 +192,22 @@ describe('Sanity Queries', function () {
146
192
 
147
193
  test('fetchAll-CustomFields', async () => {
148
194
  let response = await fetchAll('drumeo', 'challenge',{customFields:['garbage']});
149
- // console.log(response);
195
+ log(response);
150
196
  expect(response.entity[0].garbage).toBeDefined();
151
197
  expect(response.entity[0].id).toBeDefined();
152
198
 
153
199
  response = await fetchAll('drumeo', 'challenge',{useDefaultFields: false, customFields:['garbage']});
154
- // console.log(response);
200
+ log(response);
155
201
  expect(response.entity[0].garbage).toBeDefined();
156
202
  expect.not.objectContaining(response.entity[0].id);
157
203
  });
158
204
 
159
205
  test('fetchRelatedLessons', async () => {
160
206
  const id = 380094;
161
- const document = await fetchByRailContentId(id);
207
+ const document = await fetchByRailContentId(id, 'song');
162
208
  let artist = document.artist.name;
163
209
  const response = await fetchRelatedLessons(id, 'singeo');
164
- let relatedDoc = await fetchByRailContentId(response.related_lessons[0].id);
210
+ let relatedDoc = await fetchByRailContentId(response.related_lessons[0].id, 'song');
165
211
  // match on artist or any genre
166
212
  let isMatch = artist === relatedDoc.artist.name;
167
213
  isMatch = isMatch || document.genre.some((genre) => {
@@ -177,8 +223,8 @@ describe('Sanity Queries', function () {
177
223
  const id = 191338; ////https://web-staging-one.musora.com/admin/studio/publishing/structure/play-along;play-along_191338
178
224
  const expectedChildID = 191492;
179
225
  const response = await fetchChildren(id);
180
- // console.log('num children', response.length);
181
- // console.log(response);
226
+ log('num children', response.length);
227
+ log(response);
182
228
 
183
229
  expect(response.length > 0).toBeTruthy();
184
230
  const foundExpectedChild = response.some((child) => {
@@ -209,15 +255,14 @@ describe('Sanity Queries', function () {
209
255
  });
210
256
 
211
257
  test('fetchMethod', async () => {
212
- const response = await fetchMethod('drumeo', 'drumeo-method');
213
- //console.log(response);
258
+ const response = await fetchMethod('drumeo', 'drumeo-method');log(response);
214
259
  expect(response).toBeDefined();
215
260
  expect(response.levels.length).toBeGreaterThan(0);
216
261
  });
217
262
 
218
263
  test('fetchMethods', async () => {
219
264
  const response = await fetchMethods('drumeo');
220
- // console.log(response);
265
+ log(response);
221
266
  expect(response.length).toBeGreaterThan(0);
222
267
  expect(response[0].type).toBe('learning-path');
223
268
  });
@@ -250,15 +295,14 @@ describe('Sanity Queries', function () {
250
295
  });
251
296
 
252
297
  test('fetchFoundation', async () => {
253
- const response = await fetchFoundation('foundations-2019');
254
- // console.log(response);
298
+ const response = await fetchFoundation('foundations-2019');log(response);
255
299
  expect(response.units.length).toBeGreaterThan(0);
256
300
  expect(response.type).toBe('foundation');
257
301
  });
258
302
 
259
303
  test('fetchPackAll', async () => {
260
304
  const response = await fetchPackAll(212899); //https://web-staging-one.musora.com/admin/studio/publishing/structure/pack;pack_212899%2Cinspect%3Don
261
- // console.log(response);
305
+ log(response);
262
306
  expect(response.slug).toBe('creative-control');
263
307
  });
264
308
 
@@ -275,7 +319,7 @@ describe('Sanity Queries', function () {
275
319
  });
276
320
 
277
321
  test('fetchCoachLessons', async () => {
278
- const response = await fetchCoachLessons('drumeo',233797);
322
+ const response = await fetchCoachLessons('drumeo',411493, {});
279
323
  expect(response.entity.length).toBeGreaterThan(0);
280
324
  });
281
325
 
@@ -293,4 +337,167 @@ describe('Sanity Queries', function () {
293
337
  const response = await fetchScheduledReleases('drumeo', {});
294
338
  expect(response.length).toBeGreaterThan(0);
295
339
  });
340
+
341
+ test('fetchAll-GroupBy-Genre', async () => {
342
+ let response = await fetchAll('drumeo', 'solo',{groupBy: 'genre'});
343
+ log(response);
344
+ expect(response.entity[0].web_url_path).toContain('/drumeo/genres/');
345
+ });
346
+
347
+ test('fetchAll-GroupBy-Artists', async () => {
348
+ let response = await fetchAll('drumeo', 'song',{groupBy: 'artist'});
349
+ log(response);
350
+ expect(response.entity[0].web_url_path).toContain('/drumeo/artists/');
351
+ });
352
+
353
+ test('fetchAll-GroupBy-Instructors', async () => {
354
+ let response = await fetchAll('drumeo', 'course',{groupBy: 'instructor'});
355
+ log(response);
356
+ expect(response.entity[0].web_url_path).toContain('/drumeo/coaches/');
357
+ });
358
+ });
359
+
360
+ describe('Filter Builder', function () {
361
+
362
+ test('baseConstructor', async () => {
363
+ const filter = 'railcontent_id = 111'
364
+ let builder = new FilterBuilder(filter);
365
+ let finalFilter = builder.buildFilter(filter);
366
+ let clauses = spliceFilterForAnds(finalFilter);
367
+ expect(clauses[0].phrase).toBe(filter);
368
+ expect(clauses[1].field).toBe('published_on');
369
+
370
+ builder = new FilterBuilder();
371
+ finalFilter = builder.buildFilter(filter);
372
+ clauses = spliceFilterForAnds(finalFilter);
373
+ expect(clauses[0].field).toBe('published_on');
374
+ expect(clauses[0].operator).toBe('<=');
375
+ });
376
+
377
+ test('withOnlyFilterAvailableStatuses', async () => {
378
+ const filter = 'railcontent_id = 111'
379
+ const builder = FilterBuilder.withOnlyFilterAvailableStatuses(filter,['published', 'unlisted']);
380
+ const finalFilter = builder.buildFilter();
381
+ const clauses = spliceFilterForAnds(finalFilter);
382
+ expect(clauses[0].phrase).toBe(filter);
383
+ expect(clauses[1].field).toBe('status');
384
+ expect(clauses[1].operator).toBe('in');
385
+ // not sure I like this
386
+ expect(clauses[1].condition).toBe("['published','unlisted']");
387
+ expect(clauses[2].field).toBe('published_on');
388
+ });
389
+
390
+ test('withContentStatusAndFutureScheduledContent', async () => {
391
+ const filter = 'railcontent_id = 111'
392
+ const builder = new FilterBuilder(filter,{
393
+ availableContentStatuses: ['published', 'unlisted', 'scheduled'],
394
+ getFutureScheduledContentsOnly: true});
395
+ const finalFilter = builder.buildFilter();
396
+ const clauses = spliceFilterForAnds(finalFilter);
397
+ expect(clauses[0].phrase).toBe(filter);
398
+ expect(clauses[1].field).toBe('(status'); // extra ( because it's a multi part filter
399
+ expect(clauses[1].operator).toBe('in');
400
+ // getFutureScheduledContentsOnly doesn't make a filter that's splicable, so we match on the more static string
401
+ const expected = "['published','unlisted'] || (status == 'scheduled' && published_on >=";
402
+ console.log(clauses[1].condition);
403
+ console.log(expected)
404
+ const isMatch = finalFilter.includes(expected);
405
+ expect(isMatch).toBeTruthy();
406
+ });
407
+
408
+ test('withUserPermissions', async () => {
409
+ const filter = 'railcontent_id = 111'
410
+ const builder = new FilterBuilder(filter,
411
+ { user: {
412
+ user: {},
413
+ permissions: [91, 92],
414
+ }});
415
+ const finalFilter = builder.buildFilter();
416
+ const expected = "references(*[_type == 'permission' && railcontent_id in [91,92]]._id)"
417
+ const isMatch = finalFilter.includes(expected);
418
+ expect(isMatch).toBeTruthy();
419
+ });
420
+
421
+ test('withUserPermissionsForPlusUser', async () => {
422
+ const filter = 'railcontent_id = 111'
423
+ const builder = new FilterBuilder(filter,
424
+ {
425
+ user: getPlusUser()
426
+ });
427
+ const finalFilter = builder.buildFilter();
428
+ const expected = "references(*[_type == 'permission' && railcontent_id in [91,92]]._id)"
429
+ const isMatch = finalFilter.includes(expected);
430
+ expect(isMatch).toBeTruthy();
431
+ });
432
+
433
+ test('withPermissionBypass', async () => {
434
+ const filter = 'railcontent_id = 111'
435
+ const builder = new FilterBuilder(filter,
436
+ {
437
+ user: getPlusUser(),
438
+ bypassPermissions:true
439
+ });
440
+ const finalFilter = builder.buildFilter();
441
+ const expected = "references(*[_type == 'permission' && railcontent_id in [91,92]]._id)"
442
+ const isMatch = finalFilter.includes(expected);
443
+ expect(isMatch).toBeFalsy();
444
+ const clauses = spliceFilterForAnds(finalFilter);
445
+ expect(clauses[0].field).toBe('railcontent_id');
446
+ expect(clauses[1].field).toBe('published_on');
447
+ });
448
+
449
+
450
+ test('withPublishOnRestrictions', async () => {
451
+ // testing dates is a pain more frustration than I'm willing to deal with, so I'm just testing operators.
452
+
453
+ const filter = 'railcontent_id = 111'
454
+ let builder = new FilterBuilder(filter, {
455
+ user: {},
456
+ pullFutureContent: true,
457
+ });
458
+
459
+ let finalFilter = builder.buildFilter();
460
+ let clauses = spliceFilterForAnds(finalFilter);
461
+ expect(clauses[0].phrase).toBe(filter);
462
+
463
+ expect(clauses[1].field).toBe('published_on');
464
+ expect(clauses[1].operator).toBe('<=');
465
+ const restrictionDate = new Date(clauses[1].condition)
466
+ const now = new Date();
467
+ expect(now.getTime()).toBeLessThan(restrictionDate.getTime());
468
+
469
+ builder = new FilterBuilder(filter,
470
+ {
471
+ user: {},
472
+ getFutureContentOnly: true,
473
+ });
474
+ finalFilter = builder.buildFilter();
475
+ clauses = spliceFilterForAnds(finalFilter);
476
+ expect(clauses[0].phrase).toBe(filter);
477
+ expect(clauses[1].field).toBe('published_on');
478
+ expect(clauses[1].operator).toBe('>=');
479
+ });
480
+
481
+ function getPlusUser() {
482
+ return {
483
+ permissions: [91,92],
484
+ }
485
+ }
486
+
487
+ function spliceFilterForAnds(filter) {
488
+ // this will not correctly split complex filters with && and || conditions.
489
+ let phrases = filter.split(' && ');
490
+ let clauses= [];
491
+ phrases.forEach((phrase) => {
492
+ let field = phrase.substring(0, phrase.indexOf(' '));
493
+ //if(field.charAt(0) === '(' ) field = field.substring(1);
494
+ const temp = phrase.substring(phrase.indexOf(' ') + 1);
495
+ const operator = temp.substring(0, temp.indexOf(' '));
496
+ let condition = temp.substring(temp.indexOf(' ') + 1);
497
+ //if(condition.charAt(condition.length) === ')') condition = condition.slice(-1);
498
+ clauses.push({phrase, field, operator, condition});
499
+ });
500
+ return clauses;
501
+ }
502
+
296
503
  });