musora-content-services 1.0.164 → 1.0.166
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/CHANGELOG.md +4 -0
- package/jest.config.js +1 -1
- package/package.json +1 -1
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
- package/src/services/config.js +2 -1
- package/src/services/contentProgress.js +1 -1
- package/src/services/railcontent.js +9 -6
- package/src/services/sanity.js +21 -0
- package/test/contentProgress.test.js +1 -2
- package/test/initializeTests.js +39 -2
- package/test/live/contentProgressLive.test.js +112 -0
- package/test/sanityQueryService.test.js +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.0.166](https://github.com/railroadmedia/musora-content-services/compare/v1.0.165...v1.0.166) (2024-11-11)
|
|
6
|
+
|
|
7
|
+
### [1.0.165](https://github.com/railroadmedia/musora-content-services/compare/v1.0.164...v1.0.165) (2024-11-11)
|
|
8
|
+
|
|
5
9
|
### [1.0.164](https://github.com/railroadmedia/musora-content-services/compare/v1.0.163...v1.0.164) (2024-11-09)
|
|
6
10
|
|
|
7
11
|
### [1.0.163](https://github.com/railroadmedia/musora-content-services/compare/v1.0.162...v1.0.163) (2024-11-08)
|
package/jest.config.js
CHANGED
|
@@ -92,7 +92,7 @@ const config = {
|
|
|
92
92
|
// moduleNameMapper: {},
|
|
93
93
|
|
|
94
94
|
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
|
|
95
|
-
|
|
95
|
+
modulePathIgnorePatterns: ["<rootDir>/test/live"],
|
|
96
96
|
|
|
97
97
|
// Activates notifications for test results
|
|
98
98
|
// notify: false,
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
fetchChallengeOverview,
|
|
84
84
|
fetchChildren,
|
|
85
85
|
fetchCoachLessons,
|
|
86
|
+
fetchCommentModContentData,
|
|
86
87
|
fetchCourseOverview,
|
|
87
88
|
fetchFoundation,
|
|
88
89
|
fetchGenreLessons,
|
|
@@ -152,6 +153,7 @@ declare module 'musora-content-services' {
|
|
|
152
153
|
fetchChallengeOverview,
|
|
153
154
|
fetchChildren,
|
|
154
155
|
fetchCoachLessons,
|
|
156
|
+
fetchCommentModContentData,
|
|
155
157
|
fetchCompletedContent,
|
|
156
158
|
fetchCompletedState,
|
|
157
159
|
fetchContentInProgress,
|
package/src/index.js
CHANGED
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
fetchChallengeOverview,
|
|
84
84
|
fetchChildren,
|
|
85
85
|
fetchCoachLessons,
|
|
86
|
+
fetchCommentModContentData,
|
|
86
87
|
fetchCourseOverview,
|
|
87
88
|
fetchFoundation,
|
|
88
89
|
fetchGenreLessons,
|
|
@@ -151,6 +152,7 @@ export {
|
|
|
151
152
|
fetchChallengeOverview,
|
|
152
153
|
fetchChildren,
|
|
153
154
|
fetchCoachLessons,
|
|
155
|
+
fetchCommentModContentData,
|
|
154
156
|
fetchCompletedContent,
|
|
155
157
|
fetchCompletedState,
|
|
156
158
|
fetchContentInProgress,
|
package/src/services/config.js
CHANGED
|
@@ -32,7 +32,8 @@ const excludeFromGeneratedIndex = [];
|
|
|
32
32
|
* @param {Object} config.railcontentConfig - Configuration for user services.
|
|
33
33
|
* @param {string} config.railcontentConfig.token - The token for authenticating user-specific requests.
|
|
34
34
|
* @param {string} config.railcontentConfig.userId - The user ID for fetching user-specific data.
|
|
35
|
-
* @param {string} config.railcontentConfig.baseUrl - The url for the
|
|
35
|
+
* @param {string} config.railcontentConfig.baseUrl - The url for the environment.
|
|
36
|
+
* @param {string} config.railcontentConfig.authToken - The bearer authorization token.
|
|
36
37
|
* @param {Object} config.localStorage - Cache to use for localStorage
|
|
37
38
|
* @param {boolean} config.isMA - Variable that tells if the library is used by MA or FEW
|
|
38
39
|
|
|
@@ -114,7 +114,7 @@ function completeStatusInLocalContext(contentId, localContext, hierarchy) {
|
|
|
114
114
|
export async function contentStatusReset(contentId) {
|
|
115
115
|
await dataContext.update(
|
|
116
116
|
function (localContext) {
|
|
117
|
-
const index = Object.keys(localContext.data).indexOf(contentId);
|
|
117
|
+
const index = Object.keys(localContext.data).indexOf(contentId.toString());
|
|
118
118
|
if (index > -1) { // only splice array when item is found
|
|
119
119
|
delete localContext.data[contentId];
|
|
120
120
|
}
|
|
@@ -256,6 +256,9 @@ export async function fetchHandler(url, method = "get", dataVersion = null, body
|
|
|
256
256
|
'Content-Type': 'application/json',
|
|
257
257
|
'X-CSRF-TOKEN': globalConfig.railcontentConfig.token,
|
|
258
258
|
};
|
|
259
|
+
if (globalConfig.railcontentConfig.authToken) {
|
|
260
|
+
headers['Authorization'] = `Bearer ${globalConfig.railcontentConfig.authToken}`;
|
|
261
|
+
}
|
|
259
262
|
if (dataVersion) headers['Data-Version'] = dataVersion;
|
|
260
263
|
const options = {
|
|
261
264
|
method,
|
|
@@ -269,7 +272,7 @@ export async function fetchHandler(url, method = "get", dataVersion = null, body
|
|
|
269
272
|
if (response.ok) {
|
|
270
273
|
return await response.json();
|
|
271
274
|
} else {
|
|
272
|
-
console.
|
|
275
|
+
console.error(`Fetch error: ${method} ${url} ${response.status} ${response.statusText}`);
|
|
273
276
|
console.log(response);
|
|
274
277
|
}
|
|
275
278
|
} catch (error) {
|
|
@@ -826,13 +829,13 @@ export async function fetchPlaylistItem(payload) {
|
|
|
826
829
|
}
|
|
827
830
|
|
|
828
831
|
export async function postContentCompleted(contentId) {
|
|
829
|
-
let url = `/content
|
|
830
|
-
return postDataHandler(url);
|
|
832
|
+
let url = `/content/user/progress/complete`;
|
|
833
|
+
return postDataHandler(url, {"contentId": contentId});
|
|
831
834
|
}
|
|
832
835
|
|
|
833
836
|
export async function postContentReset(contentId) {
|
|
834
|
-
let url = `/content
|
|
835
|
-
return postDataHandler(url);
|
|
837
|
+
let url = `/content/user/progress/reset`;
|
|
838
|
+
return postDataHandler(url, {"contentId": contentId});
|
|
836
839
|
}
|
|
837
840
|
|
|
838
841
|
/**
|
|
@@ -918,4 +921,4 @@ function fetchAbsolute(url, params) {
|
|
|
918
921
|
}
|
|
919
922
|
}
|
|
920
923
|
return fetch(url, params);
|
|
921
|
-
}
|
|
924
|
+
}
|
package/src/services/sanity.js
CHANGED
|
@@ -1436,6 +1436,27 @@ function populateHierarchyLookups(currentLevel, data, parentId) {
|
|
|
1436
1436
|
}
|
|
1437
1437
|
}
|
|
1438
1438
|
|
|
1439
|
+
/**
|
|
1440
|
+
* Fetch data for comment mod page
|
|
1441
|
+
*
|
|
1442
|
+
* @param {array} ids - List of ids get data for
|
|
1443
|
+
* @returns {Promise<Object|null>} - A promise that resolves to an object containing the data
|
|
1444
|
+
*/
|
|
1445
|
+
export async function fetchCommentModContentData(ids) {
|
|
1446
|
+
const idsString = ids.join(',');
|
|
1447
|
+
const fields = `"id": railcontent_id, title, "parent": *[^._id in child[]._ref]{"id":railcontent_id, title}`;
|
|
1448
|
+
const query = await buildQuery(`railcontent_id in [${idsString}]`,
|
|
1449
|
+
{bypassPermissions: true},
|
|
1450
|
+
fields,
|
|
1451
|
+
{});
|
|
1452
|
+
let data = await fetchSanity(query, true);
|
|
1453
|
+
let mapped = {};
|
|
1454
|
+
data.forEach(function (content) {
|
|
1455
|
+
mapped[content.id] = {"id": content.id, "title": content.title, "parentTitle": content.parent[0].title};
|
|
1456
|
+
});
|
|
1457
|
+
return mapped;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1439
1460
|
|
|
1440
1461
|
/**
|
|
1441
1462
|
*
|
|
@@ -21,9 +21,8 @@ describe('contentProgressDataContext', function () {
|
|
|
21
21
|
beforeEach(() => {
|
|
22
22
|
initializeTestService();
|
|
23
23
|
mock = jest.spyOn(dataContext, 'fetchData');
|
|
24
|
-
var json = JSON.parse(`{"version":${testVersion},"data":{"234191":{"s":"started","p":6,"t":20,"u":1731108082},"233955":{"s":"started","p":1,"u":1731108083},"259426":{"s":"completed","p":100,"u":1731108085}}}`);
|
|
24
|
+
var json = JSON.parse(`{"version":${testVersion},"config":{"key":1,"enabled":1,"checkInterval":1,"refreshInterval":2},"data":{"234191":{"s":"started","p":6,"t":20,"u":1731108082},"233955":{"s":"started","p":1,"u":1731108083},"259426":{"s":"completed","p":100,"u":1731108085}}}`);
|
|
25
25
|
mock.mockImplementation(() => json);
|
|
26
|
-
|
|
27
26
|
});
|
|
28
27
|
|
|
29
28
|
test('getProgressPercentage', async () => {
|
package/test/initializeTests.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import {initializeService} from '../src';
|
|
1
|
+
import {globalConfig, initializeService} from '../src';
|
|
2
2
|
import {LocalStorageMock} from "./localStorageMock";
|
|
3
|
+
|
|
3
4
|
const railContentModule = require('../src/services/railcontent.js')
|
|
5
|
+
let token = null;
|
|
6
|
+
let userId = null;
|
|
4
7
|
|
|
5
|
-
export function initializeTestService() {
|
|
8
|
+
export async function initializeTestService(useLive = false) {
|
|
9
|
+
if (useLive && !token && process.env.RAILCONTENT_BASE_URL) {
|
|
10
|
+
let data = await fetchLoginToken(process.env.RAILCONTENT_EMAIL, process.env.RAILCONTENT_PASSWORD);
|
|
11
|
+
token = data['token'];
|
|
12
|
+
userId = data['userId'];
|
|
13
|
+
}
|
|
6
14
|
const config = {
|
|
7
15
|
sanityConfig: {
|
|
8
16
|
token: process.env.SANITY_API_TOKEN,
|
|
@@ -13,6 +21,11 @@ export function initializeTestService() {
|
|
|
13
21
|
debug: process.env.DEBUG === 'true' || false,
|
|
14
22
|
useDummyRailContentMethods: true,
|
|
15
23
|
},
|
|
24
|
+
railcontentConfig: {
|
|
25
|
+
baseUrl: process.env.RAILCONTENT_BASE_URL,
|
|
26
|
+
userId: userId,
|
|
27
|
+
authToken: token,
|
|
28
|
+
},
|
|
16
29
|
localStorage: new LocalStorageMock()
|
|
17
30
|
};
|
|
18
31
|
initializeService(config);
|
|
@@ -20,4 +33,28 @@ export function initializeTestService() {
|
|
|
20
33
|
let mock = jest.spyOn(railContentModule, 'fetchUserPermissionsData');
|
|
21
34
|
let testData = {"permissions": [78, 91, 92], "isAdmin": false};
|
|
22
35
|
mock.mockImplementation(() => testData);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function fetchLoginToken(email, password) {
|
|
39
|
+
try {
|
|
40
|
+
const url = `${process.env.RAILCONTENT_BASE_URL}/user-management-system/login/token`;
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
headers: {
|
|
44
|
+
'Accept': 'application/json',
|
|
45
|
+
'Content-Type': 'application/json'
|
|
46
|
+
},
|
|
47
|
+
body: JSON.stringify({"email": email, "password": password, "device_name": "test"})
|
|
48
|
+
});
|
|
49
|
+
if (response.ok) {
|
|
50
|
+
let data = await response.json();
|
|
51
|
+
return {token: data.token, userId: data.user.id};
|
|
52
|
+
} else {
|
|
53
|
+
console.log('fetch error:', response.status);
|
|
54
|
+
console.log(response);
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error('Fetch error:', error);
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
23
60
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
recordWatchSession,
|
|
3
|
+
getProgressPercentage,
|
|
4
|
+
dataContext,
|
|
5
|
+
getProgressState, contentStatusCompleted, contentStatusReset
|
|
6
|
+
} from "../../src/services/contentProgress";
|
|
7
|
+
import {initializeTestService} from "../initializeTests";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
describe('contentProgressDataContextLocal', function () {
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
await initializeTestService(true);
|
|
13
|
+
}, 1000000);
|
|
14
|
+
|
|
15
|
+
test('verifyProgressPercentage', async () => {
|
|
16
|
+
let contentId = 241250;
|
|
17
|
+
await contentStatusReset(contentId);
|
|
18
|
+
|
|
19
|
+
await recordWatchSession(contentId, "video", "vimeo", 100, 50, 50);
|
|
20
|
+
|
|
21
|
+
let result = await getProgressPercentage(contentId);
|
|
22
|
+
expect(result).toBe(50);
|
|
23
|
+
dataContext.clearCache();
|
|
24
|
+
|
|
25
|
+
result = await getProgressPercentage(contentId);
|
|
26
|
+
expect(result).toBe(50);
|
|
27
|
+
}, 100000);
|
|
28
|
+
|
|
29
|
+
test('verifyState', async () => {
|
|
30
|
+
let contentId = 241251;
|
|
31
|
+
await contentStatusReset(contentId);
|
|
32
|
+
|
|
33
|
+
let result = await getProgressState(contentId);
|
|
34
|
+
expect(result).toBe("");
|
|
35
|
+
|
|
36
|
+
await recordWatchSession(contentId, "video", "vimeo", 100, 50, 50);
|
|
37
|
+
|
|
38
|
+
result = await getProgressState(contentId);
|
|
39
|
+
expect(result).toBe("started");
|
|
40
|
+
dataContext.clearCache();
|
|
41
|
+
|
|
42
|
+
result = await getProgressState(contentId);
|
|
43
|
+
expect(result).toBe("started");
|
|
44
|
+
}, 100000);
|
|
45
|
+
|
|
46
|
+
test('verifyStateCompleted', async () => {
|
|
47
|
+
let contentId = 241252;
|
|
48
|
+
await contentStatusReset(contentId);
|
|
49
|
+
|
|
50
|
+
await contentStatusCompleted(241252);
|
|
51
|
+
let result = await getProgressState(241252);
|
|
52
|
+
expect(result).toBe("completed");
|
|
53
|
+
|
|
54
|
+
result = await getProgressState(contentId);
|
|
55
|
+
expect(result).toBe("completed");
|
|
56
|
+
dataContext.clearCache();
|
|
57
|
+
|
|
58
|
+
result = await getProgressState(contentId);
|
|
59
|
+
expect(result).toBe("completed");
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
}, 100000);
|
|
63
|
+
|
|
64
|
+
test('verifyStateReset', async () => {
|
|
65
|
+
let contentId = 241253;
|
|
66
|
+
await contentStatusReset(contentId);
|
|
67
|
+
|
|
68
|
+
await contentStatusCompleted(contentId);
|
|
69
|
+
|
|
70
|
+
let result = await getProgressState(contentId);
|
|
71
|
+
expect(result).toBe("completed");
|
|
72
|
+
await contentStatusReset(contentId);
|
|
73
|
+
|
|
74
|
+
result = await getProgressState(contentId);
|
|
75
|
+
expect(result).toBe("");
|
|
76
|
+
dataContext.clearCache();
|
|
77
|
+
|
|
78
|
+
result = await getProgressState(contentId);
|
|
79
|
+
expect(result).toBe("");
|
|
80
|
+
}, 100000);
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
//
|
|
84
|
+
// test('progressBubbling', async () => {
|
|
85
|
+
// let serverVersion = 2;
|
|
86
|
+
// let mock2 = jest.spyOn(railContentModule, 'postRecordWatchSession');
|
|
87
|
+
// mock2.mockImplementation(() => JSON.parse(`{"version": ${serverVersion}}`));
|
|
88
|
+
// let progress = await getProgressPercentage(241250); //force load context
|
|
89
|
+
//
|
|
90
|
+
// await recordWatchSession(241250, "video", "vimeo", 100, 50, 50);
|
|
91
|
+
// serverVersion++;
|
|
92
|
+
// await recordWatchSession(241251, "video", "vimeo", 100, 50, 50);
|
|
93
|
+
// serverVersion++;
|
|
94
|
+
// await recordWatchSession(241252, "video", "vimeo", 100, 50, 50);
|
|
95
|
+
// serverVersion++;
|
|
96
|
+
// await recordWatchSession(241260, "video", "vimeo", 100, 100, 100);
|
|
97
|
+
// serverVersion++;
|
|
98
|
+
// await recordWatchSession(241261, "video", "vimeo", 100, 100, 100);
|
|
99
|
+
// serverVersion++;
|
|
100
|
+
// progress = await getProgressPercentage(241250);
|
|
101
|
+
//
|
|
102
|
+
// expect(progress).toBe(50);
|
|
103
|
+
// let progress241249 = await getProgressPercentage(241249);
|
|
104
|
+
// expect(progress241249).toBe(15);
|
|
105
|
+
// let progress241248 = await getProgressPercentage(241248);
|
|
106
|
+
// expect(progress241248).toBe(7);
|
|
107
|
+
// let progress241247 = await getProgressPercentage(241247);
|
|
108
|
+
// expect(progress241247).toBe(1);
|
|
109
|
+
//
|
|
110
|
+
// }, 100000);
|
|
111
|
+
|
|
112
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {getFieldsForContentType} from "../src/contentTypeConfig";
|
|
2
|
-
import {fetchSanity} from "../src/services/sanity";
|
|
2
|
+
import {fetchCommentModContentData, fetchSanity} from "../src/services/sanity";
|
|
3
3
|
import {log} from './log.js';
|
|
4
4
|
import {initializeTestService} from "./initializeTests";
|
|
5
5
|
|
|
@@ -572,6 +572,13 @@ describe('Sanity Queries', function () {
|
|
|
572
572
|
expect(hierarchy.children[243085]).toStrictEqual([243170, 243171, 243172, 243174, 243176]);
|
|
573
573
|
});
|
|
574
574
|
|
|
575
|
+
test('fetchCommentData', async()=>{
|
|
576
|
+
let data = await fetchCommentModContentData([241251,241252]);
|
|
577
|
+
expect(data[241251].title).toBe("Setting Up Your Space");
|
|
578
|
+
expect(data[241251].parentTitle).toBe("Gear");
|
|
579
|
+
expect(data[241252].title).toBe("Setting Up Your Pedals & Throne");
|
|
580
|
+
});
|
|
581
|
+
|
|
575
582
|
});
|
|
576
583
|
|
|
577
584
|
describe('Filter Builder', function () {
|