Skip to content

Commit ce48020

Browse files
committed
feat(dyn catalog): schema migration to async
1 parent 9914e63 commit ce48020

40 files changed

Lines changed: 1470 additions & 339 deletions

packages/ui/src/components/Visualization/Canvas/Form/CanvasForm.test.tsx

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,12 @@ import {
99
CamelRouteVisualEntity,
1010
CatalogKind,
1111
createVisualizationNode,
12-
ICamelComponentDefinition,
13-
ICamelProcessorDefinition,
14-
IKameletDefinition,
1512
KameletVisualEntity,
1613
KaotoSchemaDefinition,
1714
} from '../../../../models';
1815
import { EntityType } from '../../../../models/entities';
1916
import { IVisualizationNode } from '../../../../models/visualization/base-visual-entity';
17+
import { setupDynamicCatalogRegistryMock } from '../../../../models/visualization/flows/dynamic-catalog-registry-mock';
2018
import { VisualFlowsApi } from '../../../../models/visualization/flows/support/flows-visibility';
2119
import { VisibleFlowsContext, VisibleFlowsProvider } from '../../../../providers';
2220
import { EntitiesContext, EntitiesProvider } from '../../../../providers/entities.provider';
@@ -27,27 +25,18 @@ import { CanvasNode } from '../canvas.models';
2725
import { FlowService } from '../flow.service';
2826
import { CanvasForm } from './CanvasForm';
2927

28+
jest.mock('../../../../dynamic-catalog/dynamic-catalog-registry');
29+
3030
describe('CanvasForm', () => {
3131
let camelRouteVisualEntity: CamelRouteVisualEntity;
3232
let selectedNode: CanvasNode;
33-
let componentCatalogMap: Record<string, ICamelComponentDefinition>;
34-
let patternCatalogMap: Record<string, ICamelProcessorDefinition>;
35-
let kameletCatalogMap: Record<string, IKameletDefinition>;
3633

3734
beforeAll(async () => {
3835
const catalogsMap = await getFirstCatalogMap(catalogLibrary as CatalogLibrary);
39-
componentCatalogMap = catalogsMap.componentCatalogMap;
40-
patternCatalogMap = catalogsMap.patternCatalogMap;
41-
kameletCatalogMap = catalogsMap.kameletsCatalogMap;
42-
43-
CamelCatalogService.setCatalogKey(CatalogKind.Component, componentCatalogMap);
44-
CamelCatalogService.setCatalogKey(CatalogKind.Pattern, patternCatalogMap);
45-
CamelCatalogService.setCatalogKey(CatalogKind.Kamelet, kameletCatalogMap);
46-
CamelCatalogService.setCatalogKey(CatalogKind.Processor, catalogsMap.modelCatalogMap);
36+
37+
setupDynamicCatalogRegistryMock(catalogsMap);
38+
4739
CamelCatalogService.setCatalogKey(CatalogKind.Language, catalogsMap.languageCatalog);
48-
CamelCatalogService.setCatalogKey(CatalogKind.Dataformat, catalogsMap.dataformatCatalog);
49-
CamelCatalogService.setCatalogKey(CatalogKind.Loadbalancer, catalogsMap.loadbalancerCatalog);
50-
CamelCatalogService.setCatalogKey(CatalogKind.Entity, catalogsMap.entitiesCatalog);
5140
});
5241

5342
beforeEach(async () => {
@@ -125,7 +114,7 @@ describe('CanvasForm', () => {
125114
},
126115
};
127116

128-
jest.spyOn(vizNode, 'getNodeSchema').mockReturnValue(undefined);
117+
jest.spyOn(vizNode, 'getNodeSchema').mockResolvedValue(undefined);
129118
jest.spyOn(vizNode, 'getNodeDefinition').mockReturnValue(undefined);
130119

131120
const { container } = await act(async () =>
@@ -166,7 +155,7 @@ describe('CanvasForm', () => {
166155
},
167156
};
168157

169-
jest.spyOn(vizNode, 'getNodeSchema').mockReturnValue(null as unknown as KaotoSchemaDefinition['schema']);
158+
jest.spyOn(vizNode, 'getNodeSchema').mockResolvedValue(null as unknown as KaotoSchemaDefinition['schema']);
170159
jest.spyOn(vizNode, 'getNodeDefinition').mockReturnValue(null);
171160

172161
const { container } = await act(async () =>

packages/ui/src/components/Visualization/Canvas/Form/CanvasFormBody.test.tsx

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,39 @@ import catalogLibrary from '@kaoto/camel-catalog/index.json';
22
import { CatalogLibrary, RouteDefinition } from '@kaoto/camel-catalog/types';
33
import { CanvasFormTabsContext, SuggestionRegistryProvider } from '@kaoto/forms';
44
import { KaotoFormPageObject } from '@kaoto/forms/testing';
5-
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
6-
7-
import {
8-
CamelCatalogService,
9-
CamelRouteVisualEntity,
10-
CatalogKind,
11-
ICamelComponentDefinition,
12-
ICamelProcessorDefinition,
13-
IKameletDefinition,
14-
} from '../../../../models';
5+
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
6+
7+
import { CamelCatalogService, CamelRouteVisualEntity, CatalogKind } from '../../../../models';
158
import { IVisualizationNode } from '../../../../models/visualization/base-visual-entity';
9+
import { setupDynamicCatalogRegistryMock } from '../../../../models/visualization/flows/dynamic-catalog-registry-mock';
1610
import { VisibleFlowsProvider } from '../../../../providers';
1711
import { EntitiesContext } from '../../../../providers/entities.provider';
1812
import { TestProvidersWrapper } from '../../../../stubs';
1913
import { getFirstCatalogMap } from '../../../../stubs/test-load-catalog';
2014
import { ROOT_PATH } from '../../../../utils';
2115
import { CanvasFormBody } from './CanvasFormBody';
2216

23-
describe('CanvasFormBody', () => {
24-
let componentCatalogMap: Record<string, ICamelComponentDefinition>;
25-
let patternCatalogMap: Record<string, ICamelProcessorDefinition>;
26-
let kameletCatalogMap: Record<string, IKameletDefinition>;
17+
jest.mock('../../../../dynamic-catalog/dynamic-catalog-registry');
2718

19+
describe('CanvasFormBody', () => {
2820
beforeAll(async () => {
2921
const catalogsMap = await getFirstCatalogMap(catalogLibrary as CatalogLibrary);
30-
componentCatalogMap = catalogsMap.componentCatalogMap;
31-
patternCatalogMap = catalogsMap.patternCatalogMap;
32-
kameletCatalogMap = catalogsMap.kameletsCatalogMap;
33-
34-
CamelCatalogService.setCatalogKey(CatalogKind.Component, componentCatalogMap);
35-
CamelCatalogService.setCatalogKey(CatalogKind.Pattern, patternCatalogMap);
36-
CamelCatalogService.setCatalogKey(CatalogKind.Kamelet, kameletCatalogMap);
37-
CamelCatalogService.setCatalogKey(CatalogKind.Processor, catalogsMap.modelCatalogMap);
22+
23+
setupDynamicCatalogRegistryMock(catalogsMap);
24+
3825
CamelCatalogService.setCatalogKey(CatalogKind.Language, catalogsMap.languageCatalog);
39-
CamelCatalogService.setCatalogKey(CatalogKind.Dataformat, catalogsMap.dataformatCatalog);
40-
CamelCatalogService.setCatalogKey(CatalogKind.Loadbalancer, catalogsMap.loadbalancerCatalog);
41-
CamelCatalogService.setCatalogKey(CatalogKind.Entity, catalogsMap.entitiesCatalog);
4226
});
4327

4428
describe('should persists changes from both expression editor and main form', () => {
4529
beforeEach(() => {
4630
jest.spyOn(console, 'error').mockImplementation(() => {});
4731
});
4832

33+
afterEach(() => {
34+
cleanup();
35+
jest.restoreAllMocks();
36+
});
37+
4938
it('expression => main form', async () => {
5039
const camelRoute = {
5140
from: {
@@ -83,6 +72,14 @@ describe('CanvasFormBody', () => {
8372
</EntitiesContext.Provider>,
8473
);
8574

75+
// Wait for async schema to load and form to render
76+
await waitFor(
77+
() => {
78+
expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
79+
},
80+
{ timeout: 5000 },
81+
);
82+
8683
const formPageObject = new KaotoFormPageObject(screen, act);
8784
await formPageObject.showAllFields();
8885
await formPageObject.toggleExpressionFieldForProperty(ROOT_PATH);
@@ -137,6 +134,14 @@ describe('CanvasFormBody', () => {
137134
</EntitiesContext.Provider>,
138135
);
139136

137+
// Wait for async schema to load and form to render
138+
await waitFor(
139+
() => {
140+
expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
141+
},
142+
{ timeout: 5000 },
143+
);
144+
140145
const formPageObject = new KaotoFormPageObject(screen, act);
141146
await formPageObject.showAllFields();
142147
await formPageObject.inputText('Name', 'bar');
@@ -159,6 +164,11 @@ describe('CanvasFormBody', () => {
159164
jest.spyOn(console, 'error').mockImplementation(() => {});
160165
});
161166

167+
afterEach(() => {
168+
cleanup();
169+
jest.restoreAllMocks();
170+
});
171+
162172
it('dataformat => main form', async () => {
163173
const camelRoute = {
164174
from: {
@@ -196,6 +206,14 @@ describe('CanvasFormBody', () => {
196206
</EntitiesContext.Provider>,
197207
);
198208

209+
// Wait for async schema to load and form to render
210+
await waitFor(
211+
() => {
212+
expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
213+
},
214+
{ timeout: 5000 },
215+
);
216+
199217
const formPageObject = new KaotoFormPageObject(screen, act);
200218
await formPageObject.showAllFields();
201219
await formPageObject.toggleOneOfFieldForProperty(ROOT_PATH);
@@ -247,6 +265,14 @@ describe('CanvasFormBody', () => {
247265
</EntitiesContext.Provider>,
248266
);
249267

268+
// Wait for async schema to load and form to render
269+
await waitFor(
270+
() => {
271+
expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
272+
},
273+
{ timeout: 5000 },
274+
);
275+
250276
const formPageObject = new KaotoFormPageObject(screen, act);
251277
await formPageObject.showAllFields();
252278
await formPageObject.inputText('Id', 'modified', { index: 0 });
@@ -266,6 +292,11 @@ describe('CanvasFormBody', () => {
266292
jest.spyOn(console, 'error').mockImplementation(() => {});
267293
});
268294

295+
afterEach(() => {
296+
cleanup();
297+
jest.restoreAllMocks();
298+
});
299+
269300
it('loadbalancer => main form', async () => {
270301
const camelRoute = {
271302
from: {
@@ -303,6 +334,14 @@ describe('CanvasFormBody', () => {
303334
</EntitiesContext.Provider>,
304335
);
305336

337+
// Wait for async schema to load and form to render
338+
await waitFor(
339+
() => {
340+
expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
341+
},
342+
{ timeout: 5000 },
343+
);
344+
306345
const formPageObject = new KaotoFormPageObject(screen, act);
307346
await formPageObject.showAllFields();
308347
await formPageObject.toggleOneOfFieldForProperty(ROOT_PATH);
@@ -354,6 +393,14 @@ describe('CanvasFormBody', () => {
354393
</EntitiesContext.Provider>,
355394
);
356395

396+
// Wait for async schema to load and form to render
397+
await waitFor(
398+
() => {
399+
expect(screen.getByRole('button', { name: 'All' })).toBeInTheDocument();
400+
},
401+
{ timeout: 5000 },
402+
);
403+
357404
const formPageObject = new KaotoFormPageObject(screen, act);
358405
await formPageObject.showAllFields();
359406
await formPageObject.inputText('Id', 'modified', { index: 0 });
@@ -371,7 +418,7 @@ describe('CanvasFormBody', () => {
371418
it('should show suggestions', async () => {
372419
const { Provider, camelResource } = TestProvidersWrapper();
373420
const vizNode = await camelResource.getVisualEntities()[0].toVizNode();
374-
jest.spyOn(vizNode, 'getNodeSchema').mockReturnValue({
421+
jest.spyOn(vizNode, 'getNodeSchema').mockResolvedValue({
375422
type: 'object',
376423
properties: {
377424
name: {
@@ -395,6 +442,11 @@ describe('CanvasFormBody', () => {
395442
</Provider>,
396443
);
397444

445+
// Wait for async schema to load
446+
await waitFor(() => {
447+
expect(screen.queryByRole('button', { name: 'All' })).toBeInTheDocument();
448+
});
449+
398450
const formPageObject = new KaotoFormPageObject(screen, act);
399451
const inputField = formPageObject.getFieldByDisplayName('Name')!;
400452

packages/ui/src/components/Visualization/Canvas/Form/CanvasFormBody.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { isDefined, KaotoForm } from '@kaoto/forms';
2-
import { FunctionComponent, useCallback, useContext, useMemo, useRef } from 'react';
2+
import { FunctionComponent, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
33

44
import { IVisualizationNode } from '../../../../models';
55
import { EntitiesContext } from '../../../../providers/entities.provider';
@@ -15,7 +15,21 @@ interface CanvasFormTabsProps {
1515
export const CanvasFormBody: FunctionComponent<CanvasFormTabsProps> = ({ vizNode }) => {
1616
const entitiesContext = useContext(EntitiesContext);
1717
const omitFields = useRef(vizNode.getOmitFormFields() ?? []);
18-
const schema = useMemo(() => vizNode.getNodeSchema(), [vizNode]);
18+
const [schema, setSchema] = useState<Record<string, unknown> | undefined>(undefined);
19+
20+
useEffect(() => {
21+
let cancelled = false;
22+
23+
vizNode.getNodeSchema().then((loadedSchema) => {
24+
if (!cancelled) {
25+
setSchema(loadedSchema);
26+
}
27+
});
28+
29+
return () => {
30+
cancelled = true;
31+
};
32+
}, [vizNode]);
1933

2034
const isUnknownComponent = useMemo(() => {
2135
return !isDefined(schema) || Object.keys(schema).length === 0;

packages/ui/src/components/Visualization/Canvas/Form/__snapshots__/CanvasForm.test.tsx.snap

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ exports[`CanvasForm should render 1`] = `
2222
class="pf-v6-l-grid__item pf-m-11-col form-header"
2323
>
2424
<img
25-
alt="choice"
25+
alt="Choice"
2626
class="form-header__icon-test|route.from.steps.1.choice"
2727
src="file-mock-data"
2828
/>
@@ -32,7 +32,7 @@ exports[`CanvasForm should render 1`] = `
3232
data-ouia-component-type="PF6/Title"
3333
data-ouia-safe="true"
3434
>
35-
choice
35+
Choice
3636
</h2>
3737
</div>
3838
<div
@@ -171,7 +171,7 @@ exports[`CanvasForm should render 1`] = `
171171
/>
172172
<div
173173
class="pf-v6-c-card kaoto-form kaoto-form__empty"
174-
data-ouia-component-id="OUIA-Generated-Card-2"
174+
data-ouia-component-id="OUIA-Generated-Card-3"
175175
data-ouia-component-type="PF6/Card"
176176
data-ouia-safe="true"
177177
data-testid="no-field-found"
@@ -248,7 +248,7 @@ exports[`CanvasForm should render nothing if no schema and no definition is avai
248248
<div>
249249
<div
250250
class="pf-v6-c-card canvas-form"
251-
data-ouia-component-id="OUIA-Generated-Card-5"
251+
data-ouia-component-id="OUIA-Generated-Card-6"
252252
data-ouia-component-type="PF6/Card"
253253
data-ouia-safe="true"
254254
id=""
@@ -410,7 +410,7 @@ exports[`CanvasForm should render nothing if no schema and no definition is avai
410410
>
411411
<div
412412
class="pf-v6-c-card"
413-
data-ouia-component-id="OUIA-Generated-Card-6"
413+
data-ouia-component-id="OUIA-Generated-Card-7"
414414
data-ouia-component-type="PF6/Card"
415415
data-ouia-safe="true"
416416
id=""
@@ -459,7 +459,7 @@ exports[`CanvasForm should render nothing if no schema and no definition is avai
459459
>
460460
<div
461461
class="pf-v6-c-alert pf-m-warning"
462-
data-ouia-component-id="OUIA-Generated-Alert-warning-2"
462+
data-ouia-component-id="OUIA-Generated-Alert-warning-3"
463463
data-ouia-component-type="PF6/Alert"
464464
data-ouia-safe="true"
465465
>
@@ -507,7 +507,7 @@ exports[`CanvasForm should render nothing if no schema is available 1`] = `
507507
<div>
508508
<div
509509
class="pf-v6-c-card canvas-form"
510-
data-ouia-component-id="OUIA-Generated-Card-3"
510+
data-ouia-component-id="OUIA-Generated-Card-4"
511511
data-ouia-component-type="PF6/Card"
512512
data-ouia-safe="true"
513513
id=""
@@ -669,7 +669,7 @@ exports[`CanvasForm should render nothing if no schema is available 1`] = `
669669
>
670670
<div
671671
class="pf-v6-c-card"
672-
data-ouia-component-id="OUIA-Generated-Card-4"
672+
data-ouia-component-id="OUIA-Generated-Card-5"
673673
data-ouia-component-type="PF6/Card"
674674
data-ouia-safe="true"
675675
id=""
@@ -715,7 +715,7 @@ exports[`CanvasForm should render nothing if no schema is available 1`] = `
715715
>
716716
<div
717717
class="pf-v6-c-alert pf-m-warning"
718-
data-ouia-component-id="OUIA-Generated-Alert-warning-1"
718+
data-ouia-component-id="OUIA-Generated-Alert-warning-2"
719719
data-ouia-component-type="PF6/Alert"
720720
data-ouia-safe="true"
721721
>

0 commit comments

Comments
 (0)