musora-content-services 1.0.59 → 1.0.62

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/src/index.d.ts CHANGED
@@ -14,8 +14,10 @@ import {
14
14
  fetchByRailContentIds,
15
15
  fetchAll,
16
16
  fetchAllFilterOptions,
17
+ fetchMethods,
18
+ fetchMethod,
17
19
  fetchMethodNextLesson,
18
- fetchMethodChildren,
20
+ fetchMethodChildrenIds,
19
21
  fetchNextPreviousLesson,
20
22
  fetchRelatedLessons,
21
23
  fetchPackAll,
@@ -43,8 +45,10 @@ declare module 'musora-content-services' {
43
45
  fetchByRailContentIds,
44
46
  fetchAll,
45
47
  fetchAllFilterOptions,
48
+ fetchMethods,
49
+ fetchMethod,
46
50
  fetchMethodNextLesson,
47
- fetchMethodChildren,
51
+ fetchMethodChildrenIds,
48
52
  fetchNextPreviousLesson,
49
53
  fetchRelatedLessons,
50
54
  fetchPackAll,
package/src/index.js CHANGED
@@ -16,14 +16,18 @@ import {
16
16
  fetchAll,
17
17
  fetchAllFilterOptions,
18
18
  fetchMethodNextLesson,
19
+ fetchMethod,
19
20
  fetchMethods,
20
- fetchMethodChildren,
21
+ fetchMethodChildrenIds,
21
22
  fetchNextPreviousLesson,
22
23
  fetchRelatedLessons,
23
24
  fetchPackAll,
24
25
  fetchPackChildren,
25
26
  fetchLessonContent,
26
27
  fetchCourseOverview,
28
+ fetchChildren,
29
+ fetchParentByRailContentId,
30
+ fetchMethodPreviousNextLesson,
27
31
  } from './services/sanity.js';
28
32
 
29
33
  import {
@@ -50,8 +54,9 @@ export {
50
54
  fetchAll,
51
55
  fetchAllFilterOptions,
52
56
  fetchMethods,
57
+ fetchMethod,
53
58
  fetchMethodNextLesson,
54
- fetchMethodChildren,
59
+ fetchMethodChildrenIds,
55
60
  fetchNextPreviousLesson,
56
61
  fetchRelatedLessons,
57
62
  fetchPackAll,
@@ -61,4 +66,7 @@ export {
61
66
  fetchAllCompletedStates,
62
67
  fetchContentInProgress,
63
68
  fetchCourseOverview,
69
+ fetchChildren,
70
+ fetchParentByRailContentId,
71
+ fetchMethodPreviousNextLesson,
64
72
  }
@@ -1,23 +1,11 @@
1
1
  /**
2
2
  * @module Sanity-Services
3
3
  */
4
- import {contentTypeConfig} from "../contentTypeConfig";
4
+ import {assignmentsField, contentTypeConfig, DEFAULT_FIELDS, getFieldsForContentType} from "../contentTypeConfig";
5
5
  import {globalConfig} from "./config";
6
6
 
7
7
  import { fetchAllCompletedStates, fetchCurrentSongComplete } from './railcontent.js';
8
8
 
9
- const DEFAULT_FIELDS = [
10
- '"id": railcontent_id',
11
- 'railcontent_id',
12
- '"type": _type',
13
- 'title',
14
- '"image": thumbnail.asset->url',
15
- 'difficulty',
16
- 'difficulty_string',
17
- 'web_url_path',
18
- 'published_on'
19
- ];
20
-
21
9
  /**
22
10
  * Fetch a song by its document ID from Sanity.
23
11
  *
@@ -30,25 +18,10 @@ const DEFAULT_FIELDS = [
30
18
  * .catch(error => console.error(error));
31
19
  */
32
20
  export async function fetchSongById(documentId) {
33
- const fields = [
34
- '"id": railcontent_id',
35
- 'railcontent_id',
36
- '"type": _type',
37
- 'description',
38
- 'title',
39
- '"thumbnail_url": thumbnail.asset->url',
40
- '"style": genre[0]->name',
41
- '"artist": artist->name',
42
- 'album',
43
- 'instrumentless',
44
- 'soundslice',
45
- '"resources": resource[]{resource_url, resource_name}',
46
- '"url": web_url_path',
47
- ];
48
21
 
49
22
  const query = `
50
23
  *[_type == "song" && railcontent_id == ${documentId}]{
51
- ${fields.join(', ')}
24
+ ${getFieldsForContentType('song', true)}
52
25
  }`;
53
26
 
54
27
  return fetchSanity(query, false);
@@ -249,10 +222,10 @@ export async function fetchSongCount(brand) {
249
222
  * Fetch the latest workouts for a specific brand, including completion status and progress.
250
223
  * This function retrieves up to five of the latest workout content for a given brand, sorted in descending order by their publication date.
251
224
  * It also includes completion status and progress percentage for each workout by fetching additional data about user progress.
252
- *
225
+ *
253
226
  * @param {string} brand - The brand for which to fetch workouts (e.g., 'drumeo', 'pianote').
254
227
  * @returns {Promise<Array<Object>|null>} - A promise that resolves to an array of workout data objects with additional properties for completion status and progress percentage, or null if no workouts are found.
255
- *
228
+ *
256
229
  * @example
257
230
  * fetchWorkouts('drumeo')
258
231
  * .then(workouts => console.log(workouts))
@@ -263,12 +236,12 @@ export async function fetchWorkouts(brand) {
263
236
  "id": railcontent_id,
264
237
  title,
265
238
  "image": thumbnail.asset->url,
266
- "artist_name": instructor[0]->name,
267
- "artists": instructor[]->name,
239
+ ${artistOrInstructor()},
240
+ ${artistOrInstructorAsArray()},
268
241
  difficulty,
269
242
  difficulty_string,
270
243
  length_in_seconds,
271
- published_on,
244
+ published_on,;
272
245
  "type": _type,
273
246
  web_url_path,
274
247
  } | order(published_on desc)[0...5]`
@@ -356,17 +329,9 @@ export async function fetchUpcomingEvents(brand) {
356
329
  * .then(content => console.log(content))
357
330
  * .catch(error => console.error(error));
358
331
  */
359
- export async function fetchByRailContentId(id) {
332
+ export async function fetchByRailContentId(id, contentType) {
360
333
  const query = `*[railcontent_id == ${id}]{
361
- railcontent_id,
362
- title,
363
- "image": thumbnail.asset->url,
364
- "artist_name": artist->name,
365
- artist,
366
- difficulty,
367
- difficulty_string,
368
- web_url_path,
369
- published_on
334
+ ${getFieldsForContentType(contentType)}
370
335
  }`
371
336
  return fetchSanity(query, false);
372
337
  }
@@ -384,10 +349,9 @@ export async function fetchByRailContentId(id) {
384
349
  * .catch(error => console.error(error));
385
350
  */
386
351
  export async function fetchByRailContentIds(ids, contentType = undefined) {
387
- const fields = contentType ? DEFAULT_FIELDS.concat(contentTypeConfig?.[contentType]?.fields ?? []) : DEFAULT_FIELDS;
388
352
  const idsString = ids.join(',');
389
353
  const query = `*[railcontent_id in [${idsString}]]{
390
- ${fields.join(', ')}
354
+ ${getFieldsForContentType(contentType)}
391
355
  }`
392
356
  return fetchSanity(query, true);
393
357
  }
@@ -448,37 +412,7 @@ export async function fetchAll(brand, type, {
448
412
  : "";
449
413
 
450
414
  // Determine the sort order
451
- let sortOrder;
452
- switch (sort) {
453
- case "slug":
454
- if(groupBy){
455
- sortOrder = "name asc";
456
- } else {
457
- sortOrder = "title asc";
458
- }
459
-
460
- break;
461
- case "published_on":
462
- sortOrder = "published_on asc";
463
- break;
464
- case "-published_on":
465
- sortOrder = "published_on desc";
466
- break;
467
- case "-slug":
468
- if(groupBy){
469
- sortOrder = "name desc";
470
- } else {
471
- sortOrder = "title desc";
472
- }
473
-
474
- break;
475
- case "-popularity":
476
- sortOrder = "popularity desc";
477
- break;
478
- default:
479
- sortOrder = "published_on asc";
480
- break;
481
- }
415
+ const sortOrder = getSortOrder(sort);
482
416
 
483
417
  let fields = DEFAULT_FIELDS.concat(additionalFields);
484
418
  let fieldsString = fields.join(',');
@@ -537,6 +471,28 @@ export async function fetchAll(brand, type, {
537
471
  return fetchSanity(query, true);
538
472
  }
539
473
 
474
+ export function getSortOrder(sort= '-published_on', groupBy)
475
+ {
476
+ // Determine the sort order
477
+ let sortOrder = '';
478
+ const isDesc = sort.startsWith('-');
479
+ sort = isDesc ? sort.substring(1) : sort;
480
+ switch (sort) {
481
+ case "slug":
482
+ sortOrder = groupBy ? 'name' : "title";
483
+ break;
484
+ case "popularity":
485
+ sortOrder = "popularity";
486
+ break;
487
+ case "published_on":
488
+ default:
489
+ sortOrder = "published_on";
490
+ break;
491
+ }
492
+ sortOrder += isDesc ? ' desc' : ' asc';
493
+ return sortOrder;
494
+ }
495
+
540
496
  /**
541
497
  * Fetches all available filter options based on various criteria such as brand, filters, style, artist, content type, and search term.
542
498
  *
@@ -574,10 +530,10 @@ export async function fetchAllFilterOptions(
574
530
  return `&& ${key} == "${value}"`;
575
531
  }).join(' ')
576
532
  : undefined;
577
-
533
+
578
534
  const commonFilter = `_type == '${contentType}' && brand == "${brand}"${style ? ` && '${style}' in genre[]->name` : ''}${artist ? ` && artist->name == '${artist}'` : ''} ${filtersToGroq ? filtersToGroq : ''}`;
579
535
  const query = `
580
- {
536
+ {
581
537
  "meta": {
582
538
  "totalResults": count(*[${commonFilter}
583
539
  ${term ? ` && (title match "${term}" || album match "${term}" || artist->name match "${term}" || genre[]->name match "${term}")` : ''}]),
@@ -606,22 +562,33 @@ export async function fetchAllFilterOptions(
606
562
  /**
607
563
  * Fetch children content by Railcontent ID.
608
564
  * @param {string} railcontentId - The Railcontent ID of the parent content.
609
- * @returns {Promise<Array<Object>|null>} - The fetched children content data or null if not found.
565
+ * @returns {Promise<Array<Object>|null>} - The fetched children content data or [] if not found.
610
566
  */
611
567
  export async function fetchChildren(railcontentId) {
612
- //TODO: Implement getByParentId include sum XP
613
- const query = `*[_railcontent_id == ${railcontentId}]{
614
- railcontent_id,
615
- title,
616
- "image": thumbnail.asset->url,
617
- "artist_name": artist->name,
618
- artist,
619
- difficulty,
620
- difficulty_string,
621
- web_url_path,
622
- published_on
623
- } | order(published_on asc)`
624
- return fetchSanity(query, true);
568
+ const query = `*[railcontent_id == ${railcontentId}]{
569
+ 'children': child[]->{
570
+ ${getFieldsForContentType()}
571
+ },
572
+ }[0..1]`;
573
+ let parent = await fetchSanity(query, true);
574
+ return parent[0]['children'] ?? [];
575
+ }
576
+
577
+ /**
578
+ *
579
+ * @param railcontentId - railcontent id of the child
580
+ * @returns {Promise<Array<string>|null>} - The fetched parent content data or [] if not found
581
+ */
582
+ export async function fetchParentByRailContentId(railcontentId) {
583
+ const query = `*[railcontent_id == ${railcontentId}]{
584
+ 'parents': array::unique([
585
+ ...(*[references(^._id)]{
586
+ ${getFieldsForContentType()}
587
+ })
588
+ ])
589
+ }[0...1]`;
590
+ let child = await fetchSanity(query, true);
591
+ return child[0]['parents'][0] ?? [];
625
592
  }
626
593
 
627
594
  /**
@@ -633,50 +600,76 @@ export async function fetchMethods(brand) {
633
600
  //TODOS
634
601
  //ADD INSTRUCTORS AND POSITION
635
602
  const query = `*[_type == 'learning-path' && brand == '${brand}'] {
636
- difficulty,
637
- difficulty_string,
638
- "description": description[0].children[0].text,
639
- hide_from_recsys,
640
- "image": thumbnail.asset->url,
641
- "instructors":instructor[]->name,
642
- "lesson_count": child_count,
643
- length_in_seconds,
644
- permission,
645
- popularity,
603
+ ${getFieldsForContentType('method')}
646
604
  "position": count(*[_type == 'learning-path' && brand == '${brand}' && (published_on < ^.published_on || (published_on == ^.published_on && _id < ^._id))]) + 1,
647
- published_on,
648
- railcontent_id,
649
- "slug": slug.current,
650
- status,
651
- "thumbnail_logo": logo_image_url.asset->url,
652
- title,
653
- total_xp,
654
- "type": _type,
655
- "url": web_url_path,
656
- xp
657
- }`
605
+ } | order(published_on asc)`
658
606
  return fetchSanity(query, true);
659
607
  }
660
608
 
609
+ /**
610
+ * Fetch the Method (learning-paths) for a specific brand.
611
+ * @param {string} brand - The brand for which to fetch methods.
612
+ * @param {string} slug - The slug of the method.
613
+ * @returns {Promise<Object|null>} - The fetched methods data or null if not found.
614
+ */
615
+ export async function fetchMethod(brand, slug) {
616
+ const query = `*[_type == 'learning-path' && brand == "${brand}" && slug.current == "${slug}"] {
617
+ "description": description[0].children[0].text,
618
+ "instructors":instructor[]->name,
619
+ published_on,
620
+ "id": railcontent_id,
621
+ railcontent_id,
622
+ "slug": slug.current,
623
+ status,
624
+ title,
625
+ video,
626
+ "type": _type,
627
+ "levels": child[]->
628
+ {
629
+ "id": railcontent_id,
630
+ published_on,
631
+ "thumbnail_url": thumbnail.asset->url,
632
+ "instructor": instructor[]->{name},
633
+ title,
634
+ "description": description[0].children[0].text,
635
+ }
636
+ } | order(published_on asc)`
637
+ return fetchSanity(query, false);
638
+ }
639
+
661
640
  /**
662
641
  * Fetch the next lesson for a specific method by Railcontent ID.
663
642
  * @param {string} railcontentId - The Railcontent ID of the current lesson.
643
+ * @param {string} methodId - The RailcontentID of the method
664
644
  * @returns {Promise<Object|null>} - The fetched next lesson data or null if not found.
665
645
  */
666
- export async function fetchMethodNextLesson(railcontentId) {
667
- //TODO: Implement getNextContentForParentContentForUser
668
- const query = `*[_railcontent_id == ${railcontentId}]{
669
- railcontent_id,
670
- title,
671
- "image": thumbnail.asset->url,
672
- "artist_name": artist->name,
673
- artist,
674
- difficulty,
675
- difficulty_string,
676
- web_url_path,
677
- published_on
678
- }`
679
- return fetchSanity(query, false);
646
+ export async function fetchMethodNextLesson(railcontentId, methodId) {
647
+ const sortedChildren = await fetchMethodChildrenIds(methodId);
648
+ const index = sortedChildren.indexOf(railcontentId);
649
+ const childIndex = sortedChildren[index + 1];
650
+ return childIndex ? await fetchByRailContentId(childIndex) : null;
651
+ }
652
+
653
+
654
+ /**
655
+ * Fetch the next lesson for a specific method by Railcontent ID.
656
+ * @param {string} railcontentId - The Railcontent ID of the current lesson.
657
+ * @param {string} methodId - The RailcontentID of the method
658
+ * @returns {Promise<Object|null>} - object with `nextLesson` and `previousLesson` attributes
659
+ * @example
660
+ * fetchMethodPreviousNextLesson(241284, 241247)
661
+ * .then(data => { console.log('nextLesson', data.nextLesson); console.log('prevlesson', data.prevLesson);})
662
+ * .catch(error => console.error(error));
663
+ */
664
+ export async function fetchMethodPreviousNextLesson(railcontentId, methodId) {
665
+ const sortedChildren = await fetchMethodChildrenIds(methodId);
666
+ const index = sortedChildren.indexOf(railcontentId);
667
+ let nextId = sortedChildren[index + 1];
668
+ let previousId = sortedChildren[index -1];
669
+ let nextPrev = await fetchByRailContentIds([nextId, previousId]);
670
+ const nextLesson = nextPrev.find((elem) => {return elem['id'] === nextId});
671
+ const prevLesson = nextPrev.find((elem) => {return elem['id'] === previousId});
672
+ return {nextLesson, prevLesson};
680
673
  }
681
674
 
682
675
  /**
@@ -684,11 +677,37 @@ export async function fetchMethodNextLesson(railcontentId) {
684
677
  * @param {string} railcontentId - The Railcontent ID of the method.
685
678
  * @returns {Promise<Array<Object>|null>} - The fetched children data or null if not found.
686
679
  */
687
- export async function fetchMethodChildren(railcontentId) {
680
+ export async function fetchMethodChildrenIds(railcontentId) {
688
681
  //TODO: Implement getByParentId include sum XP
689
- return fetchChildren(railcontentId);
682
+ const query = `*[_type == 'learning-path' && railcontent_id == ${railcontentId}]{
683
+ 'children': child[]-> {
684
+ 'id': railcontent_id,
685
+ 'children': child[]-> {
686
+ 'id': railcontent_id,
687
+ 'children': child[]-> {
688
+ 'id': railcontent_id,
689
+ }
690
+ }
691
+ }
692
+ }`;
693
+ let allChildren = await fetchSanity(query, false);
694
+ return getChildrenToDepth(allChildren, 4);;
695
+ }
696
+
697
+ function getChildrenToDepth(parent, depth = 1)
698
+ {
699
+ let allChildrenIds = [];
700
+ if (parent['children']) {
701
+ parent['children'].forEach((child) => {
702
+ allChildrenIds.push(child['id']);
703
+ allChildrenIds = allChildrenIds.concat(getChildrenToDepth(child, depth-1));
704
+ })
705
+ }
706
+ return allChildrenIds;
690
707
  }
691
708
 
709
+
710
+
692
711
  /**
693
712
  * Fetch the next and previous lessons for a specific lesson by Railcontent ID.
694
713
  * @param {string} railcontentId - The Railcontent ID of the current lesson.
@@ -727,22 +746,15 @@ export async function fetchLessonContent(railContentId) {
727
746
  chapter_description,
728
747
  chapter_timecode,
729
748
  "chapter_thumbnail_url": chapter_thumbnail_url.asset->url
730
- },
749
+ },
731
750
  "coaches": instructor[]-> {
732
- name,
751
+ name,
733
752
  "id":_id,
734
753
  "coach_profile_image":thumbnail_url.asset->url
735
754
  },
736
755
  "instructors":instructor[]->name,
737
756
  instructor[]->,
738
- "assignments":assignment[]{
739
- "id": railcontent_id,
740
- "soundslice_slug": assignment_soundslice,
741
- "title": assignment_title,
742
- "sheet_music_image_url": assignment_sheet_music_image,
743
- "timecode": assignment_timecode,
744
- "description": assignment_description
745
- },
757
+ ${assignmentsField}
746
758
  video}`
747
759
  return fetchSanity(query, false);
748
760
  }
@@ -808,7 +820,7 @@ export async function fetchPackChildren(railcontentId) {
808
820
  * Fetch the data needed for the Course Overview screen.
809
821
  * @param {string} id - The Railcontent ID of the course
810
822
  * @returns {Promise<Object|null>} - The course information and lessons or null if not found.
811
- *
823
+ *
812
824
  * @example
813
825
  * fetchCourseOverview('course123')
814
826
  * .then(course => console.log(course))
@@ -893,6 +905,32 @@ export async function fetchSanity(query, isList) {
893
905
  }
894
906
  }
895
907
 
908
+ /**
909
+ * Fetch CatalogueMetadata from Sanity. This information may be duplicated in the contentTypeConfig.js.
910
+ * It's an ongoing discussion (Aug 2024), but it's been included here if necessary
911
+ *
912
+ * @param {string} contentType - name of the contentype to pull
913
+ * @returns {Promise<Object|null>} - A promise that resolves to the fetched data or null if an error occurs or no results are found.
914
+ *
915
+ * @example
916
+ *
917
+ * fetchCatalogMetadata('song')
918
+ * .then(data => console.log(data))
919
+ * .catch(error => console.error(error));
920
+ */
921
+ export async function fetchCatalogMetadata(contentType)
922
+ { const query = `*[_type == 'CatalogMetadata']{
923
+ catalog_type,
924
+ brand,
925
+ groq_results,
926
+ groq_search_fields,
927
+ meta_data_groq,
928
+ modal_text,
929
+ sort_by,
930
+ }`
931
+ return fetchSanity(query, false);
932
+ }
933
+
896
934
 
897
935
  //Helper Functions
898
936
  function arrayJoinWithQuotes(array, delimiter = ',') {
@@ -923,3 +961,5 @@ function checkSanityConfig(config) {
923
961
  }
924
962
  return true;
925
963
  }
964
+
965
+
@@ -16,12 +16,17 @@ const {
16
16
  fetchAll,
17
17
  fetchAllFilterOptions,
18
18
  fetchMethodNextLesson,
19
- fetchMethodChildren,
19
+ fetchMethodChildrenIds,
20
20
  fetchNextPreviousLesson,
21
21
  fetchRelatedLessons,
22
22
  fetchPackAll,
23
23
  fetchPackChildren,
24
- fetchLessonContent
24
+ fetchLessonContent,
25
+ getSortOrder,
26
+ fetchParentByRailContentId,
27
+ fetchChildren,
28
+ fetchMethod,
29
+ fetchMethods,
25
30
  } = require('../src/services/sanity.js');
26
31
 
27
32
  describe('Sanity Queries', function () {
@@ -42,7 +47,7 @@ describe('Sanity Queries', function () {
42
47
  test('fetchSongById', async () => {
43
48
  const id = 380094;
44
49
  const response = await fetchSongById(id);
45
- expect(response.railcontent_id).toBe(id);
50
+ expect(response.id).toBe(id);
46
51
 
47
52
  });
48
53
 
@@ -62,14 +67,14 @@ describe('Sanity Queries', function () {
62
67
  test('fetchByRailContentId', async () => {
63
68
  const id = 380094;
64
69
  const response = await fetchByRailContentId(id);
65
- expect(response.railcontent_id).toBe(id);
70
+ expect(response.id).toBe(id);
66
71
  });
67
72
 
68
73
  test('fetchByRailContentIds', async () => {
69
74
  const id = 380094;
70
75
  const id2 = 402204;
71
76
  const response = await fetchByRailContentIds([id, id2]);
72
- const returnedIds = response.map((x) => x.railcontent_id);
77
+ const returnedIds = response.map((x) => x.id);
73
78
  expect(returnedIds).toContain(id);
74
79
  expect(returnedIds).toContain(id2);
75
80
  expect(returnedIds.length).toBe(2);
@@ -79,7 +84,7 @@ describe('Sanity Queries', function () {
79
84
  test('fetchLessonContent', async () => {
80
85
  const id = 380094;
81
86
  const response = await fetchLessonContent(id);
82
- expect(response.railcontent_id).toBe(id);
87
+ expect(response.id).toBe(id);
83
88
  });
84
89
 
85
90
  test('fetchAllSongs', async () => {
@@ -101,7 +106,7 @@ describe('Sanity Queries', function () {
101
106
  test('fetchAllWorkouts', async () => {
102
107
  const response = await fetchAll('drumeo', 'workout',{});
103
108
  console.log(response);
104
- expect(response.entity[0].railcontent_id).toBeDefined();
109
+ expect(response.entity[0].id).toBeDefined();
105
110
  });
106
111
 
107
112
  test('fetchAllChallenges', async () => {
@@ -117,10 +122,70 @@ describe('Sanity Queries', function () {
117
122
  expect(response.entity[0].challenge_state_text).toBeDefined();
118
123
 
119
124
  });
120
- // test('fetchRelatedLessons', async () => {
121
- // const id = 380094;
122
- // const response = await fetchRelatedLessons(id, 'singeo', 'song');
123
- // console.log(response.related_lessons[0]);
124
- // expect(response.related_lessons[0]).toBe(id);
125
- // });
125
+
126
+ test('fetchRelatedLessons', async () => {
127
+ const id = 380094;
128
+ const document = await fetchByRailContentId(id);
129
+ let artist = document.artist.name;
130
+ const response = await fetchRelatedLessons(id, 'singeo', 'song');
131
+ let relatedDoc = await fetchByRailContentId(response.related_lessons[0].id);
132
+ // match on artist or any genre
133
+ let isMatch = artist === relatedDoc.artist.name;
134
+ isMatch = isMatch || document.genre.some((genre) => {
135
+ return relatedDoc.genre.some((relatedGenre) => {
136
+ return genre._ref === relatedGenre._ref;
137
+ });
138
+ });
139
+ expect(isMatch).toBeTruthy();
140
+ });
141
+
142
+ test('fetchChildren', async () => {
143
+ // complement test to fetchParentByRailContentId
144
+ const id = 191338; ////https://web-staging-one.musora.com/admin/studio/publishing/structure/play-along;play-along_191338
145
+ const expectedChildID = 191492;
146
+ const response = await fetchChildren(id);
147
+ console.log('num children', response.length);
148
+ console.log(response);
149
+
150
+ expect(response.length > 0).toBeTruthy();
151
+ const foundExpectedChild = response.some((child) => {
152
+ return child['id'] = expectedChildID;
153
+ });
154
+ expect(foundExpectedChild).toBeTruthy();
155
+ });
156
+
157
+ test('fetchParentByRailContentId', async () => {
158
+ // complement test to fetchChildren
159
+ const childId = 191492; // child of https://web-staging-one.musora.com/admin/studio/publishing/structure/play-along;play-along_191338
160
+ const expectedParent = 191338;
161
+ const response = await fetchParentByRailContentId(childId);
162
+ expect(response['id']).toBe(expectedParent);
163
+ });
164
+
165
+ test('getSortOrder', () => {
166
+ let sort = getSortOrder()
167
+ expect(sort).toBe('published_on desc');
168
+ sort = getSortOrder('slug')
169
+ expect(sort).toBe('title asc');
170
+ sort = getSortOrder('-slug')
171
+ expect(sort).toBe('title desc');
172
+ sort = getSortOrder('-slug', true)
173
+ expect(sort).toBe('name desc');
174
+ sort = getSortOrder('published-on')
175
+ expect(sort).toBe('published_on asc');
176
+ });
177
+
178
+ test('fetchMethod', async () => {
179
+ const response = await fetchMethod('drumeo', 'drumeo-method');
180
+ //console.log(response);
181
+ expect(response).toBeDefined();
182
+ expect(response.levels.length).toBeGreaterThan(0);
183
+ });
184
+
185
+ test('fetchMethods', async () => {
186
+ const response = await fetchMethods('drumeo');
187
+ //console.log(response);
188
+ expect(response.length).toBeGreaterThan(0);
189
+ expect(response[0].type).toBe('learning-path');
190
+ });
126
191
  });