@truedat/bg 7.10.3 → 7.11.0
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.
- package/package.json +3 -3
- package/src/concepts/api.js +2 -0
- package/src/concepts/components/ConceptLinksUploadButton.js +0 -4
- package/src/concepts/components/ConceptRoutes.js +28 -46
- package/src/concepts/components/ConceptSuggestions.js +71 -0
- package/src/concepts/components/__tests__/ConceptRoutes.spec.js +201 -0
- package/src/concepts/components/__tests__/ConceptSuggestions.spec.js +74 -0
- package/src/concepts/components/__tests__/__snapshots__/ConceptRoutes.spec.js.snap +165 -0
- package/src/concepts/hooks/useConcepts.js +7 -0
- package/src/concepts/relations/api.js +9 -1
- package/src/concepts/relations/components/ConceptLinksApprovalResults.js +91 -0
- package/src/concepts/relations/components/ConceptLinksApprovals.js +225 -0
- package/src/concepts/relations/components/ConceptLinksApprovalsLabelResults.js +42 -0
- package/src/concepts/relations/components/ConceptLinksApprovalsRow.js +43 -0
- package/src/concepts/relations/components/ConceptLinksApprovalsTable.js +104 -0
- package/src/concepts/relations/components/ConceptSelector.js +117 -75
- package/src/concepts/relations/components/__tests__/ConceptLinksApprovalResults.spec.js +123 -0
- package/src/concepts/relations/components/__tests__/ConceptLinksApprovals.spec.js +77 -0
- package/src/concepts/relations/components/__tests__/ConceptLinksApprovalsLabelResults.spec.js +47 -0
- package/src/concepts/relations/components/__tests__/ConceptLinksApprovalsRow.spec.js +68 -0
- package/src/concepts/relations/components/__tests__/ConceptLinksApprovalsTable.spec.js +107 -0
- package/src/concepts/relations/components/__tests__/ConceptSelector.spec.js +90 -1
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalResults.spec.js.snap +217 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovals.spec.js.snap +559 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalsLabelResults.spec.js.snap +34 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalsRow.spec.js.snap +47 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalsTable.spec.js.snap +132 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptSelector.spec.js.snap +99 -0
- package/src/concepts/relations/hooks/useLinks.js +25 -0
- package/src/concepts/relations/sagas/linkConcept.js +1 -0
- package/src/concepts/relations/selectors/getLinksSearchColumns.js +106 -0
- package/src/concepts/relations/selectors/index.js +2 -0
- package/src/concepts/relations/styles/ConceptLinksApprovals.less +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/bg",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.11.0",
|
|
4
4
|
"description": "Truedat Web Business Glossary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@testing-library/jest-dom": "^6.6.3",
|
|
49
49
|
"@testing-library/react": "^16.3.0",
|
|
50
50
|
"@testing-library/user-event": "^14.6.1",
|
|
51
|
-
"@truedat/test": "7.
|
|
51
|
+
"@truedat/test": "7.11.0",
|
|
52
52
|
"identity-obj-proxy": "^3.0.0",
|
|
53
53
|
"jest": "^29.7.0",
|
|
54
54
|
"redux-saga-test-plan": "^4.0.6"
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"semantic-ui-react": "^3.0.0-beta.2",
|
|
82
82
|
"swr": "^2.3.3"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "c8c0d3e62835df86440869c7b797bbe2fc12f3a6"
|
|
85
85
|
}
|
package/src/concepts/api.js
CHANGED
|
@@ -20,8 +20,10 @@ const API_BUSINESS_CONCEPT_BULK_UPLOAD =
|
|
|
20
20
|
"/api/business_concepts/bulk_upload_event";
|
|
21
21
|
const API_BUSINESS_CONCEPT_SET_CONFIDENTIAL =
|
|
22
22
|
"/api/business_concept_versions/:id/set_confidential";
|
|
23
|
+
const API_CONCEPT_SUGGESTIONS = "/api/business_concept_versions/suggestions"
|
|
23
24
|
|
|
24
25
|
export {
|
|
26
|
+
API_CONCEPT_SUGGESTIONS,
|
|
25
27
|
API_BUSINESS_CONCEPT_VERSION,
|
|
26
28
|
API_BUSINESS_CONCEPT_VERSIONS_ACTIONS,
|
|
27
29
|
API_BUSINESS_CONCEPT_VERSIONS_CSV,
|
|
@@ -38,18 +38,14 @@ export const ConceptLinksUploadButton = () => {
|
|
|
38
38
|
triggerUpload(data)
|
|
39
39
|
.then(({ status, data }) => {
|
|
40
40
|
const alertMessage = getUploadAlertMessage({ status, data });
|
|
41
|
-
console.log("alertMessage --->", alertMessage);
|
|
42
41
|
setAlertMessage(alertMessage);
|
|
43
42
|
})
|
|
44
43
|
.catch((error) => {
|
|
45
|
-
console.log("error --->", error);
|
|
46
44
|
if (error.response) {
|
|
47
45
|
const { status, data } = error.response;
|
|
48
46
|
const alertMessage = getUploadAlertMessage({ status, data });
|
|
49
|
-
console.log("error response alertMessage --->", alertMessage);
|
|
50
47
|
setAlertMessage(alertMessage);
|
|
51
48
|
} else {
|
|
52
|
-
console.log("error.message --->", error.message);
|
|
53
49
|
setAlertMessage(error.message);
|
|
54
50
|
}
|
|
55
51
|
});
|
|
@@ -4,8 +4,7 @@ import PropTypes from "prop-types";
|
|
|
4
4
|
import { Route, useParams, Routes } from "react-router";
|
|
5
5
|
import { connect } from "react-redux";
|
|
6
6
|
import { ProtectedRoute } from "@truedat/core/router";
|
|
7
|
-
|
|
8
|
-
// import { useAuthorized } from "@truedat/core/hooks";
|
|
7
|
+
|
|
9
8
|
import {
|
|
10
9
|
CONCEPT_EDIT,
|
|
11
10
|
CONCEPT_LINKS_MANAGEMENT,
|
|
@@ -25,6 +24,8 @@ import {
|
|
|
25
24
|
} from "@truedat/core/routes";
|
|
26
25
|
import { useIntl } from "react-intl";
|
|
27
26
|
import { getSidemenuGlossarySubscopes } from "@truedat/core/selectors/getSidemenuGlossarySubscopes";
|
|
27
|
+
import { SearchContextProvider } from "@truedat/core/search/SearchContext";
|
|
28
|
+
import { useLinksSearch, useLinksFilters } from "../relations/hooks/useLinks";
|
|
28
29
|
import Concept from "./Concept";
|
|
29
30
|
import ConceptCrumbs from "./ConceptCrumbs";
|
|
30
31
|
import ConceptEdit from "./ConceptEdit";
|
|
@@ -36,6 +37,8 @@ import ConceptsBulkUpdate from "./ConceptsBulkUpdate";
|
|
|
36
37
|
|
|
37
38
|
import ConceptSubscriptionLoader from "./ConceptSubscriptionLoader";
|
|
38
39
|
import ConceptsUploadEvents from "./ConceptsUploadEvents";
|
|
40
|
+
import ConceptLinksApprovals from "../relations/components/ConceptLinksApprovals";
|
|
41
|
+
import ConceptLinksApprovalResults from "../relations/components/ConceptLinksApprovalResults";
|
|
39
42
|
|
|
40
43
|
const RelationTagsLoader = React.lazy(
|
|
41
44
|
() => import("@truedat/lm/components/RelationTagsLoader")
|
|
@@ -85,13 +88,6 @@ const ConceptRoutes = ({
|
|
|
85
88
|
sidemenuGlossarySubscopes,
|
|
86
89
|
}) => {
|
|
87
90
|
const { formatMessage } = useIntl();
|
|
88
|
-
// const authorized = useAuthorized([
|
|
89
|
-
// "business_glossary_view",
|
|
90
|
-
// "business_glossary_management",
|
|
91
|
-
// ]);
|
|
92
|
-
// if (!authorized) {
|
|
93
|
-
// return <Unauthorized />;
|
|
94
|
-
// }
|
|
95
91
|
|
|
96
92
|
return (
|
|
97
93
|
<Routes>
|
|
@@ -181,6 +177,29 @@ const ConceptRoutes = ({
|
|
|
181
177
|
element={<ConceptsUploadEvents />}
|
|
182
178
|
/>
|
|
183
179
|
|
|
180
|
+
<Route
|
|
181
|
+
path="approvals/results"
|
|
182
|
+
element={<ConceptLinksApprovalResults />}
|
|
183
|
+
/>
|
|
184
|
+
|
|
185
|
+
<Route
|
|
186
|
+
path="approvals"
|
|
187
|
+
element={
|
|
188
|
+
<>
|
|
189
|
+
<SearchContextProvider
|
|
190
|
+
initialSortColumn="updated_at"
|
|
191
|
+
initialSortDirection="ascending"
|
|
192
|
+
useSearch={useLinksSearch}
|
|
193
|
+
useFilters={useLinksFilters}
|
|
194
|
+
pageSize={20}
|
|
195
|
+
defaultFilters={{ status: ["pending"] }}
|
|
196
|
+
>
|
|
197
|
+
<ConceptLinksApprovals />
|
|
198
|
+
</SearchContextProvider>
|
|
199
|
+
</>
|
|
200
|
+
}
|
|
201
|
+
/>
|
|
202
|
+
|
|
184
203
|
<Route
|
|
185
204
|
// CONCEPT_LINKS_MANAGEMENT = "/concepts/management/links";
|
|
186
205
|
path="links"
|
|
@@ -251,43 +270,6 @@ const ConceptRoutes = ({
|
|
|
251
270
|
/>
|
|
252
271
|
</Route>
|
|
253
272
|
|
|
254
|
-
{/* <Route
|
|
255
|
-
path={CONCEPTS_NEW}
|
|
256
|
-
element={
|
|
257
|
-
<>
|
|
258
|
-
<ConceptCrumbs conceptAction="concepts.actions.create" />
|
|
259
|
-
<ConceptCreate />
|
|
260
|
-
</>
|
|
261
|
-
}
|
|
262
|
-
/> */}
|
|
263
|
-
|
|
264
|
-
<Route path="glossaryManagement">
|
|
265
|
-
<Route
|
|
266
|
-
// CONCEPTS_SIDEMENU_MANAGEMENT_UPLOADS = "/glossaryManagement/uploads";
|
|
267
|
-
path="uploads"
|
|
268
|
-
element={<ConceptsUploadEvents />}
|
|
269
|
-
/>
|
|
270
|
-
<Route
|
|
271
|
-
// CONCEPTS_SIDEMENU_MANAGEMENT_LINKS = "/glossaryManagement/links";
|
|
272
|
-
path="links"
|
|
273
|
-
element={
|
|
274
|
-
<>
|
|
275
|
-
<RelationTagsLoader />
|
|
276
|
-
<ConceptsLinksManagement
|
|
277
|
-
header={formatMessage({ id: "concepts.header.linksManager" })}
|
|
278
|
-
subheader={formatMessage({
|
|
279
|
-
id: "concepts.subheader.linksManager",
|
|
280
|
-
})}
|
|
281
|
-
icon={formatMessage({
|
|
282
|
-
id: "concepts.header.linksManager.icon",
|
|
283
|
-
defaultMessage: "linkify",
|
|
284
|
-
})}
|
|
285
|
-
/>
|
|
286
|
-
</>
|
|
287
|
-
}
|
|
288
|
-
/>
|
|
289
|
-
</Route>
|
|
290
|
-
|
|
291
273
|
<Route path="glossarySubscope">
|
|
292
274
|
<Route
|
|
293
275
|
// CONCEPTS_SIDEMENU_SUBSCOPE = "/glossarySubscope/:subscope/published";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useEffect } from "react";
|
|
3
|
+
import { Popup } from "semantic-ui-react";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { useParams } from "react-router";
|
|
6
|
+
import { useSelector } from "react-redux";
|
|
7
|
+
import PropTypes from "prop-types";
|
|
8
|
+
import { useConceptSuggestions } from "../hooks/useConcepts";
|
|
9
|
+
import { ConceptSelectorTable } from "../relations/components/ConceptSelector";
|
|
10
|
+
|
|
11
|
+
const SimilarityColumn = (similarity) => {
|
|
12
|
+
const { formatMessage } = useIntl();
|
|
13
|
+
return (
|
|
14
|
+
<Popup
|
|
15
|
+
content={formatMessage({ id: "suggestions.similarity.cosine.popup" })}
|
|
16
|
+
trigger={<span>{similarity.toFixed(3)}</span>}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const similarityColumnDefinition = {
|
|
22
|
+
name: "similarity",
|
|
23
|
+
fieldSelector: _.prop("similarity"),
|
|
24
|
+
fieldDecorator: SimilarityColumn,
|
|
25
|
+
width: 1,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const ConceptSuggestions = ({
|
|
29
|
+
selectedConcept,
|
|
30
|
+
handleConceptSelected,
|
|
31
|
+
}) => {
|
|
32
|
+
const { id } = useParams();
|
|
33
|
+
const structureLinks = useSelector((state) => state.structureLinks);
|
|
34
|
+
|
|
35
|
+
const {
|
|
36
|
+
trigger: fetchSuggestions,
|
|
37
|
+
data,
|
|
38
|
+
} = useConceptSuggestions();
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (id && structureLinks) {
|
|
42
|
+
fetchSuggestions({
|
|
43
|
+
resource: {
|
|
44
|
+
id,
|
|
45
|
+
type: "structures",
|
|
46
|
+
links: _.filter(
|
|
47
|
+
({ resource_type }) => resource_type == "concept"
|
|
48
|
+
)(structureLinks),
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}, [id, structureLinks]);
|
|
53
|
+
|
|
54
|
+
const concepts = data?.data?.data || [];
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<ConceptSelectorTable
|
|
58
|
+
concepts={concepts}
|
|
59
|
+
selectedConcept={selectedConcept}
|
|
60
|
+
handleConceptSelected={handleConceptSelected}
|
|
61
|
+
extraColumns={[similarityColumnDefinition]}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
ConceptSuggestions.propTypes = {
|
|
67
|
+
handleSelectedStructure: PropTypes.func,
|
|
68
|
+
selectedStructure: PropTypes.object,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default ConceptSuggestions;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
+
import { useAuthorized } from "@truedat/core/hooks/useAuthorized";
|
|
4
|
+
import {
|
|
5
|
+
CONCEPTS,
|
|
6
|
+
CONCEPTS_PENDING,
|
|
7
|
+
CONCEPTS_DEPRECATED,
|
|
8
|
+
CONCEPTS_NEW,
|
|
9
|
+
CONCEPTS_BULK_UPDATE,
|
|
10
|
+
CONCEPTS_BULK_UPLOAD_EVENTS,
|
|
11
|
+
CONCEPT_LINKS_MANAGEMENT,
|
|
12
|
+
CONCEPT_VERSION,
|
|
13
|
+
CONCEPT_EDIT,
|
|
14
|
+
CONCEPTS_SUBSCOPE,
|
|
15
|
+
CONCEPTS_SIDEMENU_SUBSCOPE,
|
|
16
|
+
CONCEPTS_SIDEMENU_SUBSCOPE_PENDING,
|
|
17
|
+
CONCEPTS_SIDEMENU_SUBSCOPE_DEPRECATED,
|
|
18
|
+
} from "@truedat/core/routes";
|
|
19
|
+
import ConceptRoutes from "../ConceptRoutes";
|
|
20
|
+
|
|
21
|
+
jest.mock("@truedat/core/hooks/useAuthorized", () => ({
|
|
22
|
+
useAuthorized: jest.fn(() => true),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
jest.mock("../Concept", () => () => <div>Concept</div>);
|
|
26
|
+
jest.mock("../ConceptCrumbs", () => () => <div>ConceptCrumbs</div>);
|
|
27
|
+
jest.mock("../ConceptEdit", () => () => <div>ConceptEdit</div>);
|
|
28
|
+
jest.mock("../ConceptCreate", () => () => <div>ConceptCreate</div>);
|
|
29
|
+
jest.mock("../ConceptsLinksManagement", () => () => (
|
|
30
|
+
<div>ConceptsLinksManagement</div>
|
|
31
|
+
));
|
|
32
|
+
jest.mock("../ConceptLoader", () => () => <div>ConceptLoader</div>);
|
|
33
|
+
jest.mock("../Concepts", () => () => <div>Concepts</div>);
|
|
34
|
+
jest.mock("../ConceptsBulkUpdate", () => () => <div>ConceptsBulkUpdate</div>);
|
|
35
|
+
jest.mock("../ConceptSubscriptionLoader", () => () => (
|
|
36
|
+
<div>ConceptSubscriptionLoader</div>
|
|
37
|
+
));
|
|
38
|
+
jest.mock("../ConceptsUploadEvents", () => () => (
|
|
39
|
+
<div>ConceptsUploadEvents</div>
|
|
40
|
+
));
|
|
41
|
+
jest.mock("../../relations/components/ConceptLinksApprovals", () => () => (
|
|
42
|
+
<div>ConceptLinksApprovals</div>
|
|
43
|
+
));
|
|
44
|
+
jest.mock(
|
|
45
|
+
"../../relations/components/ConceptLinksApprovalResults",
|
|
46
|
+
() => () => <div>ConceptsLinksApprovalsResults</div>
|
|
47
|
+
);
|
|
48
|
+
jest.mock("@truedat/lm/components/RelationTagsLoader", () => () => (
|
|
49
|
+
<div>RelationTagsLoader</div>
|
|
50
|
+
));
|
|
51
|
+
jest.mock("@truedat/core/components/TemplatesLoader", () => () => (
|
|
52
|
+
<div>TemplatesLoader</div>
|
|
53
|
+
));
|
|
54
|
+
jest.mock("@truedat/lm/components/RelationsGraphLoader", () => () => (
|
|
55
|
+
<div>RelationsGraphLoader</div>
|
|
56
|
+
));
|
|
57
|
+
|
|
58
|
+
describe("<ConceptRoutes />", () => {
|
|
59
|
+
it("renders correctly with default route", async () => {
|
|
60
|
+
const rendered = render(<ConceptRoutes />);
|
|
61
|
+
await waitForLoad(rendered);
|
|
62
|
+
expect(rendered.container).toMatchSnapshot();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("renders correctly with concepts route", async () => {
|
|
66
|
+
const rendered = render(<ConceptRoutes />, {
|
|
67
|
+
routes: [CONCEPTS],
|
|
68
|
+
});
|
|
69
|
+
await waitForLoad(rendered);
|
|
70
|
+
expect(rendered.container).toMatchSnapshot();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("renders correctly with pending concepts route", async () => {
|
|
74
|
+
const rendered = render(<ConceptRoutes />, {
|
|
75
|
+
routes: [CONCEPTS_PENDING],
|
|
76
|
+
});
|
|
77
|
+
await waitForLoad(rendered);
|
|
78
|
+
expect(rendered.container).toMatchSnapshot();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("renders correctly with deprecated concepts route", async () => {
|
|
82
|
+
const rendered = render(<ConceptRoutes />, {
|
|
83
|
+
routes: [CONCEPTS_DEPRECATED],
|
|
84
|
+
});
|
|
85
|
+
await waitForLoad(rendered);
|
|
86
|
+
expect(rendered.container).toMatchSnapshot();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("renders correctly with new concept route", async () => {
|
|
90
|
+
const rendered = render(<ConceptRoutes />, {
|
|
91
|
+
routes: [CONCEPTS_NEW],
|
|
92
|
+
});
|
|
93
|
+
await waitForLoad(rendered);
|
|
94
|
+
expect(rendered.container).toMatchSnapshot();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("renders correctly with bulk update route", async () => {
|
|
98
|
+
const rendered = render(<ConceptRoutes />, {
|
|
99
|
+
routes: [CONCEPTS_BULK_UPDATE],
|
|
100
|
+
state: {
|
|
101
|
+
templatesLoading: false,
|
|
102
|
+
templates: { some: "template" },
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
await waitForLoad(rendered);
|
|
106
|
+
expect(rendered.container).toMatchSnapshot();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("renders correctly with bulk upload events route", async () => {
|
|
110
|
+
const rendered = render(<ConceptRoutes />, {
|
|
111
|
+
routes: [CONCEPTS_BULK_UPLOAD_EVENTS],
|
|
112
|
+
});
|
|
113
|
+
await waitForLoad(rendered);
|
|
114
|
+
expect(rendered.container).toMatchSnapshot();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("renders correctly with links management route", async () => {
|
|
118
|
+
const rendered = render(<ConceptRoutes />, {
|
|
119
|
+
routes: [CONCEPT_LINKS_MANAGEMENT],
|
|
120
|
+
});
|
|
121
|
+
await waitForLoad(rendered);
|
|
122
|
+
expect(rendered.container).toMatchSnapshot();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("renders correctly with concept version route", async () => {
|
|
126
|
+
const rendered = render(<ConceptRoutes />, {
|
|
127
|
+
routes: [
|
|
128
|
+
CONCEPT_VERSION.replace(":business_concept_id", "123").replace(
|
|
129
|
+
":id",
|
|
130
|
+
"456"
|
|
131
|
+
),
|
|
132
|
+
],
|
|
133
|
+
state: {
|
|
134
|
+
concept: { business_concept_id: "123" },
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
await waitForLoad(rendered);
|
|
138
|
+
expect(rendered.container).toMatchSnapshot();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("renders correctly with concept edit route", async () => {
|
|
142
|
+
const rendered = render(<ConceptRoutes />, {
|
|
143
|
+
routes: [
|
|
144
|
+
CONCEPT_EDIT.replace(":business_concept_id", "123").replace(
|
|
145
|
+
":id",
|
|
146
|
+
"456"
|
|
147
|
+
),
|
|
148
|
+
],
|
|
149
|
+
state: {
|
|
150
|
+
concept: { business_concept_id: "123" },
|
|
151
|
+
templatesLoading: false,
|
|
152
|
+
templates: { some: "template" },
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
await waitForLoad(rendered);
|
|
156
|
+
expect(rendered.container).toMatchSnapshot();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("renders correctly with subscope route", async () => {
|
|
160
|
+
const rendered = render(<ConceptRoutes />, {
|
|
161
|
+
routes: [CONCEPTS_SUBSCOPE.replace(":subscope", "test")],
|
|
162
|
+
});
|
|
163
|
+
await waitForLoad(rendered);
|
|
164
|
+
expect(rendered.container).toMatchSnapshot();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("renders correctly with sidemenu subscope route", async () => {
|
|
168
|
+
const rendered = render(<ConceptRoutes />, {
|
|
169
|
+
routes: [CONCEPTS_SIDEMENU_SUBSCOPE.replace(":subscope", "test")],
|
|
170
|
+
});
|
|
171
|
+
await waitForLoad(rendered);
|
|
172
|
+
expect(rendered.container).toMatchSnapshot();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("renders correctly with sidemenu subscope pending route", async () => {
|
|
176
|
+
const rendered = render(<ConceptRoutes />, {
|
|
177
|
+
routes: [CONCEPTS_SIDEMENU_SUBSCOPE_PENDING.replace(":subscope", "test")],
|
|
178
|
+
});
|
|
179
|
+
await waitForLoad(rendered);
|
|
180
|
+
expect(rendered.container).toMatchSnapshot();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("renders correctly with sidemenu subscope deprecated route", async () => {
|
|
184
|
+
const rendered = render(<ConceptRoutes />, {
|
|
185
|
+
routes: [
|
|
186
|
+
CONCEPTS_SIDEMENU_SUBSCOPE_DEPRECATED.replace(":subscope", "test"),
|
|
187
|
+
],
|
|
188
|
+
});
|
|
189
|
+
await waitForLoad(rendered);
|
|
190
|
+
expect(rendered.container).toMatchSnapshot();
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("renders unauthorized component when not authorized", async () => {
|
|
194
|
+
useAuthorized.mockReturnValueOnce(false);
|
|
195
|
+
const rendered = render(<ConceptRoutes />, {
|
|
196
|
+
routes: [CONCEPTS],
|
|
197
|
+
});
|
|
198
|
+
await waitForLoad(rendered);
|
|
199
|
+
expect(rendered.container).toMatchSnapshot();
|
|
200
|
+
});
|
|
201
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
+
import { useParams } from "react-router";
|
|
4
|
+
import { ConceptSuggestions } from "../ConceptSuggestions";
|
|
5
|
+
import { ConceptSelectorTable } from "../../relations/components/ConceptSelector";
|
|
6
|
+
import { useConceptSuggestions } from "../../hooks/useConcepts";
|
|
7
|
+
|
|
8
|
+
jest.mock("react-router", () => ({
|
|
9
|
+
...jest.requireActual("react-router"),
|
|
10
|
+
useParams: jest.fn(),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock("../../hooks/useConcepts", () => ({
|
|
14
|
+
useConceptSuggestions: jest.fn(),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
jest.mock("../../relations/components/ConceptSelector", () => {
|
|
18
|
+
return {
|
|
19
|
+
__esModule: true,
|
|
20
|
+
ConceptSelectorTable: jest.fn(() => <div>MockSearchResults</div>),
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("ConceptSuggestions", () => {
|
|
25
|
+
const mockFetchSuggestions = jest.fn();
|
|
26
|
+
|
|
27
|
+
const structureLinks = [
|
|
28
|
+
{ resource_type: "concept", id: "c1" },
|
|
29
|
+
{ resource_type: "other", id: "not-c" }
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
jest.clearAllMocks();
|
|
34
|
+
useParams.mockReturnValue({ id: "123" });
|
|
35
|
+
|
|
36
|
+
useConceptSuggestions.mockReturnValue({
|
|
37
|
+
trigger: mockFetchSuggestions,
|
|
38
|
+
data: {
|
|
39
|
+
data: {
|
|
40
|
+
data: [
|
|
41
|
+
{ id: "concept1", similarity: 0.89 },
|
|
42
|
+
{ id: "concept2", similarity: 0.77 },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
isMutating: false,
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const state = { structureLinks };
|
|
51
|
+
|
|
52
|
+
it("calls fetchSuggestions on mount with correct parameters", async () => {
|
|
53
|
+
const rendered = render(<ConceptSuggestions selectedConcept={null} handleConceptSelected={jest.fn()} />, { state });
|
|
54
|
+
await waitForLoad(rendered);
|
|
55
|
+
expect(mockFetchSuggestions).toHaveBeenCalledWith({
|
|
56
|
+
resource: {
|
|
57
|
+
id: "123",
|
|
58
|
+
type: "structures",
|
|
59
|
+
links: [{ resource_type: "concept", id: "c1" }],
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("renders ConceptSelectorTable with props", async () => {
|
|
65
|
+
const rendered = render(<ConceptSuggestions selectedConcept={{}} handleConceptSelected={jest.fn()} />, { state });
|
|
66
|
+
await waitForLoad(rendered);
|
|
67
|
+
expect(rendered.getByText("MockSearchResults")).toBeInTheDocument();
|
|
68
|
+
const props = ConceptSelectorTable.mock.calls[0][0];
|
|
69
|
+
expect(props.concepts).toEqual([
|
|
70
|
+
{ id: "concept1", similarity: 0.89 },
|
|
71
|
+
{ id: "concept2", similarity: 0.77 },
|
|
72
|
+
]);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ConceptRoutes /> renders correctly with bulk update route 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div>
|
|
6
|
+
ConceptCrumbs
|
|
7
|
+
</div>
|
|
8
|
+
<div>
|
|
9
|
+
TemplatesLoader
|
|
10
|
+
</div>
|
|
11
|
+
<div>
|
|
12
|
+
ConceptsBulkUpdate
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
exports[`<ConceptRoutes /> renders correctly with bulk upload events route 1`] = `
|
|
18
|
+
<div>
|
|
19
|
+
<div>
|
|
20
|
+
ConceptsUploadEvents
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
exports[`<ConceptRoutes /> renders correctly with concept edit route 1`] = `
|
|
26
|
+
<div>
|
|
27
|
+
<div>
|
|
28
|
+
ConceptCrumbs
|
|
29
|
+
</div>
|
|
30
|
+
<div>
|
|
31
|
+
TemplatesLoader
|
|
32
|
+
</div>
|
|
33
|
+
<div>
|
|
34
|
+
ConceptLoader
|
|
35
|
+
</div>
|
|
36
|
+
<div>
|
|
37
|
+
ConceptEdit
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
exports[`<ConceptRoutes /> renders correctly with concept version route 1`] = `
|
|
43
|
+
<div>
|
|
44
|
+
<div>
|
|
45
|
+
ConceptLoader
|
|
46
|
+
</div>
|
|
47
|
+
<div>
|
|
48
|
+
RelationTagsLoader
|
|
49
|
+
</div>
|
|
50
|
+
<div>
|
|
51
|
+
ConceptSubscriptionLoader
|
|
52
|
+
</div>
|
|
53
|
+
<div>
|
|
54
|
+
RelationsGraphLoader
|
|
55
|
+
</div>
|
|
56
|
+
<div>
|
|
57
|
+
Concept
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
exports[`<ConceptRoutes /> renders correctly with concepts route 1`] = `
|
|
63
|
+
<div>
|
|
64
|
+
<div>
|
|
65
|
+
Concepts
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
exports[`<ConceptRoutes /> renders correctly with default route 1`] = `<div />`;
|
|
71
|
+
|
|
72
|
+
exports[`<ConceptRoutes /> renders correctly with deprecated concepts route 1`] = `
|
|
73
|
+
<div>
|
|
74
|
+
<div>
|
|
75
|
+
Concepts
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
exports[`<ConceptRoutes /> renders correctly with links management route 1`] = `
|
|
81
|
+
<div>
|
|
82
|
+
<div>
|
|
83
|
+
RelationTagsLoader
|
|
84
|
+
</div>
|
|
85
|
+
<div>
|
|
86
|
+
ConceptsLinksManagement
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
exports[`<ConceptRoutes /> renders correctly with new concept route 1`] = `
|
|
92
|
+
<div>
|
|
93
|
+
<div>
|
|
94
|
+
ConceptCrumbs
|
|
95
|
+
</div>
|
|
96
|
+
<div>
|
|
97
|
+
ConceptCreate
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
exports[`<ConceptRoutes /> renders correctly with pending concepts route 1`] = `
|
|
103
|
+
<div>
|
|
104
|
+
<div>
|
|
105
|
+
Concepts
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
`;
|
|
109
|
+
|
|
110
|
+
exports[`<ConceptRoutes /> renders correctly with sidemenu subscope deprecated route 1`] = `
|
|
111
|
+
<div>
|
|
112
|
+
<div>
|
|
113
|
+
Concepts
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
exports[`<ConceptRoutes /> renders correctly with sidemenu subscope pending route 1`] = `
|
|
119
|
+
<div>
|
|
120
|
+
<div>
|
|
121
|
+
Concepts
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
`;
|
|
125
|
+
|
|
126
|
+
exports[`<ConceptRoutes /> renders correctly with sidemenu subscope route 1`] = `
|
|
127
|
+
<div>
|
|
128
|
+
<div>
|
|
129
|
+
Concepts
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
`;
|
|
133
|
+
|
|
134
|
+
exports[`<ConceptRoutes /> renders correctly with subscope route 1`] = `
|
|
135
|
+
<div>
|
|
136
|
+
<div>
|
|
137
|
+
Concepts
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
`;
|
|
141
|
+
|
|
142
|
+
exports[`<ConceptRoutes /> renders unauthorized component when not authorized 1`] = `
|
|
143
|
+
<div>
|
|
144
|
+
<div
|
|
145
|
+
class="ui icon visible bottom attached message center"
|
|
146
|
+
>
|
|
147
|
+
<i
|
|
148
|
+
aria-hidden="true"
|
|
149
|
+
class="warning sign icon"
|
|
150
|
+
/>
|
|
151
|
+
<div
|
|
152
|
+
class="content"
|
|
153
|
+
>
|
|
154
|
+
<div
|
|
155
|
+
class="header"
|
|
156
|
+
>
|
|
157
|
+
view.unauthorized.head
|
|
158
|
+
</div>
|
|
159
|
+
<p>
|
|
160
|
+
view.unauthorized.content
|
|
161
|
+
</p>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
`;
|