Skip to content

Commit cd64f47

Browse files
committed
test: update tests for pluggable component
test: another tests
1 parent 55468d6 commit cd64f47

File tree

6 files changed

+146
-68
lines changed

6 files changed

+146
-68
lines changed

package-lock.json

Lines changed: 6 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"@loadable/component": "^5.15.3",
4949
"@openedx-plugins/communications-app-check-box-form": "file:plugins/communications-app/CheckBoxForm",
5050
"@openedx-plugins/communications-app-input-form": "file:plugins/communications-app/InputForm",
51+
"@openedx-plugins/communications-app-test-component": "file:plugins/communications-app/TestComponent",
5152
"@tinymce/tinymce-react": "3.14.0",
5253
"axios": "0.27.2",
5354
"classnames": "2.3.2",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import PropTypes from 'prop-types';
2+
3+
const TestComponent = ({ handleClick, title }) => (
4+
<button type="button" onClick={handleClick} data-testid="button-test">
5+
{title}
6+
</button>
7+
);
8+
9+
TestComponent.defaultProps = {
10+
handleClick: () => {},
11+
};
12+
13+
TestComponent.propTypes = {
14+
handleClick: PropTypes.func,
15+
title: PropTypes.string.isRequired,
16+
};
17+
18+
export default TestComponent;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "@openedx-plugins/communications-app-test-component",
3+
"version": "1.0.0",
4+
"description": "edx input form to use it in this mfe",
5+
"scripts": {
6+
"test": "echo \"Error: no test specified\" && exit 1"
7+
},
8+
"peerDependencies": {
9+
"@edx/frontend-app-communications": "*",
10+
"@edx/frontend-platform": "*",
11+
"@edx/paragon": "*",
12+
"prop-types": "*",
13+
"react": "*"
14+
},
15+
"peerDependenciesMeta": {
16+
"@edx/frontend-app-communications": {
17+
"optional": true
18+
}
19+
}
20+
}

src/components/PluggableComponent/__snapshots__/index.test.jsx.snap

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,11 @@
22

33
exports[`PluggableComponent renders correctly 1`] = `
44
<div>
5-
<div
6-
class="pgn__form-group p-3 border border-success-300"
7-
data-testid="plugin-input"
5+
<button
6+
data-testid="button-test"
7+
type="button"
88
>
9-
<label
10-
class="pgn__form-label h3 text-primary-500"
11-
for="randomID"
12-
>
13-
Hello
14-
</label>
15-
<div
16-
class="row container-fluid"
17-
>
18-
<div
19-
class="pgn__form-control-decorator-group col-3"
20-
>
21-
<input
22-
class="form-control is-valid"
23-
id="randomID"
24-
/>
25-
</div>
26-
<p
27-
class="col-8"
28-
>
29-
@openedx-plugins/communications-app-input-form
30-
</p>
31-
</div>
32-
<div
33-
class="pgn__form-control-description pgn__form-text pgn__form-text-valid"
34-
>
35-
<span
36-
class="pgn__icon"
37-
>
38-
<svg
39-
aria-hidden="true"
40-
fill="none"
41-
focusable="false"
42-
height="24"
43-
role="img"
44-
viewBox="0 0 24 24"
45-
width="24"
46-
xmlns="http://www.w3.org/2000/svg"
47-
>
48-
<path
49-
d="M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2Z"
50-
fill="currentColor"
51-
/>
52-
</svg>
53-
</span>
54-
<div>
55-
You are correct
56-
</div>
57-
</div>
58-
</div>
9+
button title
10+
</button>
5911
</div>
6012
`;

src/components/PluggableComponent/index.test.jsx

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,49 @@
1-
import React from 'react';
2-
import { render, waitFor, screen } from '@testing-library/react';
1+
import React, { useState } from 'react';
2+
import {
3+
render, waitFor, screen, fireEvent,
4+
} from '@testing-library/react';
35
import PluggableComponent from '.';
46

7+
const ToggleContentComponent = () => {
8+
const [showContent, setShowContent] = useState(false);
9+
10+
return (
11+
<div>
12+
<button type="button" onClick={() => setShowContent((prev) => !prev)}>
13+
Toggle Content
14+
</button>
15+
{showContent && <div data-testid="toggle-content">Toggle On</div>}
16+
</div>
17+
);
18+
};
19+
520
describe('PluggableComponent', () => {
21+
beforeEach(() => {
22+
jest.resetModules();
23+
});
624
it('renders correctly', async () => {
25+
const handleClickMock = jest.fn();
726
const props = {
8-
isValid: true,
9-
controlId: 'randomID',
10-
label: 'Hello',
11-
feedbackText: 'You are correct',
27+
title: 'button title',
28+
handleClick: handleClickMock,
1229
};
30+
1331
const { container } = render(
1432
<PluggableComponent
1533
id="pluggableComponent"
16-
as="communications-app-input-form"
34+
as="communications-app-test-component"
1735
{...props}
1836
>
1937
<h1>Hi this is the original component</h1>
2038
</PluggableComponent>,
2139
);
2240

2341
await waitFor(() => {
24-
const inputForm = screen.getByTestId('plugin-input');
25-
expect(inputForm).toBeInTheDocument();
26-
expect(screen.getByText(props.label)).toBeInTheDocument();
27-
expect(screen.getByText(props.feedbackText)).toBeInTheDocument();
42+
const buttonComponent = screen.getByTestId('button-test');
43+
expect(buttonComponent).toBeInTheDocument();
44+
expect(screen.getByText(props.title)).toBeInTheDocument();
45+
fireEvent.click(buttonComponent);
46+
expect(handleClickMock).toHaveBeenCalled();
2847
expect(container).toMatchSnapshot();
2948
});
3049
});
@@ -43,7 +62,7 @@ describe('PluggableComponent', () => {
4362
});
4463
});
4564

46-
it('loads children component when import object', async () => {
65+
it('loads children component when import is empty', async () => {
4766
render(
4867
<PluggableComponent
4968
id="test-pluggable"
@@ -59,4 +78,69 @@ describe('PluggableComponent', () => {
5978
expect(defaultComponent).toBeInTheDocument();
6079
});
6180
});
81+
82+
it('returns null when do not have children and import is invalid', async () => {
83+
render(
84+
<PluggableComponent
85+
id="test-pluggable"
86+
as="invalid-module"
87+
/>,
88+
);
89+
90+
await waitFor(() => {
91+
expect(screen.queryByTestId('plugin')).not.toBeInTheDocument();
92+
});
93+
});
94+
95+
test('updates component when props change', async () => {
96+
const { rerender } = render(
97+
<PluggableComponent
98+
id="test-pluggable"
99+
as="communications-app-test-component"
100+
title="Testing title component"
101+
/>,
102+
);
103+
104+
await waitFor(() => {
105+
expect(screen.getByText('Testing title component')).toBeInTheDocument();
106+
});
107+
108+
rerender(
109+
<PluggableComponent
110+
id="test-pluggable"
111+
as="communications-app-test-component"
112+
title="Testing a new title component"
113+
/>,
114+
);
115+
116+
await waitFor(() => {
117+
expect(screen.getByText('Testing a new title component')).toBeInTheDocument();
118+
});
119+
});
120+
121+
it('updates component when children change', async () => {
122+
const { getByText, getByTestId } = render(
123+
<PluggableComponent
124+
id="test-pluggable"
125+
as="default-children"
126+
>
127+
<ToggleContentComponent />
128+
</PluggableComponent>,
129+
);
130+
131+
await waitFor(() => {
132+
const toggleContent = screen.queryByTestId('toggle-content');
133+
expect(toggleContent).not.toBeInTheDocument();
134+
});
135+
136+
const toggleButton = getByText('Toggle Content');
137+
fireEvent.click(toggleButton);
138+
139+
// Now, after toggling the content, we expect it to be visible inside PluggableComponent
140+
await waitFor(() => {
141+
const toggleContent = getByTestId('toggle-content');
142+
expect(toggleContent).toBeInTheDocument();
143+
expect(toggleContent).toHaveTextContent('Toggle On');
144+
});
145+
});
62146
});

0 commit comments

Comments
 (0)