musora-content-services 2.3.6 → 2.3.8
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/.coderabbit.yaml +0 -0
- package/.editorconfig +0 -0
- package/.github/workflows/node.js.yml +0 -0
- package/.prettierignore +0 -0
- package/.prettierrc +0 -0
- package/.yarnrc.yml +1 -0
- package/CHANGELOG.md +9 -0
- package/README.md +0 -0
- package/babel.config.cjs +0 -0
- package/docs/Content-Organization.html +0 -0
- package/docs/ContentOrganization.html +0 -0
- package/docs/Gamification.html +0 -0
- package/docs/UserManagement.html +0 -0
- package/docs/UserManagementSystem.html +0 -0
- package/docs/api_types.js.html +0 -0
- package/docs/config.js.html +0 -0
- package/docs/content-org_content-org.js.html +0 -0
- package/docs/content-org_playlists-types.js.html +0 -0
- package/docs/content-org_playlists.js.html +0 -0
- package/docs/content.js.html +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/gamification_awards.js.html +0 -0
- package/docs/gamification_gamification.js.html +0 -0
- package/docs/gamification_types.js.html +0 -0
- package/docs/global.html +0 -0
- package/docs/global.html#User +0 -0
- package/docs/index.html +0 -0
- package/docs/module-Awards.html +0 -0
- package/docs/module-Config.html +0 -0
- package/docs/module-Content-Services-V2.html +0 -0
- package/docs/module-Content-Services.html +763 -0
- package/docs/module-Permissions.html +0 -0
- package/docs/module-Playlists.html +0 -0
- package/docs/module-Railcontent-Services.html +0 -0
- package/docs/module-Sanity-Services.html +0 -0
- package/docs/module-Session-Management.html +0 -0
- package/docs/module-Sessions.html +0 -0
- package/docs/module-User-Management.html +0 -0
- package/docs/module-User-Permissions.html +0 -0
- package/docs/module-UserManagement.html +0 -0
- package/docs/railcontent.js.html +0 -0
- package/docs/sanity.js.html +0 -0
- package/docs/scripts/collapse.js +0 -0
- package/docs/scripts/commonNav.js +0 -0
- package/docs/scripts/linenumber.js +0 -0
- package/docs/scripts/nav.js +0 -0
- package/docs/scripts/polyfill.js +0 -0
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -0
- package/docs/scripts/prettify/lang-css.js +0 -0
- package/docs/scripts/prettify/prettify.js +0 -0
- package/docs/scripts/search.js +0 -0
- package/docs/styles/jsdoc.css +0 -0
- package/docs/styles/prettify.css +0 -0
- package/docs/types.js.html +0 -0
- package/docs/user_management.js.html +0 -0
- package/docs/user_permissions.js.html +0 -0
- package/docs/user_sessions.js.html +0 -0
- package/docs/user_types.js.html +0 -0
- package/docs/user_user-management-system.js.html +0 -0
- package/docs/user_user-management.js.html +0 -0
- package/jest.config.js +0 -0
- package/jsdoc.json +0 -0
- package/link_mcs.sh +0 -0
- package/package.json +1 -1
- package/src/contentMetaData.js +0 -0
- package/src/filterBuilder.js +0 -0
- package/src/index.d.ts +13 -0
- package/src/index.js +13 -0
- package/src/lib/httpHelper.js +0 -0
- package/src/lib/lastUpdated.js +0 -0
- package/src/services/api/types.js +0 -0
- package/src/services/config.js +0 -0
- package/src/services/content-org/content-org.js +0 -0
- package/src/services/content-org/playlists-types.js +0 -0
- package/src/services/content-org/playlists.js +0 -0
- package/src/services/content.js +0 -0
- package/src/services/contentLikes.js +0 -0
- package/src/services/contentProgress.js +0 -0
- package/src/services/dataContext.js +0 -0
- package/src/services/dateUtils.js +55 -0
- package/src/services/forum.js +0 -0
- package/src/services/gamification/awards.js +0 -0
- package/src/services/gamification/gamification.js +0 -0
- package/src/services/gamification/types.js +0 -0
- package/src/services/imageSRCBuilder.js +0 -0
- package/src/services/imageSRCVerify.js +0 -0
- package/src/services/railcontent.js +30 -18
- package/src/services/recommendations.js +10 -9
- package/src/services/types.js +0 -0
- package/src/services/user/management.js +0 -0
- package/src/services/user/permissions.js +0 -0
- package/src/services/user/sessions.js +0 -0
- package/src/services/user/types.js +0 -0
- package/src/services/user/user-management-system.js +0 -0
- package/src/services/userActivity.js +289 -106
- package/test/content.test.js +0 -0
- package/test/contentLikes.test.js +0 -0
- package/test/contentProgress.test.js +0 -0
- package/test/dataContext.test.js +0 -0
- package/test/forum.test.js +0 -0
- package/test/imageSRCBuilder.test.js +0 -0
- package/test/imageSRCVerify.test.js +0 -0
- package/test/initializeTests.js +0 -0
- package/test/lib/lastUpdated.test.js +0 -0
- package/test/live/contentProgressLive.test.js +0 -0
- package/test/live/railcontentLive.test.js +0 -0
- package/test/localStorageMock.js +0 -0
- package/test/log.js +0 -0
- package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
- package/test/mockData/mockData_user_practices.json +9 -0
- package/test/sanityQueryService.test.js +0 -0
- package/test/streakMessage.test.js +263 -0
- package/test/user/permissions.test.js +0 -0
- package/test/userActivity.test.js +6 -6
- package/tools/generate-index.cjs +0 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { initializeTestService } from './initializeTests.js'
|
|
2
|
+
import {getUserWeeklyStats, userActivityContext} from '../src/services/userActivity.js'
|
|
3
|
+
import {log} from './log.js'
|
|
4
|
+
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
global.fetch = jest.fn()
|
|
9
|
+
let mock = null
|
|
10
|
+
const DEBUG = false
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// Test Examples are taken from this document
|
|
14
|
+
// https://docs.google.com/spreadsheets/d/1pBmBTAODeRWI5uIO84lXjaQFW-lRPNh6gi7GV0lCwyc/edit?gid=0#gid=0
|
|
15
|
+
describe('Streak Messages', function () {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
initializeTestService()
|
|
18
|
+
const userLocalMidnight = new Date();
|
|
19
|
+
userLocalMidnight.setFullYear(2025, 2, 24);
|
|
20
|
+
jest.useFakeTimers();
|
|
21
|
+
jest.setSystemTime(userLocalMidnight);
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('streak message - example1', async () => {
|
|
25
|
+
const fixedDate = new Date('2025-03-24T12:00:00.000Z');
|
|
26
|
+
const allData = [
|
|
27
|
+
{ day: 1, date: '2025-03-24', duration_seconds: 120 },
|
|
28
|
+
{ day: 2, date: '2025-03-25', duration_seconds: 120 },
|
|
29
|
+
{ day: 3, date: '2025-03-26', duration_seconds: 120 },
|
|
30
|
+
{ day: 7, date: '2025-03-30', duration_seconds: 120 },
|
|
31
|
+
{ day: 8, date: '2025-03-31', duration_seconds: 120 },
|
|
32
|
+
{ day: 22, date: '2025-04-14', duration_seconds: 120 },
|
|
33
|
+
{ day: 23, date: '2025-04-15', duration_seconds: 120 },
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
const expectedMessages = [
|
|
37
|
+
{day: 1, incomplete: 'Start your streak by taking any lesson!', complete: 'Nice! You have a 1 day streak!'},
|
|
38
|
+
{day: 2, incomplete: 'You have a 1 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 2 day streak! Way to keep it going!'},
|
|
39
|
+
{day: 3, incomplete: 'You have a 2 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 3 day streak! Way to keep it going!'},
|
|
40
|
+
{day: 4, incomplete: 'You have a 3 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
41
|
+
{day: 5, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
42
|
+
{day: 6, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
43
|
+
{day: 7, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: 'You have a 1 week streak! Way to keep up the momentum!'},
|
|
44
|
+
{day: 8, incomplete: 'You have a 1 week streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 2 day streak! Way to keep it going!'},
|
|
45
|
+
{day: 9, incomplete: 'You have a 2 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
46
|
+
{day: 10, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
47
|
+
{day: 11, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
48
|
+
{day: 12, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
49
|
+
{day: 13, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
50
|
+
{day: 14, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
51
|
+
{day: 15, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
52
|
+
{day: 16, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
53
|
+
{day: 17, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
54
|
+
{day: 18, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
55
|
+
{day: 19, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
56
|
+
{day: 20, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
57
|
+
{day: 21, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
58
|
+
{day: 22, incomplete: 'Restart your streak by taking any lesson!', complete: 'Nice! You have a 1 day streak!'},
|
|
59
|
+
{day: 23, incomplete: 'You have a 1 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 2 day streak! Way to keep it going!'},
|
|
60
|
+
{day: 24, incomplete: 'You have a 2 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
mock = jest.spyOn(userActivityContext, 'fetchData')
|
|
64
|
+
// you can test a specific day by setting this value to the correct date and the test will only run that day
|
|
65
|
+
// this is 0 indexed
|
|
66
|
+
const testSpecificDay = null;
|
|
67
|
+
await testExpectedMessageForDays(allData, expectedMessages, fixedDate, testSpecificDay)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('streak message - example2', async () => {
|
|
71
|
+
const fixedDate = new Date('2025-03-24T12:00:00.000Z');
|
|
72
|
+
const allData = [
|
|
73
|
+
{ day: 1, date: '2025-03-24', duration_seconds: 120 },
|
|
74
|
+
{ day: 8, date: '2025-03-31', duration_seconds: 120 },
|
|
75
|
+
{ day: 10, date: '2025-04-02', duration_seconds: 120 },
|
|
76
|
+
{ day: 11, date: '2025-04-03', duration_seconds: 120 },
|
|
77
|
+
{ day: 13, date: '2025-04-05', duration_seconds: 120 },
|
|
78
|
+
{ day: 16, date: '2025-04-08', duration_seconds: 120 },
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
const expectedMessages = [
|
|
82
|
+
{day: 1, incomplete: 'Start your streak by taking any lesson!', complete: 'Nice! You have a 1 day streak!'},
|
|
83
|
+
{day: 2, incomplete: 'You have a 1 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
84
|
+
{day: 3, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
85
|
+
{day: 4, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
86
|
+
{day: 5, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
87
|
+
{day: 6, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
88
|
+
{day: 7, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
89
|
+
{day: 8, incomplete: 'You have a 1 week streak! Keep it going with any lesson or song!', complete: 'Great job! You have a 2 week streak! Way to keep it going!'},
|
|
90
|
+
{day: 9, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
91
|
+
{day: 10, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: 'You have a 2 week streak! Way to keep up the momentum!'},
|
|
92
|
+
{day: 11, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: 'Nice! You have a 2 day streak! Way to keep it going!'},
|
|
93
|
+
{day: 12, incomplete: 'You have a 2 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
94
|
+
{day: 13, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: 'You have a 2 week streak! Way to keep up the momentum!'},
|
|
95
|
+
{day: 14, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
96
|
+
{day: 15, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
97
|
+
{day: 16, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: 'Great job! You have a 3 week streak! Way to keep it going!'},
|
|
98
|
+
{day: 17, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: ''},
|
|
99
|
+
{day: 18, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: ''},
|
|
100
|
+
{day: 19, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: ''},
|
|
101
|
+
{day: 20, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: ''},
|
|
102
|
+
{day: 21, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: ''},
|
|
103
|
+
{day: 22, incomplete: 'You have a 3 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
104
|
+
{day: 23, incomplete: 'You have a 3 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
105
|
+
{day: 24, incomplete: 'You have a 3 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
106
|
+
{day: 25, incomplete: 'You have a 3 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
107
|
+
{day: 26, incomplete: 'You have a 3 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
108
|
+
{day: 27, incomplete: 'You have a 3 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
109
|
+
{day: 28, incomplete: 'You have a 3 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
mock = jest.spyOn(userActivityContext, 'fetchData')
|
|
113
|
+
// you can test a specific day by setting this value to the correct date and the test will only run that day
|
|
114
|
+
// this is zero indexed so do 1 day below the day you want to test
|
|
115
|
+
const testSpecificDay = null;
|
|
116
|
+
await testExpectedMessageForDays(allData, expectedMessages, fixedDate, testSpecificDay)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('streak message - example3', async () => {
|
|
120
|
+
const fixedDate = new Date('2025-03-24T12:00:00.000Z');
|
|
121
|
+
const allData = [
|
|
122
|
+
{ day: 2, date: '2025-03-25', duration_seconds: 120 },
|
|
123
|
+
{ day: 5, date: '2025-03-28', duration_seconds: 120 },
|
|
124
|
+
{ day: 6, date: '2025-03-29', duration_seconds: 120 },
|
|
125
|
+
{ day: 7, date: '2025-03-30', duration_seconds: 120 },
|
|
126
|
+
{ day: 9, date: '2025-04-01', duration_seconds: 120 },
|
|
127
|
+
{ day: 11, date: '2025-04-03', duration_seconds: 120 },
|
|
128
|
+
{ day: 12, date: '2025-04-04', duration_seconds: 120 },
|
|
129
|
+
{ day: 17, date: '2025-04-09', duration_seconds: 120 },
|
|
130
|
+
{ day: 19, date: '2025-04-11', duration_seconds: 120 },
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
const expectedMessages = [
|
|
134
|
+
{day: 1, incomplete: 'Start your streak by taking any lesson!', complete: ''},
|
|
135
|
+
{day: 2, incomplete: 'Start your streak by taking any lesson!', complete: 'Nice! You have a 1 day streak!'},
|
|
136
|
+
{day: 3, incomplete: 'You have a 1 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
137
|
+
{day: 4, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: ''},
|
|
138
|
+
{day: 5, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: 'You have a 1 week streak! Way to keep up the momentum!'},
|
|
139
|
+
{day: 6, incomplete: 'You have a 1 week streak! Keep up the momentum!', complete: 'Nice! You have a 2 day streak! Way to keep it going!'},
|
|
140
|
+
{day: 7, incomplete: 'You have a 2 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 3 day streak! Way to keep it going!'},
|
|
141
|
+
{day: 8, incomplete: 'You have a 3 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
142
|
+
{day: 9, incomplete: 'You have a 1 week streak! Keep it going with any lesson or song!', complete: 'Great job! You have a 2 week streak! Way to keep it going!'},
|
|
143
|
+
{day: 10, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
144
|
+
{day: 11, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: 'You have a 2 week streak! Way to keep up the momentum!'},
|
|
145
|
+
{day: 12, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: 'Nice! You have a 2 day streak! Way to keep it going!'},
|
|
146
|
+
{day: 13, incomplete: 'You have a 2 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
147
|
+
{day: 14, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: ''},
|
|
148
|
+
{day: 15, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
149
|
+
{day: 16, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: ''},
|
|
150
|
+
{day: 17, incomplete: 'You have a 2 week streak! Keep it going with any lesson or song!', complete: 'Great job! You have a 3 week streak! Way to keep it going!'},
|
|
151
|
+
{day: 18, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: ''},
|
|
152
|
+
{day: 19, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: 'You have a 3 week streak! Way to keep up the momentum!'},
|
|
153
|
+
{day: 20, incomplete: 'You have a 3 week streak! Keep up the momentum!', complete: ''},
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
mock = jest.spyOn(userActivityContext, 'fetchData')
|
|
157
|
+
// you can test a specific day by setting this value to the correct date and the test will only run that day
|
|
158
|
+
// this is 0 indexed
|
|
159
|
+
const testSpecificDay = null;
|
|
160
|
+
await testExpectedMessageForDays(allData, expectedMessages, fixedDate, testSpecificDay)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
test('streak message - example4', async () => {
|
|
164
|
+
const fixedDate = new Date('2025-03-24T12:00:00.000Z');
|
|
165
|
+
const allData = [
|
|
166
|
+
{ day: 1, date: '2025-03-24', duration_seconds: 120},
|
|
167
|
+
{ day: 2, date: '2025-03-25', duration_seconds: 120},
|
|
168
|
+
{ day: 3, date: '2025-03-26', duration_seconds: 120},
|
|
169
|
+
{ day: 4, date: '2025-03-27', duration_seconds: 120},
|
|
170
|
+
{ day: 5, date: '2025-03-28', duration_seconds: 120},
|
|
171
|
+
{ day: 6, date: '2025-03-29', duration_seconds: 120},
|
|
172
|
+
{ day: 7, date: '2025-03-30', duration_seconds: 120},
|
|
173
|
+
{ day: 8, date: '2025-03-31', duration_seconds: 120},
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
const expectedMessages = [
|
|
177
|
+
{day: 1, incomplete: 'Start your streak by taking any lesson!', complete: 'Nice! You have a 1 day streak!'},
|
|
178
|
+
{day: 2, incomplete: 'You have a 1 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 2 day streak! Way to keep it going!'},
|
|
179
|
+
{day: 3, incomplete: 'You have a 2 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 3 day streak! Way to keep it going!'},
|
|
180
|
+
{day: 4, incomplete: 'You have a 3 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 4 day streak! Way to keep it going!'},
|
|
181
|
+
{day: 5, incomplete: 'You have a 4 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 5 day streak! Way to keep it going!'},
|
|
182
|
+
{day: 6, incomplete: 'You have a 5 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 6 day streak! Way to keep it going!'},
|
|
183
|
+
{day: 7, incomplete: 'You have a 6 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have a 7 day streak! Way to keep it going!'},
|
|
184
|
+
{day: 8, incomplete: 'You have a 7 day streak! Keep it going with any lesson or song!', complete: 'Nice! You have an 8 day streak! Way to keep it going!'},
|
|
185
|
+
{day: 9, incomplete: 'You have an 8 day streak! Keep it going with any lesson or song!', complete: ''},
|
|
186
|
+
{day: 10, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: 'You have a 2 week streak! Keep up the momentum!'},
|
|
187
|
+
{day: 11, incomplete: 'You have a 2 week streak! Keep up the momentum!', complete: 'You have a 2 week streak! Keep up the momentum!'},
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
mock = jest.spyOn(userActivityContext, 'fetchData')
|
|
191
|
+
// you can test a specific day by setting this value to the correct date and the test will only run that day
|
|
192
|
+
// this is 0 indexed
|
|
193
|
+
const testSpecificDay = null;
|
|
194
|
+
await testExpectedMessageForDays(allData, expectedMessages, fixedDate, testSpecificDay)
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
function incrementFakeDate(nDays = 1){
|
|
199
|
+
let today = new Date();
|
|
200
|
+
today.setFullYear(today.getFullYear(), today.getMonth(), (today.getDate() + nDays));
|
|
201
|
+
jest.useFakeTimers();
|
|
202
|
+
jest.setSystemTime(today);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const loadMockDataForDays = (fileName, datesArray) => {
|
|
206
|
+
const jsonPath = path.join(__dirname, 'mockData/', fileName);
|
|
207
|
+
let json = JSON.parse(fs.readFileSync(jsonPath, 'utf-8'));
|
|
208
|
+
let practices = {};
|
|
209
|
+
// Loop through the provided dates and durations
|
|
210
|
+
datesArray.forEach(({ date, duration_seconds }) => {
|
|
211
|
+
practices[date] = [{ "duration_seconds": duration_seconds }];
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Replace the placeholder with dynamically generated data
|
|
215
|
+
json.data.practices = practices;
|
|
216
|
+
return json;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
function sliceExampleData(startDate, nDays, includeToday, activeDays)
|
|
220
|
+
{
|
|
221
|
+
if (nDays === 0 && !includeToday) {
|
|
222
|
+
return []
|
|
223
|
+
}
|
|
224
|
+
nDays = includeToday ? nDays : nDays - 1
|
|
225
|
+
let target = new Date(startDate)
|
|
226
|
+
target.setDate(target.getDate() + nDays)
|
|
227
|
+
return activeDays.filter((obj) => {
|
|
228
|
+
let activeDate = new Date(obj.date)
|
|
229
|
+
return activeDate <= target
|
|
230
|
+
})
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function testExpectedMessageForDays(exampleData, expectedMessages, startDate, testDayN = null) {
|
|
234
|
+
const start = testDayN ?? 0;
|
|
235
|
+
const end = testDayN != null ? testDayN + 1 : expectedMessages.length
|
|
236
|
+
if (testDayN != null) incrementFakeDate(testDayN)
|
|
237
|
+
for (let i = start; i < end; i++) {
|
|
238
|
+
let target = new Date(startDate)
|
|
239
|
+
target.setDate(target.getDate() + i)
|
|
240
|
+
const setDataAndCheckStreakMessage = async function(includeToday) {
|
|
241
|
+
let activeDays = sliceExampleData(startDate, i, includeToday, exampleData)
|
|
242
|
+
let json = loadMockDataForDays('mockData_user_practices.json', activeDays);
|
|
243
|
+
mock.mockImplementation(() => json);
|
|
244
|
+
userActivityContext.clearCache()
|
|
245
|
+
let practices = await getUserWeeklyStats()
|
|
246
|
+
const state = includeToday ? 'STARTED' : 'NOT-STARTED'
|
|
247
|
+
const expected = includeToday && !!expectedMessages[i].complete ? expectedMessages[i].complete :
|
|
248
|
+
expectedMessages[i].incomplete
|
|
249
|
+
const day = expectedMessages[i].day
|
|
250
|
+
log(`Running ${state} content tests for Day ${day} on ${target}`)
|
|
251
|
+
log(`Expecting ${expected}`)
|
|
252
|
+
expect(practices.data.streakMessage).toBeDefined()
|
|
253
|
+
if (practices.data.streakMessage !== expected) {
|
|
254
|
+
throw new Error(`Mismatch on Day ${expectedMessages[i].day} [${target.toDateString()}]:
|
|
255
|
+
Expected: "${expected}"
|
|
256
|
+
Received: "${practices.data.streakMessage}"`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
await setDataAndCheckStreakMessage(false)
|
|
260
|
+
await setDataAndCheckStreakMessage(true)
|
|
261
|
+
incrementFakeDate(1)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
File without changes
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { initializeTestService } from './initializeTests.js'
|
|
2
|
-
import {getUserMonthlyStats, getUserWeeklyStats, userActivityContext, recordUserPractice
|
|
3
|
-
import { logUserPractice } from '../src/services/railcontent.js'
|
|
2
|
+
import {getUserMonthlyStats, getUserWeeklyStats, userActivityContext, recordUserPractice} from '../src/services/userActivity.js'
|
|
4
3
|
import {fetchByRailContentIds} from "../src";
|
|
5
4
|
import mockData_fetchByRailContentIds_one_content from './mockData/mockData_fetchByRailContentIds_one_content.json';
|
|
6
5
|
|
|
@@ -53,10 +52,9 @@ describe('User Activity API Tests', function () {
|
|
|
53
52
|
const practices = await getUserMonthlyStats()
|
|
54
53
|
consoleLog(practices)
|
|
55
54
|
// Assert that dailyActiveStats contains correct data
|
|
56
|
-
const dailyStats = practices.dailyActiveStats
|
|
55
|
+
const dailyStats = practices.data.dailyActiveStats
|
|
57
56
|
const currentDate = new Date()
|
|
58
57
|
const currentDateString = currentDate.toISOString().split('T')[0]
|
|
59
|
-
expect(dailyStats).toHaveLength(42)
|
|
60
58
|
|
|
61
59
|
// Verify current day's stats (e.g., March 17, 2025)
|
|
62
60
|
const current = dailyStats.find(stat => stat.label === currentDateString)
|
|
@@ -75,7 +73,7 @@ describe('User Activity API Tests', function () {
|
|
|
75
73
|
consoleLog(practices)
|
|
76
74
|
|
|
77
75
|
// Assert that dailyActiveStats contains correct data
|
|
78
|
-
const dailyStats = practices.dailyActiveStats
|
|
76
|
+
const dailyStats = practices.data.dailyActiveStats
|
|
79
77
|
const feb10 = dailyStats.find(stat => stat.label === '2025-02-10')
|
|
80
78
|
expect(feb10.inStreak).toBe(true)
|
|
81
79
|
expect(feb10.type).toBe('tracked')
|
|
@@ -87,7 +85,7 @@ describe('User Activity API Tests', function () {
|
|
|
87
85
|
const practices = await getUserWeeklyStats( )
|
|
88
86
|
consoleLog(practices)
|
|
89
87
|
|
|
90
|
-
const dailyStats = practices.dailyActiveStats
|
|
88
|
+
const dailyStats = practices.data.dailyActiveStats
|
|
91
89
|
const monday = dailyStats.find(stat => stat.label === 'M')
|
|
92
90
|
expect(monday).toBeDefined
|
|
93
91
|
const tuesday = dailyStats.find(stat => stat.label === 'T')
|
|
@@ -116,3 +114,5 @@ describe('User Activity API Tests', function () {
|
|
|
116
114
|
}
|
|
117
115
|
}
|
|
118
116
|
})
|
|
117
|
+
|
|
118
|
+
|
package/tools/generate-index.cjs
CHANGED
|
File without changes
|