@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
@@ -9,26 +9,19 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
9
9
  import { render, screen, fireEvent, waitFor } from '@testing-library/react';
10
10
  import { ResourceComposePage } from '../components/ResourceComposePage';
11
11
  import type { ResourceComposePageProps, SaveResourceParams } from '../components/ResourceComposePage';
12
-
13
- // Mock dependencies
14
- vi.mock('@semiont/react-ui', async () => {
15
- const actual = await vi.importActual('@semiont/react-ui');
16
- return {
17
- ...actual,
18
- buttonStyles: {
19
- primary: { base: 'btn-primary' },
20
- tertiary: { base: 'btn-tertiary' },
21
- },
22
- CodeMirrorRenderer: ({ content, onChange, editable }: any) => (
23
- <textarea
24
- data-testid="code-editor"
25
- value={content}
26
- onChange={(e) => editable && onChange?.(e.target.value)}
27
- disabled={!editable}
28
- />
29
- ),
30
- };
31
- });
12
+ import { EventBusProvider, resetEventBusForTesting } from '../../../contexts/EventBusContext';
13
+
14
+ // Mock CodeMirrorRenderer to avoid CodeMirror dependencies
15
+ vi.mock('../../../components/CodeMirrorRenderer', () => ({
16
+ CodeMirrorRenderer: ({ content, onChange, editable }: any) => (
17
+ <textarea
18
+ data-testid="code-editor"
19
+ value={content}
20
+ onChange={(e) => editable && onChange?.(e.target.value)}
21
+ disabled={!editable}
22
+ />
23
+ ),
24
+ }));
32
25
 
33
26
  const createMockTranslations = () => ({
34
27
  title: 'Compose Resource',
@@ -69,11 +62,8 @@ const createMockProps = (overrides?: Partial<ResourceComposePageProps>): Resourc
69
62
  availableEntityTypes: ['Document', 'Article', 'Report'],
70
63
  initialLocale: 'en',
71
64
  theme: 'light',
72
- onThemeChange: vi.fn(),
73
65
  showLineNumbers: false,
74
- onLineNumbersToggle: vi.fn(),
75
66
  activePanel: null,
76
- onPanelToggle: vi.fn(),
77
67
  onSaveResource: vi.fn().mockResolvedValue(undefined),
78
68
  onCancel: vi.fn(),
79
69
  translations: createMockTranslations(),
@@ -82,18 +72,27 @@ const createMockProps = (overrides?: Partial<ResourceComposePageProps>): Resourc
82
72
  ...overrides,
83
73
  });
84
74
 
75
+ // Helper to render with EventBusProvider
76
+ const renderWithProviders = (ui: React.ReactElement) => {
77
+ return render(<EventBusProvider>{ui}</EventBusProvider>);
78
+ };
79
+
85
80
  describe('ResourceComposePage', () => {
81
+ beforeEach(() => {
82
+ resetEventBusForTesting();
83
+ });
84
+
86
85
  describe('Basic Rendering - New Resource Mode', () => {
87
86
  it('renders without crashing', () => {
88
87
  const props = createMockProps();
89
- render(<ResourceComposePage {...props} />);
88
+ renderWithProviders(<ResourceComposePage {...props} />);
90
89
 
91
90
  expect(screen.getByText('Compose Resource')).toBeInTheDocument();
92
91
  });
93
92
 
94
93
  it('renders resource name input', () => {
95
94
  const props = createMockProps();
96
- render(<ResourceComposePage {...props} />);
95
+ renderWithProviders(<ResourceComposePage {...props} />);
97
96
 
98
97
  expect(screen.getByLabelText('Resource Name')).toBeInTheDocument();
99
98
  expect(screen.getByPlaceholderText('Enter resource name')).toBeInTheDocument();
@@ -101,7 +100,7 @@ describe('ResourceComposePage', () => {
101
100
 
102
101
  it('renders entity type selection', () => {
103
102
  const props = createMockProps();
104
- render(<ResourceComposePage {...props} />);
103
+ renderWithProviders(<ResourceComposePage {...props} />);
105
104
 
106
105
  expect(screen.getByText('Entity Types')).toBeInTheDocument();
107
106
  expect(screen.getByRole('button', { name: /Document entity type/ })).toBeInTheDocument();
@@ -111,14 +110,14 @@ describe('ResourceComposePage', () => {
111
110
 
112
111
  it('renders language selector', () => {
113
112
  const props = createMockProps();
114
- render(<ResourceComposePage {...props} />);
113
+ renderWithProviders(<ResourceComposePage {...props} />);
115
114
 
116
115
  expect(screen.getByLabelText('Language')).toBeInTheDocument();
117
116
  });
118
117
 
119
118
  it('renders content source toggle', () => {
120
119
  const props = createMockProps();
121
- render(<ResourceComposePage {...props} />);
120
+ renderWithProviders(<ResourceComposePage {...props} />);
122
121
 
123
122
  expect(screen.getByText('Upload File')).toBeInTheDocument();
124
123
  expect(screen.getByText('Write Content')).toBeInTheDocument();
@@ -126,7 +125,7 @@ describe('ResourceComposePage', () => {
126
125
 
127
126
  it('renders toolbar component', () => {
128
127
  const props = createMockProps();
129
- render(<ResourceComposePage {...props} />);
128
+ renderWithProviders(<ResourceComposePage {...props} />);
130
129
 
131
130
  expect(screen.getByTestId('toolbar')).toBeInTheDocument();
132
131
  });
@@ -144,7 +143,7 @@ describe('ResourceComposePage', () => {
144
143
  sourceContent: 'Original content',
145
144
  },
146
145
  });
147
- render(<ResourceComposePage {...props} />);
146
+ renderWithProviders(<ResourceComposePage {...props} />);
148
147
 
149
148
  expect(screen.getByText('Edit Cloned Resource')).toBeInTheDocument();
150
149
  expect(screen.getByText('Editing a cloned resource')).toBeInTheDocument();
@@ -161,7 +160,7 @@ describe('ResourceComposePage', () => {
161
160
  sourceContent: 'Original content',
162
161
  },
163
162
  });
164
- render(<ResourceComposePage {...props} />);
163
+ renderWithProviders(<ResourceComposePage {...props} />);
165
164
 
166
165
  const nameInput = screen.getByLabelText('Resource Name') as HTMLInputElement;
167
166
  expect(nameInput.value).toBe('Original Resource');
@@ -181,7 +180,7 @@ describe('ResourceComposePage', () => {
181
180
  sourceContent: 'Original content',
182
181
  },
183
182
  });
184
- render(<ResourceComposePage {...props} />);
183
+ renderWithProviders(<ResourceComposePage {...props} />);
185
184
 
186
185
  expect(screen.getByLabelText('Archive original resource')).toBeInTheDocument();
187
186
  });
@@ -197,7 +196,7 @@ describe('ResourceComposePage', () => {
197
196
  sourceContent: 'Original content',
198
197
  },
199
198
  });
200
- render(<ResourceComposePage {...props} />);
199
+ renderWithProviders(<ResourceComposePage {...props} />);
201
200
 
202
201
  expect(screen.queryByText('Upload File')).not.toBeInTheDocument();
203
202
  expect(screen.queryByText('Write Content')).not.toBeInTheDocument();
@@ -215,7 +214,7 @@ describe('ResourceComposePage', () => {
215
214
  entityTypes: ['Document'],
216
215
  },
217
216
  });
218
- render(<ResourceComposePage {...props} />);
217
+ renderWithProviders(<ResourceComposePage {...props} />);
219
218
 
220
219
  expect(screen.getByText('Complete Reference')).toBeInTheDocument();
221
220
  expect(screen.getByText('Creating a new resource for reference')).toBeInTheDocument();
@@ -232,7 +231,7 @@ describe('ResourceComposePage', () => {
232
231
  entityTypes: ['Document', 'Article'],
233
232
  },
234
233
  });
235
- render(<ResourceComposePage {...props} />);
234
+ renderWithProviders(<ResourceComposePage {...props} />);
236
235
 
237
236
  const nameInput = screen.getByLabelText('Resource Name') as HTMLInputElement;
238
237
  expect(nameInput.value).toBe('Referenced Resource');
@@ -251,7 +250,7 @@ describe('ResourceComposePage', () => {
251
250
  entityTypes: ['Document'],
252
251
  },
253
252
  });
254
- render(<ResourceComposePage {...props} />);
253
+ renderWithProviders(<ResourceComposePage {...props} />);
255
254
 
256
255
  // Should show read-only entity types
257
256
  expect(screen.getByText('Document')).toBeInTheDocument();
@@ -267,7 +266,7 @@ describe('ResourceComposePage', () => {
267
266
  describe('Content Input Method', () => {
268
267
  it('defaults to write mode', () => {
269
268
  const props = createMockProps();
270
- render(<ResourceComposePage {...props} />);
269
+ renderWithProviders(<ResourceComposePage {...props} />);
271
270
 
272
271
  const writeButton = screen.getByText('Write Content').closest('button');
273
272
  expect(writeButton).toHaveAttribute('data-active', 'true');
@@ -275,7 +274,7 @@ describe('ResourceComposePage', () => {
275
274
 
276
275
  it('allows switching to upload mode', () => {
277
276
  const props = createMockProps();
278
- render(<ResourceComposePage {...props} />);
277
+ renderWithProviders(<ResourceComposePage {...props} />);
279
278
 
280
279
  const uploadButton = screen.getByText('Upload File').closest('button');
281
280
  fireEvent.click(uploadButton!);
@@ -285,28 +284,28 @@ describe('ResourceComposePage', () => {
285
284
 
286
285
  it('shows format selector in write mode', () => {
287
286
  const props = createMockProps();
288
- render(<ResourceComposePage {...props} />);
287
+ renderWithProviders(<ResourceComposePage {...props} />);
289
288
 
290
289
  expect(screen.getByLabelText('Format')).toBeInTheDocument();
291
290
  });
292
291
 
293
292
  it('shows encoding selector in write mode', () => {
294
293
  const props = createMockProps();
295
- render(<ResourceComposePage {...props} />);
294
+ renderWithProviders(<ResourceComposePage {...props} />);
296
295
 
297
296
  expect(screen.getByLabelText('Encoding')).toBeInTheDocument();
298
297
  });
299
298
 
300
299
  it('shows code editor in write mode', () => {
301
300
  const props = createMockProps();
302
- render(<ResourceComposePage {...props} />);
301
+ renderWithProviders(<ResourceComposePage {...props} />);
303
302
 
304
303
  expect(screen.getByTestId('code-editor')).toBeInTheDocument();
305
304
  });
306
305
 
307
306
  it('shows file upload in upload mode', () => {
308
307
  const props = createMockProps();
309
- render(<ResourceComposePage {...props} />);
308
+ renderWithProviders(<ResourceComposePage {...props} />);
310
309
 
311
310
  const uploadButton = screen.getByText('Upload File').closest('button');
312
311
  fireEvent.click(uploadButton!);
@@ -319,7 +318,7 @@ describe('ResourceComposePage', () => {
319
318
  it('calls onSaveResource with correct params for new resource', async () => {
320
319
  const onSaveResource = vi.fn().mockResolvedValue(undefined);
321
320
  const props = createMockProps({ onSaveResource });
322
- render(<ResourceComposePage {...props} />);
321
+ renderWithProviders(<ResourceComposePage {...props} />);
323
322
 
324
323
  // Fill in name
325
324
  const nameInput = screen.getByLabelText('Resource Name');
@@ -353,7 +352,7 @@ describe('ResourceComposePage', () => {
353
352
  it('includes selected entity types', async () => {
354
353
  const onSaveResource = vi.fn().mockResolvedValue(undefined);
355
354
  const props = createMockProps({ onSaveResource });
356
- render(<ResourceComposePage {...props} />);
355
+ renderWithProviders(<ResourceComposePage {...props} />);
357
356
 
358
357
  // Fill in name
359
358
  const nameInput = screen.getByLabelText('Resource Name');
@@ -378,7 +377,7 @@ describe('ResourceComposePage', () => {
378
377
 
379
378
  it('requires resource name', () => {
380
379
  const props = createMockProps();
381
- render(<ResourceComposePage {...props} />);
380
+ renderWithProviders(<ResourceComposePage {...props} />);
382
381
 
383
382
  const submitButton = screen.getByRole('button', { name: 'Create Resource' });
384
383
  expect(submitButton).toBeDisabled();
@@ -386,7 +385,7 @@ describe('ResourceComposePage', () => {
386
385
 
387
386
  it('enables submit button when name is provided', () => {
388
387
  const props = createMockProps();
389
- render(<ResourceComposePage {...props} />);
388
+ renderWithProviders(<ResourceComposePage {...props} />);
390
389
 
391
390
  const nameInput = screen.getByLabelText('Resource Name');
392
391
  fireEvent.change(nameInput, { target: { value: 'Test Resource' } });
@@ -398,7 +397,7 @@ describe('ResourceComposePage', () => {
398
397
  it('disables form during submission', async () => {
399
398
  const onSaveResource = vi.fn(() => new Promise<void>(resolve => setTimeout(resolve, 100)));
400
399
  const props = createMockProps({ onSaveResource });
401
- render(<ResourceComposePage {...props} />);
400
+ renderWithProviders(<ResourceComposePage {...props} />);
402
401
 
403
402
  const nameInput = screen.getByLabelText('Resource Name');
404
403
  fireEvent.change(nameInput, { target: { value: 'Test Resource' } });
@@ -419,7 +418,7 @@ describe('ResourceComposePage', () => {
419
418
  it('calls onCancel when cancel button clicked', () => {
420
419
  const onCancel = vi.fn();
421
420
  const props = createMockProps({ onCancel });
422
- render(<ResourceComposePage {...props} />);
421
+ renderWithProviders(<ResourceComposePage {...props} />);
423
422
 
424
423
  const cancelButton = screen.getByRole('button', { name: 'Cancel' });
425
424
  fireEvent.click(cancelButton);
@@ -431,7 +430,7 @@ describe('ResourceComposePage', () => {
431
430
  describe('Toolbar Integration', () => {
432
431
  it('renders ToolbarPanels component', () => {
433
432
  const props = createMockProps();
434
- render(<ResourceComposePage {...props} />);
433
+ renderWithProviders(<ResourceComposePage {...props} />);
435
434
 
436
435
  expect(screen.getByTestId('toolbar-panels')).toBeInTheDocument();
437
436
  });
@@ -440,16 +439,14 @@ describe('ResourceComposePage', () => {
440
439
  const ToolbarPanels = vi.fn(() => <div data-testid="toolbar-panels" />);
441
440
  const props = createMockProps({
442
441
  theme: 'dark',
443
- onThemeChange: vi.fn(),
444
442
  ToolbarPanels,
445
443
  });
446
444
 
447
- render(<ResourceComposePage {...props} />);
445
+ renderWithProviders(<ResourceComposePage {...props} />);
448
446
 
449
447
  expect(ToolbarPanels).toHaveBeenCalledWith(
450
448
  expect.objectContaining({
451
449
  theme: 'dark',
452
- onThemeChange: expect.any(Function),
453
450
  }),
454
451
  expect.anything()
455
452
  );
@@ -459,7 +456,7 @@ describe('ResourceComposePage', () => {
459
456
  describe('Code Editor Integration', () => {
460
457
  it('allows editing content', () => {
461
458
  const props = createMockProps();
462
- render(<ResourceComposePage {...props} />);
459
+ renderWithProviders(<ResourceComposePage {...props} />);
463
460
 
464
461
  const editor = screen.getByTestId('code-editor') as HTMLTextAreaElement;
465
462
  fireEvent.change(editor, { target: { value: 'New content' } });
@@ -469,7 +466,7 @@ describe('ResourceComposePage', () => {
469
466
 
470
467
  it('respects showLineNumbers prop', () => {
471
468
  const props = createMockProps({ showLineNumbers: true });
472
- render(<ResourceComposePage {...props} />);
469
+ renderWithProviders(<ResourceComposePage {...props} />);
473
470
 
474
471
  expect(screen.getByTestId('code-editor')).toBeInTheDocument();
475
472
  });
@@ -9,8 +9,9 @@
9
9
  import React, { useState, useEffect } from 'react';
10
10
  import type { components } from '@semiont/api-client';
11
11
  import { isImageMimeType, isPdfMimeType, LOCALES } from '@semiont/api-client';
12
- import { buttonStyles, CodeMirrorRenderer } from '@semiont/react-ui';
13
- import { useFormAnnouncements } from '@semiont/react-ui';
12
+ import { buttonStyles } from '../../../lib/button-styles';
13
+ import { CodeMirrorRenderer } from '../../../components/CodeMirrorRenderer';
14
+ import { useFormAnnouncements } from '../../../components/LiveRegion';
14
15
 
15
16
  type ResourceDescriptor = components['schemas']['ResourceDescriptor'];
16
17
 
@@ -40,11 +41,8 @@ export interface ResourceComposePageProps {
40
41
 
41
42
  // UI state
42
43
  theme: 'light' | 'dark';
43
- onThemeChange: (theme: 'light' | 'dark') => void;
44
44
  showLineNumbers: boolean;
45
- onLineNumbersToggle: () => void;
46
45
  activePanel: string | null;
47
- onPanelToggle: (panel: string) => void;
48
46
 
49
47
  // Actions
50
48
  onSaveResource: (params: SaveResourceParams) => Promise<void>;
@@ -111,11 +109,8 @@ export function ResourceComposePage({
111
109
  availableEntityTypes,
112
110
  initialLocale,
113
111
  theme,
114
- onThemeChange,
115
112
  showLineNumbers,
116
- onLineNumbersToggle,
117
113
  activePanel,
118
- onPanelToggle,
119
114
  onSaveResource,
120
115
  onCancel,
121
116
  translations: t,
@@ -529,12 +524,10 @@ export function ResourceComposePage({
529
524
  <div className="semiont-form__editor-wrapper" lang={selectedLanguage}>
530
525
  <CodeMirrorRenderer
531
526
  content={newResourceContent}
532
- segments={[]}
533
527
  editable={!isCreating}
534
528
  sourceView={true}
535
529
  showLineNumbers={showLineNumbers}
536
530
  onChange={(newContent) => setNewResourceContent(newContent)}
537
- annotators={{}}
538
531
  />
539
532
  </div>
540
533
  </div>
@@ -610,16 +603,13 @@ export function ResourceComposePage({
610
603
  <ToolbarPanels
611
604
  activePanel={activePanel}
612
605
  theme={theme}
613
- onThemeChange={onThemeChange}
614
606
  showLineNumbers={showLineNumbers}
615
- onLineNumbersToggle={onLineNumbersToggle}
616
607
  />
617
608
 
618
609
  {/* Toolbar - Always visible on the right */}
619
610
  <Toolbar
620
611
  context="simple"
621
612
  activePanel={activePanel}
622
- onPanelToggle={onPanelToggle}
623
613
  />
624
614
  </div>
625
615
  </div>
@@ -5,23 +5,11 @@
5
5
  * No Next.js mocking required - all dependencies passed as props!
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, fireEvent, waitFor } from '@testing-library/react';
10
10
  import { ResourceDiscoveryPage } from '../components/ResourceDiscoveryPage';
11
11
  import type { ResourceDiscoveryPageProps } from '../components/ResourceDiscoveryPage';
12
-
13
- // Mock dependencies
14
- vi.mock('@semiont/react-ui', async () => {
15
- const actual = await vi.importActual('@semiont/react-ui');
16
- return {
17
- ...actual,
18
- useRovingTabIndex: () => ({
19
- containerRef: { current: null },
20
- handleKeyDown: vi.fn(),
21
- }),
22
- Toolbar: () => <div data-testid="toolbar">Toolbar</div>,
23
- };
24
- });
12
+ import { EventBusProvider, resetEventBusForTesting } from '../../../contexts/EventBusContext';
25
13
 
26
14
  const createMockResource = (id: string, name: string, entityTypes: string[] = []) => ({
27
15
  '@context': 'https://www.w3.org/ns/anno.jsonld',
@@ -42,11 +30,8 @@ const createMockProps = (overrides?: Partial<ResourceDiscoveryPageProps>): Resou
42
30
  isLoadingRecent: false,
43
31
  isSearching: false,
44
32
  theme: 'light',
45
- onThemeChange: vi.fn(),
46
33
  showLineNumbers: false,
47
- onLineNumbersToggle: vi.fn(),
48
34
  activePanel: null,
49
- onPanelToggle: vi.fn(),
50
35
  onNavigateToResource: vi.fn(),
51
36
  onNavigateToCompose: vi.fn(),
52
37
  translations: {
@@ -71,18 +56,27 @@ const createMockProps = (overrides?: Partial<ResourceDiscoveryPageProps>): Resou
71
56
  ...overrides,
72
57
  });
73
58
 
59
+ // Helper to render with EventBusProvider
60
+ const renderWithProviders = (ui: React.ReactElement) => {
61
+ return render(<EventBusProvider>{ui}</EventBusProvider>);
62
+ };
63
+
74
64
  describe('ResourceDiscoveryPage', () => {
65
+ beforeEach(() => {
66
+ resetEventBusForTesting();
67
+ });
68
+
75
69
  describe('Basic Rendering', () => {
76
70
  it('renders without crashing', () => {
77
71
  const props = createMockProps();
78
- render(<ResourceDiscoveryPage {...props} />);
72
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
79
73
 
80
74
  expect(screen.getByText('Discover Resources')).toBeInTheDocument();
81
75
  });
82
76
 
83
77
  it('displays page title and subtitle', () => {
84
78
  const props = createMockProps();
85
- render(<ResourceDiscoveryPage {...props} />);
79
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
86
80
 
87
81
  expect(screen.getByText('Discover Resources')).toBeInTheDocument();
88
82
  expect(screen.getByText('Search and browse available resources')).toBeInTheDocument();
@@ -90,37 +84,39 @@ describe('ResourceDiscoveryPage', () => {
90
84
 
91
85
  it('renders search input', () => {
92
86
  const props = createMockProps();
93
- render(<ResourceDiscoveryPage {...props} />);
87
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
94
88
 
95
89
  expect(screen.getByPlaceholderText('Search resources...')).toBeInTheDocument();
96
90
  });
97
91
 
98
92
  it('renders search button', () => {
99
93
  const props = createMockProps();
100
- render(<ResourceDiscoveryPage {...props} />);
94
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
101
95
 
102
96
  expect(screen.getByRole('button', { name: 'Search' })).toBeInTheDocument();
103
97
  });
104
98
 
105
99
  it('renders toolbar component', () => {
106
100
  const props = createMockProps();
107
- render(<ResourceDiscoveryPage {...props} />);
101
+ const { container } = renderWithProviders(<ResourceDiscoveryPage {...props} />);
108
102
 
109
- expect(screen.getByTestId('toolbar')).toBeInTheDocument();
103
+ // Toolbar renders with context="simple" - check for toolbar element
104
+ const toolbar = container.querySelector('.semiont-toolbar[data-context="simple"]');
105
+ expect(toolbar).toBeInTheDocument();
110
106
  });
111
107
  });
112
108
 
113
109
  describe('Loading State', () => {
114
110
  it('shows loading message when isLoadingRecent is true', () => {
115
111
  const props = createMockProps({ isLoadingRecent: true });
116
- render(<ResourceDiscoveryPage {...props} />);
112
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
117
113
 
118
114
  expect(screen.getByText('Loading knowledge base...')).toBeInTheDocument();
119
115
  });
120
116
 
121
117
  it('does not show main content when loading', () => {
122
118
  const props = createMockProps({ isLoadingRecent: true });
123
- render(<ResourceDiscoveryPage {...props} />);
119
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
124
120
 
125
121
  expect(screen.queryByText('Discover Resources')).not.toBeInTheDocument();
126
122
  });
@@ -135,7 +131,7 @@ describe('ResourceDiscoveryPage', () => {
135
131
  ];
136
132
 
137
133
  const props = createMockProps({ recentDocuments });
138
- render(<ResourceDiscoveryPage {...props} />);
134
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
139
135
 
140
136
  expect(screen.getByText('Document 1')).toBeInTheDocument();
141
137
  expect(screen.getByText('Document 2')).toBeInTheDocument();
@@ -146,28 +142,28 @@ describe('ResourceDiscoveryPage', () => {
146
142
  const props = createMockProps({
147
143
  recentDocuments: [createMockResource('1', 'Document 1')],
148
144
  });
149
- render(<ResourceDiscoveryPage {...props} />);
145
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
150
146
 
151
147
  expect(screen.getByText('Recent Resources')).toBeInTheDocument();
152
148
  });
153
149
 
154
150
  it('shows empty state when no documents', () => {
155
151
  const props = createMockProps({ recentDocuments: [] });
156
- render(<ResourceDiscoveryPage {...props} />);
152
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
157
153
 
158
154
  expect(screen.getByText('No resources available')).toBeInTheDocument();
159
155
  });
160
156
 
161
157
  it('shows compose button in empty state', () => {
162
158
  const props = createMockProps({ recentDocuments: [] });
163
- render(<ResourceDiscoveryPage {...props} />);
159
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
164
160
 
165
161
  expect(screen.getByRole('button', { name: 'Compose First Resource' })).toBeInTheDocument();
166
162
  });
167
163
 
168
164
  it('calls onNavigateToCompose when compose button clicked', () => {
169
165
  const props = createMockProps({ recentDocuments: [] });
170
- render(<ResourceDiscoveryPage {...props} />);
166
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
171
167
 
172
168
  const button = screen.getByRole('button', { name: 'Compose First Resource' });
173
169
  fireEvent.click(button);
@@ -179,7 +175,7 @@ describe('ResourceDiscoveryPage', () => {
179
175
  describe('Search Functionality', () => {
180
176
  it('allows typing in search input', () => {
181
177
  const props = createMockProps();
182
- render(<ResourceDiscoveryPage {...props} />);
178
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
183
179
 
184
180
  const input = screen.getByPlaceholderText('Search resources...') as HTMLInputElement;
185
181
  fireEvent.change(input, { target: { value: 'test query' } });
@@ -189,14 +185,14 @@ describe('ResourceDiscoveryPage', () => {
189
185
 
190
186
  it('shows "Searching..." when isSearching is true', () => {
191
187
  const props = createMockProps({ isSearching: true });
192
- render(<ResourceDiscoveryPage {...props} />);
188
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
193
189
 
194
190
  expect(screen.getByRole('button', { name: 'Searching...' })).toBeInTheDocument();
195
191
  });
196
192
 
197
193
  it('disables search input when isSearching is true', () => {
198
194
  const props = createMockProps({ isSearching: true });
199
- render(<ResourceDiscoveryPage {...props} />);
195
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
200
196
 
201
197
  const input = screen.getByPlaceholderText('Search resources...') as HTMLInputElement;
202
198
  expect(input).toBeDisabled();
@@ -204,7 +200,7 @@ describe('ResourceDiscoveryPage', () => {
204
200
 
205
201
  it('disables search button when isSearching is true', () => {
206
202
  const props = createMockProps({ isSearching: true });
207
- render(<ResourceDiscoveryPage {...props} />);
203
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
208
204
 
209
205
  const button = screen.getByRole('button', { name: 'Searching...' });
210
206
  expect(button).toBeDisabled();
@@ -217,7 +213,7 @@ describe('ResourceDiscoveryPage', () => {
217
213
  ];
218
214
 
219
215
  const props = createMockProps({ searchDocuments });
220
- render(<ResourceDiscoveryPage {...props} />);
216
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
221
217
 
222
218
  // Type in search input to trigger search state
223
219
  const input = screen.getByPlaceholderText('Search resources...');
@@ -232,7 +228,7 @@ describe('ResourceDiscoveryPage', () => {
232
228
  searchDocuments: [],
233
229
  recentDocuments: [createMockResource('1', 'Recent Doc')],
234
230
  });
235
- render(<ResourceDiscoveryPage {...props} />);
231
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
236
232
 
237
233
  const input = screen.getByPlaceholderText('Search resources...');
238
234
  fireEvent.change(input, { target: { value: 'nonexistent' } });
@@ -248,7 +244,7 @@ describe('ResourceDiscoveryPage', () => {
248
244
  const props = createMockProps({
249
245
  entityTypes: ['Document', 'Article', 'Report'],
250
246
  });
251
- render(<ResourceDiscoveryPage {...props} />);
247
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
252
248
 
253
249
  expect(screen.getByText('Filter by type')).toBeInTheDocument();
254
250
  expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
@@ -266,7 +262,7 @@ describe('ResourceDiscoveryPage', () => {
266
262
  ],
267
263
  entityTypes: ['Document', 'Article'],
268
264
  });
269
- render(<ResourceDiscoveryPage {...props} />);
265
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
270
266
 
271
267
  // Initially all documents shown
272
268
  expect(screen.getByText('Doc 1')).toBeInTheDocument();
@@ -287,7 +283,7 @@ describe('ResourceDiscoveryPage', () => {
287
283
  recentDocuments: [createMockResource('1', 'Doc 1', ['Document'])],
288
284
  entityTypes: ['Document'],
289
285
  });
290
- render(<ResourceDiscoveryPage {...props} />);
286
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
291
287
 
292
288
  const documentButton = screen.getByRole('button', { name: 'Document' });
293
289
  fireEvent.click(documentButton);
@@ -303,7 +299,7 @@ describe('ResourceDiscoveryPage', () => {
303
299
  ],
304
300
  entityTypes: ['Document', 'Article'],
305
301
  });
306
- render(<ResourceDiscoveryPage {...props} />);
302
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
307
303
 
308
304
  // Filter by Document
309
305
  const documentButton = screen.getByRole('button', { name: 'Document' });
@@ -326,7 +322,7 @@ describe('ResourceDiscoveryPage', () => {
326
322
  const props = createMockProps({
327
323
  recentDocuments: [createMockResource('test-123', 'Test Document')],
328
324
  });
329
- render(<ResourceDiscoveryPage {...props} />);
325
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
330
326
 
331
327
  const card = screen.getByRole('button', { name: /Open resource: Test Document/ });
332
328
  fireEvent.click(card);
@@ -338,7 +334,7 @@ describe('ResourceDiscoveryPage', () => {
338
334
  describe('Toolbar Integration', () => {
339
335
  it('renders ToolbarPanels component', () => {
340
336
  const props = createMockProps();
341
- render(<ResourceDiscoveryPage {...props} />);
337
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
342
338
 
343
339
  expect(screen.getByTestId('toolbar-panels')).toBeInTheDocument();
344
340
  });
@@ -347,16 +343,14 @@ describe('ResourceDiscoveryPage', () => {
347
343
  const ToolbarPanels = vi.fn(() => <div data-testid="toolbar-panels" />);
348
344
  const props = createMockProps({
349
345
  theme: 'dark',
350
- onThemeChange: vi.fn(),
351
346
  ToolbarPanels,
352
347
  });
353
348
 
354
- render(<ResourceDiscoveryPage {...props} />);
349
+ renderWithProviders(<ResourceDiscoveryPage {...props} />);
355
350
 
356
351
  expect(ToolbarPanels).toHaveBeenCalledWith(
357
352
  expect.objectContaining({
358
353
  theme: 'dark',
359
- onThemeChange: expect.any(Function),
360
354
  }),
361
355
  expect.anything()
362
356
  );