docbrown/app/javascript/Search/__tests__/Search.test.jsx
Ben Halpern 036d75aa6e
Admin-configurable display locale (#14620)
* Admin-configurable display locale

* Add i18n-js and namespacing

* Basic tests and clean up

* A few test adjustments

* Update vendor cache

* Fix a few tests

* Fix a few tests

* Update app/views/articles/_actions.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/views/articles/_comments_actions.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/views/articles/_single_story.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/views/articles/_single_story.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/views/comments/_comment_header.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/views/layouts/_sidebar_tags.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/views/listings/index.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update spec/system/homepage/user_visits_homepage_articles_spec.rb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update spec/system/user/view_user_index_spec.rb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Alphabetical locale page

* Add activerecord custom validation error translations

* Add i18n to webpacker

* Fix a few tests

* Adjust error messages

* Add i18n-tasks

* Adjust JS to get working with jest

* Adjust the way translations are pulled in

* Adjust jest tests

* Remove time localization

* Remove superfluous public js

* Add basic tests for i18n application controller

* Remove unnecessary content

Co-authored-by: Michael Kohl <citizen428@dev.to>
2021-09-28 11:04:35 -04:00

146 lines
4 KiB
JavaScript

import { h } from 'preact';
import { render, fireEvent, waitFor } from '@testing-library/preact';
import userEvent from '@testing-library/user-event';
import { axe } from 'jest-axe';
import { Search } from '../Search';
import { locale } from '../../utilities/locale';
describe('<Search />', () => {
beforeEach(() => {
global.filterXSS = jest.fn();
global.InstantClick = jest.fn(() => ({
on: jest.fn(),
off: jest.fn(),
preload: jest.fn(),
display: jest.fn(),
}))();
global.instantClick = jest.fn(() => ({}))();
});
it('should have no a11y violations', async () => {
const props = {
searchTerm: 'fish',
setSearchTerm: jest.fn(),
};
const { container } = render(<Search {...props} />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
it('should have a search textbox', () => {
const props = {
searchTerm: 'fish',
setSearchTerm: jest.fn(),
};
const { getByRole } = render(<Search {...props} />);
const searchInput = getByRole('textbox', { name: /search/i });
expect(searchInput.value).toEqual('fish');
expect(searchInput.getAttribute('placeholder')).toEqual(`${locale('core.search')}...`);
expect(searchInput.getAttribute('autocomplete')).toEqual('off');
});
it('should contain text the user entered in the search textbox', async () => {
const props = {
searchTerm: 'fish',
setSearchTerm: jest.fn(),
};
const { getByRole, findByRole } = render(<Search {...props} />);
let searchInput = getByRole('textbox', { name: /search/i });
expect(searchInput.value).toEqual('fish');
fireEvent.change(searchInput, { target: { value: 'hello' } });
searchInput = await findByRole('textbox', { name: /search/i });
expect(searchInput.value).toEqual('hello');
});
it('should set the search term', async () => {
const props = {
searchTerm: '',
setSearchTerm: jest.fn(),
};
const { getByRole } = render(<Search {...props} />);
const searchInput = getByRole('textbox', { name: /search/i });
expect(searchInput.value).toEqual('');
userEvent.type(searchInput, 'hello');
waitFor(() => {
expect(searchInput.value).toEqual('hello');
expect(props.setSearchTerm).toHaveBeenCalledWith('hello');
});
});
it('should submit the search form', async () => {
const props = {
searchTerm: '',
setSearchTerm: jest.fn(),
onSubmitSearch: jest.fn(),
};
const { getByRole, findByRole } = render(<Search {...props} />);
let searchInput = getByRole('textbox', { name: /search/i });
expect(searchInput.value).toEqual('');
userEvent.type(searchInput, 'hello');
fireEvent.submit(getByRole('search'));
searchInput = await findByRole('textbox', { name: /search/i });
waitFor(() => {
expect(searchInput.value).toEqual('hello');
expect(props.onSubmitSearch).toHaveBeenCalledWith('hello');
});
});
it('should be listening for history state changes', async () => {
// This is an implementation detail, but I want to make sure that this
// listener is registered as it affects the UI.
jest.spyOn(window, 'addEventListener');
const props = {
searchTerm: '',
setSearchTerm: jest.fn(),
};
render(<Search {...props} />);
expect(window.addEventListener).toHaveBeenNthCalledWith(
1,
'popstate',
expect.any(Function),
);
});
it('should stop listening for history state changes when the component is destroyed', async () => {
// This is an implementation detail, but I want to make sure that this
// listener is unregistered as it affects the UI.
jest.spyOn(window, 'removeEventListener');
const props = {
searchTerm: '',
setSearchTerm: jest.fn(),
};
const { unmount } = render(<Search {...props} />);
unmount();
expect(window.removeEventListener).toHaveBeenNthCalledWith(
1,
'popstate',
expect.any(Function),
);
});
});