musora-content-services 2.167.0 → 2.167.2
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/.agent/decisions/2026-04-28-tma-275-mcs-sanity-add-a-v2-url-segmen.md +0 -0
- package/.agent/decisions/2026-05-19-content-progress-ts-part-2.md +0 -0
- package/.agent/decisions/2026-05-20-live-event-fetch-permissions-id.md +0 -0
- package/.agent/decisions/2026-07-17-onboarding-statuses.md +21 -0
- package/.claude/settings.local.json +48 -19
- package/.coderabbit.yaml +0 -0
- package/.editorconfig +0 -0
- package/.github/pull_request_template.md +0 -0
- package/.github/workflows/automated-testing.yml +0 -0
- package/.github/workflows/conventional-commits.yaml +0 -0
- package/.github/workflows/docs.js.yml +0 -0
- package/.prettierignore +0 -0
- package/.prettierrc +0 -0
- package/CHANGELOG.md +14 -0
- package/CLAUDE.md +0 -0
- package/README.md +0 -0
- package/babel.config.cjs +0 -0
- package/codecov.yml +0 -0
- package/jest.config.js +0 -0
- package/jest.integration.config.js +0 -0
- package/jest.live.config.js +0 -0
- package/jsdoc.json +0 -0
- package/package.json +1 -1
- package/src/constants/membership-permissions.ts +0 -0
- package/src/contentMetaData.js +0 -0
- package/src/contentTypeConfig.js +1 -0
- package/src/filterBuilder.js +0 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
- package/src/infrastructure/http/HttpClient.ts +0 -0
- package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
- package/src/infrastructure/http/index.ts +0 -0
- package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
- package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
- package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
- package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
- package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
- package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
- package/src/infrastructure/sanity/README.md +0 -0
- package/src/infrastructure/sanity/SanityClient.ts +0 -0
- package/src/infrastructure/sanity/clients/ContentClient.ts +0 -0
- package/src/infrastructure/sanity/examples/usage.ts +0 -0
- package/src/infrastructure/sanity/executors/FetchQueryExecutor.ts +0 -0
- package/src/infrastructure/sanity/index.ts +0 -0
- package/src/infrastructure/sanity/interfaces/ConfigProvider.ts +0 -0
- package/src/infrastructure/sanity/interfaces/FetchByIdOptions.ts +0 -0
- package/src/infrastructure/sanity/interfaces/QueryExecutor.ts +0 -0
- package/src/infrastructure/sanity/interfaces/SanityConfig.ts +0 -0
- package/src/infrastructure/sanity/interfaces/SanityError.ts +0 -0
- package/src/infrastructure/sanity/interfaces/SanityQuery.ts +0 -0
- package/src/infrastructure/sanity/interfaces/SanityResponse.ts +0 -0
- package/src/infrastructure/sanity/providers/DefaultConfigProvider.ts +0 -0
- package/src/lib/ads/monoid.ts +0 -0
- package/src/lib/ads/semigroup.ts +0 -0
- package/src/lib/brands.ts +0 -0
- package/src/lib/lastUpdated.js +0 -0
- package/src/lib/sanity/decorators/base.ts +0 -0
- package/src/lib/sanity/decorators/examples.ts +0 -0
- package/src/lib/sanity/decorators/navigate-to.ts +0 -0
- package/src/lib/sanity/decorators/need-access.ts +0 -0
- package/src/lib/sanity/decorators/need-lifetime-upgrade.ts +0 -0
- package/src/lib/sanity/decorators/page-type.ts +0 -0
- package/src/lib/sanity/field-access.ts +0 -0
- package/src/lib/sanity/filter.ts +0 -0
- package/src/lib/sanity/query.ts +0 -0
- package/src/services/api/types.js +0 -0
- package/src/services/api/types.ts +0 -0
- package/src/services/awards/award-callbacks.js +0 -0
- package/src/services/awards/award-query.js +0 -0
- package/src/services/awards/internal/.indexignore +0 -0
- package/src/services/awards/internal/award-definitions.js +0 -0
- package/src/services/awards/internal/award-events.js +0 -0
- package/src/services/awards/internal/award-manager.js +0 -0
- package/src/services/awards/internal/certificate-builder.js +0 -0
- package/src/services/awards/internal/completion-data-generator.js +0 -0
- package/src/services/awards/internal/content-progress-observer.js +0 -0
- package/src/services/awards/internal/image-utils.js +0 -0
- package/src/services/awards/internal/message-generator.js +0 -0
- package/src/services/awards/internal/types.js +0 -0
- package/src/services/awards/types.d.ts +0 -0
- package/src/services/awards/types.js +0 -0
- package/src/services/config.js +0 -0
- package/src/services/content/artist.ts +0 -0
- package/src/services/content/content.ts +0 -0
- package/src/services/content/genre.ts +0 -0
- package/src/services/content/instructor.ts +0 -0
- package/src/services/content-org/content-org.js +0 -0
- package/src/services/content-org/guided-courses.ts +0 -0
- package/src/services/content-org/learning-paths.ts +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/contentAggregator.js +0 -0
- package/src/services/contentLikes.js +0 -0
- package/src/services/contentProgress.js +1 -1
- package/src/services/dataContext.js +0 -0
- package/src/services/dateUtils.js +0 -0
- package/src/services/endScreen/README.md +0 -0
- package/src/services/endScreen/endScreen.ts +0 -0
- package/src/services/endScreen/types.ts +0 -0
- package/src/services/eventsAPI.js +49 -7
- package/src/services/forums/categories.ts +0 -0
- package/src/services/forums/forums.ts +0 -0
- package/src/services/forums/posts.ts +0 -0
- package/src/services/forums/threads.ts +0 -0
- package/src/services/gamification/awards.ts +0 -0
- package/src/services/gamification/gamification.js +0 -0
- package/src/services/imageSRCBuilder.js +0 -0
- package/src/services/imageSRCVerify.js +0 -0
- package/src/services/liveTesting.ts +0 -0
- package/src/services/multi-user-accounts/multi-user-accounts.ts +0 -0
- package/src/services/offline/activities.ts +0 -0
- package/src/services/offline/practices.ts +0 -0
- package/src/services/offline/progress.ts +0 -0
- package/src/services/permissions/PermissionsAdapter.ts +0 -0
- package/src/services/permissions/PermissionsAdapterFactory.ts +0 -0
- package/src/services/permissions/PermissionsV1Adapter.ts +0 -0
- package/src/services/permissions/PermissionsV2Adapter.ts +0 -0
- package/src/services/permissions/README.md +0 -0
- package/src/services/permissions/index.ts +0 -0
- package/src/services/permissions/permissions.ts +0 -0
- package/src/services/permissions/types.d.ts +0 -0
- package/src/services/progress/.indexignore +0 -0
- package/src/services/progress/collections.ts +0 -0
- package/src/services/progress/index.ts +0 -0
- package/src/services/progress/internal/bubble.ts +0 -0
- package/src/services/progress/internal/queries.ts +0 -0
- package/src/services/progress/state.ts +0 -0
- package/src/services/progress/types.ts +0 -0
- package/src/services/progress/utils.ts +0 -0
- package/src/services/progress-events.js +0 -0
- package/src/services/progress-row/base.js +0 -0
- package/src/services/progress-row/rows/.indexignore +0 -0
- package/src/services/progress-row/rows/content-card.js +0 -0
- package/src/services/progress-row/rows/method-card.js +0 -0
- package/src/services/progress-row/rows/playlist-card.js +0 -0
- package/src/services/railcontent.js +0 -0
- package/src/services/recommendations.js +0 -0
- package/src/services/reporting/README.md +0 -0
- package/src/services/reporting/reporting.ts +0 -0
- package/src/services/reporting/types.ts +0 -0
- package/src/services/search.ts +0 -0
- package/src/services/sentry/.indexignore +0 -0
- package/src/services/sentry/index.ts +0 -0
- package/src/services/state.ts +0 -0
- package/src/services/sync/.indexignore +0 -0
- package/src/services/sync/adapters/factory.ts +0 -0
- package/src/services/sync/adapters/lokijs.ts +0 -0
- package/src/services/sync/adapters/sqlite.ts +0 -0
- package/src/services/sync/context/index.ts +0 -0
- package/src/services/sync/context/providers/base.ts +0 -0
- package/src/services/sync/context/providers/connectivity.ts +0 -0
- package/src/services/sync/context/providers/durability.ts +0 -0
- package/src/services/sync/context/providers/index.ts +0 -0
- package/src/services/sync/context/providers/session.ts +0 -0
- package/src/services/sync/context/providers/tabs.ts +0 -0
- package/src/services/sync/context/providers/visibility.ts +0 -0
- package/src/services/sync/database/factory.ts +0 -0
- package/src/services/sync/debug.ts +0 -0
- package/src/services/sync/effects/index.ts +0 -0
- package/src/services/sync/effects/logout-warning.ts +0 -0
- package/src/services/sync/effects/push-failure-notification.ts +0 -0
- package/src/services/sync/errors/boundary.ts +0 -0
- package/src/services/sync/errors/index.ts +0 -0
- package/src/services/sync/errors/validators.ts +0 -0
- package/src/services/sync/fetch.ts +0 -0
- package/src/services/sync/index.ts +0 -0
- package/src/services/sync/manager.ts +0 -0
- package/src/services/sync/models/Base.ts +0 -0
- package/src/services/sync/models/ContentLike.ts +0 -0
- package/src/services/sync/models/ContentProgress.ts +0 -0
- package/src/services/sync/models/Practice.ts +0 -0
- package/src/services/sync/models/PracticeDayNote.ts +0 -0
- package/src/services/sync/models/UserAwardProgress.ts +0 -0
- package/src/services/sync/models/index.ts +0 -0
- package/src/services/sync/repositories/base.ts +0 -0
- package/src/services/sync/repositories/content-likes.ts +0 -0
- package/src/services/sync/repositories/content-progress.ts +0 -0
- package/src/services/sync/repositories/index.ts +0 -0
- package/src/services/sync/repositories/practice-day-notes.ts +0 -0
- package/src/services/sync/repositories/practices.ts +0 -0
- package/src/services/sync/repositories/user-award-progress.ts +0 -0
- package/src/services/sync/repository-proxy.ts +0 -0
- package/src/services/sync/resolver.ts +0 -0
- package/src/services/sync/retry.ts +0 -0
- package/src/services/sync/run-scope.ts +0 -0
- package/src/services/sync/schema/index.ts +0 -0
- package/src/services/sync/serializers/index.ts +0 -0
- package/src/services/sync/serializers/model.ts +0 -0
- package/src/services/sync/serializers/raw.ts +0 -0
- package/src/services/sync/stale-record-cleanup.ts +0 -0
- package/src/services/sync/store/index.ts +0 -0
- package/src/services/sync/store/push-coalescer.ts +0 -0
- package/src/services/sync/store-configs.ts +0 -0
- package/src/services/sync/strategies/base.ts +0 -0
- package/src/services/sync/strategies/index.ts +0 -0
- package/src/services/sync/strategies/initial.ts +0 -0
- package/src/services/sync/strategies/polling.ts +0 -0
- package/src/services/sync/telemetry/flood-prevention.ts +0 -0
- package/src/services/sync/telemetry/index.ts +0 -0
- package/src/services/sync/telemetry/sampling.ts +0 -0
- package/src/services/sync/utils/event-emitter.ts +0 -0
- package/src/services/sync/utils/index.ts +0 -0
- package/src/services/sync/utils/throttle.ts +0 -0
- package/src/services/sync/utils/timers.ts +0 -0
- package/src/services/types.js +0 -0
- package/src/services/urlBuilder.ts +0 -0
- package/src/services/user/account.ts +12 -2
- package/src/services/user/chat.js +0 -0
- package/src/services/user/interests.js +0 -0
- package/src/services/user/management.js +0 -0
- package/src/services/user/notifications.js +0 -0
- package/src/services/user/onboarding.ts +22 -0
- package/src/services/user/payments.ts +0 -0
- package/src/services/user/playerSettings.ts +0 -0
- package/src/services/user/profile.ts +0 -0
- package/src/services/user/sessions.js +0 -0
- package/src/services/user/streakCalculator.ts +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 +0 -0
- package/src/services/whoLiked.ts +0 -0
- package/test/initializeTests.js +0 -0
- package/test/integration/awards/award-exclusion-handling.test.ts +0 -0
- package/test/integration/awards/internal/image-utils.test.ts +0 -0
- package/test/integration/content-progress/__mocks__/mocks.ts +0 -0
- package/test/integration/content-progress/contentProgress.test.ts +0 -0
- package/test/integration/content-progress/e2eOfflineProgress.test.ts +0 -0
- package/test/integration/content-progress/e2eProgress.test.ts +0 -0
- package/test/integration/content-progress/getters.test.ts +0 -0
- package/test/integration/content-progress/helpers.test.ts +0 -0
- package/test/integration/content-progress/offlineContentProgress.test.ts +0 -0
- package/test/integration/forums.test.ts +0 -0
- package/test/integration/infrastructure/FetchRequestExecutor.test.ts +0 -0
- package/test/integration/initializeTestDB.ts +0 -0
- package/test/integration/learning-paths.test.ts +0 -0
- package/test/integration/notifications.test.ts +0 -0
- package/test/integration/progress-row/content-card.test.ts +0 -0
- package/test/integration/sync/adapters/idb-errors.test.ts +0 -0
- package/test/integration/sync/adapters/sqlite-errors.test.ts +0 -0
- package/test/integration/sync/fetch.test.ts +0 -0
- package/test/integration/sync/repositories/content-likes.test.ts +0 -0
- package/test/integration/sync/repositories/practices.test.ts +0 -0
- package/test/integration/sync/repositories/progress.test.ts +0 -0
- package/test/integration/sync/repositories/user-award-progress.static.test.ts +0 -0
- package/test/integration/sync/repositories/user-award-progress.test.ts +0 -0
- package/test/integration/sync/store/cross-user-protection.test.ts +0 -0
- package/test/integration/sync/store/store-idb.test.ts +0 -0
- package/test/integration/sync/store/store.test.ts +0 -0
- package/test/integration/user/permissions.test.js +0 -0
- package/test/integration/userActivity.test.ts +0 -0
- package/test/live/README.md +0 -0
- package/test/live/content.test.js +0 -0
- package/test/localStorageMock.js +0 -0
- package/test/log.js +0 -0
- package/test/mockData/award-definitions.js +0 -0
- package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
- package/test/mockData/mockData_progress_content.json +0 -0
- package/test/mockData/mockData_sanity_progress_content.json +0 -0
- package/test/mockData/mockData_user_practices.json +0 -0
- package/test/setupConsole.js +0 -0
- package/test/setupNetworkGuard.js +0 -0
- package/test/setupTimers.js +0 -0
- package/test/unit/HttpClient.test.ts +0 -0
- package/test/unit/awards/award-alacarte-observer.test.ts +0 -0
- package/test/unit/awards/award-auto-refresh.test.ts +0 -0
- package/test/unit/awards/award-calculations.test.ts +0 -0
- package/test/unit/awards/award-callbacks.test.ts +0 -0
- package/test/unit/awards/award-certificate-display.test.ts +0 -0
- package/test/unit/awards/award-collection-edge-cases.test.ts +0 -0
- package/test/unit/awards/award-collection-filtering.test.ts +0 -0
- package/test/unit/awards/award-completion-flow.test.ts +0 -0
- package/test/unit/awards/award-multi-lesson.test.ts +0 -0
- package/test/unit/awards/award-observer-integration.test.ts +0 -0
- package/test/unit/awards/award-query-messages.test.ts +0 -0
- package/test/unit/awards/award-user-collection.test.ts +0 -0
- package/test/unit/awards/duplicate-prevention.test.ts +0 -0
- package/test/unit/awards/helpers/completion-mock.ts +0 -0
- package/test/unit/awards/helpers/index.ts +0 -0
- package/test/unit/awards/helpers/mock-setup.ts +0 -0
- package/test/unit/awards/helpers/progress-emitter.ts +0 -0
- package/test/unit/awards/message-generator.test.ts +0 -0
- package/test/unit/content-progress/bubbleTrickle.test.ts +0 -0
- package/test/unit/content-progress/helpers.test.ts +0 -0
- package/test/unit/content-progress/navigateTo.test.ts +11 -0
- package/test/unit/contentLikes.test.ts +0 -0
- package/test/unit/contentMetaData.test.ts +0 -0
- package/test/unit/dataContext.test.ts +0 -0
- package/test/unit/dateUtils.test.ts +0 -0
- package/test/unit/endScreen.test.js +0 -0
- package/test/unit/eventsAPI.test.ts +159 -0
- package/test/unit/imageSRCBuilder.test.ts +0 -0
- package/test/unit/imageSRCVerify.test.ts +0 -0
- package/test/unit/infrastructure/DefaultHeaderProvider.test.ts +0 -0
- package/test/unit/infrastructure/sanity/ContentClient.test.ts +0 -0
- package/test/unit/infrastructure/sanity/DefaultConfigProvider.test.ts +0 -0
- package/test/unit/infrastructure/sanity/FetchQueryExecutor.test.ts +0 -0
- package/test/unit/infrastructure/sanity/SanityClient.test.ts +0 -0
- package/test/unit/lib/__snapshots__/filter.test.ts.snap +0 -0
- package/test/unit/lib/filter.test.ts +0 -0
- package/test/unit/lib/lastUpdated.test.ts +0 -0
- package/test/unit/lib/query.test.ts +0 -0
- package/test/unit/lib/sanity/decorators/base.test.ts +0 -0
- package/test/unit/lib/sanity/decorators/navigate-to.test.ts +0 -0
- package/test/unit/lib/sanity/decorators/need-access.test.ts +0 -0
- package/test/unit/lib/sanity/decorators/need-lifetime-upgrade.test.ts +0 -0
- package/test/unit/lib/sanity/decorators/page-type.test.ts +0 -0
- package/test/unit/playerSettings.test.ts +0 -0
- package/test/unit/progress-row/content-card.test.ts +0 -0
- package/test/unit/progress-row/playlist-card.test.ts +0 -0
- package/test/unit/progressRows.test.ts +0 -0
- package/test/unit/recommendations.test.js +0 -0
- package/test/unit/sanityQueryService.test.ts +0 -0
- package/test/unit/search.test.ts +0 -0
- package/test/unit/sentry.test.ts +0 -0
- package/test/unit/services/progress-internal/bubble.test.ts +0 -0
- package/test/unit/services/progress.test.ts +0 -0
- package/test/unit/streakMessage.test.ts +0 -0
- package/test/unit/sync/context.test.ts +0 -0
- package/test/unit/sync/effects/logout-warning.test.ts +0 -0
- package/test/unit/sync/effects/push-failure-notification.test.ts +0 -0
- package/test/unit/sync/errors/sync-errors.test.ts +0 -0
- package/test/unit/sync/errors/validators.test.ts +0 -0
- package/test/unit/sync/helpers/TestModel.ts +0 -0
- package/test/unit/sync/helpers/index.ts +0 -0
- package/test/unit/sync/manager.test.ts +0 -0
- package/test/unit/sync/models/user-award-progress.test.ts +0 -0
- package/test/unit/sync/resolver.test.ts +0 -0
- package/test/unit/sync/retry.test.ts +0 -0
- package/test/unit/sync/run-scope.test.ts +0 -0
- package/test/unit/sync/stale-record-cleanup.test.ts +0 -0
- package/test/unit/sync/store/push-coalescer.test.ts +0 -0
- package/test/unit/sync/store-configs.test.ts +0 -0
- package/test/unit/sync/telemetry/sync-telemetry.test.ts +0 -0
- package/test/unit/sync/utils/event-emitter.test.ts +0 -0
- package/test/unit/sync/utils/throttle.test.ts +0 -0
- package/test/unit/url-builder.test.ts +0 -0
- package/test/unit/user/account.test.ts +14 -3
- package/test/unit/user/permissions.test.js +0 -0
- package/tools/generate-index.cjs +0 -0
- package/tsconfig.json +0 -0
- package/usage/sanity/decorators/examples.ts +0 -0
package/src/services/state.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/services/types.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -22,17 +22,27 @@ export async function status(email: string): Promise<{ requires_setup: boolean }
|
|
|
22
22
|
)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export interface SendAccountSetupEmailOptions {
|
|
26
|
+
has_skipped_paywall?: boolean
|
|
27
|
+
[key: string]: any
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
/**
|
|
26
|
-
* @param {
|
|
31
|
+
* @param {Send} email - The email address to send the account setup email to.
|
|
27
32
|
* @returns {Promise<void>} - A promise that resolves when the email is sent or an HttpError if the request fails.
|
|
28
33
|
* @throws {HttpError} - Throws HttpError if the request fails.
|
|
29
34
|
*/
|
|
30
|
-
export async function sendAccountSetupEmail(
|
|
35
|
+
export async function sendAccountSetupEmail(
|
|
36
|
+
email: string,
|
|
37
|
+
token?: string,
|
|
38
|
+
options: SendAccountSetupEmailOptions = { has_skipped_paywall: false }
|
|
39
|
+
): Promise<void> {
|
|
31
40
|
const httpClient = new HttpClient(globalConfig.baseUrl)
|
|
32
41
|
return httpClient.post<void>(
|
|
33
42
|
`/api/user-management-system/v1/accounts/${encodeURIComponent(email)}/send-setup-email`,
|
|
34
43
|
{
|
|
35
44
|
token,
|
|
45
|
+
...options,
|
|
36
46
|
}
|
|
37
47
|
)
|
|
38
48
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -117,6 +117,28 @@ export async function userOnboardingForBrand(brand: string): Promise<Onboarding>
|
|
|
117
117
|
)
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
export interface OnboardingBrandStatus {
|
|
121
|
+
brand: string
|
|
122
|
+
is_completed: boolean
|
|
123
|
+
completed_flow: string | null
|
|
124
|
+
completed_at: Date | null
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface OnboardingStatus {
|
|
128
|
+
has_completed_onboarding: boolean
|
|
129
|
+
brands: OnboardingBrandStatus[]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Fetches the current user's onboarding completion status across all brands.
|
|
134
|
+
*
|
|
135
|
+
* @returns {Promise<OnboardingStatus>} - A promise that resolves with the cross-brand onboarding status.
|
|
136
|
+
* @throws {HttpError} - If the HTTP request fails.
|
|
137
|
+
*/
|
|
138
|
+
export async function getOnboardingStatus(): Promise<OnboardingStatus> {
|
|
139
|
+
return GET(`/api/user-management-system/v1/users/${globalConfig.sessionConfig.userId}/onboardings/status`)
|
|
140
|
+
}
|
|
141
|
+
|
|
120
142
|
export interface OnboardingRecommendedContent {
|
|
121
143
|
id: number
|
|
122
144
|
title: string
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/services/whoLiked.ts
CHANGED
|
File without changes
|
package/test/initializeTests.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/live/README.md
CHANGED
|
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
|
|
File without changes
|
package/test/setupConsole.js
CHANGED
|
File without changes
|
|
File without changes
|
package/test/setupTimers.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -254,6 +254,17 @@ describe('getNavigateTo', () => {
|
|
|
254
254
|
expect(result[1]).toMatchObject({ id: 101 })
|
|
255
255
|
})
|
|
256
256
|
|
|
257
|
+
test('documentary started lastInteracted started navigates to lastInteracted child', async () => {
|
|
258
|
+
mockProgressRecords = [
|
|
259
|
+
{ content_id: 1, state: 'started', progress_percent: 50, updated_at: 1000 },
|
|
260
|
+
{ content_id: 101, state: 'started', progress_percent: 100, updated_at: 900 },
|
|
261
|
+
{ content_id: 102, state: 'started', progress_percent: 30, updated_at: 1000 },
|
|
262
|
+
]
|
|
263
|
+
mockLastInteracted = 101
|
|
264
|
+
const result = await getNavigateTo([{ id: 1, type: 'documentary', children: [child(101), child(102)] }])
|
|
265
|
+
expect(result[1]).toMatchObject({ id: 101 })
|
|
266
|
+
})
|
|
267
|
+
|
|
257
268
|
test('course started lastInteracted completed navigates to first incomplete after lastInteracted', async () => {
|
|
258
269
|
mockProgressRecords = [
|
|
259
270
|
{ content_id: 1, state: 'started', progress_percent: 60, updated_at: 1000 },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import eventsAPISingleton from '../../src/services/eventsAPI.js'
|
|
2
|
+
import { initializeTestService } from '../initializeTests.js'
|
|
3
|
+
|
|
4
|
+
const notificationsModule = require('../../src/services/user/notifications.js')
|
|
5
|
+
const EventsAPI = eventsAPISingleton.constructor as new () => typeof eventsAPISingleton
|
|
6
|
+
|
|
7
|
+
function deferred<T>() {
|
|
8
|
+
let resolve!: (value: T) => void
|
|
9
|
+
const promise = new Promise<T>((res) => {
|
|
10
|
+
resolve = res
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
return { promise, resolve }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('EventsAPI notification polling lifecycle', () => {
|
|
17
|
+
let api: typeof eventsAPISingleton
|
|
18
|
+
let fetchUnreadCountMock: jest.SpyInstance
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
initializeTestService()
|
|
22
|
+
jest.useFakeTimers()
|
|
23
|
+
|
|
24
|
+
api = new EventsAPI()
|
|
25
|
+
jest.spyOn(api, 'initPollingControl').mockResolvedValue({})
|
|
26
|
+
fetchUnreadCountMock = jest
|
|
27
|
+
.spyOn(notificationsModule, 'fetchUnreadCount')
|
|
28
|
+
.mockResolvedValue({ data: 0 })
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
api.destroy()
|
|
33
|
+
jest.useRealTimers()
|
|
34
|
+
jest.restoreAllMocks()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test('initialize keeps the existing polling behavior', async () => {
|
|
38
|
+
await api.initialize({ brand: 'pianote' })
|
|
39
|
+
|
|
40
|
+
expect(fetchUnreadCountMock).toHaveBeenCalledWith({ brand: 'pianote' })
|
|
41
|
+
expect(api.pollingInterval).not.toBeNull()
|
|
42
|
+
|
|
43
|
+
fetchUnreadCountMock.mockClear()
|
|
44
|
+
await jest.advanceTimersByTimeAsync(60000)
|
|
45
|
+
|
|
46
|
+
expect(fetchUnreadCountMock).toHaveBeenCalledTimes(1)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('pause stops polling without removing subscribers', async () => {
|
|
50
|
+
const handler = jest.fn()
|
|
51
|
+
api.addNotificationStateUpdatedHandler(handler)
|
|
52
|
+
await api.initialize()
|
|
53
|
+
handler.mockClear()
|
|
54
|
+
fetchUnreadCountMock.mockClear()
|
|
55
|
+
|
|
56
|
+
api.pauseNotificationPolling()
|
|
57
|
+
await jest.advanceTimersByTimeAsync(120000)
|
|
58
|
+
|
|
59
|
+
expect(api.pollingInterval).toBeNull()
|
|
60
|
+
expect(api.onNotificationStateUpdated).toEqual([handler])
|
|
61
|
+
expect(fetchUnreadCountMock).not.toHaveBeenCalled()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('resume starts one interval and immediately refreshes existing subscribers', async () => {
|
|
65
|
+
const handler = jest.fn()
|
|
66
|
+
api.addNotificationStateUpdatedHandler(handler)
|
|
67
|
+
await api.initialize()
|
|
68
|
+
api.pauseNotificationPolling()
|
|
69
|
+
fetchUnreadCountMock.mockResolvedValue({ data: 1, liveEvent: null })
|
|
70
|
+
fetchUnreadCountMock.mockClear()
|
|
71
|
+
handler.mockClear()
|
|
72
|
+
|
|
73
|
+
await api.resumeNotificationPolling()
|
|
74
|
+
const resumedInterval = api.pollingInterval
|
|
75
|
+
await api.resumeNotificationPolling()
|
|
76
|
+
|
|
77
|
+
expect(resumedInterval).not.toBeNull()
|
|
78
|
+
expect(api.pollingInterval).toBe(resumedInterval)
|
|
79
|
+
expect(fetchUnreadCountMock).toHaveBeenCalledTimes(2)
|
|
80
|
+
expect(handler).toHaveBeenLastCalledWith({ unreadCount: 1, liveEvent: null })
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test('repeated pause calls are safe', async () => {
|
|
84
|
+
await api.initialize()
|
|
85
|
+
|
|
86
|
+
api.pauseNotificationPolling()
|
|
87
|
+
api.pauseNotificationPolling()
|
|
88
|
+
|
|
89
|
+
expect(api.pollingInterval).toBeNull()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
test('pause during asynchronous setup prevents the interval from being created', async () => {
|
|
93
|
+
const pollingControl = deferred<Record<string, never>>()
|
|
94
|
+
jest.spyOn(api, 'initPollingControl').mockReturnValue(pollingControl.promise)
|
|
95
|
+
|
|
96
|
+
const initializePromise = api.initialize()
|
|
97
|
+
api.pauseNotificationPolling()
|
|
98
|
+
pollingControl.resolve({})
|
|
99
|
+
await initializePromise
|
|
100
|
+
|
|
101
|
+
expect(api.pollingInterval).toBeNull()
|
|
102
|
+
expect(fetchUnreadCountMock).toHaveBeenCalledTimes(1)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
test('resume during asynchronous setup creates no duplicate interval', async () => {
|
|
106
|
+
const pollingControl = deferred<Record<string, never>>()
|
|
107
|
+
jest.spyOn(api, 'initPollingControl').mockReturnValue(pollingControl.promise)
|
|
108
|
+
|
|
109
|
+
const initializePromise = api.initialize()
|
|
110
|
+
api.pauseNotificationPolling()
|
|
111
|
+
const resumePromise = api.resumeNotificationPolling()
|
|
112
|
+
const resumedInterval = api.pollingInterval
|
|
113
|
+
pollingControl.resolve({})
|
|
114
|
+
await Promise.all([initializePromise, resumePromise])
|
|
115
|
+
|
|
116
|
+
expect(resumedInterval).not.toBeNull()
|
|
117
|
+
expect(api.pollingInterval).toBe(resumedInterval)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
test('pause and resume while the initial unread request is pending restores polling', async () => {
|
|
121
|
+
const initialUnreadCount = deferred<{ data: number }>()
|
|
122
|
+
fetchUnreadCountMock
|
|
123
|
+
.mockReturnValueOnce(initialUnreadCount.promise)
|
|
124
|
+
.mockResolvedValue({ data: 1 })
|
|
125
|
+
|
|
126
|
+
const initializePromise = api.initialize()
|
|
127
|
+
await Promise.resolve()
|
|
128
|
+
await Promise.resolve()
|
|
129
|
+
expect(api.pollingInterval).not.toBeNull()
|
|
130
|
+
|
|
131
|
+
api.pauseNotificationPolling()
|
|
132
|
+
const resumePromise = api.resumeNotificationPolling()
|
|
133
|
+
|
|
134
|
+
expect(api.pollingInterval).not.toBeNull()
|
|
135
|
+
initialUnreadCount.resolve({ data: 0 })
|
|
136
|
+
await Promise.all([initializePromise, resumePromise])
|
|
137
|
+
|
|
138
|
+
fetchUnreadCountMock.mockClear()
|
|
139
|
+
await jest.advanceTimersByTimeAsync(60000)
|
|
140
|
+
expect(fetchUnreadCountMock).toHaveBeenCalledTimes(1)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
test('destroy remains a full teardown and initialize can start again', async () => {
|
|
144
|
+
api.addNotificationStateUpdatedHandler(jest.fn())
|
|
145
|
+
await api.initialize()
|
|
146
|
+
|
|
147
|
+
api.destroy()
|
|
148
|
+
|
|
149
|
+
expect(api.pollingInterval).toBeNull()
|
|
150
|
+
expect(api.onNotificationStateUpdated).toEqual([])
|
|
151
|
+
expect(api.isLiveEventPollingActive).toBe(false)
|
|
152
|
+
|
|
153
|
+
fetchUnreadCountMock.mockClear()
|
|
154
|
+
await api.initialize()
|
|
155
|
+
|
|
156
|
+
expect(api.pollingInterval).not.toBeNull()
|
|
157
|
+
expect(fetchUnreadCountMock).toHaveBeenCalledTimes(1)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|