-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathCustomTree.test.tsx
138 lines (128 loc) · 6.09 KB
/
CustomTree.test.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/* eslint-disable import/no-duplicates */
import { join } from "path";
// __PUBLISH_EXTRACT_START__ Presentation.TreeWidget.CustomTreeExampleImports
import type { ComponentPropsWithoutRef } from "react";
import type { IModelConnection } from "@itwin/core-frontend";
import { Tree, TreeRenderer } from "@itwin/tree-widget-react";
import { createClassBasedHierarchyDefinition, createNodesQueryClauseFactory } from "@itwin/presentation-hierarchies";
import { createBisInstanceLabelSelectClauseFactory } from "@itwin/presentation-shared";
// __PUBLISH_EXTRACT_END__
import sinon from "sinon";
import { UiFramework } from "@itwin/appui-react";
import { IModelReadRpcInterface, SnapshotIModelRpcInterface } from "@itwin/core-common";
import { IModelApp, NoRenderApp } from "@itwin/core-frontend";
import { ECSchemaRpcInterface } from "@itwin/ecschema-rpcinterface-common";
import { ECSchemaRpcImpl } from "@itwin/ecschema-rpcinterface-impl";
import { PresentationRpcInterface } from "@itwin/presentation-common";
import { HierarchyCacheMode, initialize as initializePresentationTesting, terminate as terminatePresentationTesting } from "@itwin/presentation-testing";
import { createStorage } from "@itwin/unified-selection";
import { cleanup, render, waitFor } from "@testing-library/react";
import { buildIModel, insertPhysicalElement, insertPhysicalModelWithPartition, insertSpatialCategory } from "../../utils/IModelUtils";
import { getSchemaContext, getTestViewer, mockGetBoundingClientRect, TestUtils } from "../../utils/TestUtils";
describe("Tree widget", () => {
describe("Learning snippets", () => {
describe("Components", () => {
before(async function () {
await initializePresentationTesting({
backendProps: {
caching: {
hierarchies: {
mode: HierarchyCacheMode.Memory,
},
},
},
testOutputDir: join(__dirname, "output"),
backendHostProps: {
cacheDir: join(__dirname, "cache"),
},
rpcs: [SnapshotIModelRpcInterface, IModelReadRpcInterface, PresentationRpcInterface, ECSchemaRpcInterface],
});
// eslint-disable-next-line @itwin/no-internal
ECSchemaRpcImpl.register();
});
after(async function () {
await terminatePresentationTesting();
});
beforeEach(async () => {
await NoRenderApp.startup();
await TestUtils.initialize();
});
afterEach(async () => {
TestUtils.terminate();
await IModelApp.shutdown();
sinon.restore();
});
it("Renders custom tree", async function () {
const imodelConnection = (
await buildIModel(this, async (builder) => {
const physicalModel = insertPhysicalModelWithPartition({ builder, codeValue: "TestPhysicalModel" });
const category = insertSpatialCategory({ builder, codeValue: "Test SpatialCategory" });
insertPhysicalElement({ builder, modelId: physicalModel.id, categoryId: category.id });
return { category };
})
).imodel;
const testViewport = getTestViewer(imodelConnection);
const unifiedSelectionStorage = createStorage();
sinon.stub(IModelApp.viewManager, "selectedView").get(() => testViewport);
sinon.stub(UiFramework, "getIModelConnection").returns(imodelConnection);
mockGetBoundingClientRect();
// __PUBLISH_EXTRACT_START__ Presentation.TreeWidget.CustomTreeExample
type TreeProps = ComponentPropsWithoutRef<typeof Tree>;
const getHierarchyDefinition: TreeProps["getHierarchyDefinition"] = ({ imodelAccess }) => {
// create a hierarchy definition that defines what should be shown in the tree
// see https://github.com/iTwin/presentation/blob/master/packages/hierarchies/README.md#hierarchy-definition
const nodesQueryFactory = createNodesQueryClauseFactory({ imodelAccess });
const labelsQueryFactory = createBisInstanceLabelSelectClauseFactory({ classHierarchyInspector: imodelAccess });
return createClassBasedHierarchyDefinition({
classHierarchyInspector: imodelAccess,
hierarchy: {
// For root nodes, select all BisCore.GeometricModel3d instances
rootNodes: async () => [
{
fullClassName: "BisCore.GeometricModel3d",
query: {
ecsql: `
SELECT
${await nodesQueryFactory.createSelectClause({
ecClassId: { selector: "this.ECClassId" },
ecInstanceId: { selector: "this.ECInstanceId" },
nodeLabel: {
selector: await labelsQueryFactory.createSelectClause({ classAlias: "this", className: "BisCore.GeometricModel3d" }),
},
})}
FROM BisCore.GeometricModel3d this
`,
},
},
],
childNodes: [],
},
});
};
interface MyTreeProps {
imodel: IModelConnection;
}
function MyTree({ imodel }: MyTreeProps) {
return (
<Tree
treeName="MyTree"
imodel={imodel}
selectionStorage={unifiedSelectionStorage}
getSchemaContext={getSchemaContext}
getHierarchyDefinition={getHierarchyDefinition}
treeRenderer={(props) => <TreeRenderer {...props} />}
/>
);
}
// __PUBLISH_EXTRACT_END__
const result = render(<MyTree imodel={imodelConnection} />);
await waitFor(() => result.getByText("TestPhysicalModel"));
cleanup();
});
});
});
});