use renderInTestApp

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2023-09-14 21:22:11 +02:00
parent 8a6a66f621
commit ab6474579f
72 changed files with 2587 additions and 2982 deletions
@@ -15,8 +15,8 @@
*/
import { configApiRef } from '@backstage/core-plugin-api';
import { wrapInTestApp } from '@backstage/test-utils';
import { render } from '@testing-library/react';
import { renderInTestApp } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
import { rootDocsRouteRef } from '../../../routes';
import { DocsCardGrid } from './DocsCardGrid';
@@ -46,42 +46,40 @@ describe('Entity Docs Card Grid', () => {
});
it('should render all entities passed to it', async () => {
const { findByText, findAllByRole } = render(
wrapInTestApp(
<DocsCardGrid
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
},
spec: {
owner: 'techdocs@example.com',
},
await renderInTestApp(
<DocsCardGrid
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
},
{
apiVersion: 'version',
kind: 'TestKind2',
metadata: {
name: 'testName2',
},
spec: {
owner: 'not-owned@example.com',
},
spec: {
owner: 'techdocs@example.com',
},
]}
/>,
{
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
},
{
apiVersion: 'version',
kind: 'TestKind2',
metadata: {
name: 'testName2',
},
spec: {
owner: 'not-owned@example.com',
},
},
]}
/>,
{
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
},
),
},
);
expect(await findByText('testName')).toBeInTheDocument();
expect(await findByText('testName2')).toBeInTheDocument();
const [button1, button2] = await findAllByRole('button');
expect(await screen.findByText('testName')).toBeInTheDocument();
expect(await screen.findByText('testName2')).toBeInTheDocument();
const [button1, button2] = await screen.findAllByRole('button');
expect(button1.getAttribute('href')).toContain(
'/docs/default/testkind/testname',
);
@@ -93,32 +91,30 @@ describe('Entity Docs Card Grid', () => {
it('should fall back to case-sensitive links when configured', async () => {
getOptionalBooleanMock.mockReturnValue(true);
const { findByRole } = render(
wrapInTestApp(
<DocsCardGrid
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
namespace: 'SomeNamespace',
},
spec: {
owner: 'techdocs@example.com',
},
await renderInTestApp(
<DocsCardGrid
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
namespace: 'SomeNamespace',
},
spec: {
owner: 'techdocs@example.com',
},
]}
/>,
{
mountedRoutes: {
'/techdocs/:namespace/:kind/:name/*': rootDocsRouteRef,
},
]}
/>,
{
mountedRoutes: {
'/techdocs/:namespace/:kind/:name/*': rootDocsRouteRef,
},
),
},
);
const button = await findByRole('button');
const button = await screen.findByRole('button');
expect(getOptionalBooleanMock).toHaveBeenCalledWith(
'techdocs.legacyUseCaseSensitiveTripletPaths',
);
@@ -128,30 +124,28 @@ describe('Entity Docs Card Grid', () => {
});
it('should render entity title if available', async () => {
const { findByText } = render(
wrapInTestApp(
<DocsCardGrid
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
title: 'TestTitle',
},
spec: {
owner: 'techdocs@example.com',
},
await renderInTestApp(
<DocsCardGrid
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
title: 'TestTitle',
},
spec: {
owner: 'techdocs@example.com',
},
]}
/>,
{
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
},
]}
/>,
{
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
},
),
},
);
expect(await findByText('TestTitle')).toBeInTheDocument();
expect(await screen.findByText('TestTitle')).toBeInTheDocument();
});
});
@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInTestApp } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import { renderInTestApp } from '@backstage/test-utils';
import { configApiRef } from '@backstage/core-plugin-api';
import { DocsTable } from './DocsTable';
import { rootDocsRouteRef } from '../../../routes';
@@ -46,55 +47,53 @@ describe('DocsTable test', () => {
});
it('should render documents passed', async () => {
const { findByText } = render(
wrapInTestApp(
<DocsTable
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
},
spec: {
owner: 'user:owned',
},
relations: [
{
targetRef: 'user:default/owned',
type: 'ownedBy',
},
],
await renderInTestApp(
<DocsTable
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
},
{
apiVersion: 'version',
kind: 'TestKind2',
metadata: {
name: 'testName2',
},
spec: {
owner: 'not-owned@example.com',
},
relations: [
{
targetRef: 'user:default/not-owned',
type: 'ownedBy',
},
],
spec: {
owner: 'user:owned',
},
]}
/>,
{
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
relations: [
{
targetRef: 'user:default/owned',
type: 'ownedBy',
},
],
},
{
apiVersion: 'version',
kind: 'TestKind2',
metadata: {
name: 'testName2',
},
spec: {
owner: 'not-owned@example.com',
},
relations: [
{
targetRef: 'user:default/not-owned',
type: 'ownedBy',
},
],
},
]}
/>,
{
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
},
),
},
);
const link1 = await findByText('testName');
const link2 = await findByText('testName2');
const link1 = await screen.findByText('testName');
const link2 = await screen.findByText('testName2');
expect(link1).toBeInTheDocument();
expect(link1.getAttribute('href')).toContain(
'/docs/default/testkind/testname',
@@ -108,39 +107,37 @@ describe('DocsTable test', () => {
it('should fall back to case-sensitive links when configured', async () => {
getOptionalBooleanMock.mockReturnValue(true);
const { findByText } = render(
wrapInTestApp(
<DocsTable
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
namespace: 'SomeNamespace',
},
spec: {
owner: 'user:owned',
},
relations: [
{
targetRef: 'user:default/owned',
type: 'ownedBy',
},
],
await renderInTestApp(
<DocsTable
entities={[
{
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'testName',
namespace: 'SomeNamespace',
},
]}
/>,
{
mountedRoutes: {
'/techdocs/:namespace/:kind/:name/*': rootDocsRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
spec: {
owner: 'user:owned',
},
relations: [
{
targetRef: 'user:default/owned',
type: 'ownedBy',
},
],
},
]}
/>,
{
mountedRoutes: {
'/techdocs/:namespace/:kind/:name/*': rootDocsRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
},
),
},
);
const button = await findByText('testName');
const button = await screen.findByText('testName');
expect(getOptionalBooleanMock).toHaveBeenCalledWith(
'techdocs.legacyUseCaseSensitiveTripletPaths',
);
@@ -150,15 +147,13 @@ describe('DocsTable test', () => {
});
it('should render empty state if no owned documents exist', async () => {
const { findByText } = render(
wrapInTestApp(<DocsTable entities={[]} />, {
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
},
}),
);
await renderInTestApp(<DocsTable entities={[]} />, {
mountedRoutes: {
'/docs/:namespace/:kind/:name/*': rootDocsRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
},
});
expect(await findByText('No documents to show')).toBeInTheDocument();
expect(await screen.findByText('No documents to show')).toBeInTheDocument();
});
});
@@ -13,45 +13,42 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TechDocsNotFound } from './TechDocsNotFound';
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInTestApp } from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import { renderInTestApp } from '@backstage/test-utils';
describe('<TechDocsNotFound />', () => {
it('should render with status code, status message and go back link', () => {
const rendered = render(wrapInTestApp(<TechDocsNotFound />));
rendered.getByText(/Documentation not found/i);
rendered.getByText(/404/i);
rendered.getByText(/Looks like someone dropped the mic!/i);
expect(rendered.getByTestId('go-back-link')).toBeDefined();
it('should render with status code, status message and go back link', async () => {
await renderInTestApp(<TechDocsNotFound />);
screen.getByText(/Documentation not found/i);
screen.getByText(/404/i);
screen.getByText(/Looks like someone dropped the mic!/i);
expect(screen.getByTestId('go-back-link')).toBeDefined();
});
});
describe('<TechDocsNotFound errorMessage="This is a custom error message" />', () => {
it('should render with status code, custom error message and go back link', () => {
const rendered = render(
wrapInTestApp(
<TechDocsNotFound errorMessage="This is a custom error message" />,
),
it('should render with status code, custom error message and go back link', async () => {
await renderInTestApp(
<TechDocsNotFound errorMessage="This is a custom error message" />,
);
rendered.getByText(/This is a custom error message/i);
rendered.getByText(/404/i);
rendered.getByText(/Looks like someone dropped the mic!/i);
expect(rendered.getByTestId('go-back-link')).toBeDefined();
screen.getByText(/This is a custom error message/i);
screen.getByText(/404/i);
screen.getByText(/Looks like someone dropped the mic!/i);
expect(screen.getByTestId('go-back-link')).toBeDefined();
});
});
describe('<TechDocsNotFound statusCode={500} errorMessage="This is a custom error message" />', () => {
it('should render with a 404 code, custom error message and go back link', () => {
const rendered = render(
wrapInTestApp(
<TechDocsNotFound errorMessage="This is a custom error message" />,
),
it('should render with a 404 code, custom error message and go back link', async () => {
await renderInTestApp(
<TechDocsNotFound errorMessage="This is a custom error message" />,
);
rendered.getByText(/This is a custom error message/i);
rendered.getByText(/404/i);
rendered.getByText(/Looks like someone dropped the mic!/i);
expect(rendered.getByTestId('go-back-link')).toBeDefined();
screen.getByText(/This is a custom error message/i);
screen.getByText(/404/i);
screen.getByText(/Looks like someone dropped the mic!/i);
expect(screen.getByTestId('go-back-link')).toBeDefined();
});
});
@@ -13,17 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ApiProvider } from '@backstage/core-app-api';
import { searchApiRef } from '@backstage/plugin-search-react';
import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils';
import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils';
import Button from '@material-ui/core/Button';
import {
act,
fireEvent,
render,
waitFor,
within,
} from '@testing-library/react';
import { fireEvent, screen, waitFor, within } from '@testing-library/react';
import React, { useState } from 'react';
import { TechDocsSearch } from './TechDocsSearch';
@@ -57,125 +52,115 @@ describe('<TechDocsSearch />', () => {
const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
await act(async () => {
const rendered = render(
wrapInTestApp(
<ApiProvider apis={apiRegistry}>
<TechDocsSearch entityId={entityId} />
</ApiProvider>,
),
);
await renderInTestApp(
<ApiProvider apis={apiRegistry}>
<TechDocsSearch entityId={entityId} />
</ApiProvider>,
);
await emptyResults;
expect(querySpy).toHaveBeenCalled();
expect(rendered.getByTestId('techdocs-search-bar')).toBeInTheDocument();
});
});
it('should trigger query when autocomplete input changed', async () => {
const query = () => singleResult;
const querySpy = jest.fn(query);
const searchApi = { query: querySpy };
const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
await act(async () => {
const rendered = render(
wrapInTestApp(
<ApiProvider apis={apiRegistry}>
<TechDocsSearch entityId={entityId} debounceTime={0} />
</ApiProvider>,
),
);
await singleResult;
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'Testable',
name: 'test',
namespace: 'testspace',
},
pageCursor: '',
term: '',
types: ['techdocs'],
});
const autocomplete = rendered.getByTestId('techdocs-search-bar');
const input = within(autocomplete).getByRole('textbox');
autocomplete.click();
autocomplete.focus();
fireEvent.change(input, { target: { value: 'asdf' } });
await singleResult;
await waitFor(() =>
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'Testable',
name: 'test',
namespace: 'testspace',
},
pageCursor: '',
term: 'asdf',
types: ['techdocs'],
}),
);
});
});
it('should update filter values when a new entityName is provided', async () => {
const query = () => singleResult;
const querySpy = jest.fn(query);
const searchApi = { query: querySpy };
const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
const newEntityId = {
name: 'test-diff',
namespace: 'testspace-diff',
kind: 'TestableDiff',
};
const WrappedSearchBar = () => {
const [entityName, setEntityName] = useState(entityId);
return wrapInTestApp(
<ApiProvider apis={apiRegistry}>
<Button onClick={() => setEntityName(newEntityId)}>
Update Entity
</Button>
<TechDocsSearch entityId={entityName} debounceTime={0} />
</ApiProvider>,
);
};
await act(async () => {
const rendered = render(<WrappedSearchBar />);
await singleResult;
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'Testable',
name: 'test',
namespace: 'testspace',
},
pageCursor: '',
term: '',
types: ['techdocs'],
});
const button = rendered.getByText('Update Entity');
button.click();
await singleResult;
await waitFor(() =>
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'TestableDiff',
name: 'test-diff',
namespace: 'testspace-diff',
},
pageCursor: '',
term: '',
types: ['techdocs'],
}),
);
});
await emptyResults;
expect(querySpy).toHaveBeenCalled();
expect(screen.getByTestId('techdocs-search-bar')).toBeInTheDocument();
});
});
it('should trigger query when autocomplete input changed', async () => {
const query = () => singleResult;
const querySpy = jest.fn(query);
const searchApi = { query: querySpy };
const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
await renderInTestApp(
<ApiProvider apis={apiRegistry}>
<TechDocsSearch entityId={entityId} debounceTime={0} />
</ApiProvider>,
);
await singleResult;
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'Testable',
name: 'test',
namespace: 'testspace',
},
pageCursor: '',
term: '',
types: ['techdocs'],
});
const autocomplete = screen.getByTestId('techdocs-search-bar');
const input = within(autocomplete).getByRole('textbox');
autocomplete.click();
autocomplete.focus();
fireEvent.change(input, { target: { value: 'asdf' } });
await singleResult;
await waitFor(() =>
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'Testable',
name: 'test',
namespace: 'testspace',
},
pageCursor: '',
term: 'asdf',
types: ['techdocs'],
}),
);
});
it('should update filter values when a new entityName is provided', async () => {
const query = () => singleResult;
const querySpy = jest.fn(query);
const searchApi = { query: querySpy };
const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
const newEntityId = {
name: 'test-diff',
namespace: 'testspace-diff',
kind: 'TestableDiff',
};
const WrappedSearchBar = () => {
const [entityName, setEntityName] = useState(entityId);
return (
<ApiProvider apis={apiRegistry}>
<Button onClick={() => setEntityName(newEntityId)}>
Update Entity
</Button>
<TechDocsSearch entityId={entityName} debounceTime={0} />
</ApiProvider>
);
};
await renderInTestApp(<WrappedSearchBar />);
await singleResult;
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'Testable',
name: 'test',
namespace: 'testspace',
},
pageCursor: '',
term: '',
types: ['techdocs'],
});
const button = screen.getByText('Update Entity');
button.click();
await singleResult;
await waitFor(() =>
expect(querySpy).toHaveBeenCalledWith({
filters: {
kind: 'TestableDiff',
name: 'test-diff',
namespace: 'testspace-diff',
},
pageCursor: '',
term: '',
types: ['techdocs'],
}),
);
});