musora-content-services 1.0.155 → 1.0.157

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.
Files changed (58) hide show
  1. package/.github/workflows/node.js.yml +0 -0
  2. package/CHANGELOG.md +4 -0
  3. package/README.md +0 -0
  4. package/babel.config.js +0 -0
  5. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  6. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  7. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  8. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  9. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  10. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  11. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  12. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  13. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  14. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
  15. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  16. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  17. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  18. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  19. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
  20. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  21. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  22. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  23. package/docs/scripts/collapse.js +0 -0
  24. package/docs/scripts/commonNav.js +0 -0
  25. package/docs/scripts/linenumber.js +0 -0
  26. package/docs/scripts/nav.js +0 -0
  27. package/docs/scripts/polyfill.js +0 -0
  28. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
  29. package/docs/scripts/prettify/lang-css.js +0 -0
  30. package/docs/scripts/prettify/prettify.js +0 -0
  31. package/docs/scripts/search.js +0 -0
  32. package/docs/styles/jsdoc.css +0 -0
  33. package/docs/styles/prettify.css +0 -0
  34. package/jest.config.js +0 -0
  35. package/jsdoc.json +0 -0
  36. package/link_mcs.sh +0 -0
  37. package/package.json +1 -1
  38. package/src/contentMetaData.js +0 -0
  39. package/src/filterBuilder.js +22 -26
  40. package/src/index.d.ts +10 -1
  41. package/src/index.js +10 -1
  42. package/src/services/config.js +0 -0
  43. package/src/services/contentLikes.js +0 -0
  44. package/src/services/contentProgress.js +31 -25
  45. package/src/services/dataContext.js +3 -3
  46. package/src/services/lastUpdated.js +18 -0
  47. package/src/services/railcontent.js +35 -33
  48. package/src/services/sanity.js +558 -555
  49. package/src/services/userPermissions.js +26 -0
  50. package/test/contentLikes.test.js +2 -3
  51. package/test/contentProgress.test.js +7 -7
  52. package/test/initializeTests.js +23 -0
  53. package/test/lastUpdated.test.js +22 -0
  54. package/test/localStorageMock.js +0 -0
  55. package/test/log.js +0 -0
  56. package/test/sanityQueryService.test.js +29 -58
  57. package/test/userPermissions.test.js +19 -0
  58. package/tools/generate-index.js +0 -0
@@ -0,0 +1,26 @@
1
+ import {
2
+ fetchUserPermissionsData
3
+ } from "./railcontent";
4
+ import {setLastUpdatedTime, wasLastUpdateOlderThanXSeconds} from "./lastUpdated";
5
+
6
+ /**
7
+ * Exported functions that are excluded from index generation.
8
+ *
9
+ * @type {string[]}
10
+ */
11
+ const excludeFromGeneratedIndex = [];
12
+ let userPermissionsPromise = null;
13
+ let lastUpdatedKey = `userPermissions_lastUpdated`;
14
+
15
+ export async function fetchUserPermissions() {
16
+ if (!userPermissionsPromise || wasLastUpdateOlderThanXSeconds(10, lastUpdatedKey)) {
17
+ userPermissionsPromise = fetchUserPermissionsData();
18
+ setLastUpdatedTime(lastUpdatedKey);
19
+ }
20
+
21
+ return await userPermissionsPromise;
22
+ }
23
+
24
+ export async function reset() {
25
+ userPermissionsPromise = null;
26
+ }
@@ -1,6 +1,5 @@
1
1
  import {isContentLiked, dataContext, likeContent, unlikeContent} from "../src/services/contentLikes";
2
- import {LocalStorageMock} from "./localStorageMock";
3
- import {initializeService} from "../src";
2
+ import {initializeTestService} from "./initializeTests";
4
3
 
5
4
  const railContentModule = require('../src/services/railcontent.js')
6
5
 
@@ -9,7 +8,7 @@ describe('contentLikesDataContext', function () {
9
8
  const testVersion = 1;
10
9
 
11
10
  beforeEach(() => {
12
- initializeService({localStorage: new LocalStorageMock()});
11
+ initializeTestService();
13
12
  mock = jest.spyOn(dataContext, 'fetchData');
14
13
  var json = JSON.parse(`{"version":${testVersion},"data":[308516,308515,308514,308518]}`);
15
14
  mock.mockImplementation(() => json);
@@ -4,7 +4,7 @@ import {
4
4
  recordWatchSession,
5
5
  getProgressPercentageByIds, getProgressState, getProgressStateByIds
6
6
  } from "../src/services/contentProgress";
7
- import {initializeTestService} from "./sanityQueryService.test";
7
+ import {initializeTestService} from "./initializeTests";
8
8
 
9
9
  const railContentModule = require('../src/services/railcontent.js')
10
10
 
@@ -53,17 +53,17 @@ describe('contentProgressDataContext', function () {
53
53
  mock2.mockImplementation(() => JSON.parse(`{"version": ${serverVersion}}`));
54
54
  let progress = await getProgressPercentage(241250); //force load context
55
55
 
56
- let result = await recordWatchSession({watchPositionSeconds: 50, totalDurationSeconds: 100, contentId: 241250});
56
+ await recordWatchSession(241250, "video", "vimeo", 100, 50, 50);
57
57
  serverVersion++;
58
- await recordWatchSession({watchPositionSeconds: 50, totalDurationSeconds: 100, contentId: 241251});
58
+ await recordWatchSession(241251, "video", "vimeo", 100, 50, 50);
59
59
  serverVersion++;
60
- await recordWatchSession({watchPositionSeconds: 50, totalDurationSeconds: 100, contentId: 241252});
60
+ await recordWatchSession(241252, "video", "vimeo", 100, 50, 50);
61
61
  serverVersion++;
62
- await recordWatchSession({watchPositionSeconds: 100, totalDurationSeconds: 100, contentId: 241260});
62
+ await recordWatchSession(241260, "video", "vimeo", 100, 100, 100);
63
63
  serverVersion++;
64
- await recordWatchSession({watchPositionSeconds: 100, totalDurationSeconds: 100, contentId: 241261});
64
+ await recordWatchSession(241261, "video", "vimeo", 100, 100, 100);
65
65
  serverVersion++;
66
- progress = await getProgressPercentage(241250); //force load context
66
+ progress = await getProgressPercentage(241250);
67
67
 
68
68
  expect(progress).toBe(50);
69
69
  let progress241249 = await getProgressPercentage(241249);
@@ -0,0 +1,23 @@
1
+ import {initializeService} from '../src';
2
+ import {LocalStorageMock} from "./localStorageMock";
3
+ const railContentModule = require('../src/services/railcontent.js')
4
+
5
+ export function initializeTestService() {
6
+ const config = {
7
+ sanityConfig: {
8
+ token: process.env.SANITY_API_TOKEN,
9
+ projectId: process.env.SANITY_PROJECT_ID,
10
+ dataset: process.env.SANITY_DATASET,
11
+ useCachedAPI: process.env.SANITY_USE_CACHED_API === 'true' || true,
12
+ version: '2021-06-07',
13
+ debug: process.env.DEBUG === 'true' || false,
14
+ useDummyRailContentMethods: true,
15
+ },
16
+ localStorage: new LocalStorageMock()
17
+ };
18
+ initializeService(config);
19
+
20
+ let mock = jest.spyOn(railContentModule, 'fetchUserPermissionsData');
21
+ let testData = {"permissions": [78, 91, 92], "isAdmin": false};
22
+ mock.mockImplementation(() => testData);
23
+ }
@@ -0,0 +1,22 @@
1
+ const {setLastUpdatedTime, wasLastUpdateOlderThanXSeconds} = require("../src/services/lastUpdated");
2
+ const {initializeTestService} = require("./initializeTests");
3
+
4
+ describe('lastUpdated', function () {
5
+
6
+ beforeEach(() => {
7
+ initializeTestService();
8
+ });
9
+
10
+ test('lastUpdated', async () => {
11
+ setLastUpdatedTime("testKey");
12
+ let test1 = wasLastUpdateOlderThanXSeconds(1, "testKey");
13
+ await new Promise((r) => setTimeout(r, 800));
14
+ let test2 = wasLastUpdateOlderThanXSeconds(1, "testKey");
15
+ await new Promise((r) => setTimeout(r, 500));
16
+ let test3 = wasLastUpdateOlderThanXSeconds(1, "testKey");
17
+
18
+ expect(test1).toEqual(false);
19
+ expect(test2).toEqual(false);
20
+ expect(test3).toEqual(true);
21
+ });
22
+ });
File without changes
package/test/log.js CHANGED
File without changes
@@ -1,8 +1,7 @@
1
- import {initializeService} from '../src/services/config.js';
2
1
  import {getFieldsForContentType} from "../src/contentTypeConfig";
3
2
  import {fetchSanity} from "../src/services/sanity";
4
3
  import {log} from './log.js';
5
- import {LocalStorageMock} from "./localStorageMock";
4
+ import {initializeTestService} from "./initializeTests";
6
5
 
7
6
  const {
8
7
  fetchSongById,
@@ -50,22 +49,6 @@ const {
50
49
  processMetadata,
51
50
  } = require('../src/contentMetaData.js');
52
51
 
53
- export function initializeTestService(){
54
- const config = {
55
- sanityConfig: {
56
- token: process.env.SANITY_API_TOKEN,
57
- projectId: process.env.SANITY_PROJECT_ID,
58
- dataset: process.env.SANITY_DATASET,
59
- useCachedAPI: process.env.SANITY_USE_CACHED_API === 'true' || true,
60
- version: '2021-06-07',
61
- debug: process.env.DEBUG === 'true' || false,
62
- useDummyRailContentMethods: true,
63
- },
64
- localStorage: new LocalStorageMock()
65
- };
66
- initializeService(config);
67
- }
68
-
69
52
  describe('Sanity Queries', function () {
70
53
  beforeEach(() => {
71
54
  initializeTestService();
@@ -295,7 +278,7 @@ describe('Sanity Queries', function () {
295
278
  expect(relatedLessons.some(
296
279
  lesson => lessonIds.includes(lesson.id)
297
280
  )).toBe(true);
298
- },10000);
281
+ }, 10000);
299
282
 
300
283
  test('fetchChildren', async () => {
301
284
  // complement test to fetchParentByRailContentId
@@ -404,7 +387,7 @@ describe('Sanity Queries', function () {
404
387
  expect(response.entity.length).toBeGreaterThan(0);
405
388
  });
406
389
  test('fetchCoachLessons-WithTypeFilters', async () => {
407
- const response = await fetchAllFilterOptions('drumeo',['type,course','type,live'], '','','coach-lessons','',[],31880);
390
+ const response = await fetchAllFilterOptions('drumeo', ['type,course', 'type,live'], '', '', 'coach-lessons', '', [], 31880);
408
391
  log(response);
409
392
  expect(response.meta.filterOptions.difficulty).toBeDefined();
410
393
  expect(response.meta.filterOptions.type).toBeDefined();
@@ -423,7 +406,7 @@ describe('Sanity Queries', function () {
423
406
  });
424
407
 
425
408
  test('fetchCoachLessons-IncludedFields', async () => {
426
- const response = await fetchCoachLessons('drumeo',31880, {includedFields: ['genre,Pop/Rock','difficulty,Beginner']});
409
+ const response = await fetchCoachLessons('drumeo', 31880, {includedFields: ['genre,Pop/Rock', 'difficulty,Beginner']});
427
410
  log(response);
428
411
  expect(response.entity.length).toBeGreaterThan(0);
429
412
  });
@@ -526,7 +509,7 @@ describe('Sanity Queries', function () {
526
509
  });
527
510
 
528
511
  test('fetchMetadata-Coach-Lessons', async () => {
529
- const response = await fetchMetadata('drumeo','coach-lessons');
512
+ const response = await fetchMetadata('drumeo', 'coach-lessons');
530
513
  log(response);
531
514
  expect(response).toBeDefined();
532
515
  });
@@ -586,23 +569,27 @@ describe('Sanity Queries', function () {
586
569
  expect(hierarchy.parents[241249]).toBe(241248);
587
570
  expect(hierarchy.parents[241248]).toBe(241247);
588
571
  expect(hierarchy.children[241250]).toStrictEqual([]);
589
- expect(hierarchy.children[243085]).toStrictEqual([ 243170, 243171, 243172, 243174, 243176 ]);
572
+ expect(hierarchy.children[243085]).toStrictEqual([243170, 243171, 243172, 243174, 243176]);
590
573
  });
591
574
 
592
575
  });
593
576
 
594
577
  describe('Filter Builder', function () {
595
578
 
579
+ beforeEach(() => {
580
+ initializeTestService();
581
+ });
582
+
596
583
  test('baseConstructor', async () => {
597
584
  const filter = 'railcontent_id = 111'
598
- let builder = new FilterBuilder(filter);
599
- let finalFilter = builder.buildFilter(filter);
585
+ let builder = new FilterBuilder(filter, {bypassPermissions: true});
586
+ let finalFilter = await builder.buildFilter(filter);
600
587
  let clauses = spliceFilterForAnds(finalFilter);
601
588
  expect(clauses[0].phrase).toBe(filter);
602
589
  expect(clauses[1].field).toBe('published_on');
603
590
 
604
- builder = new FilterBuilder();
605
- finalFilter = builder.buildFilter(filter);
591
+ builder = new FilterBuilder('', {bypassPermissions: true});
592
+ finalFilter = await builder.buildFilter(filter);
606
593
  clauses = spliceFilterForAnds(finalFilter);
607
594
  expect(clauses[0].field).toBe('published_on');
608
595
  expect(clauses[0].operator).toBe('<=');
@@ -610,8 +597,8 @@ describe('Filter Builder', function () {
610
597
 
611
598
  test('withOnlyFilterAvailableStatuses', async () => {
612
599
  const filter = 'railcontent_id = 111'
613
- const builder = FilterBuilder.withOnlyFilterAvailableStatuses(filter, ['published', 'unlisted']);
614
- const finalFilter = builder.buildFilter();
600
+ const builder = FilterBuilder.withOnlyFilterAvailableStatuses(filter, ['published', 'unlisted'], true);
601
+ const finalFilter = await builder.buildFilter();
615
602
  const clauses = spliceFilterForAnds(finalFilter);
616
603
  expect(clauses[0].phrase).toBe(filter);
617
604
  expect(clauses[1].field).toBe('status');
@@ -627,7 +614,7 @@ describe('Filter Builder', function () {
627
614
  availableContentStatuses: ['published', 'unlisted', 'scheduled'],
628
615
  getFutureScheduledContentsOnly: true
629
616
  });
630
- const finalFilter = builder.buildFilter();
617
+ const finalFilter = await builder.buildFilter();
631
618
  const clauses = spliceFilterForAnds(finalFilter);
632
619
  expect(clauses[0].phrase).toBe(filter);
633
620
  expect(clauses[1].field).toBe('(status'); // extra ( because it's a multi part filter
@@ -642,27 +629,18 @@ describe('Filter Builder', function () {
642
629
 
643
630
  test('withUserPermissions', async () => {
644
631
  const filter = 'railcontent_id = 111'
645
- const builder = new FilterBuilder(filter,
646
- {
647
- user: {
648
- user: {},
649
- permissions: [91, 92],
650
- }
651
- });
652
- const finalFilter = builder.buildFilter();
653
- const expected = "references(*[_type == 'permission' && railcontent_id in [91,92]]._id)"
632
+ const builder = new FilterBuilder(filter);
633
+ const finalFilter = await builder.buildFilter();
634
+ const expected = "references(*[_type == 'permission' && railcontent_id in [78,91,92]]._id)"
654
635
  const isMatch = finalFilter.includes(expected);
655
636
  expect(isMatch).toBeTruthy();
656
637
  });
657
638
 
658
639
  test('withUserPermissionsForPlusUser', async () => {
659
640
  const filter = 'railcontent_id = 111'
660
- const builder = new FilterBuilder(filter,
661
- {
662
- user: getPlusUser()
663
- });
664
- const finalFilter = builder.buildFilter();
665
- const expected = "references(*[_type == 'permission' && railcontent_id in [91,92]]._id)"
641
+ const builder = new FilterBuilder(filter);
642
+ const finalFilter = await builder.buildFilter();
643
+ const expected = "references(*[_type == 'permission' && railcontent_id in [78,91,92]]._id)"
666
644
  const isMatch = finalFilter.includes(expected);
667
645
  expect(isMatch).toBeTruthy();
668
646
  });
@@ -671,11 +649,10 @@ describe('Filter Builder', function () {
671
649
  const filter = 'railcontent_id = 111'
672
650
  const builder = new FilterBuilder(filter,
673
651
  {
674
- user: getPlusUser(),
675
652
  bypassPermissions: true
676
653
  });
677
- const finalFilter = builder.buildFilter();
678
- const expected = "references(*[_type == 'permission' && railcontent_id in [91,92]]._id)"
654
+ const finalFilter = await builder.buildFilter();
655
+ const expected = "references(*[_type == 'permission' && railcontent_id in [78,91,92]]._id)"
679
656
  const isMatch = finalFilter.includes(expected);
680
657
  expect(isMatch).toBeFalsy();
681
658
  const clauses = spliceFilterForAnds(finalFilter);
@@ -689,11 +666,11 @@ describe('Filter Builder', function () {
689
666
 
690
667
  const filter = 'railcontent_id = 111'
691
668
  let builder = new FilterBuilder(filter, {
692
- user: {},
693
669
  pullFutureContent: true,
670
+ bypassPermissions: true
694
671
  });
695
672
 
696
- let finalFilter = builder.buildFilter();
673
+ let finalFilter = await builder.buildFilter();
697
674
  let clauses = spliceFilterForAnds(finalFilter);
698
675
  expect(clauses[0].phrase).toBe(filter);
699
676
 
@@ -705,22 +682,16 @@ describe('Filter Builder', function () {
705
682
 
706
683
  builder = new FilterBuilder(filter,
707
684
  {
708
- user: {},
709
685
  getFutureContentOnly: true,
686
+ bypassPermissions: true
710
687
  });
711
- finalFilter = builder.buildFilter();
688
+ finalFilter = await builder.buildFilter();
712
689
  clauses = spliceFilterForAnds(finalFilter);
713
690
  expect(clauses[0].phrase).toBe(filter);
714
691
  expect(clauses[1].field).toBe('published_on');
715
692
  expect(clauses[1].operator).toBe('>=');
716
693
  });
717
694
 
718
- function getPlusUser() {
719
- return {
720
- permissions: [91, 92],
721
- }
722
- }
723
-
724
695
  function spliceFilterForAnds(filter) {
725
696
  // this will not correctly split complex filters with && and || conditions.
726
697
  let phrases = filter.split(' && ');
@@ -0,0 +1,19 @@
1
+ const {fetchUserPermissions} = require("../src/services/userPermissions");
2
+ const {initializeTestService} = require("./initializeTests");
3
+
4
+ describe('userPermissions', function () {
5
+ beforeEach(() => {
6
+ initializeTestService();
7
+ });
8
+
9
+ test('fetchUserPermissions', async () => {
10
+ let result = await fetchUserPermissions(); //fetch from server
11
+ let result2 = await fetchUserPermissions(); //fetch locally
12
+
13
+ //This breaks when running tests in parallel
14
+ //expect(railContentModule.fetchUserPermissionsData).toHaveBeenCalledTimes(1);
15
+ expect(result.permissions).toStrictEqual([78,91,92]);
16
+ expect(result.isAdmin).toStrictEqual(false);
17
+ expect(result).toBe(result2);
18
+ });
19
+ });
File without changes