@truedat/dd 5.5.2 → 5.6.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 (40) hide show
  1. package/package.json +6 -6
  2. package/src/components/GrantRemoval.js +6 -3
  3. package/src/components/GrantRequestCancel.js +4 -2
  4. package/src/components/GrantRoutes.js +27 -0
  5. package/src/components/StructureGrantCart.js +19 -12
  6. package/src/components/StructureGrantDropdown.js +25 -35
  7. package/src/components/StructureGrantListButton.js +85 -0
  8. package/src/components/StructureGrantRequestButton.js +1 -21
  9. package/src/components/StructureGrantSummaryButton.js +87 -0
  10. package/src/components/StructureRow.js +10 -6
  11. package/src/components/StructureSummary.js +4 -2
  12. package/src/components/StructuresGrantRequest.js +0 -0
  13. package/src/components/StructuresGrantRequestView.js +68 -0
  14. package/src/components/StructuresLoader.js +4 -2
  15. package/src/components/StructuresSearch.js +1 -0
  16. package/src/components/StructuresSearchResults.js +3 -0
  17. package/src/components/StructuresTable.js +37 -24
  18. package/src/components/StructuresView.js +9 -10
  19. package/src/components/__tests__/StructureGrantDropdown.spec.js +66 -29
  20. package/src/components/__tests__/StructureGrantListButton.spec.js +77 -0
  21. package/src/components/__tests__/{StructureGrantButton.spec.js → StructureGrantSummaryButton.spec.js} +9 -9
  22. package/src/components/__tests__/StructureRow.spec.js +10 -10
  23. package/src/components/__tests__/StructuresGrantRequestView.spec.js +83 -0
  24. package/src/components/__tests__/StructuresLoader.spec.js +1 -1
  25. package/src/components/__tests__/__snapshots__/GrantRoutes.spec.js.snap +4 -0
  26. package/src/components/__tests__/__snapshots__/StructureGrantListButton.spec.js.snap +159 -0
  27. package/src/components/__tests__/__snapshots__/{StructureGrantButton.spec.js.snap → StructureGrantSummaryButton.spec.js.snap} +5 -5
  28. package/src/components/__tests__/__snapshots__/StructureRow.spec.js.snap +4 -1
  29. package/src/components/__tests__/__snapshots__/StructuresGrantRequestView.spec.js.snap +310 -0
  30. package/src/components/__tests__/__snapshots__/StructuresLoader.spec.js.snap +3 -1
  31. package/src/components/__tests__/__snapshots__/StructuresTable.spec.js.snap +21 -12
  32. package/src/messages/en.js +4 -0
  33. package/src/messages/es.js +5 -0
  34. package/src/reducers/structureActiveFilters.js +10 -9
  35. package/src/reducers/structureSelectedFilter.js +1 -1
  36. package/src/reducers/structures.js +5 -0
  37. package/src/sagas/createGrantRequestStatus.js +12 -3
  38. package/src/sagas/requestGrantRemoval.js +13 -3
  39. package/src/selectors/structureColumnsSelector.js +16 -6
  40. package/src/components/StructureGrantButton.js +0 -43
@@ -8,6 +8,7 @@ export const StructuresLoader = ({
8
8
  clearStructures,
9
9
  fetchStructures,
10
10
  payload,
11
+ withGrantRequests,
11
12
  }) => {
12
13
  useEffect(() => {
13
14
  return () => {
@@ -15,8 +16,8 @@ export const StructuresLoader = ({
15
16
  };
16
17
  }, [clearStructures]);
17
18
  useEffect(() => {
18
- fetchStructures(payload);
19
- }, [payload, fetchStructures]);
19
+ fetchStructures({ ...payload, my_grant_requests: !!withGrantRequests });
20
+ }, [payload, fetchStructures, withGrantRequests]);
20
21
  return null;
21
22
  };
22
23
 
@@ -24,6 +25,7 @@ StructuresLoader.propTypes = {
24
25
  clearStructures: PropTypes.func,
25
26
  fetchStructures: PropTypes.func,
26
27
  payload: PropTypes.object,
28
+ withGrantRequests: PropTypes.bool,
27
29
  };
28
30
 
29
31
  const makeMapStateToProps = () => {
@@ -13,6 +13,7 @@ const StructuresSearch = ({
13
13
  toggleStructureDateFilter,
14
14
  }) => {
15
15
  const { formatMessage } = useIntl();
16
+
16
17
  return (
17
18
  <Input
18
19
  value={query}
@@ -10,6 +10,7 @@ import StructuresLabelResults from "./StructuresLabelResults";
10
10
 
11
11
  export const StructuresSearchResults = ({
12
12
  columns,
13
+ grantable,
13
14
  size,
14
15
  onSelect,
15
16
  selectedStructure,
@@ -27,6 +28,7 @@ export const StructuresSearchResults = ({
27
28
  <StructuresLabelResults />
28
29
  <StructuresTable
29
30
  columns={columns}
31
+ grantable={grantable}
30
32
  size={size}
31
33
  selectedStructure={selectedStructure}
32
34
  structures={structures}
@@ -54,6 +56,7 @@ export const StructuresSearchResults = ({
54
56
 
55
57
  StructuresSearchResults.propTypes = {
56
58
  columns: PropTypes.array,
59
+ grantable: PropTypes.bool,
57
60
  size: PropTypes.string,
58
61
  onSelect: PropTypes.func,
59
62
  structures: PropTypes.array,
@@ -44,6 +44,7 @@ export class StructuresTable extends React.Component {
44
44
  render() {
45
45
  const {
46
46
  columns,
47
+ grantable,
47
48
  onStructureSelected,
48
49
  selectedStructure,
49
50
  size,
@@ -65,31 +66,41 @@ export class StructuresTable extends React.Component {
65
66
  ? structures
66
67
  : [selectedStructure, ...structures]
67
68
  : structures;
68
- const headerRow = columns.map((column, key) => (
69
- <Table.HeaderCell
70
- key={key}
71
- content={
72
- <FormattedMessage
73
- id={`structure.${column.header || column.name}`}
69
+ const headerRow = (
70
+ <Table.Row>
71
+ {columns.map((column, key) => (
72
+ <Table.HeaderCell
73
+ key={key}
74
+ content={
75
+ <FormattedMessage
76
+ id={`structure.${column.header || column.name}`}
77
+ />
78
+ }
79
+ sorted={
80
+ _.path("sort.name")(column) === sortedColumn ? direction : null
81
+ }
82
+ className={_.path("sort.name")(column) ? "" : "disabled"}
83
+ onClick={() =>
84
+ sortColumn(
85
+ column,
86
+ sortStructures,
87
+ this.setDirection,
88
+ this.setColumn,
89
+ direction,
90
+ sortedColumn
91
+ )
92
+ }
93
+ width={_.propOr(1, "width")(column)}
74
94
  />
75
- }
76
- sorted={
77
- _.path("sort.name")(column) === sortedColumn ? direction : null
78
- }
79
- className={_.path("sort.name")(column) ? "" : "disabled"}
80
- onClick={() =>
81
- sortColumn(
82
- column,
83
- sortStructures,
84
- this.setDirection,
85
- this.setColumn,
86
- direction,
87
- sortedColumn
88
- )
89
- }
90
- width={_.propOr(1, "width")(column)}
91
- />
92
- ));
95
+ ))}
96
+ {grantable && (
97
+ <Table.HeaderCell textAlign="center">
98
+ Request grant
99
+ </Table.HeaderCell>
100
+ )}
101
+ </Table.Row>
102
+ );
103
+
93
104
  const renderBodyRow = (s, i) => (
94
105
  <StructureRow
95
106
  key={i}
@@ -98,6 +109,7 @@ export class StructuresTable extends React.Component {
98
109
  active={selectedStructure && _.propEq("id", s.id)(selectedStructure)}
99
110
  positive={isPositive(links, s.id)}
100
111
  onClick={onStructureSelected}
112
+ grantable={grantable}
101
113
  />
102
114
  );
103
115
  return (
@@ -115,6 +127,7 @@ export class StructuresTable extends React.Component {
115
127
  }
116
128
 
117
129
  StructuresTable.propTypes = {
130
+ grantable: PropTypes.bool,
118
131
  columns: PropTypes.array.isRequired,
119
132
  onStructureSelected: PropTypes.func,
120
133
  selectedStructure: PropTypes.object,
@@ -55,6 +55,7 @@ const StructuresViewContent = ({
55
55
 
56
56
  StructuresViewContent.propTypes = {
57
57
  actions: PropTypes.object,
58
+ grantable: PropTypes.bool,
58
59
  structures: PropTypes.array,
59
60
  loading: PropTypes.bool,
60
61
  hasFilterApplied: PropTypes.bool,
@@ -91,15 +92,13 @@ const selectedFilters = ({ structureActiveFilters, structureDateFilter }) =>
91
92
 
92
93
  const isEmptyPath = (state, path) => _.flow(_.path(path), _.isEmpty)(state);
93
94
 
94
- const mapStateToProps = (state) => {
95
- return {
96
- structures: structureRowsSelector(state),
97
- actions: state.structuresActions,
98
- loading: state.structuresLoading,
99
- systemsLoading: state.systemsLoading,
100
- hasFilterApplied:
101
- !isEmptyPath(state, "structureQuery.query") || selectedFilters(state),
102
- };
103
- };
95
+ const mapStateToProps = (state) => ({
96
+ structures: structureRowsSelector(state),
97
+ actions: state.structuresActions,
98
+ loading: state.structuresLoading,
99
+ systemsLoading: state.systemsLoading,
100
+ hasFilterApplied:
101
+ !isEmptyPath(state, "structureQuery.query") || selectedFilters(state),
102
+ });
104
103
 
105
104
  export default connect(mapStateToProps)(StructuresView);
@@ -1,4 +1,3 @@
1
- import _ from "lodash/fp";
2
1
  import React from "react";
3
2
  import { fireEvent } from "@testing-library/react";
4
3
  import { render } from "@truedat/test/render";
@@ -6,12 +5,13 @@ import userEvent from "@testing-library/user-event";
6
5
  import StructureGrantDropdown from "../StructureGrantDropdown";
7
6
  import en from "../../messages/en";
8
7
 
9
- const renderOptsBuilder = (grant, structureGrantPopup) => ({
10
- state: {
11
- structure: { grant },
12
- structureGrantPopup,
13
- },
14
- messages: { en },
8
+ const renderOpts = { messages: { en } };
9
+
10
+ const propsBuilder = (grant, structureGrantPopup, requested) => ({
11
+ structure: { grant },
12
+ grant,
13
+ structureGrantPopup,
14
+ requested,
15
15
  });
16
16
 
17
17
  const mockHistory = {
@@ -25,12 +25,17 @@ jest.mock("react-router-dom", () => ({
25
25
 
26
26
  describe("<StructureGrantDropdown />", () => {
27
27
  it("matches the latest snapshot for pendingRequest state", () => {
28
+ const status = "pending";
28
29
  const grantRequest = {
29
- status: { status: "pending" },
30
+ status: { status },
31
+ };
32
+ const props = {
33
+ ...propsBuilder({}),
34
+ grantRequest,
35
+ grantRequestStatus: status,
30
36
  };
31
- const renderOpts = renderOptsBuilder({});
32
37
  const { container } = render(
33
- <StructureGrantDropdown grantRequest={grantRequest} />,
38
+ <StructureGrantDropdown {...props} />,
34
39
  renderOpts
35
40
  );
36
41
 
@@ -38,13 +43,18 @@ describe("<StructureGrantDropdown />", () => {
38
43
  });
39
44
 
40
45
  it("matches the latest snapshot for pendingRequest state with modification", () => {
46
+ const status = "pending";
41
47
  const grantRequest = {
42
48
  group: { grant: { id: 1 } },
43
- status: { status: "pending" },
49
+ status: { status },
50
+ };
51
+ const props = {
52
+ ...propsBuilder({}),
53
+ grantRequest,
54
+ grantRequestStatus: status,
44
55
  };
45
- const renderOpts = renderOptsBuilder({});
46
56
  const { container } = render(
47
- <StructureGrantDropdown grantRequest={grantRequest} />,
57
+ <StructureGrantDropdown {...props} />,
48
58
  renderOpts
49
59
  );
50
60
 
@@ -52,12 +62,17 @@ describe("<StructureGrantDropdown />", () => {
52
62
  });
53
63
 
54
64
  it("matches the latest snapshot for processingRequest state", () => {
65
+ const status = "processing";
55
66
  const grantRequest = {
56
- status: { status: "processing" },
67
+ status: { status },
68
+ };
69
+ const props = {
70
+ ...propsBuilder({}),
71
+ grantRequest,
72
+ grantRequestStatus: status,
57
73
  };
58
- const renderOpts = renderOptsBuilder({});
59
74
  const { container } = render(
60
- <StructureGrantDropdown grantRequest={grantRequest} />,
75
+ <StructureGrantDropdown {...props} />,
61
76
  renderOpts
62
77
  );
63
78
 
@@ -65,13 +80,18 @@ describe("<StructureGrantDropdown />", () => {
65
80
  });
66
81
 
67
82
  it("matches the latest snapshot for processingRequest state with modification", () => {
83
+ const status = "processing";
68
84
  const grantRequest = {
69
85
  group: { grant: { id: 1 } },
70
- status: { status: "processing" },
86
+ status: { status },
87
+ };
88
+ const props = {
89
+ ...propsBuilder({}),
90
+ grantRequest,
91
+ grantRequestStatus: status,
71
92
  };
72
- const renderOpts = renderOptsBuilder({});
73
93
  const { container } = render(
74
- <StructureGrantDropdown grantRequest={grantRequest} />,
94
+ <StructureGrantDropdown {...props} />,
75
95
  renderOpts
76
96
  );
77
97
 
@@ -80,9 +100,13 @@ describe("<StructureGrantDropdown />", () => {
80
100
 
81
101
  it("matches the latest snapshot for pendingRemovalGrant state", () => {
82
102
  const grantRequest = null;
83
- const renderOpts = renderOptsBuilder({ pending_removal: true });
103
+ const props = {
104
+ ...propsBuilder({ pending_removal: true }),
105
+ grantRequest,
106
+ grantRequestStatus: null,
107
+ };
84
108
  const { container } = render(
85
- <StructureGrantDropdown grantRequest={grantRequest} />,
109
+ <StructureGrantDropdown {...props} />,
86
110
  renderOpts
87
111
  );
88
112
 
@@ -91,9 +115,13 @@ describe("<StructureGrantDropdown />", () => {
91
115
 
92
116
  it("matches the latest snapshot for activeGrant state", () => {
93
117
  const grantRequest = null;
94
- const renderOpts = renderOptsBuilder({ pending_removal: false });
118
+ const props = {
119
+ ...propsBuilder({ pending_removal: false }),
120
+ grantRequest,
121
+ grantRequestStatus: null,
122
+ };
95
123
  const { container } = render(
96
- <StructureGrantDropdown grantRequest={grantRequest} />,
124
+ <StructureGrantDropdown {...props} />,
97
125
  renderOpts
98
126
  );
99
127
 
@@ -113,9 +141,13 @@ describe("<StructureGrantDropdown />", () => {
113
141
  foo: "bar",
114
142
  },
115
143
  };
116
- const renderOpts = renderOptsBuilder(grant, structureGrantPopup);
117
- const { findByRole, findByText, debug } = render(
118
- <StructureGrantDropdown grantRequest={grantRequest} />,
144
+ const props = {
145
+ ...propsBuilder(grant, structureGrantPopup),
146
+ grantRequest,
147
+ grantRequestStatus: null,
148
+ };
149
+ const { findByRole, findByText } = render(
150
+ <StructureGrantDropdown {...props} />,
119
151
  renderOpts
120
152
  );
121
153
 
@@ -128,14 +160,19 @@ describe("<StructureGrantDropdown />", () => {
128
160
  });
129
161
 
130
162
  it("when clicking on viewRequest action, will redirect to grantResquest page", async () => {
163
+ const status = "pending";
131
164
  const grantRequest = {
132
165
  id: 8,
133
- status: { status: "pending" },
166
+ status: { status },
167
+ };
168
+ const props = {
169
+ ...propsBuilder({}),
170
+ grantRequest,
171
+ grantRequestStatus: status,
134
172
  };
135
- const renderOpts = renderOptsBuilder({});
136
173
 
137
174
  const { findByText } = render(
138
- <StructureGrantDropdown grantRequest={grantRequest} />,
175
+ <StructureGrantDropdown {...props} />,
139
176
  renderOpts
140
177
  );
141
178
 
@@ -0,0 +1,77 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import StructureGrantListButton from "../StructureGrantListButton";
4
+
5
+ const structure = {
6
+ id: 151596,
7
+ my_grants: [],
8
+ my_grant_request: null,
9
+ external_id: "structure_ext_id",
10
+ data_fields: [
11
+ {
12
+ external_id: "child_ext_id",
13
+ id: 151597,
14
+ },
15
+ ],
16
+ user_permissions: {
17
+ create_foreign_grant_request: true,
18
+ request_grant: true,
19
+ },
20
+ };
21
+
22
+ const renderOpts = {
23
+ state: {
24
+ structureGrantPopup: ["structureGrantPopup"],
25
+ previousStructureQuery: { foo: "bar" },
26
+ grantRequestsCart: {
27
+ structures: [{ id: 1 }],
28
+ },
29
+ },
30
+ fallback: "lazy",
31
+ };
32
+
33
+ describe("<StructureGrantListButton />", () => {
34
+ it("matches the latest snapshot", () => {
35
+ const { container } = render(
36
+ <StructureGrantListButton structure={structure} />,
37
+ renderOpts
38
+ );
39
+ expect(container).toMatchSnapshot();
40
+ });
41
+
42
+ it("matches the latest snapshot for requested structure", () => {
43
+ const { container } = render(
44
+ <StructureGrantListButton structure={{ ...structure, id: 1 }} />,
45
+ renderOpts
46
+ );
47
+ expect(container).toMatchSnapshot();
48
+ });
49
+
50
+ it("matches the latest snapshot with grant", () => {
51
+ const { container } = render(
52
+ <StructureGrantListButton
53
+ structure={{
54
+ ...structure,
55
+ my_grants: [
56
+ {
57
+ id: 2,
58
+ user_id: 564,
59
+ },
60
+ ],
61
+ }}
62
+ />,
63
+ renderOpts
64
+ );
65
+ expect(container).toMatchSnapshot();
66
+ });
67
+
68
+ it("matches the latest snapshot with grant request", () => {
69
+ const { container } = render(
70
+ <StructureGrantListButton
71
+ structure={{ ...structure, my_grant_request: { status: "pending" } }}
72
+ />,
73
+ renderOpts
74
+ );
75
+ expect(container).toMatchSnapshot();
76
+ });
77
+ });
@@ -1,9 +1,8 @@
1
- import _ from "lodash/fp";
2
1
  import React from "react";
3
2
  import { waitFor } from "@testing-library/react";
4
3
  import { render } from "@truedat/test/render";
5
4
  import { LATEST_GRANT_REQUEST_QUERY } from "../../api/queries";
6
- import StructureGrantButton from "../StructureGrantButton";
5
+ import StructureGrantSummaryButton from "../StructureGrantSummaryButton";
7
6
  import en from "../../messages/en";
8
7
 
9
8
  const latestGrantMockBuilder = (status) => ({
@@ -42,14 +41,15 @@ const expectToRenderRequestButton = async (container, getByRole) => {
42
41
  expect(container.getElementsByClassName("dropdown")).toHaveLength(0);
43
42
  expect(await getByRole("button")).toBeTruthy();
44
43
  };
45
- describe("<StructureGrantButton />", () => {
44
+ describe("<StructureGrantSummaryButton />", () => {
46
45
  it("matches snapshot for active grant and inactive grantRequest", async () => {
47
- const renderOpts = renderOptsBuilder("processed", {});
46
+ const renderOpts = renderOptsBuilder("processed", { id: 1 });
48
47
 
49
48
  const { container, queryByText } = render(
50
- <StructureGrantButton />,
49
+ <StructureGrantSummaryButton />,
51
50
  renderOpts
52
51
  );
52
+
53
53
  await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
54
54
  await waitFor(() =>
55
55
  expect(queryByText(/loading/i)).not.toBeInTheDocument()
@@ -63,7 +63,7 @@ describe("<StructureGrantButton />", () => {
63
63
  const renderOpts = renderOptsBuilder("pending", {});
64
64
 
65
65
  const { container, queryByText } = render(
66
- <StructureGrantButton />,
66
+ <StructureGrantSummaryButton />,
67
67
  renderOpts
68
68
  );
69
69
  await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
@@ -79,7 +79,7 @@ describe("<StructureGrantButton />", () => {
79
79
  const renderOpts = renderOptsBuilder("approved", null);
80
80
 
81
81
  const { container, queryByText } = render(
82
- <StructureGrantButton />,
82
+ <StructureGrantSummaryButton />,
83
83
  renderOpts
84
84
  );
85
85
  await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
@@ -95,7 +95,7 @@ describe("<StructureGrantButton />", () => {
95
95
  const renderOpts = renderOptsBuilder("cancelled", null);
96
96
 
97
97
  const { container, getByRole, queryByText } = render(
98
- <StructureGrantButton />,
98
+ <StructureGrantSummaryButton />,
99
99
  renderOpts
100
100
  );
101
101
  await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
@@ -111,7 +111,7 @@ describe("<StructureGrantButton />", () => {
111
111
  const renderOpts = renderOptsBuilder(null, null);
112
112
 
113
113
  const { container, getByRole, queryByText } = render(
114
- <StructureGrantButton />,
114
+ <StructureGrantSummaryButton />,
115
115
  renderOpts
116
116
  );
117
117
  await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
@@ -11,13 +11,13 @@ describe("<StructureRow />", () => {
11
11
  name: "s1",
12
12
  description: "dd",
13
13
  group: "gp",
14
- system: "sys"
14
+ system: "sys",
15
15
  };
16
16
  const columns = [
17
17
  { name: "name" },
18
18
  { name: "domain", fieldSelector: _.path("domain.name") },
19
19
  { name: "system" },
20
- { name: "group" }
20
+ { name: "group" },
21
21
  ];
22
22
  const props = { structure, columns };
23
23
  const wrapper = shallow(<StructureRow {...props} />);
@@ -31,18 +31,18 @@ describe("<StructureRow />", () => {
31
31
  name: "s1",
32
32
  description: "dd",
33
33
  group: "gp",
34
- system: "sys"
34
+ system: "sys",
35
35
  };
36
36
  const columns = [
37
37
  { name: "name" },
38
38
  { name: "domain", fieldSelector: _.path("domain.name") },
39
39
  { name: "system" },
40
- { name: "group" }
40
+ { name: "group" },
41
41
  ];
42
42
  const onClick = jest.fn();
43
43
  const props = { structure, columns, onClick };
44
44
  const wrapper = shallow(<StructureRow {...props} />);
45
- wrapper.find("TableRow").simulate("click");
45
+ wrapper.find("TableCell").first().simulate("click");
46
46
  expect(onClick.mock.calls.length).toBe(1);
47
47
  expect(onClick.mock.calls[0][0]).toEqual(structure);
48
48
  });
@@ -51,13 +51,13 @@ describe("<StructureRow />", () => {
51
51
  const testValue = "value";
52
52
  const structure = {
53
53
  id: 1,
54
- testObject: { internalValue: testValue }
54
+ testObject: { internalValue: testValue },
55
55
  };
56
56
  const columns = [
57
57
  {
58
58
  name: "testObject",
59
- fieldSelector: ({ testObject: { internalValue } }) => internalValue
60
- }
59
+ fieldSelector: ({ testObject: { internalValue } }) => internalValue,
60
+ },
61
61
  ];
62
62
  const props = { structure, columns };
63
63
  const wrapper = shallow(<StructureRow {...props} />);
@@ -65,11 +65,11 @@ describe("<StructureRow />", () => {
65
65
  });
66
66
 
67
67
  it("row prints field decorator", () => {
68
- const fieldDecorator = x => x + "_decorated";
68
+ const fieldDecorator = (x) => x + "_decorated";
69
69
  const testValue = "value";
70
70
  const structure = {
71
71
  id: 1,
72
- testObject: testValue
72
+ testObject: testValue,
73
73
  };
74
74
  const columns = [{ name: "testObject", fieldDecorator }];
75
75
  const props = { structure, columns };
@@ -0,0 +1,83 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { waitFor } from "@testing-library/react";
4
+ import { within } from "@testing-library/dom";
5
+ import userEvent from "@testing-library/user-event";
6
+ import { functionsMock } from "@truedat/test/mocks";
7
+
8
+ import StructuresGrantRequestView from "../StructuresGrantRequestView";
9
+
10
+ const mockHistory = { push: jest.fn() };
11
+
12
+ jest.mock("react-router-dom", () => ({
13
+ ...jest.requireActual("react-router-dom"),
14
+ useLocation: () => ({ pathname: "/bar" }),
15
+ useHistory: () => mockHistory,
16
+ }));
17
+
18
+ const dispatch = jest.fn();
19
+ describe("<StructuresGrantRequestView />", () => {
20
+ const structures = [1, 2, 3].map((id) => ({
21
+ id,
22
+ name: `structure_${id}`,
23
+ type: "table",
24
+ external_id: `structure_ext_id_${id}`,
25
+ my_grants: [],
26
+ my_grant_request: null,
27
+ user_permissions: {
28
+ request_grant: true,
29
+ },
30
+ updated_at: "2023-04-27",
31
+ }));
32
+
33
+ const renderOpts = {
34
+ mocks: [functionsMock],
35
+ state: {
36
+ structures,
37
+ structureCount: 3,
38
+ userPermissions: {
39
+ request_grant: true,
40
+ },
41
+ },
42
+ dispatch,
43
+ fallback: "lazy",
44
+ };
45
+
46
+ it("Clicking a grant request button triggers action", async () => {
47
+ const { container, queryByText } = render(
48
+ <StructuresGrantRequestView />,
49
+ renderOpts
50
+ );
51
+ await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
52
+ await waitFor(() =>
53
+ expect(queryByText(/loading/i)).not.toBeInTheDocument()
54
+ );
55
+ await waitFor(() => expect(container).toMatchSnapshot());
56
+
57
+ const structure1Row = await queryByText(/structure_1/).closest("tr");
58
+ const structure1ReqButton = within(structure1Row).getByRole("button");
59
+
60
+ userEvent.click(structure1ReqButton);
61
+
62
+ await waitFor(() => {
63
+ expect(dispatch).toHaveBeenCalledWith({
64
+ payload: {
65
+ external_id: "structure_ext_id_1",
66
+ hasDataFields: false,
67
+ id: "1",
68
+ my_grant_request: null,
69
+ my_grants: [],
70
+ name: "structure_1",
71
+ structureFields: [],
72
+ structure_type: undefined,
73
+ type: "table",
74
+ updated_at: "2023-04-27",
75
+ user_permissions: {
76
+ request_grant: true,
77
+ },
78
+ },
79
+ type: "ADD_GRANT_REQUEST_TO_CART/TRIGGER",
80
+ });
81
+ });
82
+ });
83
+ });
@@ -6,7 +6,7 @@ const getProps = () => ({
6
6
  clearStructures: jest.fn(),
7
7
  payload: {},
8
8
  structuresLoading: false,
9
- fetchStructures: jest.fn()
9
+ fetchStructures: jest.fn(),
10
10
  });
11
11
 
12
12
  describe("<StructuresLoader />", () => {
@@ -52,6 +52,10 @@ exports[`<GrantRoutes /> matches the latest snapshot 1`] = `
52
52
  render={[Function]}
53
53
  />
54
54
  </Switch>
55
+ <Route
56
+ path="/structuresGrantRequests"
57
+ render={[Function]}
58
+ />
55
59
  <Route
56
60
  path="/grantRequests"
57
61
  render={[Function]}