@semiont/react-ui 0.2.33-build.79 → 0.2.33-build.81

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