@truedat/lm 7.7.0 → 7.7.2
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/components/ConceptLink.js +8 -1
- package/src/components/ConceptSuggestionLinkForm.js +3 -2
- package/src/components/__tests__/ConceptSuggestionLinkForm.spec.js +81 -72
- package/src/reducers/relations.js +1 -0
- package/src/sagas/__tests__/createRelation.spec.js +2 -0
- package/src/sagas/createRelation.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/lm",
|
|
3
|
-
"version": "7.7.
|
|
3
|
+
"version": "7.7.2",
|
|
4
4
|
"description": "Truedat Link Manager",
|
|
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.7.
|
|
51
|
+
"@truedat/test": "7.7.2",
|
|
52
52
|
"identity-obj-proxy": "^3.0.0",
|
|
53
53
|
"jest": "^29.7.0",
|
|
54
54
|
"redux-saga-test-plan": "^4.0.6"
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"semantic-ui-react": "^3.0.0-beta.2",
|
|
83
83
|
"swr": "^2.3.3"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "bb159aad74d5bd5fada2d9b753e2c4b8d902a7da"
|
|
86
86
|
}
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { Link } from "react-router";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
+
import OriginLabel from "@truedat/core/components/OriginLabel";
|
|
3
4
|
import { linkTo } from "@truedat/core/routes";
|
|
4
5
|
|
|
5
|
-
export const ConceptLink = ({
|
|
6
|
+
export const ConceptLink = ({
|
|
7
|
+
resource_id: business_concept_id,
|
|
8
|
+
name,
|
|
9
|
+
origin,
|
|
10
|
+
}) => (
|
|
6
11
|
<Link
|
|
7
12
|
to={linkTo.CONCEPT_LINKS_STRUCTURES({ business_concept_id, id: "current" })}
|
|
8
13
|
>
|
|
9
14
|
{name}
|
|
15
|
+
<OriginLabel origin={origin} />
|
|
10
16
|
</Link>
|
|
11
17
|
);
|
|
12
18
|
|
|
13
19
|
ConceptLink.propTypes = {
|
|
14
20
|
resource_id: PropTypes.number,
|
|
15
21
|
name: PropTypes.string,
|
|
22
|
+
origin: PropTypes.string,
|
|
16
23
|
};
|
|
17
24
|
|
|
18
25
|
export default ConceptLink;
|
|
@@ -12,8 +12,8 @@ import { Button } from "semantic-ui-react";
|
|
|
12
12
|
import { createRelation, clearSelectedRelationTags } from "../routines";
|
|
13
13
|
import TagTypeDropdownSelector from "./TagTypeDropdownSelector";
|
|
14
14
|
|
|
15
|
-
const StructureSuggestions = React.lazy(
|
|
16
|
-
import("@truedat/dd/components/StructureSuggestions")
|
|
15
|
+
const StructureSuggestions = React.lazy(
|
|
16
|
+
() => import("@truedat/dd/components/StructureSuggestions")
|
|
17
17
|
);
|
|
18
18
|
|
|
19
19
|
const selectTagOptions = makeTagOptionsSelector("data_field");
|
|
@@ -45,6 +45,7 @@ export const ConceptSuggestionLinkForm = () => {
|
|
|
45
45
|
target_id: selectedStructure.id,
|
|
46
46
|
target_type: "data_structure",
|
|
47
47
|
tag_ids: selectedRelationTags ? selectedRelationTags : [],
|
|
48
|
+
origin: "suggested",
|
|
48
49
|
};
|
|
49
50
|
dispatch(createRelation.trigger(structureLink));
|
|
50
51
|
};
|
|
@@ -5,111 +5,120 @@ import { useParams } from "react-router";
|
|
|
5
5
|
import { createRelation, clearSelectedRelationTags } from "../../routines";
|
|
6
6
|
|
|
7
7
|
jest.mock("react-redux", () => ({
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
useSelector: jest.fn(),
|
|
9
|
+
useDispatch: jest.fn(),
|
|
10
10
|
}));
|
|
11
11
|
|
|
12
12
|
jest.mock("react-router", () => ({
|
|
13
|
-
|
|
13
|
+
useParams: jest.fn(),
|
|
14
14
|
}));
|
|
15
15
|
|
|
16
16
|
jest.mock("react-intl", () => ({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
useIntl: () => ({
|
|
18
|
+
formatMessage: ({ id }) => id, // mock translated strings
|
|
19
|
+
}),
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
22
|
// Mock selector factory
|
|
23
23
|
jest.mock("@truedat/core/selectors", () => ({
|
|
24
|
-
|
|
24
|
+
makeTagOptionsSelector: jest.fn(() =>
|
|
25
|
+
jest.fn(() => [{ id: "tag1", name: "Tag 1" }])
|
|
26
|
+
),
|
|
25
27
|
}));
|
|
26
28
|
|
|
27
29
|
// Mock components
|
|
28
30
|
jest.mock("@truedat/dd/components/StructureSuggestions", () =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
jest.fn((props) => {
|
|
32
|
+
// Include a button to simulate structure selection
|
|
33
|
+
return (
|
|
34
|
+
<div>
|
|
35
|
+
<div>MockStructureSuggestions</div>
|
|
36
|
+
<button
|
|
37
|
+
onClick={() => props.handleSelectedStructure({ id: "structure123" })}
|
|
38
|
+
>
|
|
39
|
+
Select Structure
|
|
40
|
+
</button>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
})
|
|
40
44
|
);
|
|
41
45
|
|
|
42
46
|
jest.mock("../TagTypeDropdownSelector", () =>
|
|
43
|
-
|
|
47
|
+
jest.fn(() => <div>MockTagTypeDropdownSelector</div>)
|
|
44
48
|
);
|
|
45
49
|
|
|
46
50
|
jest.mock("@truedat/core/components", () => ({
|
|
47
|
-
|
|
51
|
+
HistoryBackButton: (props) => <button>{props.content}</button>,
|
|
48
52
|
}));
|
|
49
53
|
|
|
50
54
|
jest.mock("@truedat/core/routes", () => ({
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
linkTo: {
|
|
56
|
+
CONCEPT_LINKS_STRUCTURES: jest.fn(() => "/mocked/redirect/url"),
|
|
57
|
+
},
|
|
54
58
|
}));
|
|
55
59
|
|
|
56
60
|
describe("ConceptSuggestionLinkForm", () => {
|
|
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
|
-
|
|
61
|
+
const mockDispatch = jest.fn();
|
|
62
|
+
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
jest.clearAllMocks();
|
|
65
|
+
|
|
66
|
+
useParams.mockReturnValue({ business_concept_id: "bc1", id: "v1" });
|
|
67
|
+
useDispatch.mockReturnValue(mockDispatch);
|
|
68
|
+
useSelector.mockImplementation((selector) =>
|
|
69
|
+
selector({
|
|
70
|
+
selectedRelationTags: ["tag1"],
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
clearSelectedRelationTags.trigger = jest.fn(() => ({ type: "CLEAR_TAGS" }));
|
|
75
|
+
createRelation.trigger = jest.fn((payload) => ({
|
|
76
|
+
type: "CREATE_RELATION",
|
|
77
|
+
payload,
|
|
78
|
+
}));
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("renders structure suggestions and tag dropdown", async () => {
|
|
82
|
+
render(<ConceptSuggestionLinkForm />);
|
|
83
|
+
|
|
84
|
+
await waitFor(() => {
|
|
85
|
+
expect(screen.getByText("MockStructureSuggestions")).toBeInTheDocument();
|
|
86
|
+
expect(screen.getByText("actions.create")).toBeDisabled();
|
|
82
87
|
});
|
|
88
|
+
});
|
|
83
89
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// Simulate structure selection
|
|
88
|
-
fireEvent.click(screen.getByText("Select Structure"));
|
|
90
|
+
it("dispatches createRelation on submit", async () => {
|
|
91
|
+
render(<ConceptSuggestionLinkForm />);
|
|
89
92
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
expect(createBtn).not.toBeDisabled();
|
|
93
|
+
// Simulate structure selection
|
|
94
|
+
fireEvent.click(screen.getByText("Select Structure"));
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
// Now the submit button should be enabled
|
|
97
|
+
const createBtn = screen.getByText("actions.create");
|
|
98
|
+
expect(createBtn).not.toBeDisabled();
|
|
95
99
|
|
|
96
|
-
|
|
97
|
-
redirectUrl: "/mocked/redirect/url",
|
|
98
|
-
source_id: "bc1",
|
|
99
|
-
source_type: "business_concept",
|
|
100
|
-
target_id: "structure123",
|
|
101
|
-
target_type: "data_structure",
|
|
102
|
-
tag_ids: ["tag1"],
|
|
103
|
-
});
|
|
100
|
+
fireEvent.click(createBtn);
|
|
104
101
|
|
|
105
|
-
|
|
102
|
+
expect(createRelation.trigger).toHaveBeenCalledWith({
|
|
103
|
+
redirectUrl: "/mocked/redirect/url",
|
|
104
|
+
source_id: "bc1",
|
|
105
|
+
source_type: "business_concept",
|
|
106
|
+
target_id: "structure123",
|
|
107
|
+
target_type: "data_structure",
|
|
108
|
+
tag_ids: ["tag1"],
|
|
109
|
+
origin: "suggested",
|
|
106
110
|
});
|
|
107
111
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
expect(mockDispatch).toHaveBeenCalledWith(
|
|
113
|
+
expect.objectContaining({ type: "CREATE_RELATION" })
|
|
114
|
+
);
|
|
115
|
+
});
|
|
111
116
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
it("dispatches clearSelectedRelationTags on unmount", () => {
|
|
118
|
+
const { unmount } = render(<ConceptSuggestionLinkForm />);
|
|
119
|
+
unmount();
|
|
120
|
+
|
|
121
|
+
expect(clearSelectedRelationTags.trigger).toHaveBeenCalled();
|
|
122
|
+
expect(mockDispatch).toHaveBeenCalledWith({ type: "CLEAR_TAGS" });
|
|
123
|
+
});
|
|
115
124
|
});
|
|
@@ -39,6 +39,7 @@ describe("sagas: createRelationSaga", () => {
|
|
|
39
39
|
context: {},
|
|
40
40
|
tag_ids: [],
|
|
41
41
|
redirectUrl,
|
|
42
|
+
origin: "some origin",
|
|
42
43
|
};
|
|
43
44
|
const meta = { redirectUrl };
|
|
44
45
|
const relation = _.pick([
|
|
@@ -48,6 +49,7 @@ describe("sagas: createRelationSaga", () => {
|
|
|
48
49
|
"target_id",
|
|
49
50
|
"target_type",
|
|
50
51
|
"tag_ids",
|
|
52
|
+
"origin",
|
|
51
53
|
])(payload);
|
|
52
54
|
const request_data = {
|
|
53
55
|
relation,
|