feat: support i18n for core component

Signed-off-by: rui ma <ruima@alauda.io>
This commit is contained in:
rui ma
2024-01-08 23:55:00 +08:00
parent 94c4fe2782
commit ff7e12632d
37 changed files with 575 additions and 248 deletions
@@ -16,7 +16,7 @@
import React from 'react';
import { Entity } from '@backstage/catalog-model';
import { renderWithEffects, TestApiProvider } from '@backstage/test-utils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { BadgesApi, badgesApiRef } from '../api';
import { EntityBadgesDialog } from './EntityBadgesDialog';
import { EntityProvider } from '@backstage/plugin-catalog-react';
@@ -43,7 +43,7 @@ describe('EntityBadgesDialog', () => {
kind: 'MockKind',
} as Entity;
const rendered = await renderWithEffects(
const rendered = await renderInTestApp(
<TestApiProvider
apis={[
[badgesApiRef, mockApi],
@@ -15,8 +15,8 @@
*/
import React from 'react';
import { render } from '@testing-library/react';
import { BitriseBuildsComponent } from './BitriseBuildsComponent';
import { renderInTestApp } from '@backstage/test-utils';
let entityValue: {
entity: { metadata: { annotations?: { [key: string]: string } } };
@@ -48,10 +48,10 @@ jest.mock('../BitriseBuildsTableComponent', () => ({
describe('BitriseArtifactsComponent', () => {
entityValue = { entity: { metadata: {} } };
const renderComponent = () => render(<BitriseBuildsComponent />);
const renderComponent = () => renderInTestApp(<BitriseBuildsComponent />);
it('should display an empty state if an app annotation is missing', async () => {
const rendered = renderComponent();
const rendered = await renderComponent();
expect(await rendered.findByText('Missing Annotation')).toBeInTheDocument();
});
+1
View File
@@ -52,6 +52,7 @@
"@backstage/cli": "workspace:^",
"@backstage/core-app-api": "workspace:^",
"@backstage/dev-utils": "workspace:^",
"@backstage/test-utils": "workspace:^",
"@testing-library/dom": "^9.0.0",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^14.0.0",
@@ -21,6 +21,10 @@ import { Features } from './Features';
import { mockCalverProject } from '../test-helpers/test-helpers';
import { TEST_IDS } from '../test-helpers/test-ids';
import { mockApiClient } from '../test-helpers/mock-api-client';
import { MockErrorApi, TestApiProvider } from '@backstage/test-utils';
import { translationApiRef } from '@backstage/core-plugin-api/alpha';
import { MockTranslationApi } from '@backstage/test-utils';
import { errorApiRef } from '@backstage/core-plugin-api';
jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
@@ -35,18 +39,26 @@ jest.mock('../contexts/ProjectContext', () => ({
describe('Features', () => {
it('should omit features omitted via configuration', async () => {
const { getByTestId } = render(
<Features
features={{
info: { omit: false },
createRc: { omit: true },
promoteRc: { omit: true },
patch: { omit: true },
custom: {
// shouldn't trigger "missing key" warning in console
factory: () => [<div>Custom 1</div>, <div>Custom 2</div>],
},
}}
/>,
<TestApiProvider
apis={[
[translationApiRef, MockTranslationApi.create()],
[errorApiRef, new MockErrorApi()],
]}
>
<Features
features={{
info: { omit: false },
createRc: { omit: true },
promoteRc: { omit: true },
patch: { omit: true },
custom: {
// shouldn't trigger "missing key" warning in console
factory: () => [<div>Custom 1</div>, <div>Custom 2</div>],
},
}}
/>
,
</TestApiProvider>,
);
await waitFor(() => getByTestId(TEST_IDS.info.info));
@@ -15,14 +15,13 @@
*/
import React from 'react';
import { render } from '@testing-library/react';
import {
mockCalverProject,
mockReleaseBranch,
mockReleaseCandidateCalver,
} from '../../test-helpers/test-helpers';
import { Info } from './Info';
import { renderInTestApp } from '@backstage/test-utils';
jest.mock('../../contexts/ProjectContext', () => ({
useProjectContext: () => ({
@@ -32,7 +31,7 @@ jest.mock('../../contexts/ProjectContext', () => ({
describe('Info', () => {
it('should return early if no latestRelease exists', async () => {
const { findByText } = render(
const { findByText } = await renderInTestApp(
<Info
latestRelease={mockReleaseCandidateCalver}
releaseBranch={mockReleaseBranch}
@@ -15,7 +15,7 @@
*/
import React from 'react';
import { render, waitFor, screen } from '@testing-library/react';
import { waitFor, screen, render } from '@testing-library/react';
import {
mockBumpedTag,
@@ -29,6 +29,10 @@ import {
import { mockApiClient } from '../../test-helpers/mock-api-client';
import { PatchBody } from './PatchBody';
import { TEST_IDS } from '../../test-helpers/test-ids';
import { MockErrorApi, TestApiProvider } from '@backstage/test-utils';
import { translationApiRef } from '@backstage/core-plugin-api/alpha';
import { MockTranslationApi } from '@backstage/test-utils/alpha';
import { errorApiRef } from '@backstage/core-plugin-api';
jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
@@ -56,13 +60,21 @@ describe('PatchBody', () => {
});
const { getByTestId } = render(
<PatchBody
bumpedTag={mockBumpedTag}
latestRelease={mockReleaseCandidateCalver}
releaseBranch={mockReleaseBranch}
tagParts={mockTagParts}
ctaMessage={mockCtaMessage}
/>,
<TestApiProvider
apis={[
[translationApiRef, MockTranslationApi.create()],
[errorApiRef, new MockErrorApi()],
]}
>
<PatchBody
bumpedTag={mockBumpedTag}
latestRelease={mockReleaseCandidateCalver}
releaseBranch={mockReleaseBranch}
tagParts={mockTagParts}
ctaMessage={mockCtaMessage}
/>
,
</TestApiProvider>,
);
expect(getByTestId(TEST_IDS.patch.loading)).toBeInTheDocument();
@@ -74,13 +86,20 @@ describe('PatchBody', () => {
it('should render not-prerelease description', async () => {
const { getByTestId } = render(
<PatchBody
latestRelease={mockReleaseVersionCalver}
releaseBranch={mockReleaseBranch}
bumpedTag={mockBumpedTag}
tagParts={mockTagParts}
ctaMessage={mockCtaMessage}
/>,
<TestApiProvider
apis={[
[translationApiRef, MockTranslationApi.create()],
[errorApiRef, new MockErrorApi()],
]}
>
<PatchBody
latestRelease={mockReleaseVersionCalver}
releaseBranch={mockReleaseBranch}
bumpedTag={mockBumpedTag}
tagParts={mockTagParts}
ctaMessage={mockCtaMessage}
/>
</TestApiProvider>,
);
expect(getByTestId(TEST_IDS.patch.loading)).toBeInTheDocument();
@@ -18,7 +18,7 @@ import { Entity } from '@backstage/catalog-model';
import { ConfigReader } from '@backstage/core-app-api';
import { ConfigApi, configApiRef } from '@backstage/core-plugin-api';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { renderWithEffects, TestApiProvider } from '@backstage/test-utils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { GoCdBuildsComponent } from './GoCdBuildsComponent';
import { gocdApiRef } from '../../plugin';
import { GoCdApi } from '../../api/gocdApi';
@@ -41,7 +41,7 @@ describe('GoCdArtifactsComponent', () => {
};
const renderComponent = () =>
renderWithEffects(
renderInTestApp(
<TestApiProvider
apis={[
[gocdApiRef, mockApiClient],
@@ -16,19 +16,18 @@
import React from 'react';
import { VisitList } from './VisitList';
import { render } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import { renderInTestApp } from '@backstage/test-utils';
describe('<VisitList/>', () => {
it('renders with mandatory parameters', async () => {
const { getByText } = await render(
const { getByText } = await renderInTestApp(
<VisitList title="My title" detailType="time-ago" />,
);
expect(getByText('My title')).toBeInTheDocument();
});
it('renders skeleton when loading is true', async () => {
const { container } = await render(
const { container } = await renderInTestApp(
<VisitList title="My title" detailType="time-ago" loading />,
);
expect(container.querySelectorAll('li')).toHaveLength(8);
@@ -36,7 +35,7 @@ describe('<VisitList/>', () => {
});
it('renders specified amount of items', async () => {
const { container } = await render(
const { container } = await renderInTestApp(
<VisitList
title="My title"
detailType="time-ago"
@@ -49,7 +48,7 @@ describe('<VisitList/>', () => {
});
it('renders some items hidden', async () => {
const { container } = await render(
const { container } = await renderInTestApp(
<VisitList
title="My title"
detailType="time-ago"
@@ -63,7 +62,7 @@ describe('<VisitList/>', () => {
});
it('renders all items when not collapsed', async () => {
const { container } = await render(
const { container } = await renderInTestApp(
<VisitList
title="My title"
detailType="time-ago"
@@ -78,23 +77,20 @@ describe('<VisitList/>', () => {
});
it('renders visit with time-ago', async () => {
const { container, getByText } = await render(
<BrowserRouter>
<VisitList
title="My title"
detailType="time-ago"
visits={[
{
id: 'explore',
name: 'Explore Backstage',
pathname: '/explore',
hits: 35,
timestamp: Date.now() - 86400_000,
},
]}
/>
,
</BrowserRouter>,
const { container, getByText } = await renderInTestApp(
<VisitList
title="My title"
detailType="time-ago"
visits={[
{
id: 'explore',
name: 'Explore Backstage',
pathname: '/explore',
hits: 35,
timestamp: Date.now() - 86400_000,
},
]}
/>,
);
expect(container.querySelectorAll('li')).toHaveLength(1);
expect(getByText('Explore Backstage')).toBeInTheDocument();
@@ -102,23 +98,20 @@ describe('<VisitList/>', () => {
});
it('renders visit with hits', async () => {
const { container, getByText } = await render(
<BrowserRouter>
<VisitList
title="My title"
detailType="hits"
visits={[
{
id: 'explore',
name: 'Explore Backstage',
pathname: '/explore',
hits: 35,
timestamp: Date.now() - 86400_000,
},
]}
/>
,
</BrowserRouter>,
const { container, getByText } = await renderInTestApp(
<VisitList
title="My title"
detailType="hits"
visits={[
{
id: 'explore',
name: 'Explore Backstage',
pathname: '/explore',
hits: 35,
timestamp: Date.now() - 86400_000,
},
]}
/>,
);
expect(container.querySelectorAll('li')).toHaveLength(1);
expect(getByText('Explore Backstage')).toBeInTheDocument();
@@ -126,23 +119,20 @@ describe('<VisitList/>', () => {
});
it('renders text warning about few items', async () => {
const { getByText } = await render(
<BrowserRouter>
<VisitList
title="My title"
detailType="hits"
visits={[
{
id: 'explore',
name: 'Explore Backstage',
pathname: '/explore',
hits: 35,
timestamp: Date.now() - 86400_000,
},
]}
/>
,
</BrowserRouter>,
const { getByText } = await renderInTestApp(
<VisitList
title="My title"
detailType="hits"
visits={[
{
id: 'explore',
name: 'Explore Backstage',
pathname: '/explore',
hits: 35,
timestamp: Date.now() - 86400_000,
},
]}
/>,
);
expect(
getByText('The more pages you visit, the more pages will appear here.'),
@@ -150,10 +140,8 @@ describe('<VisitList/>', () => {
});
it('renders text warning about no items', async () => {
const { getByText } = await render(
<BrowserRouter>
<VisitList title="My title" detailType="hits" visits={[]} />,
</BrowserRouter>,
const { getByText } = await renderInTestApp(
<VisitList title="My title" detailType="hits" visits={[]} />,
);
expect(getByText('There are no visits to show yet.')).toBeInTheDocument();
});
@@ -15,10 +15,9 @@
*/
import React from 'react';
import { render } from '@testing-library/react';
import { FixDialog } from './FixDialog';
import { Pod } from 'kubernetes-models/v1/Pod';
import { renderInTestApp } from '@backstage/test-utils';
jest.mock('../Events', () => ({
Events: () => {
@@ -33,8 +32,8 @@ jest.mock('../PodLogs', () => ({
}));
describe('FixDialog', () => {
it('docs link should render', () => {
const { getByText } = render(
it('docs link should render', async () => {
const { getByText } = await renderInTestApp(
<FixDialog
open
clusterName="some-cluster"
@@ -74,8 +73,8 @@ describe('FixDialog', () => {
expect(getByText('fix1')).toBeInTheDocument();
expect(getByText('fix2')).toBeInTheDocument();
});
it('events button should render', () => {
const { getByText } = render(
it('events button should render', async () => {
const { getByText } = await renderInTestApp(
<FixDialog
open
clusterName="some-cluster"
@@ -115,8 +114,8 @@ describe('FixDialog', () => {
expect(getByText('fix1')).toBeInTheDocument();
expect(getByText('fix2')).toBeInTheDocument();
});
it('Logs button should render', () => {
const { getByText } = render(
it('Logs button should render', async () => {
const { getByText } = await renderInTestApp(
<FixDialog
open
clusterName="some-cluster"
@@ -15,8 +15,8 @@
*/
import React from 'react';
import { render } from '@testing-library/react';
import { TechDocsSearchResultListItem } from './TechDocsSearchResultListItem';
import { renderInTestApp } from '@backstage/test-utils';
// Using canvas to render text..
jest.mock('react-text-truncate', () => {
@@ -46,7 +46,7 @@ const validResultWithTitle = {
describe('TechDocsSearchResultListItem test', () => {
it('should render search doc passed in', async () => {
const { findByText } = render(
const { findByText } = await renderInTestApp(
<TechDocsSearchResultListItem result={validResult} />,
);
@@ -61,7 +61,7 @@ describe('TechDocsSearchResultListItem test', () => {
});
it('should use title if defined', async () => {
const { findByText } = render(
const { findByText } = await renderInTestApp(
<TechDocsSearchResultListItem
result={validResult}
title="Count Dookumentation"
@@ -77,7 +77,7 @@ describe('TechDocsSearchResultListItem test', () => {
});
it('should use entity title if defined', async () => {
const { findByText } = render(
const { findByText } = await renderInTestApp(
<TechDocsSearchResultListItem result={validResultWithTitle} />,
);
@@ -16,7 +16,7 @@
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { renderWithEffects, TestApiProvider } from '@backstage/test-utils';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import React from 'react';
import { TodoApi, todoApiRef } from '../../api';
import { TodoList } from './TodoList';
@@ -43,7 +43,7 @@ describe('TodoList', () => {
kind: 'MockKind',
} as Entity;
const rendered = await renderWithEffects(
const rendered = await renderInTestApp(
<TestApiProvider apis={[[todoApiRef, mockApi]]}>
<EntityProvider entity={mockEntity}>
<TodoList />
@@ -16,9 +16,12 @@
import React from 'react';
import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import {
renderInTestApp,
setupRequestMockHandlers,
} from '@backstage/test-utils';
import { ComponentEntity } from '@backstage/catalog-model';
import { render, waitFor } from '@testing-library/react';
import { waitFor } from '@testing-library/react';
import { EntityVaultCard } from './EntityVaultCard';
import { EntityProvider } from '@backstage/plugin-catalog-react';
@@ -40,7 +43,7 @@ describe('EntityVaultCard', () => {
};
it('should render missing entity annotation', async () => {
const rendered = render(
const rendered = await renderInTestApp(
<EntityProvider entity={entityAnnotationMissing}>
<EntityVaultCard />
</EntityProvider>,