@truedat/cx 4.36.7 → 4.36.8

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 (37) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +7 -6
  3. package/src/configurations/components/ConfigurationActions.js +1 -1
  4. package/src/configurations/components/ConfigurationCards.js +1 -1
  5. package/src/configurations/components/__tests__/__snapshots__/ConfigurationCards.spec.js.snap +5 -5
  6. package/src/messages/en.js +32 -25
  7. package/src/messages/es.js +32 -25
  8. package/src/sources/components/EditSource.js +3 -3
  9. package/src/sources/components/Source.js +3 -3
  10. package/src/sources/components/SourceActions.js +107 -79
  11. package/src/sources/components/SourceForm.js +15 -24
  12. package/src/sources/components/SourceRoutes.js +8 -18
  13. package/src/sources/components/{SourcesSelector.js → SourceSelector.js} +0 -0
  14. package/src/sources/components/Sources.js +53 -47
  15. package/src/sources/components/SourcesTable.js +88 -0
  16. package/src/sources/components/__tests__/SourceActions.spec.js +27 -6
  17. package/src/sources/components/__tests__/Sources.spec.js +68 -18
  18. package/src/sources/components/__tests__/SourcesTable.spec.js +59 -0
  19. package/src/sources/components/__tests__/__snapshots__/EditSource.spec.js.snap +3 -3
  20. package/src/sources/components/__tests__/__snapshots__/Source.spec.js.snap +1 -1
  21. package/src/sources/components/__tests__/__snapshots__/SourceActions.spec.js.snap +53 -65
  22. package/src/sources/components/__tests__/__snapshots__/SourceForm.spec.js.snap +10 -8
  23. package/src/sources/components/__tests__/__snapshots__/Sources.spec.js.snap +170 -62
  24. package/src/sources/components/__tests__/__snapshots__/SourcesTable.spec.js.snap +217 -0
  25. package/src/sources/components/index.js +3 -3
  26. package/src/sources/reducers/__tests__/sourceRedirect.spec.js +28 -5
  27. package/src/sources/reducers/source.js +4 -3
  28. package/src/sources/reducers/sourceRedirect.js +7 -1
  29. package/src/sources/routines.js +6 -4
  30. package/src/sources/sagas/__tests__/disableSource.spec.js +82 -0
  31. package/src/sources/sagas/__tests__/enableSource.spec.js +82 -0
  32. package/src/sources/sagas/disableSource.js +39 -0
  33. package/src/sources/sagas/enableSource.js +39 -0
  34. package/src/sources/sagas/index.js +13 -7
  35. package/src/sources/components/SourceCards.js +0 -115
  36. package/src/sources/components/__tests__/SourceCards.spec.js +0 -45
  37. package/src/sources/components/__tests__/__snapshots__/SourceCards.spec.js.snap +0 -421
@@ -31,10 +31,12 @@ export class SourceForm extends React.Component {
31
31
  static propTypes = {
32
32
  applyTemplate: PropTypes.func,
33
33
  intl: PropTypes.object,
34
+ source: PropTypes.object,
34
35
  template: PropTypes.object,
36
+ templates: PropTypes.array,
35
37
  templatesLoaded: PropTypes.bool,
36
38
  selectTemplate: PropTypes.func,
37
- handleSubmit: PropTypes.func,
39
+ onSubmit: PropTypes.func,
38
40
  };
39
41
 
40
42
  state = initialState;
@@ -88,19 +90,10 @@ export class SourceForm extends React.Component {
88
90
 
89
91
  handleSubmit = (e) => {
90
92
  e.preventDefault();
91
- const { applyTemplate, handleSubmit } = this.props;
92
- const source = _.pick(["external_id", "type"])(this.state);
93
-
93
+ const { applyTemplate, onSubmit } = this.props;
94
+ const source = _.pick(["id", "external_id", "type"])(this.state);
94
95
  const config = _.flow(_.prop("content"), applyTemplate)(this.state);
95
-
96
- // call routine submit (POST or PUT depending action)
97
- // get it from props
98
- handleSubmit({
99
- source: {
100
- ...source,
101
- config: config,
102
- },
103
- });
96
+ onSubmit({ source: { ...source, config: config } });
104
97
  };
105
98
 
106
99
  render() {
@@ -124,7 +117,7 @@ export class SourceForm extends React.Component {
124
117
  <Form>
125
118
  <Form.Field required>
126
119
  <label>
127
- {formatMessage({ id: "source.props.external_id" })}
120
+ <FormattedMessage id="source.external_id" />
128
121
  {_.isEmpty(external_id) ? (
129
122
  <Label pointing="left">
130
123
  <FormattedMessage id="template.form.validation.empty_required" />
@@ -139,11 +132,11 @@ export class SourceForm extends React.Component {
139
132
  />
140
133
  </Form.Field>
141
134
  <Form.Field required>
142
- <label>{formatMessage({ id: "type.selector.label" })}</label>
135
+ <label>
136
+ <FormattedMessage id="type.selector.label" />
137
+ </label>
143
138
  <Form.Dropdown
144
- placeholder={formatMessage({
145
- id: "type.selector.placeholder",
146
- })}
139
+ placeholder={formatMessage({ id: "type.selector.placeholder" })}
147
140
  name="type"
148
141
  search
149
142
  selection
@@ -159,7 +152,7 @@ export class SourceForm extends React.Component {
159
152
  {type && templatesLoaded && (
160
153
  <Form.Field>
161
154
  <label className="label">
162
- {formatMessage({ id: "source.config.label" })}
155
+ <FormattedMessage id="source.config.label" />
163
156
  </label>
164
157
 
165
158
  <DynamicSourceForm
@@ -177,11 +170,9 @@ export class SourceForm extends React.Component {
177
170
  primary
178
171
  disabled={this.isInvalid()}
179
172
  onClick={this.handleSubmit}
180
- content={
181
- <FormattedMessage
182
- id={_.isEmpty(source) ? "actions.create" : "actions.save"}
183
- />
184
- }
173
+ content={formatMessage({
174
+ id: _.isEmpty(source) ? "actions.create" : "actions.save",
175
+ })}
185
176
  />
186
177
  </div>
187
178
  </Form>
@@ -9,22 +9,21 @@ import { useAuthorized } from "@truedat/core/hooks";
9
9
  import {
10
10
  SOURCE,
11
11
  SOURCES,
12
- SOURCE_CREATE,
12
+ SOURCES_NEW,
13
13
  SOURCE_EDIT,
14
- SOURCE_JOBS,
15
- SOURCE_JOBS_NEW
14
+ SOURCE_JOBS_NEW,
16
15
  } from "@truedat/core/routes";
17
16
  import NewSource from "./NewSource";
18
17
  import NewJob from "./NewJob";
19
18
  import EditSource from "./EditSource";
20
19
  import Sources from "./Sources";
21
- import SourcesLoader from "./SourcesLoader";
22
20
  import SourceLoader from "./SourceLoader";
23
21
  import Source from "./Source";
24
22
 
25
23
  const TemplateLoader = React.lazy(() =>
26
24
  import("@truedat/df/templates/components/TemplateLoader")
27
25
  );
26
+
28
27
  const TemplatesLoader = React.lazy(() =>
29
28
  import("@truedat/df/templates/components/TemplatesLoader")
30
29
  );
@@ -49,7 +48,7 @@ export const SourceRoutes = ({ source, sourceLoading, templatesLoading }) => {
49
48
  />
50
49
  <Route
51
50
  exact
52
- path={SOURCE_CREATE}
51
+ path={SOURCES_NEW}
53
52
  render={() => (
54
53
  <>
55
54
  <TemplatesLoader scope="cx" />
@@ -76,24 +75,15 @@ export const SourceRoutes = ({ source, sourceLoading, templatesLoading }) => {
76
75
  path={SOURCE}
77
76
  render={() => (
78
77
  <>
78
+ <SourceLoader />
79
79
  <Segment>
80
- <SourceLoader />
81
80
  <TemplatesLoader scope="cx" />
82
81
  {!templatesLoading && <Source />}
83
82
  </Segment>
84
83
  </>
85
84
  )}
86
85
  />
87
- <Route
88
- exact
89
- path={SOURCES}
90
- render={() => (
91
- <>
92
- <SourcesLoader />
93
- <Sources />
94
- </>
95
- )}
96
- />
86
+ <Route exact path={SOURCES} render={() => <Sources />} />
97
87
  </Switch>
98
88
  ) : (
99
89
  <Unauthorized />
@@ -106,13 +96,13 @@ export const SourceRoutes = ({ source, sourceLoading, templatesLoading }) => {
106
96
  SourceRoutes.propTypes = {
107
97
  source: PropTypes.object,
108
98
  sourceLoading: PropTypes.bool,
109
- templatesLoading: PropTypes.bool
99
+ templatesLoading: PropTypes.bool,
110
100
  };
111
101
 
112
102
  const mapStateToProps = ({ source, sourceLoading, templatesLoading }) => ({
113
103
  source,
114
104
  sourceLoading,
115
- templatesLoading
105
+ templatesLoading,
116
106
  });
117
107
 
118
108
  export default connect(mapStateToProps)(SourceRoutes);
@@ -1,45 +1,65 @@
1
1
  import _ from "lodash/fp";
2
2
  import React, { useState } from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
3
+ import { matchSorter } from "match-sorter";
5
4
  import { useIntl } from "react-intl";
6
5
  import { Link } from "react-router-dom";
7
- import { Button, Grid, Header, Icon, Input, Segment } from "semantic-ui-react";
6
+ import { Button, Header, Icon, Input, Segment } from "semantic-ui-react";
8
7
  import { FormattedMessage } from "react-intl";
9
- import { SOURCE_CREATE } from "@truedat/core/routes";
10
- import SourceCards from "./SourceCards";
8
+ import { gql, useQuery } from "@apollo/client";
9
+ import { SOURCES_NEW } from "@truedat/core/routes";
10
+ import SourcesTable from "./SourcesTable";
11
11
 
12
- const toSearchable = _.flow(_.deburr, _.toLower, _.trim);
12
+ export const SOURCES = gql`
13
+ query SOURCES {
14
+ sources {
15
+ id
16
+ externalId
17
+ active
18
+ type
19
+ events(limit: 1) {
20
+ id
21
+ type
22
+ message
23
+ insertedAt
24
+ }
25
+ }
26
+ }
27
+ `;
13
28
 
14
- const matchesFilter = filter =>
15
- _.flow(
16
- _.at(["type", "external_id"]),
17
- _.map(toSearchable),
18
- _.some(_.includes(toSearchable(filter)))
19
- );
29
+ const lowerDeburrTrim = _.flow(_.toLower, _.deburr, _.trim);
20
30
 
21
- const filterData = (filter, data) => {
22
- return _.filter(matchesFilter(filter))(data);
23
- };
31
+ const sortByExternalId = _.sortBy(({ externalId }) =>
32
+ lowerDeburrTrim(externalId)
33
+ );
24
34
 
25
- export const Sources = ({ sources, sourcesLoading }) => {
26
- const [searchFilter, setSearchFilter] = useState("");
27
- const filteredSources = filterData(searchFilter, sources);
35
+ export const Sources = () => {
36
+ const [searchTerm, setSearchTerm] = useState("");
28
37
  const { formatMessage } = useIntl();
38
+ const { loading, error, data } = useQuery(SOURCES);
39
+ const items = loading || error ? [] : data?.sources;
40
+ const sources =
41
+ searchTerm === ""
42
+ ? sortByExternalId(items)
43
+ : matchSorter(items, searchTerm, {
44
+ keys: [
45
+ "externalId",
46
+ "type",
47
+ "events.0.message",
48
+ "events.0.type",
49
+ "events.0.insertedAt",
50
+ ],
51
+ threshold: matchSorter.rankings.CONTAINS,
52
+ });
29
53
 
30
- const handleFilterSources = (_e, { value }) => {
31
- setSearchFilter(value);
32
- };
33
-
34
- return sourcesLoading ? null : (
54
+ return (
35
55
  <Segment>
36
56
  <Header as="h2">
37
57
  <Button
38
58
  floated="right"
39
59
  primary
40
60
  as={Link}
41
- to={SOURCE_CREATE}
42
- content={<FormattedMessage id="sources.actions.create" />}
61
+ to={SOURCES_NEW}
62
+ content={formatMessage({ id: "sources.actions.create" })}
43
63
  />
44
64
  <Icon name="plug" circular />
45
65
  <Header.Content>
@@ -49,29 +69,15 @@ export const Sources = ({ sources, sourcesLoading }) => {
49
69
  </Header.Subheader>
50
70
  </Header.Content>
51
71
  </Header>
52
- <Grid centered columns={1}>
53
- <Grid.Column>
54
- <Input
55
- onChange={handleFilterSources}
56
- value={searchFilter}
57
- icon={{ name: "search", link: true }}
58
- placeholder={formatMessage({ id: "sources.search.placeholder" })}
59
- />
60
- </Grid.Column>
61
- </Grid>
62
- <SourceCards sources={filteredSources} />
72
+ <Input
73
+ onChange={(_e, { value }) => setSearchTerm(value)}
74
+ value={searchTerm}
75
+ icon={{ name: "search", link: true }}
76
+ placeholder={formatMessage({ id: "sources.search.placeholder" })}
77
+ />
78
+ {loading || error ? null : <SourcesTable sources={sources} />}
63
79
  </Segment>
64
80
  );
65
81
  };
66
82
 
67
- Sources.propTypes = {
68
- sources: PropTypes.array,
69
- sourcesLoading: PropTypes.bool
70
- };
71
-
72
- const mapStateToProps = ({ sources, sourcesLoading }) => ({
73
- sources,
74
- sourcesLoading
75
- });
76
-
77
- export default connect(mapStateToProps)(Sources);
83
+ export default Sources;
@@ -0,0 +1,88 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { Table } from "semantic-ui-react";
5
+ import { Link } from "react-router-dom";
6
+ import { FormattedMessage } from "react-intl";
7
+ import { useIntl } from "react-intl";
8
+ import { DateTime } from "@truedat/core/components";
9
+ import { linkTo } from "@truedat/core/routes";
10
+
11
+ export const HeaderRow = () => {
12
+ const { formatMessage } = useIntl();
13
+ const headers = [
14
+ "source.external_id",
15
+ "source.type",
16
+ "source.status",
17
+ "source.latestEvent.insertedAt",
18
+ "source.latestEvent.type",
19
+ "source.latestEvent.message",
20
+ ];
21
+ return (
22
+ <Table.Row>
23
+ {headers.map((id, key) => (
24
+ <Table.HeaderCell key={key} content={formatMessage({ id })} />
25
+ ))}
26
+ </Table.Row>
27
+ );
28
+ };
29
+
30
+ export const SourceRow = ({ active, externalId, type, events }) => {
31
+ const event = _.head(events);
32
+ const disabled = !active;
33
+ const positive = event?.type === "SUCCEEDED";
34
+ const negative = event?.type === "FAILED";
35
+ return (
36
+ <Table.Row>
37
+ <Table.Cell>
38
+ <Link to={linkTo.SOURCE({ external_id: externalId })}>
39
+ {externalId}
40
+ </Link>
41
+ </Table.Cell>
42
+ <Table.Cell disabled={disabled}>{type}</Table.Cell>
43
+ <Table.Cell disabled={disabled}>
44
+ {active ? null : <FormattedMessage id="source.disabled" />}
45
+ </Table.Cell>
46
+ <Table.Cell disabled={disabled} positive={positive} negative={negative}>
47
+ <DateTime value={event?.insertedAt} />
48
+ </Table.Cell>
49
+ <Table.Cell disabled={disabled} positive={positive} negative={negative}>
50
+ {event?.type}
51
+ </Table.Cell>
52
+ <Table.Cell disabled={disabled} positive={positive} negative={negative}>
53
+ {_.truncate({ length: 90 })(event?.message)}
54
+ </Table.Cell>
55
+ </Table.Row>
56
+ );
57
+ };
58
+
59
+ SourceRow.propTypes = {
60
+ active: PropTypes.bool,
61
+ externalId: PropTypes.string,
62
+ type: PropTypes.string,
63
+ events: PropTypes.arrayOf(PropTypes.object),
64
+ };
65
+
66
+ export const SourcesTable = ({ sources }) => {
67
+ const { formatMessage } = useIntl();
68
+
69
+ return (
70
+ <Table>
71
+ <caption className="text-right">
72
+ {formatMessage({ id: "sources.count" }, { count: _.size(sources) })}
73
+ </caption>
74
+ <Table.Header>
75
+ <HeaderRow />
76
+ </Table.Header>
77
+ <Table.Body>
78
+ {sources.map((props, key) => (
79
+ <SourceRow key={key} {...props} />
80
+ ))}
81
+ </Table.Body>
82
+ </Table>
83
+ );
84
+ };
85
+
86
+ SourcesTable.propTypes = { sources: PropTypes.array };
87
+
88
+ export default SourcesTable;
@@ -1,18 +1,39 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
2
+ import { render } from "@truedat/test/render";
3
3
  import { SourceActions } from "../SourceActions";
4
4
 
5
+ const renderOpts = {
6
+ messages: {
7
+ en: {
8
+ "source.actions.delete": "delete",
9
+ "source.actions.delete.confirmation.content": "confirm delete content",
10
+ "source.actions.delete.confirmation.header": "confirm delete header",
11
+ "source.actions.disable": "disable",
12
+ "source.actions.disable.confirmation.content": "confirm disable content",
13
+ "source.actions.disable.confirmation.header": "confirm disable header",
14
+ "source.actions.edit": "edit",
15
+ "source.actions.enable": "enable",
16
+ "source.actions.enable.confirmation.content": "confirm enable content",
17
+ "source.actions.enable.confirmation.header": "confirm enable header",
18
+ },
19
+ },
20
+ };
21
+
5
22
  describe("<SourceActions />", () => {
6
23
  const source = {
7
24
  external_id: "Micro1",
8
25
  config: { a: 1 },
9
- type: "micro"
26
+ type: "micro",
27
+ };
28
+ const props = {
29
+ source,
30
+ deleteSource: jest.fn(),
31
+ enableSource: jest.fn(),
32
+ disableSource: jest.fn(),
10
33
  };
11
- const deleteSource = jest.fn();
12
34
 
13
- const props = { source, deleteSource };
14
35
  it("matches the latest snapshot", () => {
15
- const wrapper = shallow(<SourceActions {...props} />);
16
- expect(wrapper).toMatchSnapshot();
36
+ const { container } = render(<SourceActions {...props} />, renderOpts);
37
+ expect(container).toMatchSnapshot();
17
38
  });
18
39
  });
@@ -1,29 +1,79 @@
1
1
  import React from "react";
2
- import { intl } from "@truedat/test/intl-stub";
3
- import { shallow } from "enzyme";
4
- import { Sources } from "../Sources";
2
+ import userEvent from "@testing-library/user-event";
3
+ import { render } from "@truedat/test/render";
4
+ import { Sources, SOURCES } from "../Sources";
5
5
 
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);
6
+ const messages = {
7
+ en: {
8
+ "sources.actions.create": "create",
9
+ "sources.header": "header",
10
+ "sources.search.placeholder": "search",
11
+ "sources.count": "{count} sources found",
12
+ "sources.subheader": "subheader",
13
+ "source.latestEvent.insertedAt": "insertedAt",
14
+ "source.latestEvent.message": "message",
15
+ "source.latestEvent.type": "type",
16
+ "source.status": "status",
17
+ "source.type": "type",
18
+ "source.external_id": "external_id",
19
+ },
20
+ };
9
21
 
10
22
  describe("<Sources />", () => {
11
- const defaultProps = {
12
- sourcesLoading: false,
13
- sources: []
23
+ const props = {
24
+ loading: false,
25
+ sources: [],
14
26
  };
27
+ const event = {
28
+ id: 456,
29
+ type: "eventType",
30
+ message: "eventMessage",
31
+ insertedAt: "2020-01-01T12:34:56.000Z",
32
+ };
33
+ const source1 = {
34
+ id: 123,
35
+ externalId: "aaaa",
36
+ active: true,
37
+ type: "sourceType1",
38
+ events: [event],
39
+ };
40
+ const source2 = {
41
+ id: 456,
42
+ externalId: "bbbb",
43
+ active: true,
44
+ type: "sourceType2",
45
+ events: [event],
46
+ };
47
+ const sources = [source1, source2];
48
+ const sourcesMock = {
49
+ request: { query: SOURCES },
50
+ result: { data: { sources } },
51
+ };
52
+ const renderOpts = { mocks: [sourcesMock], messages };
15
53
 
16
- it("matches the latest snapshot", () => {
17
- const wrapper = shallow(<Sources {...defaultProps} />);
18
- expect(wrapper).toMatchSnapshot();
54
+ it("matches the latest snapshot", async () => {
55
+ const { container, findByText } = render(
56
+ <Sources {...props} />,
57
+ renderOpts
58
+ );
59
+ await findByText("2 sources found");
60
+ expect(container).toMatchSnapshot();
19
61
  });
20
62
 
21
- it("renders no results when sources search result is empty", () => {
22
- const wrapper = shallow(<Sources {...defaultProps} />);
23
- const inputSearch = wrapper.find("Input");
24
- inputSearch.simulate("change", {}, { value: "bank" });
25
- expect(wrapper.findWhere(n => n.prop("sources")).props().sources).toEqual(
26
- []
63
+ it("renders count and filters rows matching search term", async () => {
64
+ const { findByText, getByRole, queryAllByRole } = render(
65
+ <Sources {...props} />,
66
+ renderOpts
27
67
  );
68
+ await findByText("2 sources found");
69
+ expect(queryAllByRole("row")).toHaveLength(3); // 2 rows + header
70
+
71
+ userEvent.type(getByRole("textbox"), source1.externalId);
72
+ await findByText("1 sources found");
73
+ expect(queryAllByRole("row")).toHaveLength(2); // 1 row + header
74
+
75
+ userEvent.type(getByRole("textbox"), "x");
76
+ await findByText("0 sources found");
77
+ expect(queryAllByRole("row")).toHaveLength(1); // header only
28
78
  });
29
79
  });
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { SourcesTable } from "../SourcesTable";
4
+
5
+ const renderOpts = {
6
+ messages: {
7
+ en: {
8
+ "source.disabled": "disabled",
9
+ "source.external_id": "external_id",
10
+ "source.latestEvent.insertedAt": "eventInsertedAt",
11
+ "source.latestEvent.message": "eventMessage",
12
+ "source.latestEvent.type": "eventType",
13
+ "source.status": "status",
14
+ "source.type": "type",
15
+ "sources.count": "{count} sources found",
16
+ },
17
+ },
18
+ };
19
+
20
+ describe("<SourcesTable />", () => {
21
+ const sources = [
22
+ {
23
+ id: 1,
24
+ externalId: "con_url",
25
+ type: "a",
26
+ config: {
27
+ a: "aaa",
28
+ lista: ["bbb", "ddd"],
29
+ url_cx: [{ url_name: "google", url_value: "https://google.es" }],
30
+ },
31
+ },
32
+ { id: 2, externalId: "id1", type: "app-admin", config: {} },
33
+ { id: 3, externalId: "id2", type: "app-admin", config: { a: 1 } },
34
+ { id: 4, externalId: "id3", type: "app-admin", config: { a: "yyyyb" } },
35
+ { id: 5, externalId: "id4", type: "a", config: { lista: ["codigo6"] } },
36
+ ];
37
+
38
+ it("matches the latest snapshot", () => {
39
+ const { container } = render(
40
+ <SourcesTable sources={sources} />,
41
+ renderOpts
42
+ );
43
+ expect(container).toMatchSnapshot();
44
+ });
45
+
46
+ it("contains a message when no sources are found", () => {
47
+ const { queryByText } = render(<SourcesTable sources={[]} />, renderOpts);
48
+ expect(queryByText(/0 sources found/)).toBeTruthy();
49
+ });
50
+
51
+ it("contains a caption, a header row and a row for each source", () => {
52
+ const { queryAllByRole, queryByText } = render(
53
+ <SourcesTable sources={sources} />,
54
+ renderOpts
55
+ );
56
+ expect(queryByText(/5 sources found/)).toBeTruthy();
57
+ expect(queryAllByRole("row")).toHaveLength(sources.length + 1);
58
+ });
59
+ });
@@ -3,7 +3,7 @@
3
3
  exports[`<EditSource /> matches the latest snapshot 1`] = `
4
4
  <Fragment>
5
5
  <SourceBreadcrumbs
6
- text="sources.actions.edit"
6
+ text="source.actions.edit"
7
7
  />
8
8
  <Container
9
9
  as={[Function]}
@@ -18,12 +18,12 @@ exports[`<EditSource /> matches the latest snapshot 1`] = `
18
18
  />
19
19
  <HeaderContent>
20
20
  <MemoizedFormattedMessage
21
- id="sources.actions.edit"
21
+ id="source.actions.edit"
22
22
  />
23
23
  </HeaderContent>
24
24
  </Header>
25
25
  <injectIntl(Connect(SourceForm))
26
- handleSubmit={[MockFunction]}
26
+ onSubmit={[MockFunction]}
27
27
  source={
28
28
  Object {
29
29
  "config": Object {
@@ -16,7 +16,7 @@ exports[`<Source /> matches the latest snapshot 1`] = `
16
16
  <Icon
17
17
  as="i"
18
18
  circular={true}
19
- name="clipboard check"
19
+ name="plug"
20
20
  />
21
21
  <HeaderContent>
22
22
  Micro1