@truedat/auth 7.5.9 → 7.5.10

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 (160) hide show
  1. package/package.json +40 -64
  2. package/src/groups/components/EditGroup.js +0 -1
  3. package/src/groups/components/Group.js +0 -1
  4. package/src/groups/components/GroupBreadcrumbs.js +1 -2
  5. package/src/groups/components/GroupCard.js +3 -3
  6. package/src/groups/components/GroupCards.js +2 -3
  7. package/src/groups/components/GroupForm.js +0 -1
  8. package/src/groups/components/GroupLoader.js +19 -51
  9. package/src/groups/components/GroupUsers.js +4 -3
  10. package/src/groups/components/GroupUsersTable.js +4 -4
  11. package/src/groups/components/GroupsLoader.js +2 -2
  12. package/src/groups/components/GroupsSearchLoader.js +1 -1
  13. package/src/groups/components/NewGroup.js +0 -1
  14. package/src/groups/components/__tests__/Group.spec.js +0 -1
  15. package/src/groups/components/__tests__/GroupCard.spec.js +23 -7
  16. package/src/groups/components/__tests__/GroupCards.spec.js +9 -6
  17. package/src/groups/components/__tests__/GroupLoader.spec.js +71 -0
  18. package/src/groups/components/__tests__/GroupUsers.spec.js +8 -12
  19. package/src/groups/components/__tests__/GroupUsersTable.spec.js +34 -42
  20. package/src/groups/components/__tests__/GroupsSearchLoader.spec.js +0 -1
  21. package/src/groups/components/__tests__/__snapshots__/Group.spec.js.snap +1 -2
  22. package/src/groups/components/__tests__/__snapshots__/GroupCard.spec.js.snap +43 -94
  23. package/src/groups/components/__tests__/__snapshots__/GroupCards.spec.js.snap +118 -53
  24. package/src/groups/components/__tests__/__snapshots__/GroupLoader.spec.js.snap +11 -0
  25. package/src/groups/components/__tests__/__snapshots__/GroupUsers.spec.js.snap +38 -45
  26. package/src/groups/components/__tests__/__snapshots__/GroupUsersTable.spec.js.snap +121 -213
  27. package/src/groups/components/index.js +1 -1
  28. package/src/groups/sagas/__tests__/deleteGroupUser.spec.js +6 -6
  29. package/src/groups/sagas/deleteGroup.js +1 -1
  30. package/src/groups/sagas/deleteGroupUser.js +2 -2
  31. package/src/groups/sagas/fetchGroup.js +1 -1
  32. package/src/groups/sagas/updateGroup.js +1 -1
  33. package/src/roles/components/NewRole.js +0 -1
  34. package/src/roles/components/PermissionGroup.js +0 -1
  35. package/src/roles/components/Role.js +8 -3
  36. package/src/roles/components/RoleCards.js +2 -3
  37. package/src/roles/components/RoleForm.js +1 -1
  38. package/src/roles/components/RoleLoader.js +26 -39
  39. package/src/roles/components/RoleRoutes.js +29 -32
  40. package/src/roles/components/RoleSelector.js +0 -1
  41. package/src/roles/components/Roles.js +1 -3
  42. package/src/roles/components/RolesLoader.js +2 -2
  43. package/src/roles/components/__tests__/PermissionGroup.spec.js +7 -17
  44. package/src/roles/components/__tests__/Role.spec.js +0 -1
  45. package/src/roles/components/__tests__/RoleCards.spec.js +11 -10
  46. package/src/roles/components/__tests__/RoleRoutes.spec.js +53 -7
  47. package/src/roles/components/__tests__/RoleSelector.spec.js +0 -1
  48. package/src/roles/components/__tests__/Roles.spec.js +2 -3
  49. package/src/roles/components/__tests__/__snapshots__/PermissionGroup.spec.js.snap +3 -5
  50. package/src/roles/components/__tests__/__snapshots__/Role.spec.js.snap +4 -4
  51. package/src/roles/components/__tests__/__snapshots__/RoleCards.spec.js.snap +57 -127
  52. package/src/roles/components/__tests__/__snapshots__/RoleRoutes.spec.js.snap +38 -5
  53. package/src/roles/components/__tests__/__snapshots__/RoleSelector.spec.js.snap +1 -1
  54. package/src/roles/components/__tests__/__snapshots__/Roles.spec.js.snap +6 -3
  55. package/src/roles/components/index.js +1 -1
  56. package/src/roles/reducers/rolePermissions.js +1 -1
  57. package/src/roles/reducers/roleRedirect.js +1 -1
  58. package/src/roles/sagas/deleteRole.js +1 -1
  59. package/src/roles/sagas/fetchRole.js +1 -1
  60. package/src/roles/sagas/fetchRolePermissions.js +1 -1
  61. package/src/roles/sagas/updateRole.js +1 -1
  62. package/src/roles/sagas/updateRolePermissions.js +1 -1
  63. package/src/sessions/components/Auth0Callback.js +5 -4
  64. package/src/sessions/components/Auth0LoginButton.js +2 -2
  65. package/src/sessions/components/AuthMethodsLoader.js +10 -19
  66. package/src/sessions/components/LoginButtons.js +4 -4
  67. package/src/sessions/components/NonceCallback.js +21 -38
  68. package/src/sessions/components/OidcLoginButton.js +0 -1
  69. package/src/sessions/components/OpenIDConnect.js +5 -4
  70. package/src/sessions/components/PrivateRoute.js +25 -57
  71. package/src/sessions/components/ProxyLoginCallback.js +0 -2
  72. package/src/sessions/components/SamlCallback.js +0 -2
  73. package/src/sessions/components/UnauthorizedRoute.js +28 -31
  74. package/src/sessions/components/__tests__/Auth0LoginButton.spec.js +12 -12
  75. package/src/sessions/components/__tests__/AuthMethodsLoader.spec.js +15 -12
  76. package/src/sessions/components/__tests__/NonceCallback.spec.js +84 -0
  77. package/src/sessions/components/__tests__/OidcLoginButton.spec.js +10 -10
  78. package/src/sessions/components/__tests__/OpenIDConnect.spec.js +7 -8
  79. package/src/sessions/components/__tests__/PrivateRoute.spec.js +90 -0
  80. package/src/sessions/components/__tests__/UnauthorizedRoute.spec.js +88 -0
  81. package/src/sessions/components/__tests__/__snapshots__/Auth0LoginButton.spec.js.snap +22 -24
  82. package/src/sessions/components/__tests__/__snapshots__/NonceCallback.spec.js.snap +18 -0
  83. package/src/sessions/components/__tests__/__snapshots__/OidcLoginButton.spec.js.snap +18 -18
  84. package/src/sessions/components/__tests__/__snapshots__/PrivateRoute.spec.js.snap +9 -0
  85. package/src/sessions/components/__tests__/__snapshots__/UnauthorizedRoute.spec.js.snap +9 -0
  86. package/src/sessions/components/index.js +1 -1
  87. package/src/sessions/sagas/__tests__/login.spec.js +4 -4
  88. package/src/sessions/sagas/__tests__/refresh.spec.js +2 -2
  89. package/src/sessions/sagas/__tests__/token.spec.js +4 -4
  90. package/src/sessions/sagas/login.js +5 -5
  91. package/src/sessions/sagas/refresh.js +2 -2
  92. package/src/sessions/sagas/token.js +2 -2
  93. package/src/users/components/AdminUserRoutes.js +35 -51
  94. package/src/users/components/EditUser.js +0 -1
  95. package/src/users/components/GroupUserCrumbs.js +8 -8
  96. package/src/users/components/InitialUser.js +0 -1
  97. package/src/users/components/NewUser.js +0 -1
  98. package/src/users/components/Password.js +0 -1
  99. package/src/users/components/User.js +2 -2
  100. package/src/users/components/UserAclRow.js +1 -2
  101. package/src/users/components/UserAcls.js +0 -1
  102. package/src/users/components/UserActions.js +1 -2
  103. package/src/users/components/UserBreadcrumbs.js +2 -3
  104. package/src/users/components/UserCard.js +3 -3
  105. package/src/users/components/UserCards.js +5 -4
  106. package/src/users/components/UserDomainsFilter.js +2 -5
  107. package/src/users/components/UserForm.js +8 -33
  108. package/src/users/components/UserGroupAclRow.js +1 -2
  109. package/src/users/components/UserGroupAcls.js +0 -1
  110. package/src/users/components/UserLoader.js +21 -48
  111. package/src/users/components/UserPassword.js +0 -1
  112. package/src/users/components/UserRoutes.js +73 -7
  113. package/src/users/components/UserSelector.js +0 -1
  114. package/src/users/components/UserTabs.js +1 -2
  115. package/src/users/components/UsersAndGroups.js +6 -6
  116. package/src/users/components/UsersLoader.js +2 -2
  117. package/src/users/components/UsersSearchLoader.js +2 -1
  118. package/src/users/components/__tests__/CanInitLoader.spec.js +6 -13
  119. package/src/users/components/__tests__/EditUser.spec.js +4 -33
  120. package/src/users/components/__tests__/InitialUser.spec.js +4 -34
  121. package/src/users/components/__tests__/NewUser.spec.js +4 -35
  122. package/src/users/components/__tests__/Password.spec.js +59 -69
  123. package/src/users/components/__tests__/User.spec.js +1 -2
  124. package/src/users/components/__tests__/UserAclRow.spec.js +5 -7
  125. package/src/users/components/__tests__/UserAcls.spec.js +8 -9
  126. package/src/users/components/__tests__/UserActions.spec.js +4 -5
  127. package/src/users/components/__tests__/UserCard.spec.js +11 -11
  128. package/src/users/components/__tests__/UserCards.spec.js +39 -31
  129. package/src/users/components/__tests__/UserDomainsFilter.spec.js +12 -22
  130. package/src/users/components/__tests__/UserForm.spec.js +24 -44
  131. package/src/users/components/__tests__/UserGroupAclRow.spec.js +1 -2
  132. package/src/users/components/__tests__/UserGroupAcls.spec.js +8 -9
  133. package/src/users/components/__tests__/UserLoader.spec.js +85 -0
  134. package/src/users/components/__tests__/UserPassword.spec.js +8 -21
  135. package/src/users/components/__tests__/UserRoutes.spec.js +129 -4
  136. package/src/users/components/__tests__/UserSelector.spec.js +0 -1
  137. package/src/users/components/__tests__/UsersAndGroups.spec.js +45 -5
  138. package/src/users/components/__tests__/UsersSearchLoader.spec.js +0 -1
  139. package/src/users/components/__tests__/__snapshots__/EditUser.spec.js.snap +23 -21
  140. package/src/users/components/__tests__/__snapshots__/InitialUser.spec.js.snap +22 -21
  141. package/src/users/components/__tests__/__snapshots__/NewUser.spec.js.snap +25 -23
  142. package/src/users/components/__tests__/__snapshots__/Password.spec.js.snap +8 -7
  143. package/src/users/components/__tests__/__snapshots__/User.spec.js.snap +7 -6
  144. package/src/users/components/__tests__/__snapshots__/UserAclRow.spec.js.snap +12 -11
  145. package/src/users/components/__tests__/__snapshots__/UserActions.spec.js.snap +56 -67
  146. package/src/users/components/__tests__/__snapshots__/UserCard.spec.js.snap +56 -70
  147. package/src/users/components/__tests__/__snapshots__/UserCards.spec.js.snap +117 -83
  148. package/src/users/components/__tests__/__snapshots__/UserDomainsFilter.spec.js.snap +2 -2
  149. package/src/users/components/__tests__/__snapshots__/UserForm.spec.js.snap +21 -20
  150. package/src/users/components/__tests__/__snapshots__/UserLoader.spec.js.snap +3 -0
  151. package/src/users/components/__tests__/__snapshots__/UserPassword.spec.js.snap +9 -7
  152. package/src/users/components/__tests__/__snapshots__/UserRoutes.spec.js.snap +170 -16
  153. package/src/users/components/__tests__/__snapshots__/UserSelector.spec.js.snap +1 -1
  154. package/src/users/components/__tests__/__snapshots__/UsersAndGroups.spec.js.snap +75 -14
  155. package/src/users/sagas/__tests__/fetchUser.spec.js +3 -5
  156. package/src/users/sagas/__tests__/updateUser.spec.js +1 -1
  157. package/src/users/sagas/deleteUser.js +1 -1
  158. package/src/users/sagas/fetchUser.js +1 -1
  159. package/src/users/sagas/updateUser.js +1 -1
  160. package/src/users/components/__tests__/__snapshots__/CanInitLoader.spec.js.snap +0 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/auth",
3
- "version": "7.5.9",
3
+ "version": "7.5.10",
4
4
  "description": "Truedat Web Auth",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -15,48 +15,15 @@
15
15
  },
16
16
  "scripts": {
17
17
  "clean": "rimraf yarn-error.log",
18
- "debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
19
18
  "test": "TZ=UTC jest --coverage",
20
- "test:watch": "TZ=UTC jest --watch",
21
19
  "eslint": "eslint src/**",
22
20
  "eslint:fix": "eslint --fix src/**"
23
21
  },
24
- "devDependencies": {
25
- "@babel/cli": "^7.19.3",
26
- "@babel/core": "^7.20.5",
27
- "@babel/plugin-proposal-class-properties": "^7.18.6",
28
- "@babel/plugin-proposal-object-rest-spread": "^7.20.2",
29
- "@babel/plugin-proposal-optional-chaining": "^7.18.9",
30
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
31
- "@babel/plugin-transform-modules-commonjs": "^7.19.6",
32
- "@babel/preset-env": "^7.20.2",
33
- "@babel/preset-react": "^7.18.6",
34
- "@testing-library/jest-dom": "^5.16.5",
35
- "@testing-library/react": "^12.0.0",
36
- "@testing-library/user-event": "^13.2.1",
37
- "@truedat/test": "7.5.9",
38
- "babel-jest": "^28.1.0",
39
- "babel-plugin-dynamic-import-node": "^2.3.3",
40
- "babel-plugin-lodash": "^3.3.4",
41
- "babel-plugin-react-intl": "^5.1.18",
42
- "babel-plugin-transform-semantic-ui-react-imports": "^1.4.1",
43
- "enzyme": "^3.11.0",
44
- "enzyme-to-json": "^3.6.2",
45
- "identity-obj-proxy": "^3.0.0",
46
- "jest": "^29.0.0",
47
- "jest-environment-jsdom": "^29.0.0",
48
- "react": "^16.14.0",
49
- "react-dom": "^16.14.0",
50
- "redux-saga-test-plan": "^4.0.4",
51
- "rimraf": "^3.0.2",
52
- "semantic-ui-react": "^2.1.4"
53
- },
54
22
  "jest": {
55
23
  "maxWorkers": "50%",
56
24
  "testTimeout": 10000,
57
25
  "moduleDirectories": [
58
- "<rootDir>/src",
59
- "../../node_modules"
26
+ "<rootDir>/src"
60
27
  ],
61
28
  "moduleNameMapper": {
62
29
  "\\.(css|less|png)$": "identity-obj-proxy",
@@ -66,13 +33,7 @@
66
33
  "setupFilesAfterEnv": [
67
34
  "@truedat/test/setup"
68
35
  ],
69
- "snapshotSerializers": [
70
- "enzyme-to-json/serializer"
71
- ],
72
36
  "testEnvironment": "jsdom",
73
- "testPathIgnorePatterns": [
74
- "<rootDir>/node_modules/"
75
- ],
76
37
  "transform": {
77
38
  "\\.js$": [
78
39
  "babel-jest",
@@ -80,34 +41,49 @@
80
41
  "rootMode": "upward"
81
42
  }
82
43
  ]
83
- },
84
- "transformIgnorePatterns": [
85
- "/node_modules/(?!@truedat).*"
86
- ]
44
+ }
45
+ },
46
+ "devDependencies": {
47
+ "@testing-library/dom": "^10.4.0",
48
+ "@testing-library/jest-dom": "^6.6.3",
49
+ "@testing-library/react": "^16.2.0",
50
+ "@testing-library/user-event": "^14.6.1",
51
+ "@truedat/test": "7.5.10",
52
+ "identity-obj-proxy": "^3.0.0",
53
+ "jest": "^29.7.0",
54
+ "redux-saga-test-plan": "^4.0.6"
87
55
  },
88
56
  "dependencies": {
89
- "@truedat/core": "7.5.9",
90
- "auth0-js": "9.23.3",
91
- "decode-uri-component": "^0.2.2",
92
- "jwt-decode": "^2.2.0",
57
+ "@apollo/client": "^3.13.5",
58
+ "@truedat/core": "7.5.10",
59
+ "auth0-js": "^9.28.0",
60
+ "axios": "^1.8.4",
61
+ "graphql": "^16.10.0",
62
+ "is-hotkey": "^0.2.0",
63
+ "is-url": "^1.2.4",
64
+ "jwt-decode": "^4.0.0",
93
65
  "lodash": "^4.17.21",
94
- "path-to-regexp": "^1.7.0",
66
+ "moment": "^2.30.1",
67
+ "path-to-regexp": "^8.2.0",
95
68
  "prop-types": "^15.8.1",
96
69
  "query-string": "^7.1.2",
97
- "react-hook-form": "^7.30.0",
98
- "react-intl": "^5.20.10",
99
- "react-redux": "^7.2.4",
100
- "react-router-dom": "^5.2.0",
101
- "redux": "^4.1.1",
102
- "redux-saga": "^1.2.1",
70
+ "react": "^19.0.0",
71
+ "react-csv": "^2.2.2",
72
+ "react-dom": "^19.0.0",
73
+ "react-dropzone": "^14.3.8",
74
+ "react-hook-form": "^7.54.2",
75
+ "react-intl": "^7.1.10",
76
+ "react-moment": "^1.1.3",
77
+ "react-redux": "^9.2.0",
78
+ "react-router": "^7.4.0",
79
+ "redux": "^5.0.1",
80
+ "redux-saga": "^1.3.0",
103
81
  "redux-saga-routines": "^3.2.3",
104
- "reselect": "^4.1.7",
105
- "semantic-ui-react": "^2.1.4"
106
- },
107
- "peerDependencies": {
108
- "react": ">= 16.8.6 < 17",
109
- "react-dom": ">= 16.8.6 < 17",
110
- "semantic-ui-react": ">= 2.0.3 < 2.2"
82
+ "reselect": "^5.1.1",
83
+ "semantic-ui-calendar-react": "^0.15.3",
84
+ "semantic-ui-react": "^3.0.0-beta.2",
85
+ "swr": "^2.3.3",
86
+ "validator": "^13.15.0"
111
87
  },
112
- "gitHead": "03770e3241daa955de2e6e40fdaea91e3d147860"
88
+ "gitHead": "8a8c49e9d5d6bb4e5f2b503b063bfd6dd20a503d"
113
89
  }
@@ -1,5 +1,4 @@
1
1
  import _ from "lodash/fp";
2
- import React from "react";
3
2
  import PropTypes from "prop-types";
4
3
  import { Header, Icon, Container, Segment } from "semantic-ui-react";
5
4
  import { connect } from "react-redux";
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import PropTypes from "prop-types";
3
2
  import { connect } from "react-redux";
4
3
  import { Header, Button, Icon, Grid } from "semantic-ui-react";
@@ -1,6 +1,5 @@
1
- import React from "react";
2
1
  import { Breadcrumb } from "semantic-ui-react";
3
- import { Link } from "react-router-dom";
2
+ import { Link } from "react-router";
4
3
  import { FormattedMessage } from "react-intl";
5
4
  import { GROUPS } from "@truedat/core/routes";
6
5
 
@@ -1,8 +1,7 @@
1
- import React from "react";
2
1
  import PropTypes from "prop-types";
3
2
  import { connect } from "react-redux";
4
3
  import { Button, Card, Icon } from "semantic-ui-react";
5
- import { Link } from "react-router-dom";
4
+ import { Link } from "react-router";
6
5
  import { FormattedMessage } from "react-intl";
7
6
  import { ConfirmModal } from "@truedat/core/components";
8
7
  import { linkTo } from "@truedat/core/routes";
@@ -15,7 +14,8 @@ export const GroupCard = ({
15
14
  <Card key={id}>
16
15
  <Card.Content>
17
16
  <Card.Header as={Link} to={linkTo.GROUP({ id })}>
18
- <Icon name="group" /> {name}
17
+ <Icon name="group" />
18
+ {name}
19
19
  </Card.Header>
20
20
  <Card.Description>{description}</Card.Description>
21
21
  </Card.Content>
@@ -1,6 +1,5 @@
1
- import React from "react";
2
1
  import PropTypes from "prop-types";
3
- import { Link } from "react-router-dom";
2
+ import { Link } from "react-router";
4
3
  import { connect } from "react-redux";
5
4
  import { Icon, Card } from "semantic-ui-react";
6
5
  import { FormattedMessage } from "react-intl";
@@ -26,7 +25,7 @@ export const GroupCards = ({ groups }) => (
26
25
  );
27
26
 
28
27
  GroupCards.propTypes = {
29
- groups: PropTypes.array
28
+ groups: PropTypes.array,
30
29
  };
31
30
 
32
31
  const mapStateToProps = ({ groups }) => ({ groups });
@@ -1,6 +1,5 @@
1
1
  import _ from "lodash/fp";
2
2
  import PropTypes from "prop-types";
3
- import React from "react";
4
3
  import { useForm, Controller } from "react-hook-form";
5
4
  import { useIntl } from "react-intl";
6
5
  import { connect } from "react-redux";
@@ -1,59 +1,27 @@
1
- import React from "react";
2
- import { withRouter } from "react-router-dom";
3
- import PropTypes from "prop-types";
4
- import { compose } from "redux";
5
- import { connect } from "react-redux";
1
+ import { useEffect } from "react";
2
+ import { useParams } from "react-router";
3
+ import { useDispatch, useSelector } from "react-redux";
6
4
  import { Loading } from "@truedat/core/components";
7
5
  import { clearGroup, fetchGroup } from "../routines";
8
6
 
9
- class GroupLoader extends React.Component {
10
- static propTypes = {
11
- fetchGroup: PropTypes.func.isRequired,
12
- clearGroup: PropTypes.func.isRequired,
13
- match: PropTypes.object.isRequired,
14
- groupLoading: PropTypes.bool.isRequired,
15
- };
7
+ const GroupLoader = () => {
8
+ const dispatch = useDispatch();
9
+ const groupLoading = useSelector((state) => state.groupLoading);
10
+ const { id } = useParams();
16
11
 
17
- componentDidMount() {
18
- const { clearGroup, fetchGroup, match } = this.props;
19
- if (match) {
20
- const { id } = match.params;
21
- if (id) {
22
- fetchGroup({ id });
23
- } else {
24
- clearGroup();
25
- }
12
+ useEffect(() => {
13
+ if (id) {
14
+ dispatch(fetchGroup({ id }));
15
+ } else {
16
+ dispatch(clearGroup());
26
17
  }
27
- }
28
18
 
29
- componentDidUpdate(prevProps) {
30
- const { clearGroup, fetchGroup, match } = this.props;
31
- if (match) {
32
- const { id } = match.params;
33
- if (prevProps.match.params.id !== id) {
34
- if (id) {
35
- fetchGroup({ id });
36
- } else {
37
- clearGroup();
38
- }
39
- }
40
- }
41
- }
42
-
43
- componentWillUnmount() {
44
- const { clearGroup } = this.props;
45
- clearGroup();
46
- }
47
-
48
- render() {
49
- const { groupLoading } = this.props;
50
- return groupLoading ? <Loading /> : null;
51
- }
52
- }
19
+ return () => {
20
+ dispatch(clearGroup());
21
+ };
22
+ }, [dispatch, id]);
53
23
 
54
- const mapStateToProps = ({ groupLoading }) => ({ groupLoading });
24
+ return groupLoading ? <Loading /> : null;
25
+ };
55
26
 
56
- export default compose(
57
- withRouter,
58
- connect(mapStateToProps, { clearGroup, fetchGroup })
59
- )(GroupLoader);
27
+ export default GroupLoader;
@@ -1,7 +1,7 @@
1
1
  import _ from "lodash/fp";
2
- import React, { useState } from "react";
2
+ import { useState } from "react";
3
3
  import PropTypes from "prop-types";
4
- import { Link } from "react-router-dom";
4
+ import { Link } from "react-router";
5
5
  import { connect } from "react-redux";
6
6
  import { Segment, Button, Divider } from "semantic-ui-react";
7
7
  import { FormattedMessage, useIntl } from "react-intl";
@@ -12,6 +12,7 @@ import GroupUsersTable from "./GroupUsersTable";
12
12
  export const GroupUsers = ({ group, groupLoading }) => {
13
13
  const [filter, setFilter] = useState("");
14
14
  const { formatMessage } = useIntl();
15
+
15
16
  return groupLoading || _.isEmpty(group) ? null : (
16
17
  <Segment attached="bottom">
17
18
  <Button
@@ -34,7 +35,7 @@ export const GroupUsers = ({ group, groupLoading }) => {
34
35
 
35
36
  GroupUsers.propTypes = {
36
37
  group: PropTypes.object,
37
- groupLoading: PropTypes.bool
38
+ groupLoading: PropTypes.bool,
38
39
  };
39
40
 
40
41
  const mapStateToProps = ({ group, groupLoading }) => ({ group, groupLoading });
@@ -1,9 +1,9 @@
1
1
  import _ from "lodash/fp";
2
- import React, { useState } from "react";
2
+ import { useState } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { useIntl } from "react-intl";
5
5
  import { connect } from "react-redux";
6
- import { useHistory } from "react-router-dom";
6
+ import { useNavigate } from "react-router";
7
7
  import { Table, Header, Icon, Button } from "semantic-ui-react";
8
8
  import { ConfirmModal } from "@truedat/core/components";
9
9
  import { linkTo } from "@truedat/core/routes";
@@ -32,7 +32,7 @@ export const GroupUsersTable = ({
32
32
  deleteGroupUser,
33
33
  group,
34
34
  }) => {
35
- const history = useHistory();
35
+ const navigate = useNavigate();
36
36
  const [sortBy, setSortBy] = useState("full_name");
37
37
  const [ascending, setAscending] = useState(true);
38
38
  const { formatMessage } = useIntl();
@@ -83,7 +83,7 @@ export const GroupUsersTable = ({
83
83
  {columns.map((column, i) =>
84
84
  column.name == "full_name" ? (
85
85
  <Table.Cell
86
- onClick={() => history.push(linkTo.USER({ id: user.id }))}
86
+ onClick={() => navigate(linkTo.USER({ id: user.id }))}
87
87
  width={_.prop("width")(column)}
88
88
  key={i}
89
89
  textAlign={column.textAlign}
@@ -1,10 +1,10 @@
1
- import React from "react";
1
+ import { Component } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { connect } from "react-redux";
4
4
  import { Loading } from "@truedat/core/components";
5
5
  import { fetchGroups } from "../routines";
6
6
 
7
- class GroupsLoader extends React.Component {
7
+ class GroupsLoader extends Component {
8
8
  static propTypes = {
9
9
  fetchGroups: PropTypes.func,
10
10
  groupsLoading: PropTypes.bool,
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from "react";
1
+ import { useEffect } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { connect } from "react-redux";
4
4
  import { Dimmer, Loader } from "semantic-ui-react";
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import PropTypes from "prop-types";
3
2
  import { Header, Icon, Container, Segment } from "semantic-ui-react";
4
3
  import { connect } from "react-redux";
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import { render } from "@truedat/test/render";
3
2
  import Group from "../Group";
4
3
 
@@ -1,18 +1,34 @@
1
- import React from "react";
2
- import { shallow } from "enzyme";
1
+ import userEvent from "@testing-library/user-event";
2
+ import { render, waitForLoad } from "@truedat/test/render";
3
3
  import { GroupCard } from "../GroupCard";
4
4
 
5
5
  describe("<GroupCard />", () => {
6
6
  const deleteGroup = jest.fn();
7
7
  const group = {
8
- id: 1,
8
+ id: "1",
9
9
  name: "administrators",
10
- description: "Administrators"
10
+ description: "Administrators",
11
11
  };
12
12
  const props = { group, deleteGroup };
13
13
 
14
- it("matches the latest snapshot", () => {
15
- const wrapper = shallow(<GroupCard {...props} />);
16
- expect(wrapper).toMatchSnapshot();
14
+ it("matches the latest snapshot", async () => {
15
+ const rendered = render(<GroupCard {...props} />);
16
+ await waitForLoad(rendered);
17
+ expect(rendered.container).toMatchSnapshot();
18
+ });
19
+
20
+ it("calls deleteGroup when delete button is clicked", async () => {
21
+ const rendered = render(<GroupCard {...props} />);
22
+ await waitForLoad(rendered);
23
+
24
+ const user = userEvent.setup({ delay: null });
25
+
26
+ await user.click(rendered.getByRole("button", { name: /delete/i }));
27
+
28
+ await user.click(
29
+ rendered.getByRole("button", { name: /modal-affirmative-action/i })
30
+ );
31
+
32
+ expect(deleteGroup).toHaveBeenCalledTimes(1);
17
33
  });
18
34
  });
@@ -1,14 +1,17 @@
1
- import React from "react";
2
- import { shallow } from "enzyme";
1
+ import { render, waitForLoad } from "@truedat/test/render";
3
2
  import { GroupCards } from "../GroupCards";
4
3
 
5
4
  describe("<GroupCards />", () => {
6
5
  const deleteGroup = jest.fn();
7
- const groups = [{ id: 1 }, { id: 2 }];
6
+ const groups = [
7
+ { id: "1", name: "administrators", description: "Administrators" },
8
+ { id: "2", name: "users", description: "Regular users" },
9
+ ];
8
10
  const props = { groups, deleteGroup };
9
11
 
10
- it("matches the latest snapshot", () => {
11
- const wrapper = shallow(<GroupCards {...props} />);
12
- expect(wrapper).toMatchSnapshot();
12
+ it("matches the latest snapshot", async () => {
13
+ const rendered = render(<GroupCards {...props} />);
14
+ await waitForLoad(rendered);
15
+ expect(rendered.container).toMatchSnapshot();
13
16
  });
14
17
  });
@@ -0,0 +1,71 @@
1
+ import { render, waitForLoad } from "@truedat/test/render";
2
+ import { useParams } from "react-router";
3
+ import { clearGroup, fetchGroup } from "../../routines";
4
+ import GroupLoader from "../GroupLoader";
5
+
6
+ jest.mock("react-router", () => ({
7
+ ...jest.requireActual("react-router"),
8
+ useParams: jest.fn(),
9
+ }));
10
+
11
+ describe("GroupLoader", () => {
12
+ const renderOpts = {
13
+ dispatch: jest.fn(),
14
+ state: {
15
+ groupLoading: false,
16
+ },
17
+ };
18
+
19
+ beforeEach(() => {
20
+ jest.clearAllMocks();
21
+ useParams.mockReturnValue({});
22
+ });
23
+
24
+ it("renders nothing when not loading", async () => {
25
+ const rendered = render(<GroupLoader />, renderOpts);
26
+ await waitForLoad(rendered);
27
+
28
+ expect(rendered.container).toMatchSnapshot();
29
+ expect(rendered.queryByTestId("loading")).not.toBeInTheDocument();
30
+ });
31
+
32
+ it("renders loading component when loading", async () => {
33
+ const loadingRenderOpts = {
34
+ ...renderOpts,
35
+ state: {
36
+ groupLoading: true,
37
+ },
38
+ };
39
+
40
+ const rendered = render(<GroupLoader />, loadingRenderOpts);
41
+
42
+ expect(rendered.container).toMatchSnapshot();
43
+ });
44
+
45
+ it("dispatches fetchGroup when id is present", async () => {
46
+ useParams.mockReturnValue({ id: "123" });
47
+
48
+ const rendered = render(<GroupLoader />, renderOpts);
49
+ await waitForLoad(rendered);
50
+
51
+ expect(renderOpts.dispatch).toHaveBeenCalledWith(fetchGroup({ id: "123" }));
52
+ });
53
+
54
+ it("dispatches clearGroup when id is not present", async () => {
55
+ useParams.mockReturnValue({});
56
+
57
+ const rendered = render(<GroupLoader />, renderOpts);
58
+ await waitForLoad(rendered);
59
+
60
+ expect(renderOpts.dispatch).toHaveBeenCalledWith(clearGroup());
61
+ });
62
+
63
+ it("dispatches clearGroup on unmount", async () => {
64
+ const rendered = render(<GroupLoader />, renderOpts);
65
+ await waitForLoad(rendered);
66
+
67
+ rendered.unmount();
68
+
69
+ expect(renderOpts.dispatch).toHaveBeenCalledWith(clearGroup());
70
+ });
71
+ });
@@ -1,17 +1,13 @@
1
- import React from "react";
2
- import { shallow } from "enzyme";
3
- import { intl } from "@truedat/test/intl-stub";
1
+ import { render, waitForLoad } from "@truedat/test/render";
4
2
  import { GroupUsers } from "../GroupUsers";
5
3
 
6
- // workaround for enzyme issue with React.useContext
7
- // see https://github.com/airbnb/enzyme/issues/2176#issuecomment-532361526
8
- jest.spyOn(React, "useContext").mockImplementation(() => intl);
9
-
10
4
  describe("<GroupUsers />", () => {
11
- it("matches the latest snapshot", () => {
12
- const group = { id: 2, name: "grupo1 ", description: "aaa bbb cc" };
13
- const props = { group };
14
- const wrapper = shallow(<GroupUsers {...props} />);
15
- expect(wrapper).toMatchSnapshot();
5
+ const group = { id: "2", name: "grupo1", description: "aaa bbb cc" };
6
+ const props = { group };
7
+
8
+ it("matches the latest snapshot", async () => {
9
+ const rendered = render(<GroupUsers {...props} />);
10
+ await waitForLoad(rendered);
11
+ expect(rendered.container).toMatchSnapshot();
16
12
  });
17
13
  });
@@ -1,21 +1,12 @@
1
- import React from "react";
2
- import { shallow } from "enzyme";
3
- import { intl } from "@truedat/test/intl-stub";
1
+ import userEvent from "@testing-library/user-event";
2
+ import { render, waitForLoad } from "@truedat/test/render";
4
3
  import { GroupUsersTable } from "../GroupUsersTable";
5
4
 
6
- const mockHistory = {
7
- push: jest.fn()
8
- };
9
-
10
- jest.mock("react-router-dom", () => ({
11
- ...jest.requireActual("react-router-dom"),
12
- useHistory: () => mockHistory
5
+ jest.mock("react-router", () => ({
6
+ ...jest.requireActual("react-router"),
7
+ useNavigate: () => jest.fn(),
13
8
  }));
14
9
 
15
- // workaround for enzyme issue with React.useContext
16
- // see https://github.com/airbnb/enzyme/issues/2176#issuecomment-532361526
17
- jest.spyOn(React, "useContext").mockImplementation(() => intl);
18
-
19
10
  describe("<GroupUsersTable />", () => {
20
11
  const group = { id: 2, name: "grupo1 ", description: "aaa bbb cc" };
21
12
  const groupUsers = [
@@ -23,50 +14,51 @@ describe("<GroupUsersTable />", () => {
23
14
  id: 9,
24
15
  full_name: "user 1",
25
16
  email: "test1@test.com",
26
- user_name: "user 1"
17
+ user_name: "user 1",
27
18
  },
28
19
  {
29
20
  id: 3,
30
21
  full_name: "user 2",
31
22
  email: "test2@test.com",
32
- user_name: "user 2"
23
+ user_name: "user 2",
33
24
  },
34
25
  {
35
26
  id: 4,
36
27
  full_name: "a user 3",
37
28
  email: "test3@test.com",
38
- user_name: "auser_3"
39
- }
29
+ user_name: "auser_3",
30
+ },
40
31
  ];
32
+ const props = { group, groupUsers };
41
33
 
42
- it("matches the latest snapshot", () => {
43
- const props = { group, groupUsers };
44
- const wrapper = shallow(<GroupUsersTable {...props} />);
45
- expect(wrapper).toMatchSnapshot();
34
+ it("matches the latest snapshot", async () => {
35
+ const rendered = render(<GroupUsersTable {...props} />);
36
+ await waitForLoad(rendered);
37
+ expect(rendered.container).toMatchSnapshot();
46
38
  });
47
39
 
48
- it("filters users according to search filter", () => {
40
+ it("filters users according to search filter", async () => {
49
41
  const filter = "1";
50
- const props = { filter, group, groupUsers };
51
- const wrapper = shallow(<GroupUsersTable {...props} />);
52
- expect(wrapper.find("TableBody").find("TableRow").length).toBe(1);
42
+ const rendered = render(<GroupUsersTable {...props} filter={filter} />);
43
+ await waitForLoad(rendered);
44
+
45
+ // Only one row should be visible with filter "1"
46
+ const rows = rendered.container.querySelectorAll("tbody tr");
47
+ expect(rows.length).toBe(1);
53
48
  });
54
49
 
55
- it("sorts users according to sortcolumn", () => {
56
- const props = { group, groupUsers };
57
- const wrapper = shallow(<GroupUsersTable {...props} />);
58
- wrapper
59
- .find("TableHeaderCell")
60
- .at(1)
61
- .prop("onClick")();
62
- expect(
63
- wrapper
64
- .find("TableBody")
65
- .find("TableRow")
66
- .at(0)
67
- .find("TableCell")
68
- .at(1)
69
- .props().content
70
- ).toEqual("auser_3");
50
+ it("sorts users when column header is clicked", async () => {
51
+ const rendered = render(<GroupUsersTable {...props} />);
52
+ await waitForLoad(rendered);
53
+
54
+ // Click on the username column header to sort
55
+ const usernameHeader = rendered.getByText(/user_name/i);
56
+ userEvent.click(usernameHeader);
57
+
58
+ // First row should now contain "auser_3" after sorting
59
+ const firstRowCells = rendered.container.querySelectorAll(
60
+ "tbody tr:first-child td"
61
+ );
62
+ expect(firstRowCells[1].textContent).toContain("auser_3");
71
63
  });
72
64
  });