Skip to content

Commit

Permalink
Add CoursewareSearchForm component (#1214)
Browse files Browse the repository at this point in the history
* feat: Add CoursewareSearchBar component

* fix: lint

* fix: Clarified component names and i18n description

* test: Add more tests

* fix: lint

* fix: Made props in CoursewareSearchForm optional
  • Loading branch information
davidnuon authored Oct 24, 2023
1 parent 040f1cb commit 7c92110
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/course-home/courseware-search/CoursewareSearch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { setShowSearch } from '../data/slice';
import { useElementBoundingBox, useLockScroll } from './hooks';
import messages from './messages';

import CoursewareSearchForm from './CoursewareSearchForm';

const CoursewareSearch = ({ intl, ...sectionProps }) => {
const dispatch = useDispatch();

Expand All @@ -31,7 +33,9 @@ const CoursewareSearch = ({ intl, ...sectionProps }) => {
</div>
<div className="courseware-search__outer-content">
<div className="courseware-search__content" style={{ height: '999px' }}>
<h2>{intl.formatMessage(messages.searchModuleTitle)}</h2>
<CoursewareSearchForm
placeholder={intl.formatMessage(messages.searchBarPlaceholderText)}
/>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis semper rutrum odio quis congue.
Duis sodales nibh et sapien elementum fermentum. Quisque magna urna, gravida at gravida et,
Expand Down
37 changes: 37 additions & 0 deletions src/course-home/courseware-search/CoursewareSearchForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { SearchField } from '@edx/paragon';
import PropTypes from 'prop-types';

const CoursewareSearchForm = ({
onSubmit,
onChange,
placeholder,
}) => (
<SearchField.Advanced
onSubmit={onSubmit}
onChange={onChange}
submitButtonLocation="external"
className="courseware-search-form"
>
<div className="pgn__searchfield_wrapper" data-testid="courseware-search-form">
<SearchField.Label />
<SearchField.Input placeholder={placeholder} />
<SearchField.ClearButton />
</div>
<SearchField.SubmitButton submitButtonLocation="external" />
</SearchField.Advanced>
);

CoursewareSearchForm.propTypes = {
onSubmit: PropTypes.func,
onChange: PropTypes.func,
placeholder: PropTypes.string,
};

CoursewareSearchForm.defaultProps = {
onSubmit: undefined,
onChange: undefined,
placeholder: undefined,
};

export default CoursewareSearchForm;
60 changes: 60 additions & 0 deletions src/course-home/courseware-search/CoursewareSearchForm.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import {
act,
initializeMockApp,
render,
screen,
waitFor,
fireEvent,
} from '../../setupTest';
import CoursewareSearchForm from './CoursewareSearchForm';

function renderComponent(placeholder, onSubmit, onChange) {
const { container } = render(<CoursewareSearchForm
placeholder={placeholder}
onSubmit={onSubmit}
onChange={onChange}
/>);
return container;
}

describe('CoursewareSearchToggle', () => {
const placeholderText = 'Search for courseware';
let onSubmitHandlerMock;
let onChangeHandlerMock;

beforeAll(async () => {
onChangeHandlerMock = jest.fn();
onSubmitHandlerMock = jest.fn();
initializeMockApp();
});

it('should render', async () => {
await act(async () => renderComponent(placeholderText, onSubmitHandlerMock, onChangeHandlerMock));
await waitFor(() => {
expect(screen.queryByTestId('courseware-search-form')).toBeInTheDocument();
});
});

it('should call onChange handler when input changes', async () => {
await act(async () => renderComponent(placeholderText, onSubmitHandlerMock, onChangeHandlerMock));
await waitFor(() => {
const element = screen.queryByPlaceholderText(placeholderText);
fireEvent.change(element, { target: { value: 'test' } });
expect(onChangeHandlerMock).toHaveBeenCalledTimes(1);
});
});

it('should call onSubmit handler when submit is clicked', async () => {
await act(async () => renderComponent(placeholderText, onSubmitHandlerMock, onChangeHandlerMock));
await waitFor(() => {
const element = screen.queryAllByText('Search')[0];
fireEvent.click(element);
expect(onSubmitHandlerMock).toHaveBeenCalledTimes(1);
});
});

afterEach(() => {
jest.clearAllMocks();
});
});
5 changes: 5 additions & 0 deletions src/course-home/courseware-search/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const messages = defineMessages({
defaultMessage: 'Search this course',
description: 'Title for the Courseware Search module.',
},
searchBarPlaceholderText: {
id: 'learn.coursewareSerch.searchBarPlaceholderText',
defaultMessage: 'Search',
description: 'Placeholder text for the Courseware Search input control',
},
});

export default messages;

0 comments on commit 7c92110

Please sign in to comment.