@semiont/react-ui 0.2.33-build.78 → 0.2.33-build.80

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 (219) hide show
  1. package/dist/EventBusContext-7GvDyO0d.d.mts +414 -0
  2. package/dist/{PdfAnnotationCanvas.client-ADC4FFSE.mjs → PdfAnnotationCanvas.client-RAJRPQLU.mjs} +42 -27
  3. package/dist/PdfAnnotationCanvas.client-RAJRPQLU.mjs.map +1 -0
  4. package/dist/{ar-RNNSPLQB.mjs → ar-4ZEORRW2.mjs} +8 -4
  5. package/dist/ar-4ZEORRW2.mjs.map +1 -0
  6. package/dist/{bn-S2CDL7EC.mjs → bn-SEDE5BQJ.mjs} +8 -4
  7. package/dist/bn-SEDE5BQJ.mjs.map +1 -0
  8. package/dist/{chunk-UDX2Q35T.mjs → chunk-D7NBW4RV.mjs} +8 -4
  9. package/dist/chunk-D7NBW4RV.mjs.map +1 -0
  10. package/dist/{chunk-35LLVRFK.mjs → chunk-ZR4ZV2LY.mjs} +206 -146
  11. package/dist/chunk-ZR4ZV2LY.mjs.map +1 -0
  12. package/dist/{cs-RSV675WU.mjs → cs-7W4WF5WD.mjs} +8 -4
  13. package/dist/cs-7W4WF5WD.mjs.map +1 -0
  14. package/dist/{da-CHXNPWJC.mjs → da-75XGBCBK.mjs} +8 -4
  15. package/dist/da-75XGBCBK.mjs.map +1 -0
  16. package/dist/{de-KPEZ53D4.mjs → de-ODJVFLHM.mjs} +8 -4
  17. package/dist/de-ODJVFLHM.mjs.map +1 -0
  18. package/dist/{el-MW2BME5T.mjs → el-C4PM4WB3.mjs} +8 -4
  19. package/dist/el-C4PM4WB3.mjs.map +1 -0
  20. package/dist/{en-EVMIX24Y.mjs → en-KJCJQ4OO.mjs} +2 -2
  21. package/dist/{es-HQ24NYS3.mjs → es-WD33R7QL.mjs} +8 -4
  22. package/dist/es-WD33R7QL.mjs.map +1 -0
  23. package/dist/{fa-W34LRLHG.mjs → fa-2BP6V56P.mjs} +8 -4
  24. package/dist/fa-2BP6V56P.mjs.map +1 -0
  25. package/dist/{fi-3U44IGOA.mjs → fi-USRRW24J.mjs} +8 -4
  26. package/dist/fi-USRRW24J.mjs.map +1 -0
  27. package/dist/{fr-N7DKX6NN.mjs → fr-EC5S6WVF.mjs} +8 -4
  28. package/dist/fr-EC5S6WVF.mjs.map +1 -0
  29. package/dist/{he-CS4WRXN3.mjs → he-7TBVIKAA.mjs} +8 -4
  30. package/dist/he-7TBVIKAA.mjs.map +1 -0
  31. package/dist/{hi-GJDY46KA.mjs → hi-FO4VIZLA.mjs} +8 -4
  32. package/dist/hi-FO4VIZLA.mjs.map +1 -0
  33. package/dist/{id-WAEZJK2Y.mjs → id-7U7GGVWY.mjs} +8 -4
  34. package/dist/id-7U7GGVWY.mjs.map +1 -0
  35. package/dist/index.css +123 -85
  36. package/dist/index.css.map +1 -1
  37. package/dist/index.d.mts +699 -529
  38. package/dist/index.mjs +4291 -3491
  39. package/dist/index.mjs.map +1 -1
  40. package/dist/{it-VDNDMZPU.mjs → it-Y4OPL6I2.mjs} +8 -4
  41. package/dist/it-Y4OPL6I2.mjs.map +1 -0
  42. package/dist/{ja-5PEH56J5.mjs → ja-PK7SQL55.mjs} +8 -4
  43. package/dist/ja-PK7SQL55.mjs.map +1 -0
  44. package/dist/{ko-JYPL3WVA.mjs → ko-L25PXMYD.mjs} +8 -4
  45. package/dist/ko-L25PXMYD.mjs.map +1 -0
  46. package/dist/{ms-5PZVW76T.mjs → ms-STH777QM.mjs} +8 -4
  47. package/dist/ms-STH777QM.mjs.map +1 -0
  48. package/dist/{nl-YXES36KM.mjs → nl-Y7LECDDR.mjs} +8 -4
  49. package/dist/nl-Y7LECDDR.mjs.map +1 -0
  50. package/dist/{no-XRA2UCQD.mjs → no-KEKCEWU6.mjs} +8 -4
  51. package/dist/no-KEKCEWU6.mjs.map +1 -0
  52. package/dist/{pl-WH6LJA5G.mjs → pl-7A7OC75O.mjs} +8 -4
  53. package/dist/pl-7A7OC75O.mjs.map +1 -0
  54. package/dist/{pt-7GAG57BM.mjs → pt-35HTM7RA.mjs} +8 -4
  55. package/dist/pt-35HTM7RA.mjs.map +1 -0
  56. package/dist/{ro-BTDDRB7N.mjs → ro-VAWL5KQA.mjs} +8 -4
  57. package/dist/ro-VAWL5KQA.mjs.map +1 -0
  58. package/dist/{sv-7V5C2IT4.mjs → sv-7ZK5EQEB.mjs} +8 -4
  59. package/dist/sv-7ZK5EQEB.mjs.map +1 -0
  60. package/dist/test-utils.d.mts +18 -8
  61. package/dist/test-utils.mjs +36 -14
  62. package/dist/test-utils.mjs.map +1 -1
  63. package/dist/{th-LPKYLBX5.mjs → th-UDWZ4X34.mjs} +8 -4
  64. package/dist/th-UDWZ4X34.mjs.map +1 -0
  65. package/dist/{tr-DU4RQL4M.mjs → tr-4WMPK3UX.mjs} +8 -4
  66. package/dist/tr-4WMPK3UX.mjs.map +1 -0
  67. package/dist/{uk-36UHTDDI.mjs → uk-SSLASQYJ.mjs} +8 -4
  68. package/dist/uk-SSLASQYJ.mjs.map +1 -0
  69. package/dist/{vi-GDHOUZDH.mjs → vi-IF42Z5PU.mjs} +8 -4
  70. package/dist/vi-IF42Z5PU.mjs.map +1 -0
  71. package/dist/{zh-TYUID4XZ.mjs → zh-HRQTNTAI.mjs} +8 -4
  72. package/dist/zh-HRQTNTAI.mjs.map +1 -0
  73. package/package.json +8 -2
  74. package/src/components/CodeMirrorRenderer.tsx +66 -93
  75. package/src/components/DetectionProgressWidget.tsx +16 -5
  76. package/src/components/LiveRegion.tsx +18 -18
  77. package/src/components/ResizeHandle.tsx +10 -4
  78. package/src/components/SessionTimer.tsx +2 -2
  79. package/src/components/Toolbar.tsx +18 -9
  80. package/src/components/__tests__/SessionTimer.test.tsx +9 -9
  81. package/src/components/annotation/AnnotateToolbar.tsx +17 -15
  82. package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +165 -63
  83. package/src/components/annotation/annotation-entries.css +10 -0
  84. package/src/components/annotation-popups/JsonLdView.tsx +8 -2
  85. package/src/components/image-annotation/AnnotationOverlay.tsx +42 -22
  86. package/src/components/image-annotation/SvgDrawingCanvas.tsx +27 -30
  87. package/src/components/layout/__tests__/LeftSidebar.test.tsx +12 -33
  88. package/src/components/layout/__tests__/PageLayout.test.tsx +37 -32
  89. package/src/components/layout/__tests__/UnifiedHeader.test.tsx +21 -40
  90. package/src/components/modals/ResourceSearchModal.tsx +2 -2
  91. package/src/components/modals/SearchModal.tsx +1 -1
  92. package/src/components/navigation/CollapsibleResourceNavigation.tsx +14 -9
  93. package/src/components/navigation/NavigationTabs.css +36 -24
  94. package/src/components/navigation/ObservableLink.tsx +91 -0
  95. package/src/components/navigation/SimpleNavigation.tsx +20 -16
  96. package/src/components/navigation/SortableResourceTab.tsx +11 -5
  97. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +51 -26
  98. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +28 -22
  99. package/src/components/resource/AnnotateView.tsx +64 -138
  100. package/src/components/resource/AnnotationHistory.tsx +12 -13
  101. package/src/components/resource/BrowseView.tsx +89 -177
  102. package/src/components/resource/HistoryEvent.tsx +16 -11
  103. package/src/components/resource/ResourceViewer.tsx +201 -370
  104. package/src/components/resource/__tests__/BrowseView.test.tsx +631 -0
  105. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +231 -0
  106. package/src/components/resource/event-formatting.ts +316 -0
  107. package/src/components/resource/panels/AssessmentEntry.tsx +25 -33
  108. package/src/components/resource/panels/AssessmentPanel.tsx +137 -31
  109. package/src/components/resource/panels/CollaborationPanel.tsx +20 -13
  110. package/src/components/resource/panels/CommentEntry.tsx +38 -32
  111. package/src/components/resource/panels/CommentsPanel.tsx +153 -31
  112. package/src/components/resource/panels/DetectSection.css +36 -1
  113. package/src/components/resource/panels/DetectSection.tsx +38 -10
  114. package/src/components/resource/panels/HighlightEntry.tsx +25 -33
  115. package/src/components/resource/panels/HighlightPanel.tsx +100 -25
  116. package/src/components/resource/panels/ReferenceEntry.tsx +61 -75
  117. package/src/components/resource/panels/ReferencesPanel.tsx +166 -49
  118. package/src/components/resource/panels/ResourceInfoPanel.tsx +47 -48
  119. package/src/components/resource/panels/StatisticsPanel.tsx +9 -19
  120. package/src/components/resource/panels/TagEntry.tsx +25 -33
  121. package/src/components/resource/panels/TaggingPanel.tsx +141 -25
  122. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +46 -101
  123. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +566 -0
  124. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +86 -78
  125. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +146 -141
  126. package/src/components/resource/panels/__tests__/DetectSection.test.tsx +480 -0
  127. package/src/components/resource/panels/__tests__/HighlightPanel.detectionProgress.test.tsx +362 -0
  128. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +228 -103
  129. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +117 -61
  130. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +586 -0
  131. package/src/components/settings/SettingsPanel.tsx +15 -12
  132. package/src/features/admin-devops/__tests__/AdminDevOpsPage.test.tsx +1 -46
  133. package/src/features/admin-devops/components/AdminDevOpsPage.tsx +0 -9
  134. package/src/features/admin-security/__tests__/AdminSecurityPage.test.tsx +0 -3
  135. package/src/features/admin-security/components/AdminSecurityPage.tsx +0 -9
  136. package/src/features/admin-users/__tests__/AdminUsersPage.test.tsx +0 -3
  137. package/src/features/admin-users/components/AdminUsersPage.tsx +0 -9
  138. package/src/features/moderate-entity-tags/__tests__/EntityTagsPage.test.tsx +0 -3
  139. package/src/features/moderate-entity-tags/components/EntityTagsPage.tsx +1 -9
  140. package/src/features/moderate-recent/__tests__/RecentDocumentsPage.test.tsx +0 -32
  141. package/src/features/moderate-recent/components/RecentDocumentsPage.tsx +1 -9
  142. package/src/features/moderate-tag-schemas/__tests__/TagSchemasPage.test.tsx +0 -32
  143. package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -9
  144. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +51 -54
  145. package/src/features/resource-compose/components/ResourceComposePage.tsx +3 -13
  146. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +39 -45
  147. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +16 -27
  148. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +231 -0
  149. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +234 -0
  150. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +388 -0
  151. package/src/features/resource-viewer/__tests__/DetectionProgressDismissal.test.tsx +318 -0
  152. package/src/features/resource-viewer/__tests__/GenerationFlowIntegration.test.tsx +504 -0
  153. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +145 -91
  154. package/src/features/resource-viewer/__tests__/detection-progress-flow.test.tsx +322 -0
  155. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +325 -476
  156. package/src/styles/motivations/motivation-assessment.css +28 -0
  157. package/src/styles/patterns/panel-helpers.css +26 -0
  158. package/translations/ar.json +7 -3
  159. package/translations/bn.json +7 -3
  160. package/translations/cs.json +7 -3
  161. package/translations/da.json +7 -3
  162. package/translations/de.json +7 -3
  163. package/translations/el.json +7 -3
  164. package/translations/en.json +7 -3
  165. package/translations/es.json +7 -3
  166. package/translations/fa.json +7 -3
  167. package/translations/fi.json +7 -3
  168. package/translations/fr.json +7 -3
  169. package/translations/he.json +7 -3
  170. package/translations/hi.json +7 -3
  171. package/translations/id.json +7 -3
  172. package/translations/it.json +7 -3
  173. package/translations/ja.json +7 -3
  174. package/translations/ko.json +7 -3
  175. package/translations/ms.json +7 -3
  176. package/translations/nl.json +7 -3
  177. package/translations/no.json +7 -3
  178. package/translations/pl.json +7 -3
  179. package/translations/pt.json +7 -3
  180. package/translations/ro.json +7 -3
  181. package/translations/sv.json +7 -3
  182. package/translations/th.json +7 -3
  183. package/translations/tr.json +7 -3
  184. package/translations/uk.json +7 -3
  185. package/translations/vi.json +7 -3
  186. package/translations/zh.json +7 -3
  187. package/dist/PdfAnnotationCanvas.client-ADC4FFSE.mjs.map +0 -1
  188. package/dist/TranslationManager-Co_5fSxl.d.mts +0 -118
  189. package/dist/ar-RNNSPLQB.mjs.map +0 -1
  190. package/dist/bn-S2CDL7EC.mjs.map +0 -1
  191. package/dist/chunk-35LLVRFK.mjs.map +0 -1
  192. package/dist/chunk-UDX2Q35T.mjs.map +0 -1
  193. package/dist/cs-RSV675WU.mjs.map +0 -1
  194. package/dist/da-CHXNPWJC.mjs.map +0 -1
  195. package/dist/de-KPEZ53D4.mjs.map +0 -1
  196. package/dist/el-MW2BME5T.mjs.map +0 -1
  197. package/dist/es-HQ24NYS3.mjs.map +0 -1
  198. package/dist/fa-W34LRLHG.mjs.map +0 -1
  199. package/dist/fi-3U44IGOA.mjs.map +0 -1
  200. package/dist/fr-N7DKX6NN.mjs.map +0 -1
  201. package/dist/he-CS4WRXN3.mjs.map +0 -1
  202. package/dist/hi-GJDY46KA.mjs.map +0 -1
  203. package/dist/id-WAEZJK2Y.mjs.map +0 -1
  204. package/dist/it-VDNDMZPU.mjs.map +0 -1
  205. package/dist/ja-5PEH56J5.mjs.map +0 -1
  206. package/dist/ko-JYPL3WVA.mjs.map +0 -1
  207. package/dist/ms-5PZVW76T.mjs.map +0 -1
  208. package/dist/nl-YXES36KM.mjs.map +0 -1
  209. package/dist/no-XRA2UCQD.mjs.map +0 -1
  210. package/dist/pl-WH6LJA5G.mjs.map +0 -1
  211. package/dist/pt-7GAG57BM.mjs.map +0 -1
  212. package/dist/ro-BTDDRB7N.mjs.map +0 -1
  213. package/dist/sv-7V5C2IT4.mjs.map +0 -1
  214. package/dist/th-LPKYLBX5.mjs.map +0 -1
  215. package/dist/tr-DU4RQL4M.mjs.map +0 -1
  216. package/dist/uk-36UHTDDI.mjs.map +0 -1
  217. package/dist/vi-GDHOUZDH.mjs.map +0 -1
  218. package/dist/zh-TYUID4XZ.mjs.map +0 -1
  219. /package/dist/{en-EVMIX24Y.mjs.map → en-KJCJQ4OO.mjs.map} +0 -0
@@ -2,22 +2,66 @@
2
2
  * Tests for ResourceViewerPage component
3
3
  *
4
4
  * Tests the main resource viewer UI component.
5
- * No Next.js mocking required - all dependencies passed as props!
5
+ * All internal data fetching (content, annotations, etc.) is mocked at the hook level.
6
6
  */
7
7
 
8
- import { describe, it, expect, vi } from 'vitest';
8
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
9
9
  import { render, screen } from '@testing-library/react';
10
+ import React from 'react';
10
11
  import { ResourceViewerPage } from '../components/ResourceViewerPage';
11
12
  import type { ResourceViewerPageProps } from '../components/ResourceViewerPage';
13
+ // Import directly from context file to bypass mocked barrel export
14
+ import { EventBusProvider, resetEventBusForTesting } from '../../../contexts/EventBusContext';
15
+ import { ApiClientProvider } from '../../../contexts/ApiClientContext';
16
+ import { AuthTokenProvider } from '../../../contexts/AuthTokenContext';
17
+ import { ToastProvider } from '../../../components/Toast';
18
+
19
+ // jsdom doesn't implement window.matchMedia — mock it for useTheme
20
+ Object.defineProperty(window, 'matchMedia', {
21
+ writable: true,
22
+ value: vi.fn().mockImplementation((query: string) => ({
23
+ matches: false,
24
+ media: query,
25
+ onchange: null,
26
+ addListener: vi.fn(),
27
+ removeListener: vi.fn(),
28
+ addEventListener: vi.fn(),
29
+ removeEventListener: vi.fn(),
30
+ dispatchEvent: vi.fn(),
31
+ })),
32
+ });
12
33
 
13
- // Mock dependencies that ResourceViewerPage imports
14
- vi.mock('@tanstack/react-query', () => ({
15
- useQueryClient: () => ({
16
- invalidateQueries: vi.fn(),
17
- setQueryData: vi.fn(),
34
+ // Mock internal hooks that fetch data
35
+ vi.mock('../../../hooks/useResourceContent', () => ({
36
+ useResourceContent: () => ({ content: 'Test content', loading: false }),
37
+ }));
38
+
39
+ vi.mock('../../../lib/api-hooks', () => ({
40
+ useResources: () => ({
41
+ annotations: { useQuery: () => ({ data: { annotations: [] } }) },
42
+ referencedBy: { useQuery: () => ({ data: { referencedBy: [] }, isLoading: false }) },
43
+ }),
44
+ useEntityTypes: () => ({
45
+ list: { useQuery: () => ({ data: { entityTypes: ['Document', 'Article', 'Book'] } }) },
18
46
  }),
19
47
  }));
20
48
 
49
+ vi.mock('../../../hooks/useResourceEvents', () => ({
50
+ useResourceEvents: () => null,
51
+ }));
52
+
53
+ // Mock dependencies that ResourceViewerPage imports
54
+ vi.mock('@tanstack/react-query', async () => {
55
+ const actual = await vi.importActual('@tanstack/react-query');
56
+ return {
57
+ ...actual,
58
+ useQueryClient: () => ({
59
+ invalidateQueries: vi.fn(),
60
+ setQueryData: vi.fn(),
61
+ }),
62
+ };
63
+ });
64
+
21
65
  vi.mock('@semiont/react-ui', async () => {
22
66
  const actual = await vi.importActual('@semiont/react-ui');
23
67
  return {
@@ -34,14 +78,47 @@ vi.mock('@semiont/react-ui', async () => {
34
78
  createCancelDetectionHandler: () => vi.fn(),
35
79
  useGenerationProgress: () => ({
36
80
  progress: null,
37
- startGeneration: vi.fn(),
38
81
  clearProgress: vi.fn(),
39
82
  }),
40
83
  useDebouncedCallback: (fn: any) => fn,
41
84
  supportsDetection: () => false,
85
+ MakeMeaningEventBusProvider: ({ children }: any) => children,
86
+ useResourceLoadingAnnouncements: () => ({
87
+ announceResourceLoading: vi.fn(),
88
+ announceResourceLoaded: vi.fn(),
89
+ }),
90
+ // Don't mock EventBusProvider, useEventBus, resetEventBusForTesting - let actual pass through via ...actual
91
+ useEventSubscriptions: vi.fn(),
92
+ useResourceAnnotations: () => ({
93
+ clearNewAnnotationId: vi.fn(),
94
+ newAnnotationIds: new Set(),
95
+ createAnnotation: vi.fn(),
96
+ deleteAnnotation: vi.fn(),
97
+ triggerSparkleAnimation: vi.fn(),
98
+ }),
42
99
  };
43
100
  });
44
101
 
102
+ vi.mock('../../../contexts/OpenResourcesContext', () => ({
103
+ useOpenResources: () => ({
104
+ openResources: [],
105
+ addResource: vi.fn(),
106
+ removeResource: vi.fn(),
107
+ isResourceOpen: vi.fn().mockReturnValue(false),
108
+ }),
109
+ }));
110
+
111
+ vi.mock('../../../contexts/ResourceAnnotationsContext', () => ({
112
+ useResourceAnnotations: () => ({
113
+ clearNewAnnotationId: vi.fn(),
114
+ newAnnotationIds: new Set(),
115
+ createAnnotation: vi.fn(),
116
+ deleteAnnotation: vi.fn(),
117
+ triggerSparkleAnimation: vi.fn(),
118
+ }),
119
+ ResourceAnnotationsProvider: ({ children }: any) => children,
120
+ }));
121
+
45
122
  vi.mock('@/components/toolbar/ToolbarPanels', () => ({
46
123
  ToolbarPanels: ({ children }: any) => <div data-testid="toolbar-panels">{children}</div>,
47
124
  }));
@@ -54,7 +131,7 @@ vi.mock('@/components/modals/GenerationConfigModal', () => ({
54
131
  GenerationConfigModal: () => <div data-testid="generation-modal">Generation Modal</div>,
55
132
  }));
56
133
 
57
- // Create mock props with all required fields
134
+ // Create mock props matching the current ResourceViewerPageProps
58
135
  const createMockProps = (overrides?: Partial<ResourceViewerPageProps>): ResourceViewerPageProps => ({
59
136
  resource: {
60
137
  '@context': 'https://www.w3.org/ns/anno.jsonld',
@@ -73,45 +150,40 @@ const createMockProps = (overrides?: Partial<ResourceViewerPageProps>): Resource
73
150
  ],
74
151
  },
75
152
  rUri: 'http://localhost/resources/test-123' as any,
76
- content: 'Test content for the resource viewer',
77
- contentLoading: false,
78
- annotations: [],
79
- referencedBy: [],
80
- referencedByLoading: false,
81
- allEntityTypes: ['Document', 'Article', 'Book'],
82
153
  locale: 'en',
83
- theme: 'light',
84
- onThemeChange: vi.fn(),
85
- showLineNumbers: false,
86
- onLineNumbersToggle: vi.fn(),
87
- activePanel: null,
88
- onPanelToggle: vi.fn(),
89
- setActivePanel: vi.fn(),
90
- onArchive: vi.fn(),
91
- onUnarchive: vi.fn(),
92
- onClone: vi.fn(),
93
- onUpdateAnnotationBody: vi.fn(),
94
- onRefetchAnnotations: vi.fn(),
95
- onCreateAnnotation: vi.fn(),
96
- onTriggerSparkleAnimation: vi.fn(),
97
- onClearNewAnnotationId: vi.fn(),
98
- showSuccess: vi.fn(),
99
- showError: vi.fn(),
100
154
  cacheManager: {},
101
- client: {},
102
155
  Link: ({ children }: any) => <a>{children}</a>,
103
156
  routes: {},
104
- ToolbarPanels: ({ children }: any) => <div data-testid="toolbar-panels">{children}</div>,
157
+ refetchDocument: vi.fn().mockResolvedValue(undefined),
158
+ ToolbarPanels: ({ children, activePanel }: any) =>
159
+ !activePanel ? null : <div data-testid="toolbar-panels">{children}</div>,
105
160
  SearchResourcesModal: () => <div data-testid="search-modal">Search Modal</div>,
106
161
  GenerationConfigModal: () => <div data-testid="generation-modal">Generation Modal</div>,
107
162
  ...overrides,
108
163
  });
109
164
 
165
+ // Test wrapper to provide all required providers
166
+ const renderWithProviders = (ui: React.ReactElement) => {
167
+ return render(
168
+ <ToastProvider>
169
+ <AuthTokenProvider token={null}>
170
+ <ApiClientProvider baseUrl="http://localhost:4000">
171
+ <EventBusProvider>{ui}</EventBusProvider>
172
+ </ApiClientProvider>
173
+ </AuthTokenProvider>
174
+ </ToastProvider>
175
+ );
176
+ };
177
+
110
178
  describe('ResourceViewerPage', () => {
179
+ beforeEach(() => {
180
+ resetEventBusForTesting();
181
+ });
182
+
111
183
  describe('Basic Rendering', () => {
112
184
  it('renders without crashing', () => {
113
185
  const props = createMockProps();
114
- render(<ResourceViewerPage {...props} />);
186
+ renderWithProviders(<ResourceViewerPage {...props} />);
115
187
 
116
188
  // Check for header element specifically
117
189
  expect(screen.getByRole('heading', { name: 'Test Resource' })).toBeInTheDocument();
@@ -125,30 +197,23 @@ describe('ResourceViewerPage', () => {
125
197
  },
126
198
  });
127
199
 
128
- render(<ResourceViewerPage {...props} />);
200
+ renderWithProviders(<ResourceViewerPage {...props} />);
129
201
 
130
202
  expect(screen.getByRole('heading', { name: 'My Special Resource' })).toBeInTheDocument();
131
203
  });
132
204
 
133
205
  it('renders toolbar component', () => {
134
206
  const props = createMockProps();
135
- render(<ResourceViewerPage {...props} />);
207
+ renderWithProviders(<ResourceViewerPage {...props} />);
136
208
 
137
209
  expect(screen.getByTestId('toolbar')).toBeInTheDocument();
138
210
  });
139
211
  });
140
212
 
141
213
  describe('Content Loading', () => {
142
- it('shows loading message when content is loading', () => {
143
- const props = createMockProps({ contentLoading: true });
144
- render(<ResourceViewerPage {...props} />);
145
-
146
- expect(screen.getByText('Loading document content...')).toBeInTheDocument();
147
- });
148
-
149
214
  it('shows ResourceViewer when content is loaded', () => {
150
- const props = createMockProps({ contentLoading: false });
151
- render(<ResourceViewerPage {...props} />);
215
+ const props = createMockProps();
216
+ renderWithProviders(<ResourceViewerPage {...props} />);
152
217
 
153
218
  expect(screen.getByTestId('resource-viewer')).toBeInTheDocument();
154
219
  });
@@ -156,43 +221,53 @@ describe('ResourceViewerPage', () => {
156
221
 
157
222
  describe('Panel Visibility', () => {
158
223
  it('shows annotations panel when activePanel is annotations', () => {
159
- const props = createMockProps({ activePanel: 'annotations' });
160
- render(<ResourceViewerPage {...props} />);
224
+ localStorage.setItem('activeToolbarPanel', 'annotations');
225
+ const props = createMockProps();
226
+ renderWithProviders(<ResourceViewerPage {...props} />);
161
227
 
162
228
  expect(screen.getByTestId('annotations-panel')).toBeInTheDocument();
229
+ localStorage.clear();
163
230
  });
164
231
 
165
232
  it('shows history panel when activePanel is history', () => {
166
- const props = createMockProps({ activePanel: 'history' });
167
- render(<ResourceViewerPage {...props} />);
233
+ localStorage.setItem('activeToolbarPanel', 'history');
234
+ const props = createMockProps();
235
+ renderWithProviders(<ResourceViewerPage {...props} />);
168
236
 
169
237
  expect(screen.getByTestId('history-panel')).toBeInTheDocument();
238
+ localStorage.clear();
170
239
  });
171
240
 
172
241
  it('shows info panel when activePanel is info', () => {
173
- const props = createMockProps({ activePanel: 'info' });
174
- render(<ResourceViewerPage {...props} />);
242
+ localStorage.setItem('activeToolbarPanel', 'info');
243
+ const props = createMockProps();
244
+ renderWithProviders(<ResourceViewerPage {...props} />);
175
245
 
176
246
  expect(screen.getByTestId('info-panel')).toBeInTheDocument();
247
+ localStorage.clear();
177
248
  });
178
249
 
179
250
  it('shows collaboration panel when activePanel is collaboration', () => {
180
- const props = createMockProps({ activePanel: 'collaboration' });
181
- render(<ResourceViewerPage {...props} />);
251
+ localStorage.setItem('activeToolbarPanel', 'collaboration');
252
+ const props = createMockProps();
253
+ renderWithProviders(<ResourceViewerPage {...props} />);
182
254
 
183
255
  expect(screen.getByTestId('collaboration-panel')).toBeInTheDocument();
256
+ localStorage.clear();
184
257
  });
185
258
 
186
259
  it('shows jsonld panel when activePanel is jsonld', () => {
187
- const props = createMockProps({ activePanel: 'jsonld' });
188
- render(<ResourceViewerPage {...props} />);
260
+ localStorage.setItem('activeToolbarPanel', 'jsonld');
261
+ const props = createMockProps();
262
+ renderWithProviders(<ResourceViewerPage {...props} />);
189
263
 
190
264
  expect(screen.getByTestId('jsonld-panel')).toBeInTheDocument();
265
+ localStorage.clear();
191
266
  });
192
267
  });
193
268
 
194
269
  describe('Archived Status', () => {
195
- it('shows archived badge when resource is archived and in annotate mode', () => {
270
+ it('does not show archived badge when not in annotate mode', () => {
196
271
  const props = createMockProps({
197
272
  resource: {
198
273
  ...createMockProps().resource,
@@ -200,10 +275,9 @@ describe('ResourceViewerPage', () => {
200
275
  },
201
276
  });
202
277
 
203
- render(<ResourceViewerPage {...props} />);
278
+ renderWithProviders(<ResourceViewerPage {...props} />);
204
279
 
205
280
  // Archived badge only shows in annotate mode, which defaults to false
206
- // So we test that it doesn't show when not in annotate mode
207
281
  expect(screen.queryByText('📦 Archived')).not.toBeInTheDocument();
208
282
  });
209
283
  });
@@ -211,58 +285,38 @@ describe('ResourceViewerPage', () => {
211
285
  describe('Modals', () => {
212
286
  it('renders search resources modal', () => {
213
287
  const props = createMockProps();
214
- render(<ResourceViewerPage {...props} />);
288
+ renderWithProviders(<ResourceViewerPage {...props} />);
215
289
 
216
290
  expect(screen.getByTestId('search-modal')).toBeInTheDocument();
217
291
  });
218
292
 
219
293
  it('renders generation config modal', () => {
220
294
  const props = createMockProps();
221
- render(<ResourceViewerPage {...props} />);
295
+ renderWithProviders(<ResourceViewerPage {...props} />);
222
296
 
223
297
  expect(screen.getByTestId('generation-modal')).toBeInTheDocument();
224
298
  });
225
299
  });
226
300
 
227
301
  describe('Props Integration', () => {
228
- it('passes resource content to ResourceViewer', () => {
229
- const props = createMockProps({
230
- content: 'Custom test content',
231
- contentLoading: false,
232
- });
233
-
234
- render(<ResourceViewerPage {...props} />);
302
+ it('renders ResourceViewer component', () => {
303
+ const props = createMockProps();
304
+ renderWithProviders(<ResourceViewerPage {...props} />);
235
305
 
236
- // ResourceViewer is mocked to show resource name
237
306
  expect(screen.getByTestId('resource-viewer')).toBeInTheDocument();
238
307
  });
239
308
 
240
- it('handles multiple annotations', () => {
309
+ it('renders with different resource names', () => {
241
310
  const props = createMockProps({
242
- annotations: [
243
- {
244
- '@context': 'http://www.w3.org/ns/anno.jsonld',
245
- id: 'http://localhost/annotations/1',
246
- type: 'Annotation',
247
- motivation: 'commenting',
248
- body: [],
249
- target: 'http://localhost/resources/test-123',
250
- },
251
- {
252
- '@context': 'http://www.w3.org/ns/anno.jsonld',
253
- id: 'http://localhost/annotations/2',
254
- type: 'Annotation',
255
- motivation: 'highlighting',
256
- body: [],
257
- target: 'http://localhost/resources/test-123',
258
- },
259
- ],
311
+ resource: {
312
+ ...createMockProps().resource,
313
+ name: 'Different Resource Name',
314
+ },
260
315
  });
261
316
 
262
- render(<ResourceViewerPage {...props} />);
317
+ renderWithProviders(<ResourceViewerPage {...props} />);
263
318
 
264
- // Component should render without errors - check for header
265
- expect(screen.getByRole('heading', { name: 'Test Resource' })).toBeInTheDocument();
319
+ expect(screen.getByRole('heading', { name: 'Different Resource Name' })).toBeInTheDocument();
266
320
  });
267
321
  });
268
322
  });