test(search): optimize search bar suite

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2023-06-21 17:33:39 +02:00
committed by Renan Mendes Carvalho
parent 556c34061a
commit ae6ee0093e
@@ -15,7 +15,7 @@
*/
import React from 'react';
import { screen, render, waitFor, act } from '@testing-library/react';
import { screen, waitFor, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { configApiRef, analyticsApiRef } from '@backstage/core-plugin-api';
import { ConfigReader } from '@backstage/core-app-api';
@@ -41,16 +41,23 @@ const createInitialState = ({
});
describe('SearchBar', () => {
const user = userEvent.setup({ delay: null });
const query = jest.fn().mockResolvedValue({ results: [] });
const analyticsApiMock = new MockAnalyticsApi();
const searchApiMock = { query };
const configApiMock = new ConfigReader({
app: { title: 'Mock title' },
app: {
title: 'Mock title',
analytics: {
ga: {
trackingId: 'xyz123',
},
},
},
});
const searchApiMock = { query };
beforeEach(() => {
jest.clearAllMocks();
});
@@ -64,20 +71,20 @@ describe('SearchBar', () => {
]}
>
<SearchContextProvider>
<SearchBar />
<SearchBar debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
await waitFor(() => {
expect(screen.getByLabelText('Search')).toBeInTheDocument();
});
await waitFor(() =>
expect(screen.getByLabelText('Search')).toBeInTheDocument(),
);
});
it('Renders with custom label', async () => {
const label = 'label';
const result = await renderWithEffects(
await renderWithEffects(
<TestApiProvider
apis={[
[configApiRef, configApiMock],
@@ -85,14 +92,14 @@ describe('SearchBar', () => {
]}
>
<SearchContextProvider>
<SearchBar label={label} />
<SearchBar label={label} debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
await waitFor(() => {
expect(result.getByLabelText(label)).toBeInTheDocument();
});
await waitFor(() =>
expect(screen.getByLabelText(label)).toBeInTheDocument(),
);
});
it('Renders with custom placeholder', async () => {
@@ -106,20 +113,20 @@ describe('SearchBar', () => {
]}
>
<SearchContextProvider>
<SearchBar placeholder={placeholder} />
<SearchBar placeholder={placeholder} debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
await waitFor(() => {
expect(screen.getByPlaceholderText(placeholder)).toBeInTheDocument();
});
await waitFor(() =>
expect(screen.getByPlaceholderText(placeholder)).toBeInTheDocument(),
);
});
it('Renders based on initial search', async () => {
const term = 'term';
render(
await renderWithEffects(
<TestApiProvider
apis={[
[configApiRef, configApiMock],
@@ -127,19 +134,18 @@ describe('SearchBar', () => {
]}
>
<SearchContextProvider initialState={createInitialState({ term })}>
<SearchBar />
<SearchBar debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
await waitFor(() => {
expect(screen.getByRole('textbox', { name: 'Search' })).toHaveValue(term);
});
await waitFor(() =>
expect(screen.getByLabelText('Search')).toHaveValue(term),
);
});
it('Updates term state when text is entered', async () => {
jest.useFakeTimers();
const user = userEvent.setup({ delay: null });
await renderWithEffects(
<TestApiProvider
@@ -154,7 +160,7 @@ describe('SearchBar', () => {
</TestApiProvider>,
);
const textbox = screen.getByRole('textbox', { name: 'Search' });
const textbox = screen.getByLabelText('Search');
const value = 'value';
@@ -164,14 +170,13 @@ describe('SearchBar', () => {
jest.advanceTimersByTime(200);
});
await waitFor(() => {
expect(textbox).toHaveValue(value);
});
await waitFor(() => expect(textbox).toHaveValue(value));
expect(query).toHaveBeenLastCalledWith(
expect.objectContaining({ term: value }),
);
jest.runAllTimers();
jest.useRealTimers();
});
@@ -186,22 +191,18 @@ describe('SearchBar', () => {
]}
>
<SearchContextProvider initialState={createInitialState({ term })}>
<SearchBar />
<SearchBar debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
const textbox = screen.getByRole('textbox', { name: 'Search' });
const textbox = screen.getByLabelText('Search');
await waitFor(() => {
expect(textbox).toHaveValue(term);
});
await waitFor(() => expect(textbox).toHaveValue(term));
await userEvent.click(screen.getByRole('button', { name: 'Clear' }));
await user.click(screen.getByLabelText('Clear'));
await waitFor(() => {
expect(textbox).toHaveValue('');
});
await waitFor(() => expect(textbox).toHaveValue(''));
expect(query).toHaveBeenLastCalledWith(
expect.objectContaining({ term: '' }),
@@ -219,22 +220,20 @@ describe('SearchBar', () => {
]}
>
<SearchContextProvider initialState={createInitialState({ term })}>
<SearchBar clearButton={false} />
<SearchBar clearButton={false} debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
await waitFor(() => {
expect(
screen.queryByRole('button', { name: 'Clear' }),
).not.toBeInTheDocument();
});
await waitFor(() =>
expect(screen.queryByLabelText('Clear')).not.toBeInTheDocument(),
);
});
it('Adheres to provided debounceTime', async () => {
jest.useFakeTimers();
const user = userEvent.setup({ delay: null });
const debounceTime = 600;
const debounceTime = 100;
await renderWithEffects(
<TestApiProvider
@@ -249,36 +248,34 @@ describe('SearchBar', () => {
</TestApiProvider>,
);
const textbox = await screen.findByRole('textbox', { name: 'Search' });
const textbox = screen.getByLabelText('Search');
const value = 'value';
await user.type(textbox, value);
await waitFor(() => {
await waitFor(() =>
expect(query).not.toHaveBeenLastCalledWith(
expect.objectContaining({ term: value }),
);
});
),
);
act(() => {
jest.advanceTimersByTime(debounceTime);
});
await waitFor(() => {
expect(textbox).toHaveValue(value);
});
await waitFor(() => expect(textbox).toHaveValue(value));
expect(query).toHaveBeenLastCalledWith(
expect.objectContaining({ term: value }),
);
jest.runAllTimers();
jest.useRealTimers();
});
it('does not capture analytics event if not enabled in app', async () => {
jest.useFakeTimers();
const user = userEvent.setup({ delay: null });
it('Does not capture analytics event if not enabled in app', async () => {
const analyticsApiMock = new MockAnalyticsApi();
await renderWithEffects(
<TestApiProvider
@@ -288,62 +285,42 @@ describe('SearchBar', () => {
]}
>
<SearchContextProvider>
<SearchBar />
<SearchBar debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
const textbox = await screen.findByRole('textbox', { name: 'Search' });
const textbox = screen.getByLabelText('Search');
const value = 'value';
await user.type(textbox, value);
act(() => {
jest.advanceTimersByTime(200);
});
await waitFor(() => {
expect(textbox).toHaveValue(value);
});
await waitFor(() => expect(textbox).toHaveValue(value));
expect(analyticsApiMock.getEvents()).toHaveLength(0);
jest.useRealTimers();
});
it('captures analytics events if enabled in app', async () => {
jest.useFakeTimers();
const user = userEvent.setup({ delay: null });
it('Captures analytics events if enabled in app', async () => {
const analyticsApiMock = new MockAnalyticsApi();
const types = ['techdocs', 'software-catalog'];
await renderWithEffects(
<TestApiProvider
apis={[
[configApiRef, configApiMock],
[searchApiRef, searchApiMock],
[analyticsApiRef, analyticsApiMock],
[
configApiRef,
new ConfigReader({
app: {
title: 'Mock title',
analytics: {
ga: {
trackingId: 'xyz123',
},
},
},
}),
],
]}
>
<SearchContextProvider initialState={createInitialState({ types })}>
<SearchBar />
<SearchBar debounceTime={0} />
</SearchContextProvider>
</TestApiProvider>,
);
const textbox = await screen.findByRole('textbox', { name: 'Search' });
const textbox = screen.getByLabelText('Search');
let value = 'value';
@@ -351,13 +328,9 @@ describe('SearchBar', () => {
expect(analyticsApiMock.getEvents()).toHaveLength(0);
act(() => {
jest.advanceTimersByTime(200);
});
await waitFor(() => expect(analyticsApiMock.getEvents()).toHaveLength(1));
await waitFor(() => expect(textbox).toHaveValue(value));
expect(analyticsApiMock.getEvents()).toHaveLength(1);
expect(textbox).toHaveValue(value);
expect(analyticsApiMock.getEvents()[0]).toEqual({
action: 'search',
context: {
@@ -376,13 +349,9 @@ describe('SearchBar', () => {
// make sure new term is captured
await user.type(textbox, value);
act(() => {
jest.advanceTimersByTime(200);
});
await waitFor(() => expect(analyticsApiMock.getEvents()).toHaveLength(2));
await waitFor(() => expect(textbox).toHaveValue(value));
expect(analyticsApiMock.getEvents()).toHaveLength(2);
expect(textbox).toHaveValue(value);
expect(analyticsApiMock.getEvents()[1]).toEqual({
action: 'search',
context: {
@@ -393,7 +362,5 @@ describe('SearchBar', () => {
},
subject: value,
});
jest.useRealTimers();
});
});