Browse Source

Merge pull request #177 from Tumao727/test/client-component

add search input and tab list test
nameczz 3 years ago
parent
commit
e213541bfd

+ 76 - 0
client/src/components/__test__/customInput/SearchInput.spec.tsx

@@ -0,0 +1,76 @@
+import { fireEvent, render } from '@testing-library/react';
+import SearchInput from '../../customInput/SearchInput';
+import { I18nextProvider } from 'react-i18next';
+import i18n from '../../../i18n';
+import { Router } from 'react-router-dom';
+
+const mockHistoryPushFn = jest.fn();
+
+jest.mock('react-router-dom', () => ({
+  useHistory: () => ({
+    push: mockHistoryPushFn,
+    location: {
+      search: '',
+    },
+  }),
+}));
+
+// clear the influence of jest.useFakeTimers
+afterEach(() => {
+  jest.useRealTimers();
+});
+
+describe('test search input component', () => {
+  it('renders default state', () => {
+    const mockSearchFn = jest.fn();
+    const container = render(
+      <I18nextProvider i18n={i18n}>
+        <SearchInput searchText="search text" onSearch={mockSearchFn} />
+      </I18nextProvider>
+    );
+
+    // material textfield input role is textbox
+    expect(container.getByRole('textbox')).toBeInTheDocument();
+    expect(container.getByRole('textbox')).toHaveValue('search text');
+  });
+
+  it('checks input value change event', () => {
+    const mockSearchFn = jest.fn();
+    const container = render(
+      <I18nextProvider i18n={i18n}>
+        <SearchInput onSearch={mockSearchFn} />
+      </I18nextProvider>
+    );
+
+    const input = container.getByRole('textbox');
+    fireEvent.change(input, { target: { value: 'search change test' } });
+    expect(input).toHaveValue('search change test');
+    // mock Enter key press event
+    fireEvent.keyPress(input, { key: 'Enter', code: 13, charCode: 13 });
+    expect(mockSearchFn).toBeCalledTimes(1);
+    // mock clear icon click event
+    const clearIcon = container.getByTestId('clear-icon');
+    fireEvent.click(clearIcon);
+    expect(input).toHaveValue('');
+  });
+
+  it('checks location change according to search value', () => {
+    const mockSearchFn = jest.fn();
+    // mock setTimeout
+    jest.useFakeTimers();
+
+    const container = render(
+      <I18nextProvider i18n={i18n}>
+        <SearchInput onSearch={mockSearchFn} />
+      </I18nextProvider>
+    );
+
+    const input = container.getByRole('textbox');
+    fireEvent.change(input, { target: { value: 'route' } });
+    expect(mockHistoryPushFn).not.toBeCalled();
+    // fast-forward until all timers have been executed
+    jest.runAllTimers();
+    expect(mockHistoryPushFn).toBeCalled();
+    expect(mockHistoryPushFn).toBeCalledWith({ search: 'search=route' });
+  });
+});

+ 32 - 0
client/src/components/__test__/customTabList/CustomTabList.spec.tsx

@@ -0,0 +1,32 @@
+import { fireEvent, render, screen } from '@testing-library/react';
+import CustomTabList from '../../customTabList/CustomTabList';
+import provideTheme from '../utils/provideTheme';
+
+const mockTabs = [
+  {
+    label: 'tab-1',
+    component: <div>tab 1 content</div>,
+  },
+  {
+    label: 'tab-2',
+    component: <div>tab 2 content</div>,
+  },
+];
+
+describe('test custom tab list component', () => {
+  beforeEach(() => {
+    render(provideTheme(<CustomTabList tabs={mockTabs} />));
+  });
+
+  it('renders default state', () => {
+    expect(screen.getAllByRole('tab').length).toBe(2);
+    // default active tab should be first one
+    expect(screen.getByText('tab 1 content')).toBeInTheDocument();
+  });
+
+  it('checks click tab event', () => {
+    const tab2 = screen.getByText('tab-2');
+    fireEvent.click(tab2);
+    expect(screen.getByText('tab 2 content')).toBeInTheDocument();
+  });
+});

+ 7 - 2
client/src/components/__test__/layout/Layout.spec.tsx

@@ -26,7 +26,7 @@ jest.mock('react-router-dom', () => ({
 
 jest.mock('../../layout/GlobalEffect', () => {
   return () => {
-    return <div id="global">{ }</div>;
+    return <div id="global">{}</div>;
   };
 });
 
@@ -44,7 +44,12 @@ describe('Test Layout', () => {
 
   it('Test Render', () => {
     act(() => {
-      render(<MuiThemeProvider theme={theme}><Layout /></MuiThemeProvider>, container);
+      render(
+        <MuiThemeProvider theme={theme}>
+          <Layout />
+        </MuiThemeProvider>,
+        container
+      );
     });
 
     expect(container.querySelectorAll('#global').length).toEqual(1);

+ 1 - 0
client/src/components/customInput/SearchInput.tsx

@@ -146,6 +146,7 @@ const SearchInput: FC<SearchType> = props => {
           endAdornment: (
             <InputAdornment position="end">
               <span
+                data-testid="clear-icon"
                 className={`flex-center ${classes.iconWrapper}`}
                 onClick={e => {
                   setSearchValue('');