@truedat/dd 4.48.12 → 4.49.1
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/CHANGELOG.md +6 -0
- package/package.json +5 -5
- package/src/api/fragments.js +2 -2
- package/src/api/mutations.js +33 -11
- package/src/api/queries.js +37 -10
- package/src/api.js +0 -4
- package/src/components/DictionaryRoutes.js +4 -4
- package/src/components/StructureSummary.js +12 -22
- package/src/components/StructureTag.js +83 -54
- package/src/components/StructureTagForm.js +149 -89
- package/src/components/StructureTags.js +57 -27
- package/src/components/Tag.js +62 -0
- package/src/components/TagCards.js +85 -0
- package/src/components/TagCrumbs.js +25 -0
- package/src/components/TagForm.js +102 -0
- package/src/components/TagStructureButton.js +58 -0
- package/src/components/Tags.js +33 -0
- package/src/components/TagsRoutes.js +39 -0
- package/src/components/__tests__/StructureSummary.spec.js +0 -7
- package/src/components/__tests__/StructureTag.spec.js +79 -5
- package/src/components/__tests__/StructureTagForm.spec.js +99 -50
- package/src/components/__tests__/Tag.spec.js +11 -0
- package/src/components/__tests__/{StructureTagsCards.spec.js → TagCards.spec.js} +10 -10
- package/src/components/__tests__/TagCrumbs.spec.js +10 -0
- package/src/components/__tests__/TagForm.spec.js +72 -0
- package/src/components/__tests__/Tags.spec.js +10 -0
- package/src/components/__tests__/__snapshots__/StructureSummary.spec.js.snap +18 -42
- package/src/components/__tests__/__snapshots__/StructureTag.spec.js.snap +10 -30
- package/src/components/__tests__/__snapshots__/StructureTagForm.spec.js.snap +255 -51
- package/src/components/__tests__/__snapshots__/Tag.spec.js.snap +36 -0
- package/src/components/__tests__/__snapshots__/{StructureTagsCards.spec.js.snap → TagCards.spec.js.snap} +1 -1
- package/src/components/__tests__/__snapshots__/TagCrumbs.spec.js.snap +102 -0
- package/src/components/__tests__/__snapshots__/TagForm.spec.js.snap +70 -0
- package/src/components/__tests__/__snapshots__/{StructureTags.spec.js.snap → Tags.spec.js.snap} +1 -1
- package/src/messages/en.js +25 -30
- package/src/messages/es.js +25 -30
- package/src/reducers/__tests__/{editableStructureTags.spec.js → availableTags.spec.js} +7 -11
- package/src/reducers/__tests__/structureTagSaving.spec.js +36 -0
- package/src/reducers/__tests__/tagSaving.spec.js +32 -0
- package/src/reducers/{editableStructureTags.js → availableTags.js} +2 -2
- package/src/reducers/index.js +6 -12
- package/src/reducers/structureRedirect.js +7 -7
- package/src/reducers/structureTagSaving.js +12 -10
- package/src/reducers/tagSaving.js +18 -0
- package/src/routines.js +5 -6
- package/src/sagas/__tests__/createTag.spec.js +81 -0
- package/src/sagas/__tests__/deleteStructureTag.spec.js +11 -12
- package/src/sagas/__tests__/deleteTag.spec.js +76 -0
- package/src/sagas/__tests__/tagStructure.spec.js +86 -0
- package/src/sagas/__tests__/updateTag.spec.js +81 -0
- package/src/sagas/createTag.js +29 -0
- package/src/sagas/deleteStructureTag.js +12 -9
- package/src/sagas/deleteTag.js +34 -0
- package/src/sagas/index.js +15 -18
- package/src/sagas/tagStructure.js +37 -0
- package/src/sagas/updateTag.js +23 -0
- package/src/components/LinkStructureTagForm.js +0 -163
- package/src/components/LinkedStructureTag.js +0 -124
- package/src/components/StructureLinkTagButton.js +0 -47
- package/src/components/StructureTagsCards.js +0 -92
- package/src/components/StructureTagsCrumbs.js +0 -44
- package/src/components/StructureTagsRoutes.js +0 -45
- package/src/components/TagsHeader.js +0 -32
- package/src/components/__tests__/LinkStructureTagForm.spec.js +0 -184
- package/src/components/__tests__/LinkedStructureTag.spec.js +0 -133
- package/src/components/__tests__/StructureTags.spec.js +0 -14
- package/src/components/__tests__/StructureTagsCrumbs.spec.js +0 -13
- package/src/components/__tests__/__snapshots__/LinkStructureTagForm.spec.js.snap +0 -456
- package/src/components/__tests__/__snapshots__/LinkedStructureTag.spec.js.snap +0 -16
- package/src/components/__tests__/__snapshots__/StructureTagsCrumbs.spec.js.snap +0 -36
- package/src/reducers/__tests__/deletingStructureTags.spec.js +0 -30
- package/src/reducers/__tests__/linkedStructureTags.spec.js +0 -69
- package/src/reducers/__tests__/linkedStructureTagsLoading.spec.js +0 -32
- package/src/reducers/__tests__/linkingStructureTags.spec.js +0 -30
- package/src/reducers/__tests__/structureTagsSaving.spec.js +0 -40
- package/src/reducers/deletingStructureTags.js +0 -16
- package/src/reducers/linkedStructureTags.js +0 -28
- package/src/reducers/linkedStructureTagsLoading.js +0 -16
- package/src/reducers/linkingStructureTags.js +0 -16
- package/src/sagas/__tests__/createStructureTag.spec.js +0 -85
- package/src/sagas/__tests__/deleteLinkStructureTag.spec.js +0 -96
- package/src/sagas/__tests__/fetchLinksStructureTags.spec.js +0 -105
- package/src/sagas/__tests__/linkStructureTag.spec.js +0 -102
- package/src/sagas/__tests__/updateStructureTag.spec.js +0 -84
- package/src/sagas/createStructureTag.js +0 -29
- package/src/sagas/deleteLinkStructureTag.js +0 -29
- package/src/sagas/fetchLinksStructureTags.js +0 -31
- package/src/sagas/linkStructureTag.js +0 -30
- package/src/sagas/updateStructureTag.js +0 -23
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { connect } from "react-redux";
|
|
6
|
+
import { Button, Popup } from "semantic-ui-react";
|
|
7
|
+
import StructureTagForm from "./StructureTagForm";
|
|
8
|
+
|
|
9
|
+
export const TagStructureButton = ({ savingId, structureId, tags }) => {
|
|
10
|
+
const { formatMessage } = useIntl();
|
|
11
|
+
const [open, setOpen] = useState(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
setOpen(savingId === structureId);
|
|
14
|
+
}, [savingId, structureId]);
|
|
15
|
+
const structureTag = { dataStructureId: structureId };
|
|
16
|
+
return _.isEmpty(tags) ? null : (
|
|
17
|
+
<Popup
|
|
18
|
+
on="click"
|
|
19
|
+
basic
|
|
20
|
+
flowing
|
|
21
|
+
onOpen={() => setOpen(true)}
|
|
22
|
+
onClose={() => setOpen(false)}
|
|
23
|
+
open={open}
|
|
24
|
+
content={
|
|
25
|
+
<StructureTagForm
|
|
26
|
+
saving={!!savingId}
|
|
27
|
+
structureTag={structureTag}
|
|
28
|
+
tags={tags}
|
|
29
|
+
/>
|
|
30
|
+
}
|
|
31
|
+
position="bottom center"
|
|
32
|
+
size="large"
|
|
33
|
+
positionFixed
|
|
34
|
+
trigger={
|
|
35
|
+
<Button
|
|
36
|
+
style={{ marginLeft: "0.5em" }}
|
|
37
|
+
icon="plus"
|
|
38
|
+
size="tiny"
|
|
39
|
+
circular
|
|
40
|
+
basic
|
|
41
|
+
content={formatMessage({ id: "structure.add.tag" })}
|
|
42
|
+
/>
|
|
43
|
+
}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
TagStructureButton.propTypes = {
|
|
49
|
+
savingId: PropTypes.string,
|
|
50
|
+
structureId: PropTypes.string,
|
|
51
|
+
tags: PropTypes.array,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const mapStateToProps = ({ structureTagSaving }) => ({
|
|
55
|
+
savingId: structureTagSaving,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export default connect(mapStateToProps)(TagStructureButton);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Link } from "react-router-dom";
|
|
3
|
+
import { Button, Header, Icon, Segment } from "semantic-ui-react";
|
|
4
|
+
import { useIntl, FormattedMessage } from "react-intl";
|
|
5
|
+
import { STRUCTURE_TAGS_NEW } from "@truedat/core/routes";
|
|
6
|
+
import TagCards from "./TagCards";
|
|
7
|
+
|
|
8
|
+
export const Tags = () => {
|
|
9
|
+
const { formatMessage } = useIntl();
|
|
10
|
+
return (
|
|
11
|
+
<Segment>
|
|
12
|
+
<Header as="h2">
|
|
13
|
+
<Button
|
|
14
|
+
floated="right"
|
|
15
|
+
primary
|
|
16
|
+
as={Link}
|
|
17
|
+
to={STRUCTURE_TAGS_NEW}
|
|
18
|
+
content={formatMessage({ id: "tags.actions.create" })}
|
|
19
|
+
/>
|
|
20
|
+
<Icon name="tags" circular />
|
|
21
|
+
<Header.Content>
|
|
22
|
+
<FormattedMessage id="tags.header" />
|
|
23
|
+
<Header.Subheader>
|
|
24
|
+
<FormattedMessage id="tags.subheader" />
|
|
25
|
+
</Header.Subheader>
|
|
26
|
+
</Header.Content>
|
|
27
|
+
</Header>
|
|
28
|
+
<TagCards />
|
|
29
|
+
</Segment>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default Tags;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Route, Switch, useParams } from "react-router-dom";
|
|
3
|
+
import { useQuery } from "@apollo/client";
|
|
4
|
+
import { Unauthorized } from "@truedat/core/components";
|
|
5
|
+
import { useAuthorized } from "@truedat/core/hooks";
|
|
6
|
+
import { STRUCTURE_TAGS, STRUCTURE_TAG_EDIT, STRUCTURE_TAGS_NEW } from "@truedat/core/routes";
|
|
7
|
+
import { TAG_QUERY } from "../api/queries";
|
|
8
|
+
import Tag from "./Tag";
|
|
9
|
+
import Tags from "./Tags";
|
|
10
|
+
|
|
11
|
+
export const TagLoader = () => {
|
|
12
|
+
const { id } = useParams();
|
|
13
|
+
const { loading, error, data } = useQuery(TAG_QUERY, {
|
|
14
|
+
variables: { id },
|
|
15
|
+
});
|
|
16
|
+
if (error) return null;
|
|
17
|
+
const tag = data?.tag;
|
|
18
|
+
return <Tag id={id} tag={tag} loading={loading} />;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const AuthorizedTagsRoutes = () => (
|
|
22
|
+
<Switch>
|
|
23
|
+
<Route exact path={STRUCTURE_TAGS_NEW} render={() => <Tag />} />
|
|
24
|
+
<Route exact path={STRUCTURE_TAGS} render={() => <Tags />} />
|
|
25
|
+
<Route path={STRUCTURE_TAG_EDIT} render={() => <TagLoader />} />
|
|
26
|
+
</Switch>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const TagsRoutes = () => {
|
|
30
|
+
const authorized = useAuthorized();
|
|
31
|
+
return (
|
|
32
|
+
<Route
|
|
33
|
+
path={STRUCTURE_TAGS}
|
|
34
|
+
render={() => (authorized ? <AuthorizedTagsRoutes /> : <Unauthorized />)}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default TagsRoutes;
|
|
@@ -24,7 +24,6 @@ describe("<StructureSummary />", () => {
|
|
|
24
24
|
profile_permission: true,
|
|
25
25
|
confidential: true,
|
|
26
26
|
},
|
|
27
|
-
linkedStructureTagsLoading: false,
|
|
28
27
|
structureVersions: [{ updated_at: "2019-01-02T03:04:05Z" }],
|
|
29
28
|
structure,
|
|
30
29
|
authentication: { role: "admin" },
|
|
@@ -41,12 +40,6 @@ describe("<StructureSummary />", () => {
|
|
|
41
40
|
expect(container).toMatchSnapshot();
|
|
42
41
|
});
|
|
43
42
|
|
|
44
|
-
it("renders loading when linkedStructureTagsLoading is true", () => {
|
|
45
|
-
const customState = _.set("linkedStructureTagsLoading", true)(state);
|
|
46
|
-
const { findByText } = render(<StructureSummary />, { state: customState });
|
|
47
|
-
expect(findByText("Loading")).toBeTruthy();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
43
|
it("renders label when grant provided", async () => {
|
|
51
44
|
const customState = _.set("structure.grant", { detail: { foo: "bar" } })(
|
|
52
45
|
state
|
|
@@ -1,13 +1,87 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { waitFor, fireEvent } from "@testing-library/react";
|
|
3
4
|
import { StructureTag } from "../StructureTag";
|
|
4
5
|
|
|
5
6
|
describe("<StructureTag />", () => {
|
|
7
|
+
const tagName = "Tag 42";
|
|
8
|
+
const structureTag = {
|
|
9
|
+
id: "1",
|
|
10
|
+
dataStructureId: "1",
|
|
11
|
+
inherit: false,
|
|
12
|
+
tag: { id: "1", name: tagName },
|
|
13
|
+
};
|
|
14
|
+
const props = {
|
|
15
|
+
structureTag,
|
|
16
|
+
editable: true,
|
|
17
|
+
savingId: null,
|
|
18
|
+
};
|
|
19
|
+
|
|
6
20
|
it("matches the latest snapshot", () => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
21
|
+
const { container } = render(<StructureTag {...props} />);
|
|
22
|
+
expect(container).toMatchSnapshot();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("Show update modal when click in tag edit icon", async () => {
|
|
26
|
+
const { getByLabelText, container } = render(<StructureTag {...props} />);
|
|
27
|
+
fireEvent.click(container.getElementsByClassName("edit")[0]);
|
|
28
|
+
await waitFor(() => expect(getByLabelText("Comments")).toBeInTheDocument());
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("Show tooltip with description and comment", async () => {
|
|
32
|
+
const comment = "foo comment";
|
|
33
|
+
const description = "foo description";
|
|
34
|
+
const tagWithDescriptionProps = {
|
|
35
|
+
...props,
|
|
36
|
+
structureTag: {
|
|
37
|
+
...structureTag,
|
|
38
|
+
tag: { id: 2, name: tagName, description },
|
|
39
|
+
comment,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const { getByText } = render(<StructureTag {...tagWithDescriptionProps} />);
|
|
44
|
+
|
|
45
|
+
fireEvent.mouseEnter(getByText(tagName));
|
|
46
|
+
|
|
47
|
+
await waitFor(() => expect(getByText("Comments")).toBeTruthy());
|
|
48
|
+
await waitFor(() => expect(getByText(comment)).toBeTruthy());
|
|
49
|
+
await waitFor(() => expect(getByText(description)).toBeTruthy());
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("Show tooltip with description", async () => {
|
|
53
|
+
const description = "foo description";
|
|
54
|
+
const tagWithDescriptionWithoutCommentProps = {
|
|
55
|
+
...props,
|
|
56
|
+
structureTag: {
|
|
57
|
+
...structureTag,
|
|
58
|
+
tag: { id: 2, name: tagName, description },
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const { getByText, queryByText } = render(
|
|
63
|
+
<StructureTag {...tagWithDescriptionWithoutCommentProps} />
|
|
10
64
|
);
|
|
11
|
-
|
|
65
|
+
|
|
66
|
+
fireEvent.mouseEnter(getByText(tagName));
|
|
67
|
+
|
|
68
|
+
await waitFor(() => expect(queryByText("Comment")).not.toBeInTheDocument());
|
|
69
|
+
await waitFor(() => expect(getByText(description)).toBeInTheDocument());
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("Show tooltip with comment", async () => {
|
|
73
|
+
const comment = "foo comment";
|
|
74
|
+
const tagWithCommentProps = {
|
|
75
|
+
...props,
|
|
76
|
+
structureTag: {
|
|
77
|
+
...structureTag,
|
|
78
|
+
comment,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
const { getByText } = render(<StructureTag {...tagWithCommentProps} />);
|
|
82
|
+
fireEvent.mouseEnter(getByText(tagName));
|
|
83
|
+
|
|
84
|
+
await waitFor(() => expect(getByText("Comments")).toBeTruthy());
|
|
85
|
+
await waitFor(() => expect(getByText(comment)).toBeTruthy());
|
|
12
86
|
});
|
|
13
87
|
});
|
|
@@ -1,72 +1,121 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { waitFor } from "@testing-library/react";
|
|
3
|
-
import userEvent from "@testing-library/user-event";
|
|
2
|
+
import { waitFor, within } from "@testing-library/react";
|
|
4
3
|
import { render } from "@truedat/test/render";
|
|
5
|
-
import
|
|
6
|
-
import StructureTagForm from "../StructureTagForm";
|
|
7
|
-
|
|
8
|
-
const domainsMock = {
|
|
9
|
-
request: { query: DOMAINS_QUERY },
|
|
10
|
-
result: { data: { domains: [{ id: "123", name: "foo" }] } },
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const renderOpts = {
|
|
14
|
-
mocks: [domainsMock],
|
|
15
|
-
};
|
|
4
|
+
import userEvent from "@testing-library/user-event";
|
|
5
|
+
import { StructureTagForm } from "../StructureTagForm";
|
|
16
6
|
|
|
17
7
|
describe("<StructureTagForm />", () => {
|
|
18
|
-
const
|
|
8
|
+
const tags = [
|
|
9
|
+
{ id: "1", name: "Tag1", description: "desc1" },
|
|
10
|
+
{ id: "2", name: "Tag2", description: "desc2" },
|
|
11
|
+
{ id: "3", name: "LongTag", description: "verylong".repeat(5) },
|
|
12
|
+
];
|
|
19
13
|
const structureTag = {
|
|
20
|
-
id:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
saving,
|
|
14
|
+
id: "55",
|
|
15
|
+
comment: "foo",
|
|
16
|
+
insertedAt: "foo",
|
|
17
|
+
inherited: false,
|
|
18
|
+
tag: {
|
|
19
|
+
id: "123",
|
|
20
|
+
},
|
|
21
|
+
dataStructureId: "56",
|
|
22
|
+
tagId: "57",
|
|
30
23
|
};
|
|
31
24
|
|
|
32
|
-
it("matches the latest snapshot", async () => {
|
|
33
|
-
const {
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
it("matches the latest snapshot create", async () => {
|
|
26
|
+
const structureTag = { structureId: "123" };
|
|
27
|
+
const props = { structureTag, tags };
|
|
28
|
+
const { container, findByRole, queryByRole } = render(
|
|
29
|
+
<StructureTagForm {...props} />
|
|
36
30
|
);
|
|
37
|
-
await findByRole("button", { name:
|
|
31
|
+
expect(await findByRole("button", { name: "Save" })).toBeInTheDocument();
|
|
32
|
+
expect(
|
|
33
|
+
await queryByRole("button", { name: "Delete" })
|
|
34
|
+
).not.toBeInTheDocument();
|
|
38
35
|
expect(container).toMatchSnapshot();
|
|
39
36
|
});
|
|
40
37
|
|
|
41
|
-
it("
|
|
42
|
-
const
|
|
38
|
+
it("matches the latest snapshot edit", async () => {
|
|
39
|
+
const props = { structureTag };
|
|
40
|
+
const { container, findByRole } = render(<StructureTagForm {...props} />);
|
|
41
|
+
expect(await findByRole("button", { name: "Save" })).toBeInTheDocument();
|
|
42
|
+
expect(await findByRole("button", { name: "Delete" })).toBeInTheDocument();
|
|
43
|
+
expect(container).toMatchSnapshot();
|
|
44
|
+
});
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
);
|
|
46
|
+
it("save button enabled if there is only one tag available", async () => {
|
|
47
|
+
const structureTag = { structureId: "123" };
|
|
48
|
+
const props = { structureTag, tags: [tags[0]] };
|
|
49
|
+
const { getByRole } = render(<StructureTagForm {...props} />);
|
|
50
|
+
await waitFor(() => {
|
|
51
|
+
expect(getByRole("button", { name: "Save" })).toBeEnabled();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
it("save button disabled if there are multiple tags", async () => {
|
|
56
|
+
const structureTag = { structureId: "123" };
|
|
57
|
+
const props = { structureTag, tags };
|
|
58
|
+
const { getByRole } = render(<StructureTagForm {...props} />);
|
|
59
|
+
await waitFor(() => {
|
|
60
|
+
expect(getByRole("button", { name: "Save" })).toBeDisabled();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
);
|
|
64
|
+
it("Tag dropdown options contain name and description", async () => {
|
|
65
|
+
const structureTag = { structureId: "123" };
|
|
66
|
+
const props = { structureTag, tags };
|
|
67
|
+
const { findByRole } = render(<StructureTagForm {...props} />);
|
|
68
|
+
expect(await findByRole("option", { name: /Tag2/ })).toBeInTheDocument();
|
|
69
|
+
expect(await findByRole("option", { name: /desc1/ })).toBeInTheDocument();
|
|
70
|
+
});
|
|
56
71
|
|
|
57
|
-
|
|
58
|
-
|
|
72
|
+
it("Tag dropdown items have 'description' class", async () => {
|
|
73
|
+
const longText = tags[2].description;
|
|
74
|
+
const structureTag = { structureId: "123" };
|
|
75
|
+
const props = { structureTag, tags };
|
|
76
|
+
const { findByRole } = render(<StructureTagForm {...props} />);
|
|
77
|
+
const option = await findByRole("option", { name: /verylong/ });
|
|
78
|
+
expect(within(option).getByText(longText)).toHaveClass("description");
|
|
79
|
+
});
|
|
59
80
|
|
|
60
|
-
|
|
61
|
-
|
|
81
|
+
it("calls tagStructure on save", async () => {
|
|
82
|
+
const tagStructure = jest.fn();
|
|
83
|
+
const props = { structureTag, tagStructure };
|
|
84
|
+
const { findByLabelText, findByRole, queryByRole } = render(
|
|
85
|
+
<StructureTagForm {...props} />
|
|
86
|
+
);
|
|
87
|
+
userEvent.type(await findByLabelText("Comments"), "bar");
|
|
88
|
+
userEvent.click(await findByLabelText(/Inherited/));
|
|
89
|
+
await waitFor(() => {
|
|
90
|
+
expect(queryByRole("button", { name: "Save" })).toBeEnabled();
|
|
91
|
+
});
|
|
92
|
+
userEvent.click(await findByRole("button", { name: "Save" }));
|
|
93
|
+
await waitFor(() => {
|
|
94
|
+
expect(tagStructure.mock.calls.length).toBe(1);
|
|
95
|
+
});
|
|
96
|
+
expect(tagStructure.mock.calls[0][0]).toEqual({
|
|
97
|
+
comment: "foobar",
|
|
98
|
+
dataStructureId: structureTag.dataStructureId,
|
|
99
|
+
id: structureTag.id,
|
|
100
|
+
inherit: true,
|
|
101
|
+
tagId: structureTag.tagId,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
62
104
|
|
|
105
|
+
it("calls deleteStructureTag on delete", async () => {
|
|
106
|
+
const deleteStructureTag = jest.fn();
|
|
107
|
+
const props = { structureTag, deleteStructureTag };
|
|
108
|
+
const { findByLabelText, findByRole, queryByRole } = render(
|
|
109
|
+
<StructureTagForm {...props} />
|
|
110
|
+
);
|
|
63
111
|
await waitFor(() => {
|
|
64
|
-
expect(
|
|
112
|
+
expect(queryByRole("button", { name: "Delete" })).toBeEnabled();
|
|
65
113
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
114
|
+
userEvent.type(await findByLabelText("Comments"), "bar");
|
|
115
|
+
userEvent.click(await findByRole("button", { name: "Delete" }));
|
|
116
|
+
await waitFor(() => {
|
|
117
|
+
expect(deleteStructureTag.mock.calls.length).toBe(1);
|
|
70
118
|
});
|
|
119
|
+
expect(deleteStructureTag).toHaveBeenCalledWith(structureTag.id);
|
|
71
120
|
});
|
|
72
121
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { shallow } from "enzyme";
|
|
3
|
+
import { Tag } from "../Tag";
|
|
4
|
+
|
|
5
|
+
describe("<Tag />", () => {
|
|
6
|
+
it("matches the latest snapshot", () => {
|
|
7
|
+
const createTag = jest.fn();
|
|
8
|
+
const wrapper = shallow(<Tag createTag={createTag} />);
|
|
9
|
+
expect(wrapper).toMatchSnapshot();
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { waitFor } from "@testing-library/react";
|
|
3
3
|
import { render } from "@truedat/test/render";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { TAGS_QUERY } from "../../api/queries";
|
|
5
|
+
import TagCards from "../TagCards";
|
|
6
6
|
import en from "../../messages/en";
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
request: { query:
|
|
8
|
+
const tagsMock = {
|
|
9
|
+
request: { query: TAGS_QUERY },
|
|
10
10
|
result: {
|
|
11
11
|
data: {
|
|
12
|
-
|
|
12
|
+
tags: [
|
|
13
13
|
{
|
|
14
|
-
__typename: "
|
|
14
|
+
__typename: "Tag",
|
|
15
15
|
id: "1",
|
|
16
16
|
name: "tag1",
|
|
17
17
|
description: "tag_desc_1",
|
|
@@ -19,7 +19,7 @@ const structureTagsMock = {
|
|
|
19
19
|
structureCount: 1,
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
|
-
__typename: "
|
|
22
|
+
__typename: "Tag",
|
|
23
23
|
id: "2",
|
|
24
24
|
name: "tag2",
|
|
25
25
|
description: "tag_desc_2",
|
|
@@ -32,11 +32,11 @@ const structureTagsMock = {
|
|
|
32
32
|
};
|
|
33
33
|
const messages = { en };
|
|
34
34
|
|
|
35
|
-
const renderOpts = { mocks: [
|
|
35
|
+
const renderOpts = { mocks: [tagsMock], messages };
|
|
36
36
|
|
|
37
|
-
describe("<
|
|
37
|
+
describe("<TagCards />", () => {
|
|
38
38
|
it("matches the latest snapshot, renders a link for each tag", async () => {
|
|
39
|
-
const { container, getByRole } = render(<
|
|
39
|
+
const { container, getByRole } = render(<TagCards />, renderOpts);
|
|
40
40
|
await waitFor(() => {
|
|
41
41
|
expect(getByRole("link", { name: /tag1/i })).toBeInTheDocument();
|
|
42
42
|
expect(getByRole("link", { name: /tag2/i })).toBeInTheDocument();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import TagCrumbs from "../TagCrumbs";
|
|
4
|
+
|
|
5
|
+
describe("<TagCrumbs />", () => {
|
|
6
|
+
it("matches the latest snapshot", () => {
|
|
7
|
+
const container = render(<TagCrumbs action="tags.actions.edit" />);
|
|
8
|
+
expect(container).toMatchSnapshot();
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { waitFor } from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import { render } from "@truedat/test/render";
|
|
5
|
+
import { DOMAINS_QUERY } from "@truedat/core/api/queries";
|
|
6
|
+
import TagForm from "../TagForm";
|
|
7
|
+
|
|
8
|
+
const domainsMock = {
|
|
9
|
+
request: { query: DOMAINS_QUERY },
|
|
10
|
+
result: { data: { domains: [{ id: "123", name: "foo" }] } },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const renderOpts = {
|
|
14
|
+
mocks: [domainsMock],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe("<TagForm />", () => {
|
|
18
|
+
const onSubmit = jest.fn();
|
|
19
|
+
const tag = {
|
|
20
|
+
id: 1,
|
|
21
|
+
name: "foo",
|
|
22
|
+
description: "bar",
|
|
23
|
+
domainIds: [],
|
|
24
|
+
};
|
|
25
|
+
const saving = false;
|
|
26
|
+
const props = {
|
|
27
|
+
onSubmit,
|
|
28
|
+
tag,
|
|
29
|
+
saving,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
it("matches the latest snapshot", async () => {
|
|
33
|
+
const { container, findByRole } = render(
|
|
34
|
+
<TagForm {...props} />,
|
|
35
|
+
renderOpts
|
|
36
|
+
);
|
|
37
|
+
await findByRole("button", { name: /save/i });
|
|
38
|
+
expect(container).toMatchSnapshot();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("calls onSubmit with data on submit", async () => {
|
|
42
|
+
const { getByRole } = render(<TagForm {...props} />, renderOpts);
|
|
43
|
+
|
|
44
|
+
// Submit button should initially be disabled
|
|
45
|
+
await waitFor(() =>
|
|
46
|
+
expect(getByRole("button", { name: /save/i })).toBeDisabled()
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Name
|
|
50
|
+
userEvent.type(getByRole("textbox", { name: /name/i }), "foo");
|
|
51
|
+
|
|
52
|
+
// Submit button should now be enabled
|
|
53
|
+
await waitFor(() =>
|
|
54
|
+
expect(getByRole("button", { name: /save/i })).not.toBeDisabled()
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Name
|
|
58
|
+
userEvent.type(getByRole("textbox", { name: /description/i }), "bar");
|
|
59
|
+
|
|
60
|
+
// Submit
|
|
61
|
+
userEvent.click(getByRole("button", { name: /save/i }));
|
|
62
|
+
|
|
63
|
+
await waitFor(() => {
|
|
64
|
+
expect(onSubmit.mock.calls.length).toBe(1);
|
|
65
|
+
});
|
|
66
|
+
expect(onSubmit.mock.calls[0][0]).toMatchObject({
|
|
67
|
+
name: "foofoo",
|
|
68
|
+
description: "barbar",
|
|
69
|
+
domainIds: [],
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import Tags from "../Tags";
|
|
4
|
+
|
|
5
|
+
describe("<Tags />", () => {
|
|
6
|
+
it("matches the latest snapshot", () => {
|
|
7
|
+
const { container } = render(<Tags />);
|
|
8
|
+
expect(container).toMatchSnapshot();
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -11,30 +11,15 @@ exports[`<StructureSummary /> matches the latest snapshot 1`] = `
|
|
|
11
11
|
<div
|
|
12
12
|
class="ten wide column"
|
|
13
13
|
>
|
|
14
|
-
<
|
|
15
|
-
class="
|
|
14
|
+
<h2
|
|
15
|
+
class="ui header"
|
|
16
16
|
>
|
|
17
|
-
<h2
|
|
18
|
-
class="ui header"
|
|
19
|
-
>
|
|
20
|
-
<div
|
|
21
|
-
class="content"
|
|
22
|
-
>
|
|
23
|
-
s1
|
|
24
|
-
</div>
|
|
25
|
-
</h2>
|
|
26
17
|
<div
|
|
27
|
-
class="
|
|
18
|
+
class="content"
|
|
28
19
|
>
|
|
29
|
-
|
|
30
|
-
class="content"
|
|
31
|
-
>
|
|
32
|
-
<div
|
|
33
|
-
class="ui loader"
|
|
34
|
-
/>
|
|
35
|
-
</div>
|
|
20
|
+
s1
|
|
36
21
|
</div>
|
|
37
|
-
</
|
|
22
|
+
</h2>
|
|
38
23
|
</div>
|
|
39
24
|
<div
|
|
40
25
|
class="right aligned six wide column"
|
|
@@ -74,6 +59,9 @@ exports[`<StructureSummary /> matches the latest snapshot 1`] = `
|
|
|
74
59
|
</div>
|
|
75
60
|
</div>
|
|
76
61
|
</div>
|
|
62
|
+
<div
|
|
63
|
+
class="ui active loader"
|
|
64
|
+
/>
|
|
77
65
|
<p
|
|
78
66
|
class="item-description"
|
|
79
67
|
>
|
|
@@ -167,35 +155,20 @@ exports[`<StructureSummary /> matches the latest snapshot with alias 1`] = `
|
|
|
167
155
|
<div
|
|
168
156
|
class="ten wide column"
|
|
169
157
|
>
|
|
170
|
-
<
|
|
171
|
-
class="
|
|
158
|
+
<h2
|
|
159
|
+
class="ui header"
|
|
172
160
|
>
|
|
173
|
-
<h2
|
|
174
|
-
class="ui header"
|
|
175
|
-
>
|
|
176
|
-
<div
|
|
177
|
-
class="content"
|
|
178
|
-
>
|
|
179
|
-
some alias
|
|
180
|
-
<div
|
|
181
|
-
class="sub header"
|
|
182
|
-
>
|
|
183
|
-
s1
|
|
184
|
-
</div>
|
|
185
|
-
</div>
|
|
186
|
-
</h2>
|
|
187
161
|
<div
|
|
188
|
-
class="
|
|
162
|
+
class="content"
|
|
189
163
|
>
|
|
164
|
+
some alias
|
|
190
165
|
<div
|
|
191
|
-
class="
|
|
166
|
+
class="sub header"
|
|
192
167
|
>
|
|
193
|
-
|
|
194
|
-
class="ui loader"
|
|
195
|
-
/>
|
|
168
|
+
s1
|
|
196
169
|
</div>
|
|
197
170
|
</div>
|
|
198
|
-
</
|
|
171
|
+
</h2>
|
|
199
172
|
</div>
|
|
200
173
|
<div
|
|
201
174
|
class="right aligned six wide column"
|
|
@@ -235,6 +208,9 @@ exports[`<StructureSummary /> matches the latest snapshot with alias 1`] = `
|
|
|
235
208
|
</div>
|
|
236
209
|
</div>
|
|
237
210
|
</div>
|
|
211
|
+
<div
|
|
212
|
+
class="ui active loader"
|
|
213
|
+
/>
|
|
238
214
|
<p
|
|
239
215
|
class="item-description"
|
|
240
216
|
>
|