musora-content-services 2.3.2 → 2.3.3
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/.editorconfig +0 -0
- package/.github/workflows/node.js.yml +0 -0
- package/.prettierignore +0 -0
- package/.prettierrc +0 -0
- package/CHANGELOG.md +2 -0
- package/README.md +0 -0
- package/babel.config.cjs +0 -0
- package/docs/Content-Organization.html +0 -0
- package/docs/Gamification.html +0 -0
- package/docs/Playlists.html +0 -0
- package/docs/api_types.js.html +0 -0
- package/docs/config.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-org_types.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/index.html +0 -0
- package/docs/module-Awards.html +0 -0
- package/docs/module-Config.html +0 -0
- package/docs/module-Content-Organization-Playlists.html +0 -0
- package/docs/module-Content-Organization.html +0 -0
- package/docs/module-Content-Services-V2.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-User-Permissions.html +0 -0
- package/docs/module-playlists.html +0 -0
- package/docs/module-playlists_.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/user_permissions.js.html +0 -0
- package/docs/user_sessions.js.html +0 -0
- package/docs/user_types.js.html +0 -0
- package/jest.config.js +0 -0
- package/jsdoc.json +0 -0
- package/package.json +1 -1
- package/src/contentMetaData.js +0 -0
- package/src/filterBuilder.js +0 -0
- package/src/index.d.ts +18 -0
- package/src/index.js +18 -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/playlists-types.js +0 -0
- package/src/services/content-org/playlists.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/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 +139 -0
- package/src/services/imageSRCVerify.js +114 -0
- package/src/services/railcontent.js +3 -3
- package/src/services/recommendations.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/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 +37 -0
- package/test/imageSRCVerify.test.js +160 -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/sanityQueryService.test.js +0 -0
- package/test/user/permissions.test.js +0 -0
- package/test/userActivity.test.js +0 -0
- package/tools/generate-index.cjs +0 -0
- package/.yarnrc.yml +0 -1
- package/docs/module-Content-Services.html +0 -763
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const { buildImageSRC, applySanityTransformations } = require('../src/services/imageSRCBuilder.js')
|
|
2
|
+
|
|
3
|
+
describe('imageSRCBuilder', function () {
|
|
4
|
+
beforeEach(() => {})
|
|
5
|
+
|
|
6
|
+
test('applySanityTransformations', async () => {
|
|
7
|
+
const url =
|
|
8
|
+
'https://cdn.sanity.io/images/4032r8py/production/83c3b6e7354a46c605804c093f707daa4e3f8f25-8000x4500.png'
|
|
9
|
+
const width = 500
|
|
10
|
+
const height = 100
|
|
11
|
+
const quality = 95
|
|
12
|
+
const resultingURL = applySanityTransformations(url, {
|
|
13
|
+
width: width,
|
|
14
|
+
quality: quality,
|
|
15
|
+
height: height,
|
|
16
|
+
})
|
|
17
|
+
const expected = `${url}?w=${width}&h=${height}&q=${quality}`
|
|
18
|
+
|
|
19
|
+
expect(resultingURL).toStrictEqual(expected)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('buildImageSRC', async () => {
|
|
23
|
+
const url = 'https://d2vyvo0tyx8ig5.cloudfront.net/books/foundations/level-2.jpg'
|
|
24
|
+
const width = 500
|
|
25
|
+
const height = 100
|
|
26
|
+
const quality = 95
|
|
27
|
+
const resultingURL = buildImageSRC(url, {
|
|
28
|
+
width: width,
|
|
29
|
+
quality: quality,
|
|
30
|
+
height: height,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const expected = `https://www.musora.com/cdn-cgi/image/width=${width},height=${height},quality=${quality}/${url}`
|
|
34
|
+
|
|
35
|
+
expect(resultingURL).toStrictEqual(expected)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Mock console.warn to avoid cluttering test output and to verify warnings
|
|
2
|
+
import { extractSanityUrl, isBucketUrl, verifyImageSRC } from '../src/services/imageSRCVerify.js'
|
|
3
|
+
|
|
4
|
+
const originalConsoleWarn = console.warn
|
|
5
|
+
const originalConsoleError = console.error
|
|
6
|
+
const originalNodeEnv = process.env.NODE_ENV
|
|
7
|
+
|
|
8
|
+
describe('Image URL Verification', () => {
|
|
9
|
+
let consoleWarnMock
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
// Mock console.warn and console.error
|
|
13
|
+
consoleWarnMock = jest.fn()
|
|
14
|
+
console.warn = consoleWarnMock
|
|
15
|
+
console.error = jest.fn()
|
|
16
|
+
|
|
17
|
+
// Set NODE_ENV to development for all tests
|
|
18
|
+
process.env.NODE_ENV = 'development'
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
// Restore the original console methods and NODE_ENV
|
|
23
|
+
console.warn = originalConsoleWarn
|
|
24
|
+
console.error = originalConsoleError
|
|
25
|
+
process.env.NODE_ENV = originalNodeEnv
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('verifyImageSRC', () => {
|
|
29
|
+
test('should not warn for Sanity URL with parameters', () => {
|
|
30
|
+
// Arrange
|
|
31
|
+
const url =
|
|
32
|
+
'https://cdn.sanity.io/images/4032r8py/staging/504c4e3393170f937a579de6f3c75c457b0c9e65-640x360.jpg?w=500&q=95'
|
|
33
|
+
|
|
34
|
+
// Act
|
|
35
|
+
verifyImageSRC(url)
|
|
36
|
+
|
|
37
|
+
// Assert
|
|
38
|
+
expect(consoleWarnMock).not.toHaveBeenCalled()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('should warn for Sanity URL without parameters', () => {
|
|
42
|
+
// Arrange
|
|
43
|
+
const url =
|
|
44
|
+
'https://cdn.sanity.io/images/4032r8py/staging/504c4e3393170f937a579de6f3c75c457b0c9e65-640x360.jpg'
|
|
45
|
+
|
|
46
|
+
// Act
|
|
47
|
+
verifyImageSRC(url)
|
|
48
|
+
|
|
49
|
+
// Assert
|
|
50
|
+
expect(consoleWarnMock).toHaveBeenCalled()
|
|
51
|
+
expect(consoleWarnMock.mock.calls[0][0]).toContain(
|
|
52
|
+
'WARNING: Sanity CDN URL without parameters detected'
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('should warn for direct S3 bucket URL', () => {
|
|
57
|
+
// Arrange
|
|
58
|
+
const url = 'https://musora-images.s3.amazonaws.com/drumeo/images/some-image.jpg'
|
|
59
|
+
|
|
60
|
+
// Act
|
|
61
|
+
verifyImageSRC(url)
|
|
62
|
+
|
|
63
|
+
// Assert
|
|
64
|
+
expect(consoleWarnMock).toHaveBeenCalled()
|
|
65
|
+
expect(consoleWarnMock.mock.calls[0][0]).toContain('Direct S3 bucket URL detected')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('should not warn when URL is empty', () => {
|
|
69
|
+
// Arrange
|
|
70
|
+
const url = ''
|
|
71
|
+
|
|
72
|
+
// Act
|
|
73
|
+
verifyImageSRC(url)
|
|
74
|
+
|
|
75
|
+
// Assert
|
|
76
|
+
expect(consoleWarnMock).not.toHaveBeenCalled()
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe('Cloudflare wrapped Sanity URLs', () => {
|
|
81
|
+
test('should extract and validate Sanity URL from Cloudflare wrapper', () => {
|
|
82
|
+
// Arrange
|
|
83
|
+
const url =
|
|
84
|
+
'https://www.musora.com/cdn-cgi/image/width=500,quality=95/https://cdn.sanity.io/images/4032r8py/staging/504c4e3393170f937a579de6f3c75c457b0c9e65-640x360.jpg'
|
|
85
|
+
|
|
86
|
+
// Act
|
|
87
|
+
verifyImageSRC(url)
|
|
88
|
+
|
|
89
|
+
// Assert
|
|
90
|
+
expect(consoleWarnMock).toHaveBeenCalled()
|
|
91
|
+
expect(consoleWarnMock.mock.calls[0][0]).toContain(
|
|
92
|
+
'WARNING: Sanity CDN URL without parameters detected'
|
|
93
|
+
)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('should not warn for Cloudflare wrapped Sanity URL with parameters', () => {
|
|
97
|
+
// Arrange
|
|
98
|
+
const url =
|
|
99
|
+
'https://www.musora.com/cdn-cgi/image/width=500,quality=95/https://cdn.sanity.io/images/4032r8py/staging/504c4e3393170f937a579de6f3c75c457b0c9e65-640x360.jpg?w=500&q=95'
|
|
100
|
+
|
|
101
|
+
// Act
|
|
102
|
+
verifyImageSRC(url)
|
|
103
|
+
|
|
104
|
+
// Assert
|
|
105
|
+
expect(consoleWarnMock).not.toHaveBeenCalled()
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('isBucketUrl', () => {
|
|
110
|
+
test('should detect standard S3 URLs', () => {
|
|
111
|
+
// Arrange & Act & Assert
|
|
112
|
+
expect(isBucketUrl('https://my-bucket.s3.amazonaws.com/image.jpg')).toBe(true)
|
|
113
|
+
expect(isBucketUrl('https://s3.us-east-1.amazonaws.com/my-bucket/image.jpg')).toBe(true)
|
|
114
|
+
expect(isBucketUrl('https://musora-images.s3.amazonaws.com/path/to/image.jpg')).toBe(true)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
test('should not flag non-S3 URLs', () => {
|
|
118
|
+
// Arrange & Act & Assert
|
|
119
|
+
expect(isBucketUrl('https://cdn.sanity.io/images/123/production/image.jpg')).toBe(false)
|
|
120
|
+
expect(isBucketUrl('https://www.musora.com/image.jpg')).toBe(false)
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
describe('extractSanityUrl', () => {
|
|
125
|
+
test('should extract Sanity URL from Cloudflare wrapper', () => {
|
|
126
|
+
// Arrange
|
|
127
|
+
const wrappedUrl =
|
|
128
|
+
'https://www.musora.com/cdn-cgi/image/width=500,quality=95/https://cdn.sanity.io/images/123/production/image.jpg'
|
|
129
|
+
const expectedExtracted = 'https://cdn.sanity.io/images/123/production/image.jpg'
|
|
130
|
+
|
|
131
|
+
// Act
|
|
132
|
+
const result = extractSanityUrl(wrappedUrl)
|
|
133
|
+
|
|
134
|
+
// Assert
|
|
135
|
+
expect(result).toBe(expectedExtracted)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test('should return original URL if not Cloudflare wrapped', () => {
|
|
139
|
+
// Arrange
|
|
140
|
+
const url = 'https://cdn.sanity.io/images/123/production/image.jpg'
|
|
141
|
+
|
|
142
|
+
// Act
|
|
143
|
+
const result = extractSanityUrl(url)
|
|
144
|
+
|
|
145
|
+
// Assert
|
|
146
|
+
expect(result).toBe(url)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
test('should handle malformed Cloudflare URLs gracefully', () => {
|
|
150
|
+
// Arrange
|
|
151
|
+
const malformedUrl = 'https://www.musora.com/cdn-cgi/image/width=500'
|
|
152
|
+
|
|
153
|
+
// Act
|
|
154
|
+
const result = extractSanityUrl(malformedUrl)
|
|
155
|
+
|
|
156
|
+
// Assert
|
|
157
|
+
expect(result).toBe(malformedUrl)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
})
|
package/test/initializeTests.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/localStorageMock.js
CHANGED
|
File without changes
|
package/test/log.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/tools/generate-index.cjs
CHANGED
|
File without changes
|
package/.yarnrc.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
nodeLinker: node-modules
|