musora-content-services 2.103.6 → 2.104.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.
Files changed (182) hide show
  1. package/.claude/settings.local.json +18 -0
  2. package/.coderabbit.yaml +0 -0
  3. package/.editorconfig +0 -0
  4. package/.github/pull_request_template.md +0 -0
  5. package/.github/workflows/conventional-commits.yaml +0 -0
  6. package/.github/workflows/docs.js.yml +0 -0
  7. package/.github/workflows/node.js.yml +0 -0
  8. package/.prettierignore +0 -0
  9. package/.prettierrc +0 -0
  10. package/CHANGELOG.md +24 -0
  11. package/CLAUDE.md +0 -0
  12. package/README.md +0 -0
  13. package/babel.config.cjs +0 -0
  14. package/jest.config.js +0 -0
  15. package/jsdoc.json +0 -0
  16. package/package.json +1 -1
  17. package/src/constants/award-assets.js +0 -0
  18. package/src/contentMetaData.js +0 -0
  19. package/src/contentTypeConfig.js +1 -1
  20. package/src/index.d.ts +3 -1
  21. package/src/index.js +3 -1
  22. package/src/infrastructure/http/HttpClient.ts +0 -0
  23. package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
  24. package/src/infrastructure/http/index.ts +0 -0
  25. package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
  26. package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
  27. package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
  28. package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
  29. package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
  30. package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
  31. package/src/lib/brands.ts +0 -0
  32. package/src/lib/lastUpdated.js +0 -0
  33. package/src/services/api/types.js +0 -0
  34. package/src/services/api/types.ts +0 -0
  35. package/src/services/awards/award-query.js +13 -0
  36. package/src/services/awards/internal/.indexignore +0 -0
  37. package/src/services/awards/internal/award-definitions.js +0 -0
  38. package/src/services/awards/internal/award-events.js +0 -0
  39. package/src/services/awards/internal/award-manager.js +5 -0
  40. package/src/services/awards/internal/certificate-builder.js +0 -0
  41. package/src/services/awards/internal/completion-data-generator.js +0 -0
  42. package/src/services/awards/internal/content-progress-observer.js +0 -0
  43. package/src/services/awards/internal/image-utils.js +0 -0
  44. package/src/services/awards/internal/message-generator.js +0 -0
  45. package/src/services/awards/internal/types.js +0 -0
  46. package/src/services/awards/types.js +0 -0
  47. package/src/services/config.js +0 -0
  48. package/src/services/content/content.ts +0 -0
  49. package/src/services/content-org/content-org.js +0 -0
  50. package/src/services/content-org/guided-courses.ts +0 -0
  51. package/src/services/content-org/playlists-types.js +0 -0
  52. package/src/services/content-org/playlists.js +0 -0
  53. package/src/services/content.js +0 -0
  54. package/src/services/contentLikes.js +0 -0
  55. package/src/services/dataContext.js +0 -0
  56. package/src/services/dateUtils.js +0 -0
  57. package/src/services/eventsAPI.js +0 -0
  58. package/src/services/forums/categories.ts +0 -0
  59. package/src/services/forums/forums.ts +2 -1
  60. package/src/services/forums/posts.ts +0 -0
  61. package/src/services/forums/types.ts +0 -0
  62. package/src/services/gamification/awards.ts +0 -0
  63. package/src/services/gamification/gamification.js +0 -0
  64. package/src/services/imageSRCBuilder.js +0 -0
  65. package/src/services/imageSRCVerify.js +0 -0
  66. package/src/services/liveTesting.ts +0 -0
  67. package/src/services/permissions/PermissionsAdapter.ts +0 -0
  68. package/src/services/permissions/PermissionsAdapterFactory.ts +0 -0
  69. package/src/services/permissions/PermissionsV1Adapter.ts +0 -0
  70. package/src/services/permissions/README.md +0 -0
  71. package/src/services/permissions/index.ts +0 -0
  72. package/src/services/progress-row/method-card.js +0 -0
  73. package/src/services/recommendations.js +0 -0
  74. package/src/services/reporting/README.md +0 -0
  75. package/src/services/reporting/reporting.ts +0 -0
  76. package/src/services/reporting/types.ts +0 -0
  77. package/src/services/sentry/.indexignore +0 -0
  78. package/src/services/sentry/index.ts +0 -0
  79. package/src/services/sync/.indexignore +0 -0
  80. package/src/services/sync/adapters/factory.ts +0 -0
  81. package/src/services/sync/adapters/lokijs.ts +0 -0
  82. package/src/services/sync/adapters/sqlite.ts +0 -0
  83. package/src/services/sync/concurrency-safety.ts +0 -0
  84. package/src/services/sync/context/index.ts +0 -0
  85. package/src/services/sync/context/providers/base.ts +0 -0
  86. package/src/services/sync/context/providers/connectivity.ts +0 -0
  87. package/src/services/sync/context/providers/durability.ts +0 -0
  88. package/src/services/sync/context/providers/index.ts +0 -0
  89. package/src/services/sync/context/providers/session.ts +0 -0
  90. package/src/services/sync/context/providers/tabs.ts +0 -0
  91. package/src/services/sync/context/providers/visibility.ts +0 -0
  92. package/src/services/sync/database/factory.ts +0 -0
  93. package/src/services/sync/errors/boundary.ts +0 -0
  94. package/src/services/sync/errors/index.ts +0 -0
  95. package/src/services/sync/index.ts +0 -0
  96. package/src/services/sync/models/Base.ts +0 -0
  97. package/src/services/sync/models/ContentLike.ts +0 -0
  98. package/src/services/sync/models/Practice.ts +0 -0
  99. package/src/services/sync/models/PracticeDayNote.ts +0 -0
  100. package/src/services/sync/models/UserAwardProgress.ts +0 -0
  101. package/src/services/sync/models/index.ts +0 -0
  102. package/src/services/sync/repositories/base.ts +0 -0
  103. package/src/services/sync/repositories/content-likes.ts +0 -0
  104. package/src/services/sync/repositories/index.ts +0 -0
  105. package/src/services/sync/repositories/practice-day-notes.ts +0 -0
  106. package/src/services/sync/repositories/practices.ts +0 -0
  107. package/src/services/sync/repositories/user-award-progress.ts +26 -0
  108. package/src/services/sync/repository-proxy.ts +0 -0
  109. package/src/services/sync/resolver.ts +0 -0
  110. package/src/services/sync/retry.ts +0 -0
  111. package/src/services/sync/run-scope.ts +0 -0
  112. package/src/services/sync/schema/index.ts +0 -0
  113. package/src/services/sync/serializers/index.ts +0 -0
  114. package/src/services/sync/serializers/model.ts +0 -0
  115. package/src/services/sync/serializers/raw.ts +0 -0
  116. package/src/services/sync/store/push-coalescer.ts +0 -0
  117. package/src/services/sync/store-configs.ts +0 -0
  118. package/src/services/sync/strategies/base.ts +0 -0
  119. package/src/services/sync/strategies/index.ts +0 -0
  120. package/src/services/sync/strategies/initial.ts +0 -0
  121. package/src/services/sync/strategies/polling.ts +0 -0
  122. package/src/services/sync/telemetry/index.ts +0 -0
  123. package/src/services/sync/telemetry/sampling.ts +0 -0
  124. package/src/services/sync/utils/event-emitter.ts +0 -0
  125. package/src/services/sync/utils/index.ts +0 -0
  126. package/src/services/sync/utils/throttle.ts +0 -0
  127. package/src/services/sync/utils/timers.ts +0 -0
  128. package/src/services/types.js +0 -0
  129. package/src/services/user/account.ts +0 -0
  130. package/src/services/user/chat.js +0 -0
  131. package/src/services/user/interests.js +0 -0
  132. package/src/services/user/management.js +0 -0
  133. package/src/services/user/notifications.js +0 -0
  134. package/src/services/user/payments.ts +0 -0
  135. package/src/services/user/permissions.js +0 -0
  136. package/src/services/user/profile.js +0 -0
  137. package/src/services/user/types.d.ts +0 -0
  138. package/src/services/user/types.js +0 -0
  139. package/src/services/user/user-management-system.js +0 -0
  140. package/test/HttpClient.test.js +0 -0
  141. package/test/awards/award-alacarte-observer.test.js +0 -0
  142. package/test/awards/award-auto-refresh.test.js +0 -0
  143. package/test/awards/award-calculations.test.js +0 -0
  144. package/test/awards/award-certificate-display.test.js +0 -0
  145. package/test/awards/award-collection-edge-cases.test.js +0 -0
  146. package/test/awards/award-collection-filtering.test.js +0 -0
  147. package/test/awards/award-completion-flow.test.js +90 -0
  148. package/test/awards/award-exclusion-handling.test.js +0 -0
  149. package/test/awards/award-multi-lesson.test.js +0 -0
  150. package/test/awards/award-observer-integration.test.js +0 -0
  151. package/test/awards/award-query-messages.test.js +0 -0
  152. package/test/awards/award-user-collection.test.js +0 -0
  153. package/test/awards/duplicate-prevention.test.js +0 -0
  154. package/test/awards/helpers/completion-mock.js +0 -0
  155. package/test/awards/helpers/index.js +0 -0
  156. package/test/awards/helpers/mock-setup.js +0 -0
  157. package/test/awards/helpers/progress-emitter.js +0 -0
  158. package/test/awards/message-generator.test.js +0 -0
  159. package/test/content.test.js +0 -0
  160. package/test/contentLikes.test.js +0 -0
  161. package/test/contentProgress.test.js +0 -0
  162. package/test/dataContext.test.js +0 -0
  163. package/test/forum.test.js +0 -0
  164. package/test/imageSRCBuilder.test.js +0 -0
  165. package/test/imageSRCVerify.test.js +0 -0
  166. package/test/lib/lastUpdated.test.js +0 -0
  167. package/test/live/contentProgressLive.test.js +0 -0
  168. package/test/live/railcontentLive.test.js +0 -0
  169. package/test/localStorageMock.js +0 -0
  170. package/test/log.js +0 -0
  171. package/test/mockData/award-definitions.js +0 -0
  172. package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
  173. package/test/mockData/mockData_progress_content.json +0 -0
  174. package/test/mockData/mockData_sanity_progress_content.json +0 -0
  175. package/test/mockData/mockData_user_practices.json +0 -0
  176. package/test/notifications.test.js +0 -0
  177. package/test/progressRows.test.js +0 -0
  178. package/test/streakMessage.test.js +0 -0
  179. package/test/sync/models/award-database-integration.test.js +0 -0
  180. package/test/user/permissions.test.js +0 -0
  181. package/test/userActivity.test.js +0 -0
  182. package/tools/generate-index.cjs +0 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(find:*)",
5
+ "Bash(docker exec:*)",
6
+ "Bash(npm test:*)",
7
+ "WebSearch",
8
+ "WebFetch(domain:watermelondb.dev)",
9
+ "WebFetch(domain:github.com)",
10
+ "Bash(git checkout:*)",
11
+ "Bash(npm run doc:*)",
12
+ "Bash(cat:*)",
13
+ "Bash(tr:*)"
14
+ ],
15
+ "deny": [],
16
+ "ask": []
17
+ }
18
+ }
package/.coderabbit.yaml CHANGED
File without changes
package/.editorconfig CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
package/.prettierignore CHANGED
File without changes
package/.prettierrc CHANGED
File without changes
package/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
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
+ ### [2.104.2](https://github.com/railroadmedia/musora-content-services/compare/v2.104.1...v2.104.2) (2025-12-12)
6
+
7
+ ### [2.104.1](https://github.com/railroadmedia/musora-content-services/compare/v2.104.0...v2.104.1) (2025-12-12)
8
+
9
+ ## [2.104.0](https://github.com/railroadmedia/musora-content-services/compare/v2.100.3...v2.104.0) (2025-12-12)
10
+
11
+
12
+ ### Features
13
+
14
+ * add isCompleted and field name updates in award callback([#648](https://github.com/railroadmedia/musora-content-services/issues/648)) ([c250d61](https://github.com/railroadmedia/musora-content-services/commit/c250d61b90bc29504827e8fa368a78b34a3f0c08))
15
+ * **auth:** authenticate via auth key ([#644](https://github.com/railroadmedia/musora-content-services/issues/644)) ([122ba63](https://github.com/railroadmedia/musora-content-services/commit/122ba63572e95faf49944a3e819b768cb0a9ab85))
16
+ * **BEH-1457:** method progress duplication ([#617](https://github.com/railroadmedia/musora-content-services/issues/617)) ([917cb9d](https://github.com/railroadmedia/musora-content-services/commit/917cb9dedce2a21c64af4e39eef013a30b236e77))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * **agi:** offset default and slug clause on artistBySlug ([10cc6d0](https://github.com/railroadmedia/musora-content-services/commit/10cc6d0390a12715aeba01c5dc72ecdb53d0f236))
22
+ * **agi:** remove count from AGI lessons functions ([5cf3bc3](https://github.com/railroadmedia/musora-content-services/commit/5cf3bc3ade98faa5200cd64ce4b0a9edaff29d7a))
23
+ * **agi:** rollback total on fetchAGILessons ([a02be05](https://github.com/railroadmedia/musora-content-services/commit/a02be0592dd8b195da7971f13ea062674510c8bb))
24
+ * lp lesson upserting ([#645](https://github.com/railroadmedia/musora-content-services/issues/645)) ([1a3094d](https://github.com/railroadmedia/musora-content-services/commit/1a3094d569bb868d62844755b876cee8bc63a365))
25
+ * mobile login broken ([785e0fc](https://github.com/railroadmedia/musora-content-services/commit/785e0fc1fc1ce58840d0e85874f68b9c77342290))
26
+ * **MU2-1305:** fix url and add postId for active discussions ([ac42889](https://github.com/railroadmedia/musora-content-services/commit/ac4288955e2d7c817e0a51aaf1364b75aec6eea1))
27
+ * user id missing on auth key ([ba4068f](https://github.com/railroadmedia/musora-content-services/commit/ba4068ff3aa8005b1b3ed615b07d4ff7eb9f751b))
28
+
5
29
  ### [2.103.6](https://github.com/railroadmedia/musora-content-services/compare/v2.103.5...v2.103.6) (2025-12-12)
6
30
 
7
31
  ### [2.103.5](https://github.com/railroadmedia/musora-content-services/compare/v2.103.4...v2.103.5) (2025-12-12)
package/CLAUDE.md CHANGED
File without changes
package/README.md CHANGED
File without changes
package/babel.config.cjs CHANGED
File without changes
package/jest.config.js CHANGED
File without changes
package/jsdoc.json CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "2.103.6",
3
+ "version": "2.104.2",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
File without changes
File without changes
@@ -862,7 +862,7 @@ export function getChildFieldsForContentType(contentType, asQueryString = true)
862
862
  export function getFieldsForContentType(contentType, asQueryString = true) {
863
863
  const fields = contentType
864
864
  ? DEFAULT_FIELDS.concat(contentTypeConfig?.[contentType]?.fields ?? [])
865
- : DEFAULT_FIELDS
865
+ : DEFAULT_FIELDS.slice() // ensure copy, not original reference
866
866
  return asQueryString ? fields.toString() + ',' : fields
867
867
  }
868
868
 
package/src/index.d.ts CHANGED
@@ -9,7 +9,8 @@ import {
9
9
  getAwardStatistics,
10
10
  getCompletedAwards,
11
11
  getContentAwards,
12
- getInProgressAwards
12
+ getInProgressAwards,
13
+ resetAllAwards
13
14
  } from './services/awards/award-query.js';
14
15
 
15
16
  import {
@@ -683,6 +684,7 @@ declare module 'musora-content-services' {
683
684
  reportPlaylist,
684
685
  requestEmailChange,
685
686
  reset,
687
+ resetAllAwards,
686
688
  resetAllLearningPaths,
687
689
  resetPassword,
688
690
  restoreComment,
package/src/index.js CHANGED
@@ -13,7 +13,8 @@ import {
13
13
  getAwardStatistics,
14
14
  getCompletedAwards,
15
15
  getContentAwards,
16
- getInProgressAwards
16
+ getInProgressAwards,
17
+ resetAllAwards
17
18
  } from './services/awards/award-query.js';
18
19
 
19
20
  import {
@@ -682,6 +683,7 @@ export {
682
683
  reportPlaylist,
683
684
  requestEmailChange,
684
685
  reset,
686
+ resetAllAwards,
685
687
  resetAllLearningPaths,
686
688
  resetPassword,
687
689
  restoreComment,
File without changes
File without changes
File without changes
package/src/lib/brands.ts CHANGED
File without changes
File without changes
File without changes
File without changes
@@ -493,3 +493,16 @@ export async function getAwardStatistics(brand = null) {
493
493
  }
494
494
  }
495
495
  }
496
+
497
+ /**
498
+ * @returns {Promise<{ deletedCount: number }>}
499
+ */
500
+ export async function resetAllAwards() {
501
+ try {
502
+ const result = await db.userAwardProgress.deleteAllAwards()
503
+ return result
504
+ } catch (error) {
505
+ console.error('Failed to reset awards:', error)
506
+ return { deletedCount: 0 }
507
+ }
508
+ }
File without changes
File without changes
File without changes
@@ -129,6 +129,11 @@ export class AwardManager {
129
129
  const completedCount = completedLessonIds.length
130
130
  const progressPercentage = Math.round((completedCount / childIds.length) * 100)
131
131
 
132
+ if (progressPercentage === 100) {
133
+ await this.grantAward(award, collection)
134
+ return
135
+ }
136
+
132
137
  const progressData = {
133
138
  completedLessonIds,
134
139
  totalLessons: childIds.length,
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
@@ -70,9 +70,10 @@ function transformLatestDiscussions(response: PaginatedResponse<ForumThread>): T
70
70
 
71
71
  return {
72
72
  id: thread.id,
73
- url: `forums/post/${postId}`,
73
+ url: `forums/threads/${thread.category_id}/${thread.id}`,
74
74
  title: thread.title,
75
75
  post: postContent,
76
+ postId:postId,
76
77
  author: {
77
78
  id: thread.author!.id,
78
79
  name: thread.author!.display_name,
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
@@ -130,4 +130,30 @@ export default class UserAwardProgressRepository extends SyncRepository<UserAwar
130
130
 
131
131
  return { definitions, progress: progressMap }
132
132
  }
133
+
134
+ async deleteAllAwards() {
135
+ const allProgress = await this.getAll()
136
+ const ids = allProgress.data.map(p => p.id)
137
+
138
+ if (ids.length === 0) {
139
+ return { deletedCount: 0 }
140
+ }
141
+
142
+ await this.deleteSome(ids)
143
+
144
+ const response = await this.store.pushRecordIdsImpatiently(ids)
145
+
146
+ if (response && response.ok) {
147
+ await this.store.db.write(async () => {
148
+ const collection = this.store.db.get<UserAwardProgress>(UserAwardProgress.table)
149
+ const deletedRecords = await collection
150
+ .query(Q.where('id', Q.oneOf(ids)))
151
+ .fetch()
152
+
153
+ await Promise.all(deletedRecords.map(record => record.destroyPermanently()))
154
+ })
155
+ }
156
+
157
+ return { deletedCount: ids.length }
158
+ }
133
159
  }
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
@@ -210,4 +210,94 @@ describe('Award Completion Flow - E2E Scenarios', () => {
210
210
  expect(db.userAwardProgress.recordAwardProgress).not.toHaveBeenCalled()
211
211
  })
212
212
  })
213
+
214
+ describe('Scenario: Race condition - eligibility check fails but progress reaches 100%', () => {
215
+ const multiLessonAward = getAwardByContentId(417049)
216
+ const parentCourseId = 417049
217
+
218
+ test('grants award with completedAt when updateAwardProgress calculates 100%', async () => {
219
+ let callCount = 0
220
+
221
+ db.contentProgress.getSomeProgressByContentIds.mockImplementation((contentIds) => {
222
+ callCount++
223
+
224
+ if (callCount === 1) {
225
+ const partialRecords = contentIds
226
+ .filter(id => [417045, 417046, 417047].includes(id))
227
+ .map(id => ({
228
+ content_id: id,
229
+ state: 'completed',
230
+ created_at: Math.floor(Date.now() / 1000)
231
+ }))
232
+ return Promise.resolve({ data: partialRecords })
233
+ }
234
+
235
+ const allRecords = contentIds.map(id => ({
236
+ content_id: id,
237
+ state: 'completed',
238
+ created_at: Math.floor(Date.now() / 1000)
239
+ }))
240
+ return Promise.resolve({ data: allRecords })
241
+ })
242
+
243
+ await awardManager.onContentCompleted(parentCourseId)
244
+
245
+ expect(db.userAwardProgress.recordAwardProgress).toHaveBeenCalledWith(
246
+ multiLessonAward._id,
247
+ 100,
248
+ expect.objectContaining({
249
+ completedAt: expect.any(Number),
250
+ completionData: expect.objectContaining({
251
+ completed_at: expect.any(String)
252
+ }),
253
+ immediate: true
254
+ })
255
+ )
256
+
257
+ expect(listeners.granted).toHaveBeenCalledTimes(1)
258
+ expect(listeners.progress).not.toHaveBeenCalled()
259
+ })
260
+
261
+ test('emits awardGranted event when race condition triggers completion', async () => {
262
+ let callCount = 0
263
+
264
+ db.contentProgress.getSomeProgressByContentIds.mockImplementation((contentIds) => {
265
+ callCount++
266
+
267
+ if (callCount === 1) {
268
+ const partialRecords = contentIds
269
+ .filter(id => [417045, 417046].includes(id))
270
+ .map(id => ({
271
+ content_id: id,
272
+ state: 'completed',
273
+ created_at: Math.floor(Date.now() / 1000)
274
+ }))
275
+ return Promise.resolve({ data: partialRecords })
276
+ }
277
+
278
+ const allRecords = contentIds.map(id => ({
279
+ content_id: id,
280
+ state: 'completed',
281
+ created_at: Math.floor(Date.now() / 1000)
282
+ }))
283
+ return Promise.resolve({ data: allRecords })
284
+ })
285
+
286
+ await awardManager.onContentCompleted(parentCourseId)
287
+
288
+ expect(listeners.granted).toHaveBeenCalledTimes(1)
289
+ expect(listeners.granted).toHaveBeenCalledWith(
290
+ expect.objectContaining({
291
+ awardId: multiLessonAward._id,
292
+ definition: expect.objectContaining({
293
+ name: multiLessonAward.name
294
+ }),
295
+ completionData: expect.objectContaining({
296
+ completed_at: expect.any(String)
297
+ }),
298
+ timestamp: expect.any(Number)
299
+ })
300
+ )
301
+ })
302
+ })
213
303
  })
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/log.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