@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.
Files changed (89) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +5 -5
  3. package/src/api/fragments.js +2 -2
  4. package/src/api/mutations.js +33 -11
  5. package/src/api/queries.js +37 -10
  6. package/src/api.js +0 -4
  7. package/src/components/DictionaryRoutes.js +4 -4
  8. package/src/components/StructureSummary.js +12 -22
  9. package/src/components/StructureTag.js +83 -54
  10. package/src/components/StructureTagForm.js +149 -89
  11. package/src/components/StructureTags.js +57 -27
  12. package/src/components/Tag.js +62 -0
  13. package/src/components/TagCards.js +85 -0
  14. package/src/components/TagCrumbs.js +25 -0
  15. package/src/components/TagForm.js +102 -0
  16. package/src/components/TagStructureButton.js +58 -0
  17. package/src/components/Tags.js +33 -0
  18. package/src/components/TagsRoutes.js +39 -0
  19. package/src/components/__tests__/StructureSummary.spec.js +0 -7
  20. package/src/components/__tests__/StructureTag.spec.js +79 -5
  21. package/src/components/__tests__/StructureTagForm.spec.js +99 -50
  22. package/src/components/__tests__/Tag.spec.js +11 -0
  23. package/src/components/__tests__/{StructureTagsCards.spec.js → TagCards.spec.js} +10 -10
  24. package/src/components/__tests__/TagCrumbs.spec.js +10 -0
  25. package/src/components/__tests__/TagForm.spec.js +72 -0
  26. package/src/components/__tests__/Tags.spec.js +10 -0
  27. package/src/components/__tests__/__snapshots__/StructureSummary.spec.js.snap +18 -42
  28. package/src/components/__tests__/__snapshots__/StructureTag.spec.js.snap +10 -30
  29. package/src/components/__tests__/__snapshots__/StructureTagForm.spec.js.snap +255 -51
  30. package/src/components/__tests__/__snapshots__/Tag.spec.js.snap +36 -0
  31. package/src/components/__tests__/__snapshots__/{StructureTagsCards.spec.js.snap → TagCards.spec.js.snap} +1 -1
  32. package/src/components/__tests__/__snapshots__/TagCrumbs.spec.js.snap +102 -0
  33. package/src/components/__tests__/__snapshots__/TagForm.spec.js.snap +70 -0
  34. package/src/components/__tests__/__snapshots__/{StructureTags.spec.js.snap → Tags.spec.js.snap} +1 -1
  35. package/src/messages/en.js +25 -30
  36. package/src/messages/es.js +25 -30
  37. package/src/reducers/__tests__/{editableStructureTags.spec.js → availableTags.spec.js} +7 -11
  38. package/src/reducers/__tests__/structureTagSaving.spec.js +36 -0
  39. package/src/reducers/__tests__/tagSaving.spec.js +32 -0
  40. package/src/reducers/{editableStructureTags.js → availableTags.js} +2 -2
  41. package/src/reducers/index.js +6 -12
  42. package/src/reducers/structureRedirect.js +7 -7
  43. package/src/reducers/structureTagSaving.js +12 -10
  44. package/src/reducers/tagSaving.js +18 -0
  45. package/src/routines.js +5 -6
  46. package/src/sagas/__tests__/createTag.spec.js +81 -0
  47. package/src/sagas/__tests__/deleteStructureTag.spec.js +11 -12
  48. package/src/sagas/__tests__/deleteTag.spec.js +76 -0
  49. package/src/sagas/__tests__/tagStructure.spec.js +86 -0
  50. package/src/sagas/__tests__/updateTag.spec.js +81 -0
  51. package/src/sagas/createTag.js +29 -0
  52. package/src/sagas/deleteStructureTag.js +12 -9
  53. package/src/sagas/deleteTag.js +34 -0
  54. package/src/sagas/index.js +15 -18
  55. package/src/sagas/tagStructure.js +37 -0
  56. package/src/sagas/updateTag.js +23 -0
  57. package/src/components/LinkStructureTagForm.js +0 -163
  58. package/src/components/LinkedStructureTag.js +0 -124
  59. package/src/components/StructureLinkTagButton.js +0 -47
  60. package/src/components/StructureTagsCards.js +0 -92
  61. package/src/components/StructureTagsCrumbs.js +0 -44
  62. package/src/components/StructureTagsRoutes.js +0 -45
  63. package/src/components/TagsHeader.js +0 -32
  64. package/src/components/__tests__/LinkStructureTagForm.spec.js +0 -184
  65. package/src/components/__tests__/LinkedStructureTag.spec.js +0 -133
  66. package/src/components/__tests__/StructureTags.spec.js +0 -14
  67. package/src/components/__tests__/StructureTagsCrumbs.spec.js +0 -13
  68. package/src/components/__tests__/__snapshots__/LinkStructureTagForm.spec.js.snap +0 -456
  69. package/src/components/__tests__/__snapshots__/LinkedStructureTag.spec.js.snap +0 -16
  70. package/src/components/__tests__/__snapshots__/StructureTagsCrumbs.spec.js.snap +0 -36
  71. package/src/reducers/__tests__/deletingStructureTags.spec.js +0 -30
  72. package/src/reducers/__tests__/linkedStructureTags.spec.js +0 -69
  73. package/src/reducers/__tests__/linkedStructureTagsLoading.spec.js +0 -32
  74. package/src/reducers/__tests__/linkingStructureTags.spec.js +0 -30
  75. package/src/reducers/__tests__/structureTagsSaving.spec.js +0 -40
  76. package/src/reducers/deletingStructureTags.js +0 -16
  77. package/src/reducers/linkedStructureTags.js +0 -28
  78. package/src/reducers/linkedStructureTagsLoading.js +0 -16
  79. package/src/reducers/linkingStructureTags.js +0 -16
  80. package/src/sagas/__tests__/createStructureTag.spec.js +0 -85
  81. package/src/sagas/__tests__/deleteLinkStructureTag.spec.js +0 -96
  82. package/src/sagas/__tests__/fetchLinksStructureTags.spec.js +0 -105
  83. package/src/sagas/__tests__/linkStructureTag.spec.js +0 -102
  84. package/src/sagas/__tests__/updateStructureTag.spec.js +0 -84
  85. package/src/sagas/createStructureTag.js +0 -29
  86. package/src/sagas/deleteLinkStructureTag.js +0 -29
  87. package/src/sagas/fetchLinksStructureTags.js +0 -31
  88. package/src/sagas/linkStructureTag.js +0 -30
  89. 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 { shallow } from "enzyme";
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 createStructureTag = jest.fn();
8
- const wrapper = shallow(
9
- <StructureTag createStructureTag={createStructureTag} />
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
- expect(wrapper).toMatchSnapshot();
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 { DOMAINS_QUERY } from "@truedat/core/api/queries";
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 onSubmit = jest.fn();
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: 1,
21
- name: "foo",
22
- description: "bar",
23
- domainIds: [],
24
- };
25
- const saving = false;
26
- const props = {
27
- onSubmit,
28
- structureTag,
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 { container, findByRole } = render(
34
- <StructureTagForm {...props} />,
35
- renderOpts
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: /save/i });
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("calls onSubmit with data on submit", async () => {
42
- const { getByRole } = render(<StructureTagForm {...props} />, renderOpts);
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
- // Submit button should initially be disabled
45
- await waitFor(() =>
46
- expect(getByRole("button", { name: /save/i })).toBeDisabled()
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
- // Name
50
- userEvent.type(getByRole("textbox", { name: /name/i }), "foo");
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
- // Submit button should now be enabled
53
- await waitFor(() =>
54
- expect(getByRole("button", { name: /save/i })).not.toBeDisabled()
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
- // Name
58
- userEvent.type(getByRole("textbox", { name: /description/i }), "bar");
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
- // Submit
61
- userEvent.click(getByRole("button", { name: /save/i }));
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(onSubmit.mock.calls.length).toBe(1);
112
+ expect(queryByRole("button", { name: "Delete" })).toBeEnabled();
65
113
  });
66
- expect(onSubmit.mock.calls[0][0]).toMatchObject({
67
- name: "foofoo",
68
- description: "barbar",
69
- domainIds: [],
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 { STRUCTURE_TAGS_QUERY } from "../../api/queries";
5
- import StructureTagsCards from "../StructureTagsCards";
4
+ import { TAGS_QUERY } from "../../api/queries";
5
+ import TagCards from "../TagCards";
6
6
  import en from "../../messages/en";
7
7
 
8
- const structureTagsMock = {
9
- request: { query: STRUCTURE_TAGS_QUERY },
8
+ const tagsMock = {
9
+ request: { query: TAGS_QUERY },
10
10
  result: {
11
11
  data: {
12
- structureTags: [
12
+ tags: [
13
13
  {
14
- __typename: "StructureTag",
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: "StructureTag",
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: [structureTagsMock], messages };
35
+ const renderOpts = { mocks: [tagsMock], messages };
36
36
 
37
- describe("<StructureTagsCards />", () => {
37
+ describe("<TagCards />", () => {
38
38
  it("matches the latest snapshot, renders a link for each tag", async () => {
39
- const { container, getByRole } = render(<StructureTagsCards />, renderOpts);
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
- <div
15
- class="dimmable"
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="ui inverted dimmer"
18
+ class="content"
28
19
  >
29
- <div
30
- class="content"
31
- >
32
- <div
33
- class="ui loader"
34
- />
35
- </div>
20
+ s1
36
21
  </div>
37
- </div>
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
- <div
171
- class="dimmable"
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="ui inverted dimmer"
162
+ class="content"
189
163
  >
164
+ some alias
190
165
  <div
191
- class="content"
166
+ class="sub header"
192
167
  >
193
- <div
194
- class="ui loader"
195
- />
168
+ s1
196
169
  </div>
197
170
  </div>
198
- </div>
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
  >