implement discovery too
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
+10
-12
@@ -14,15 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DiscoveryApi } from '@backstage/core-plugin-api';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
import { PluginProtocolResolverFetchMiddleware } from './PluginProtocolResolverFetchMiddleware';
|
||||
|
||||
describe('PluginProtocolResolverFetchMiddleware', () => {
|
||||
it.each([['https://passthrough.com/a']])(
|
||||
'passes through regular URLs, %p',
|
||||
async url => {
|
||||
const resolve = jest.fn();
|
||||
const discoveryApi = { getBaseUrl: resolve } as unknown as DiscoveryApi;
|
||||
const discoveryApi = mockApis.discovery();
|
||||
const middleware = new PluginProtocolResolverFetchMiddleware(
|
||||
discoveryApi,
|
||||
);
|
||||
@@ -31,7 +30,7 @@ describe('PluginProtocolResolverFetchMiddleware', () => {
|
||||
|
||||
await outer(url);
|
||||
expect(inner.mock.calls[0][0]).toBe(url);
|
||||
expect(resolve).not.toHaveBeenCalled();
|
||||
expect(discoveryApi.getBaseUrl).not.toHaveBeenCalled();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -76,30 +75,29 @@ describe('PluginProtocolResolverFetchMiddleware', () => {
|
||||
])(
|
||||
'resolves backstage URLs, %p',
|
||||
async (original, host, resolved, result) => {
|
||||
const resolve = jest.fn();
|
||||
const discoveryApi = { getBaseUrl: resolve } as unknown as DiscoveryApi;
|
||||
const discoveryApi = mockApis.discovery.mock({
|
||||
getBaseUrl: async () => resolved,
|
||||
});
|
||||
const middleware = new PluginProtocolResolverFetchMiddleware(
|
||||
discoveryApi,
|
||||
);
|
||||
const inner = jest.fn();
|
||||
const outer = middleware.apply(inner);
|
||||
|
||||
resolve.mockResolvedValueOnce(resolved);
|
||||
await outer(original);
|
||||
expect(inner.mock.calls[0][0]).toBe(result);
|
||||
expect(resolve).toHaveBeenLastCalledWith(host);
|
||||
expect(discoveryApi.getBaseUrl).toHaveBeenLastCalledWith(host);
|
||||
},
|
||||
);
|
||||
|
||||
it('properly supports transferring request bodies too', async () => {
|
||||
const resolve = jest.fn();
|
||||
const discoveryApi = { getBaseUrl: resolve } as unknown as DiscoveryApi;
|
||||
const discoveryApi = mockApis.discovery.mock({
|
||||
getBaseUrl: async () => 'https://elsewhere.com',
|
||||
});
|
||||
const middleware = new PluginProtocolResolverFetchMiddleware(discoveryApi);
|
||||
const inner = jest.fn();
|
||||
const outer = middleware.apply(inner);
|
||||
|
||||
resolve.mockResolvedValue('https://elsewhere.com');
|
||||
|
||||
await outer('plugin://a', {
|
||||
method: 'POST',
|
||||
body: '123',
|
||||
|
||||
@@ -878,9 +878,9 @@ describe('Integration Test', () => {
|
||||
}),
|
||||
}),
|
||||
};
|
||||
const discoveryApiMock = {
|
||||
getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7007/app'),
|
||||
};
|
||||
const discoveryApiMock = mockApis.discovery.mock({
|
||||
getBaseUrl: async () => 'http://localhost:7007/app',
|
||||
});
|
||||
|
||||
const app = new AppManager({
|
||||
icons,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import {
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
registerMswTestHooks,
|
||||
wrapInTestApp,
|
||||
} from '@backstage/test-utils';
|
||||
@@ -37,9 +38,7 @@ describe('ProxiedSignInPage', () => {
|
||||
apis={[
|
||||
[
|
||||
discoveryApiRef,
|
||||
{
|
||||
getBaseUrl: async () => 'http://example.com/api/auth',
|
||||
},
|
||||
mockApis.discovery({ baseUrl: 'http://example.com' }),
|
||||
],
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -115,6 +115,25 @@ export namespace mockApis {
|
||||
const mock: (partialImpl?: Partial<Config> | undefined) => ApiMock<Config>;
|
||||
}
|
||||
// (undocumented)
|
||||
export function discovery(options?: { baseUrl?: string }): jest.Mocked<{
|
||||
getBaseUrl(pluginId: string): Promise<string>;
|
||||
}>;
|
||||
// (undocumented)
|
||||
export namespace discovery {
|
||||
const // (undocumented)
|
||||
factory: (
|
||||
options?:
|
||||
| {
|
||||
baseUrl?: string | undefined;
|
||||
}
|
||||
| undefined,
|
||||
) => ApiFactory<DiscoveryApi, DiscoveryApi, {}>;
|
||||
const // (undocumented)
|
||||
mock: (
|
||||
partialImpl?: Partial<DiscoveryApi> | undefined,
|
||||
) => ApiMock<DiscoveryApi>;
|
||||
}
|
||||
// (undocumented)
|
||||
export function identity(options?: {
|
||||
userEntityRef?: string;
|
||||
ownershipEntityRefs?: string[];
|
||||
@@ -421,20 +440,24 @@ export function wrapInTestApp(
|
||||
// src/testUtils/apis/mockApis.d.ts:48:5 - (ae-undocumented) Missing documentation for "analytics".
|
||||
// src/testUtils/apis/mockApis.d.ts:49:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:50:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:101:5 - (ae-undocumented) Missing documentation for "identity".
|
||||
// src/testUtils/apis/mockApis.d.ts:109:5 - (ae-undocumented) Missing documentation for "identity".
|
||||
// src/testUtils/apis/mockApis.d.ts:110:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:118:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:120:5 - (ae-undocumented) Missing documentation for "permission".
|
||||
// src/testUtils/apis/mockApis.d.ts:123:5 - (ae-undocumented) Missing documentation for "permission".
|
||||
// src/testUtils/apis/mockApis.d.ts:124:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:127:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:129:5 - (ae-undocumented) Missing documentation for "storage".
|
||||
// src/testUtils/apis/mockApis.d.ts:132:5 - (ae-undocumented) Missing documentation for "storage".
|
||||
// src/testUtils/apis/mockApis.d.ts:133:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:136:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:138:5 - (ae-undocumented) Missing documentation for "translation".
|
||||
// src/testUtils/apis/mockApis.d.ts:139:5 - (ae-undocumented) Missing documentation for "translation".
|
||||
// src/testUtils/apis/mockApis.d.ts:140:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:141:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:101:5 - (ae-undocumented) Missing documentation for "discovery".
|
||||
// src/testUtils/apis/mockApis.d.ts:106:5 - (ae-undocumented) Missing documentation for "discovery".
|
||||
// src/testUtils/apis/mockApis.d.ts:107:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:110:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:112:5 - (ae-undocumented) Missing documentation for "identity".
|
||||
// src/testUtils/apis/mockApis.d.ts:120:5 - (ae-undocumented) Missing documentation for "identity".
|
||||
// src/testUtils/apis/mockApis.d.ts:121:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:129:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:131:5 - (ae-undocumented) Missing documentation for "permission".
|
||||
// src/testUtils/apis/mockApis.d.ts:134:5 - (ae-undocumented) Missing documentation for "permission".
|
||||
// src/testUtils/apis/mockApis.d.ts:135:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:138:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:140:5 - (ae-undocumented) Missing documentation for "storage".
|
||||
// src/testUtils/apis/mockApis.d.ts:143:5 - (ae-undocumented) Missing documentation for "storage".
|
||||
// src/testUtils/apis/mockApis.d.ts:144:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:147:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:149:5 - (ae-undocumented) Missing documentation for "translation".
|
||||
// src/testUtils/apis/mockApis.d.ts:150:5 - (ae-undocumented) Missing documentation for "translation".
|
||||
// src/testUtils/apis/mockApis.d.ts:151:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:152:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
```
|
||||
|
||||
@@ -79,6 +79,34 @@ describe('mockApis', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('discovery', () => {
|
||||
it('can create an instance and make assertions on it', async () => {
|
||||
const empty = mockApis.discovery();
|
||||
await expect(empty.getBaseUrl('catalog')).resolves.toBe(
|
||||
'http://example.com/api/catalog',
|
||||
);
|
||||
expect(empty.getBaseUrl).toHaveBeenCalledTimes(1);
|
||||
|
||||
const notEmpty = mockApis.discovery({ baseUrl: 'https://other.net' });
|
||||
await expect(notEmpty.getBaseUrl('catalog')).resolves.toBe(
|
||||
'https://other.net/api/catalog',
|
||||
);
|
||||
expect(notEmpty.getBaseUrl).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('can create a mock and make assertions on it', async () => {
|
||||
const empty = mockApis.discovery.mock();
|
||||
expect(empty.getBaseUrl('catalog')).toBeUndefined();
|
||||
expect(empty.getBaseUrl).toHaveBeenCalledTimes(1);
|
||||
|
||||
const notEmpty = mockApis.discovery.mock({
|
||||
getBaseUrl: async () => 'replaced',
|
||||
});
|
||||
await expect(notEmpty.getBaseUrl('catalog')).resolves.toBe('replaced');
|
||||
expect(notEmpty.getBaseUrl).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('identity', () => {
|
||||
it('can create an instance and make assertions on it', async () => {
|
||||
const empty = mockApis.identity();
|
||||
|
||||
@@ -20,14 +20,20 @@ import {
|
||||
ApiFactory,
|
||||
ApiRef,
|
||||
ConfigApi,
|
||||
DiscoveryApi,
|
||||
IdentityApi,
|
||||
StorageApi,
|
||||
analyticsApiRef,
|
||||
configApiRef,
|
||||
createApiFactory,
|
||||
discoveryApiRef,
|
||||
identityApiRef,
|
||||
storageApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import {
|
||||
TranslationApi,
|
||||
translationApiRef,
|
||||
} from '@backstage/core-plugin-api/alpha';
|
||||
import {
|
||||
AuthorizeResult,
|
||||
EvaluatePermissionRequest,
|
||||
@@ -40,10 +46,6 @@ import { JsonObject } from '@backstage/types';
|
||||
import { ApiMock } from './ApiMock';
|
||||
import { MockPermissionApi } from './PermissionApi';
|
||||
import { MockStorageApi } from './StorageApi';
|
||||
import {
|
||||
TranslationApi,
|
||||
translationApiRef,
|
||||
} from '@backstage/core-plugin-api/alpha';
|
||||
import { MockTranslationApi } from './TranslationApi';
|
||||
|
||||
/** @internal */
|
||||
@@ -200,6 +202,26 @@ export namespace mockApis {
|
||||
}));
|
||||
}
|
||||
|
||||
const discoveryMockSkeleton = (): jest.Mocked<DiscoveryApi> => ({
|
||||
getBaseUrl: jest.fn(),
|
||||
});
|
||||
export function discovery(options?: { baseUrl?: string }) {
|
||||
const baseUrl = options?.baseUrl ?? 'http://example.com';
|
||||
return simpleInstance(
|
||||
discoveryApiRef,
|
||||
{
|
||||
async getBaseUrl(pluginId: string) {
|
||||
return `${baseUrl}/api/${pluginId}`;
|
||||
},
|
||||
},
|
||||
discoveryMockSkeleton,
|
||||
);
|
||||
}
|
||||
export namespace discovery {
|
||||
export const factory = simpleFactory(discoveryApiRef, discovery);
|
||||
export const mock = simpleMock(discoveryApiRef, discoveryMockSkeleton);
|
||||
}
|
||||
|
||||
const identityMockSkeleton = (): jest.Mocked<IdentityApi> => ({
|
||||
getBackstageIdentity: jest.fn(),
|
||||
getCredentials: jest.fn(),
|
||||
|
||||
+2
-6
@@ -30,11 +30,7 @@ import {
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
describe('CookieAuthRefreshProvider', () => {
|
||||
const discoveryApiMock = {
|
||||
getBaseUrl: jest
|
||||
.fn()
|
||||
.mockResolvedValue('http://localhost:7000/api/techdocs'),
|
||||
};
|
||||
const discoveryApiMock = mockApis.discovery();
|
||||
|
||||
function getExpiresAtInFuture() {
|
||||
const tenMinutesInMilliseconds = 10 * 60 * 1000;
|
||||
@@ -118,7 +114,7 @@ describe('CookieAuthRefreshProvider', () => {
|
||||
|
||||
await waitFor(() =>
|
||||
expect(fetchApiMock.fetch).toHaveBeenCalledWith(
|
||||
'http://localhost:7000/api/techdocs/.backstage/auth/v1/cookie',
|
||||
'http://example.com/api/techdocs/.backstage/auth/v1/cookie',
|
||||
{ credentials: 'include' },
|
||||
),
|
||||
);
|
||||
|
||||
@@ -17,15 +17,11 @@
|
||||
import React from 'react';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { fetchApiRef, discoveryApiRef } from '@backstage/core-plugin-api';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { TestApiProvider, mockApis } from '@backstage/test-utils';
|
||||
import { useCookieAuthRefresh } from './useCookieAuthRefresh';
|
||||
|
||||
describe('useCookieAuthRefresh', () => {
|
||||
const discoveryApiMock = {
|
||||
getBaseUrl: jest
|
||||
.fn()
|
||||
.mockResolvedValue('http://localhost:7000/api/techdocs'),
|
||||
};
|
||||
const discoveryApiMock = mockApis.discovery();
|
||||
|
||||
const now = 1710316886171;
|
||||
const tenMinutesInMilliseconds = 10 * 60 * 1000;
|
||||
@@ -269,7 +265,7 @@ describe('useCookieAuthRefresh', () => {
|
||||
|
||||
await waitFor(() =>
|
||||
expect(fetchApiMock.fetch).toHaveBeenCalledWith(
|
||||
'http://localhost:7000/api/techdocs/.backstage/auth/v1/cookie',
|
||||
'http://example.com/api/techdocs/.backstage/auth/v1/cookie',
|
||||
{ credentials: 'include' },
|
||||
),
|
||||
);
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DiscoveryApi, discoveryApiRef } from '@backstage/core-plugin-api';
|
||||
import { discoveryApiRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
mockApis,
|
||||
renderInTestApp,
|
||||
TestApiProvider,
|
||||
textContentMatcher,
|
||||
@@ -37,9 +38,7 @@ describe('PodExecTerminal', () => {
|
||||
const podName = 'pod1';
|
||||
const podNamespace = 'podNamespace';
|
||||
|
||||
const mockDiscoveryApi: Partial<DiscoveryApi> = {
|
||||
getBaseUrl: () => Promise.resolve('http://localhost'),
|
||||
};
|
||||
const mockDiscoveryApi = mockApis.discovery();
|
||||
|
||||
it('Should render an XTerm web terminal', async () => {
|
||||
await renderInTestApp(
|
||||
@@ -62,7 +61,7 @@ describe('PodExecTerminal', () => {
|
||||
|
||||
it('Should connect to WebSocket server & render response', async () => {
|
||||
const server = new WS(
|
||||
'ws://localhost/proxy/api/v1/namespaces/podNamespace/pods/pod1/exec?container=container2&stdin=true&stdout=true&stderr=true&tty=true&command=%2Fbin%2Fsh',
|
||||
'ws://example.com/api/kubernetes/proxy/api/v1/namespaces/podNamespace/pods/pod1/exec?container=container2&stdin=true&stdout=true&stderr=true&tty=true&command=%2Fbin%2Fsh',
|
||||
);
|
||||
|
||||
await renderInTestApp(
|
||||
|
||||
@@ -17,19 +17,21 @@
|
||||
import React from 'react';
|
||||
|
||||
import { screen } from '@testing-library/react';
|
||||
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
|
||||
import {
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
renderInTestApp,
|
||||
} from '@backstage/test-utils';
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
import { PodDrawer } from './PodDrawer';
|
||||
import { DiscoveryApi, discoveryApiRef } from '@backstage/core-plugin-api';
|
||||
import { discoveryApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
jest.mock('../../../hooks/useIsPodExecTerminalSupported');
|
||||
|
||||
describe('PodDrawer', () => {
|
||||
it('Should show title and container names', async () => {
|
||||
const mockDiscoveryApi: Partial<DiscoveryApi> = {
|
||||
getBaseUrl: () => Promise.resolve('http://localhost'),
|
||||
};
|
||||
const mockDiscoveryApi = mockApis.discovery();
|
||||
|
||||
await renderInTestApp(
|
||||
<TestApiProvider apis={[[discoveryApiRef, mockDiscoveryApi]]}>
|
||||
|
||||
@@ -14,24 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DiscoveryApi } from '@backstage/core-plugin-api';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
import WS from 'jest-websocket-mock';
|
||||
import { SignalClient } from './SignalClient';
|
||||
|
||||
describe('SignalsClient', () => {
|
||||
const baseUrlFunction = jest.fn();
|
||||
const identity = mockApis.identity({ token: '12345' });
|
||||
const discoveryApi = {
|
||||
getBaseUrl: baseUrlFunction,
|
||||
} as unknown as DiscoveryApi;
|
||||
const discoveryApi = mockApis.discovery({ baseUrl: 'http://localhost:1234' });
|
||||
|
||||
let server: WS;
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
baseUrlFunction.mockResolvedValue('http://localhost:1234');
|
||||
server = new WS('ws://localhost:1234', { jsonProtocol: true });
|
||||
server = new WS('ws://localhost:1234/api/signals', {
|
||||
jsonProtocol: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
+1
-7
@@ -81,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,
|
||||
@@ -116,7 +110,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
[fetchApiRef, fetchApiMock],
|
||||
[discoveryApiRef, discoveryApiMock],
|
||||
[discoveryApiRef, mockApis.discovery()],
|
||||
[scmIntegrationsApiRef, {}],
|
||||
[configApiRef, configApi],
|
||||
[techdocsApiRef, techdocsApiMock],
|
||||
|
||||
Reference in New Issue
Block a user