Merge pull request #27026 from backstage/freben/mock-apis-config

Implement the beginnings of `mockApis`
This commit is contained in:
Fredrik Adelöw
2024-10-11 11:08:54 +02:00
committed by GitHub
114 changed files with 2273 additions and 1031 deletions
+3 -13
View File
@@ -15,10 +15,9 @@
*/
import { UrlPatternDiscovery } from '@backstage/core-app-api';
import { IdentityApi } from '@backstage/core-plugin-api';
import { NotFoundError } from '@backstage/errors';
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { MockConfigApi, MockFetchApi } from '@backstage/test-utils';
import { mockApis, MockFetchApi } from '@backstage/test-utils';
import { TechDocsStorageClient } from './client';
jest.mock('@microsoft/fetch-event-source');
@@ -34,16 +33,13 @@ const mockEntity = {
describe('TechDocsStorageClient', () => {
const mockBaseUrl = 'http://backstage:9191/api/techdocs';
const configApi = new MockConfigApi({});
const configApi = mockApis.config();
const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl);
const identityApi: jest.Mocked<IdentityApi> = {
getCredentials: jest.fn(),
} as unknown as jest.Mocked<IdentityApi>;
const identityApi = mockApis.identity();
const fetchApi = new MockFetchApi({ injectIdentityAuth: { identityApi } });
beforeEach(() => {
jest.resetAllMocks();
identityApi.getCredentials.mockResolvedValue({ token: undefined });
});
it('should return correct base url based on defined storage', async () => {
@@ -95,7 +91,6 @@ describe('TechDocsStorageClient', () => {
await Promise.resolve();
onmessage?.({ id: '', event: 'finish', data: '{"updated": false}' });
});
identityApi.getCredentials.mockResolvedValue({});
await storageApi.syncEntityDocs(mockEntity);
expect(mockFetchEventSource).toHaveBeenCalledWith(
@@ -126,7 +121,6 @@ describe('TechDocsStorageClient', () => {
onmessage?.({ id: '', event: 'finish', data: '{"updated": false}' });
});
identityApi.getCredentials.mockResolvedValue({});
await expect(storageApi.syncEntityDocs(mockEntity)).resolves.toEqual(
'cached',
);
@@ -146,7 +140,6 @@ describe('TechDocsStorageClient', () => {
onmessage?.({ id: '', event: 'finish', data: '{"updated": true}' });
});
identityApi.getCredentials.mockResolvedValue({});
await expect(storageApi.syncEntityDocs(mockEntity)).resolves.toEqual(
'updated',
);
@@ -169,7 +162,6 @@ describe('TechDocsStorageClient', () => {
onmessage?.({ id: '', event: 'finish', data: '{"updated": false}' });
});
identityApi.getCredentials.mockResolvedValue({});
const logHandler = jest.fn();
await expect(
storageApi.syncEntityDocs(mockEntity, logHandler),
@@ -192,7 +184,6 @@ describe('TechDocsStorageClient', () => {
});
// we await later after we emitted the error
identityApi.getCredentials.mockResolvedValue({});
const promise = storageApi.syncEntityDocs(mockEntity).then();
await expect(promise).rejects.toThrow(NotFoundError);
@@ -207,7 +198,6 @@ describe('TechDocsStorageClient', () => {
});
// we await later after we emitted the error
identityApi.getCredentials.mockResolvedValue({});
const promise = storageApi.syncEntityDocs(mockEntity).then();
mockFetchEventSource.mockImplementation(async (_url, options) => {
@@ -14,22 +14,18 @@
* limitations under the License.
*/
import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import {
ConfigApi,
configApiRef,
storageApiRef,
} from '@backstage/core-plugin-api';
import { ApiProvider } from '@backstage/core-app-api';
import { configApiRef, storageApiRef } from '@backstage/core-plugin-api';
import {
MockStarredEntitiesApi,
catalogApiRef,
starredEntitiesApiRef,
MockStarredEntitiesApi,
} from '@backstage/plugin-catalog-react';
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
import {
MockStorageApi,
renderInTestApp,
TestApiRegistry,
mockApis,
renderInTestApp,
} from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -50,18 +46,14 @@ const mockCatalogApi = catalogApiMock({
});
describe('TechDocs Home', () => {
const configApi: ConfigApi = new ConfigReader({
organization: {
name: 'My Company',
},
const configApi = mockApis.config({
data: { organization: { name: 'My Company' } },
});
const storageApi = MockStorageApi.create();
const apiRegistry = TestApiRegistry.from(
[catalogApiRef, mockCatalogApi],
[configApiRef, configApi],
[storageApiRef, storageApi],
[storageApiRef, mockApis.storage()],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
);
@@ -14,12 +14,8 @@
* limitations under the License.
*/
import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import {
ConfigApi,
configApiRef,
storageApiRef,
} from '@backstage/core-plugin-api';
import { ApiProvider } from '@backstage/core-app-api';
import { configApiRef, storageApiRef } from '@backstage/core-plugin-api';
import {
catalogApiRef,
starredEntitiesApiRef,
@@ -30,9 +26,9 @@ import {
catalogApiMock,
} from '@backstage/plugin-catalog-react/testUtils';
import {
MockStorageApi,
renderInTestApp,
TestApiRegistry,
mockApis,
} from '@backstage/test-utils';
import { screen } from '@testing-library/react';
import React from 'react';
@@ -68,21 +64,17 @@ const mockCatalogApi = catalogApiMock({ entities });
describe('Entity List Docs Grid', () => {
beforeEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
});
const configApi: ConfigApi = new ConfigReader({
organization: {
name: 'My Company',
},
const configApi = mockApis.config({
data: { organization: { name: 'My Company' } },
});
const storageApi = MockStorageApi.create();
const apiRegistry = TestApiRegistry.from(
[catalogApiRef, mockCatalogApi],
[configApiRef, configApi],
[storageApiRef, storageApi],
[storageApiRef, mockApis.storage()],
[starredEntitiesApiRef, new MockStarredEntitiesApi()],
);
@@ -16,12 +16,11 @@
import { TechDocsNotFound } from './TechDocsNotFound';
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { screen, waitFor } from '@testing-library/react';
import {
MockAnalyticsApi,
mockApis,
TestApiProvider,
renderInTestApp,
wrapInTestApp,
} from '@backstage/test-utils';
import { analyticsApiRef } from '@backstage/core-plugin-api';
@@ -58,18 +57,16 @@ describe('<TechDocsNotFound />', () => {
});
it('should trigger analytics event not-found', async () => {
const mockAnalyticsApi = new MockAnalyticsApi();
const mockAnalyticsApi = mockApis.analytics();
render(
wrapInTestApp(
<TestApiProvider apis={[[analyticsApiRef, mockAnalyticsApi]]}>
<TechDocsNotFound />
</TestApiProvider>,
),
await renderInTestApp(
<TestApiProvider apis={[[analyticsApiRef, mockAnalyticsApi]]}>
<TechDocsNotFound />
</TestApiProvider>,
);
await waitFor(() => {
expect(mockAnalyticsApi.getEvents()[0]).toMatchObject({
expect(mockAnalyticsApi.captureEvent).toHaveBeenCalledWith({
action: 'not-found',
subject: '/the/pathname?the=search#the-anchor',
attributes: {
@@ -77,6 +74,7 @@ describe('<TechDocsNotFound />', () => {
namespace: 'namespace',
kind: 'kind',
},
context: expect.anything(),
});
});
});
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { scmIntegrationsApiRef } from '@backstage/integration-react';
import { entityRouteRef } from '@backstage/plugin-catalog-react';
import {
MockConfigApi,
mockApis,
renderInTestApp,
TestApiProvider,
} from '@backstage/test-utils';
@@ -80,12 +81,6 @@ const techdocsStorageApiMock: jest.Mocked<typeof techdocsStorageApiRef.T> = {
syncEntityDocs: jest.fn(),
};
const discoveryApiMock = {
getBaseUrl: jest
.fn()
.mockResolvedValue('https://localhost:7000/api/techdocs'),
};
const fetchApiMock = {
fetch: jest.fn().mockResolvedValue({
ok: true,
@@ -106,10 +101,8 @@ jest.mock('@backstage/core-components', () => ({
Page: jest.fn(),
}));
const configApi = new MockConfigApi({
app: {
baseUrl: 'http://localhost:3000',
},
const configApi = mockApis.config({
data: { app: { baseUrl: 'http://localhost:3000' } },
});
const Wrapper = ({ children }: { children: React.ReactNode }) => {
@@ -117,7 +110,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => {
<TestApiProvider
apis={[
[fetchApiRef, fetchApiMock],
[discoveryApiRef, discoveryApiMock],
[discoveryApiRef, mockApis.discovery()],
[scmIntegrationsApiRef, {}],
[configApiRef, configApi],
[techdocsApiRef, techdocsApiMock],
@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import {
MockConfigApi,
mockApis,
renderInTestApp,
TestApiProvider,
} from '@backstage/test-utils';
@@ -55,16 +56,7 @@ describe('useNavigateUrl', () => {
const baseUrl = 'http://localhost:3000';
await renderInTestApp(
<TestApiProvider
apis={[
[
configApiRef,
new MockConfigApi({
app: {
baseUrl,
},
}),
],
]}
apis={[[configApiRef, mockApis.config({ data: { app: { baseUrl } } })]]}
>
<Component to={`${baseUrl}/test`} />
</TestApiProvider>,
@@ -75,16 +67,7 @@ describe('useNavigateUrl', () => {
const baseUrl = 'http://localhost:3000/instance';
await renderInTestApp(
<TestApiProvider
apis={[
[
configApiRef,
new MockConfigApi({
app: {
baseUrl,
},
}),
],
]}
apis={[[configApiRef, mockApis.config({ data: { app: { baseUrl } } })]]}
>
<Component to={`${baseUrl}/test`} />
</TestApiProvider>,
@@ -95,16 +78,7 @@ describe('useNavigateUrl', () => {
const baseUrl = 'http://localhost:3000';
await renderInTestApp(
<TestApiProvider
apis={[
[
configApiRef,
new MockConfigApi({
app: {
baseUrl,
},
}),
],
]}
apis={[[configApiRef, mockApis.config({ data: { app: { baseUrl } } })]]}
>
<Component to="/test" />
</TestApiProvider>,