implement the beginnings of mockApis
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
---
|
||||
|
||||
Minor doc string changes
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/test-utils': minor
|
||||
'@backstage/frontend-test-utils': patch
|
||||
---
|
||||
|
||||
Added a `mockApis` export, which will replace the `MockX` API implementation classes and their related types. This is analogous with the backend's `mockServices`.
|
||||
|
||||
Deprecated `MockConfigApi`, please use `mockApis.config` instead.
|
||||
@@ -150,7 +150,7 @@ export function mockErrorHandler(): ErrorRequestHandler<
|
||||
Record<string, any>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export namespace mockServices {
|
||||
// (undocumented)
|
||||
export function auth(options?: {
|
||||
@@ -491,65 +491,64 @@ export class TestDatabases {
|
||||
// src/next/services/mockCredentials.d.ts:116:9 - (ae-undocumented) Missing documentation for "invalidToken".
|
||||
// src/next/services/mockCredentials.d.ts:117:9 - (ae-undocumented) Missing documentation for "invalidHeader".
|
||||
// src/next/services/mockServices.d.ts:5:1 - (ae-undocumented) Missing documentation for "ServiceMock".
|
||||
// src/next/services/mockServices.d.ts:13:1 - (ae-undocumented) Missing documentation for "mockServices".
|
||||
// src/next/services/mockServices.d.ts:14:5 - (ae-undocumented) Missing documentation for "rootConfig".
|
||||
// src/next/services/mockServices.d.ts:15:5 - (ae-undocumented) Missing documentation for "rootConfig".
|
||||
// src/next/services/mockServices.d.ts:16:9 - (ae-undocumented) Missing documentation for "Options".
|
||||
// src/next/services/mockServices.d.ts:19:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:20:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:22:5 - (ae-undocumented) Missing documentation for "rootLogger".
|
||||
// src/next/services/mockServices.d.ts:23:5 - (ae-undocumented) Missing documentation for "rootLogger".
|
||||
// src/next/services/mockServices.d.ts:24:9 - (ae-undocumented) Missing documentation for "Options".
|
||||
// src/next/services/mockServices.d.ts:27:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:28:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:30:5 - (ae-undocumented) Missing documentation for "auth".
|
||||
// src/next/services/mockServices.d.ts:34:5 - (ae-undocumented) Missing documentation for "auth".
|
||||
// src/next/services/mockServices.d.ts:35:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:36:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:38:5 - (ae-undocumented) Missing documentation for "discovery".
|
||||
// src/next/services/mockServices.d.ts:39:5 - (ae-undocumented) Missing documentation for "discovery".
|
||||
// src/next/services/mockServices.d.ts:40:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:41:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:61:5 - (ae-undocumented) Missing documentation for "httpAuth".
|
||||
// src/next/services/mockServices.d.ts:72:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:82:5 - (ae-undocumented) Missing documentation for "userInfo".
|
||||
// src/next/services/mockServices.d.ts:90:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:92:5 - (ae-undocumented) Missing documentation for "cache".
|
||||
// src/next/services/mockServices.d.ts:93:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:94:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:96:5 - (ae-undocumented) Missing documentation for "database".
|
||||
// src/next/services/mockServices.d.ts:97:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:98:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:100:5 - (ae-undocumented) Missing documentation for "rootHealth".
|
||||
// src/next/services/mockServices.d.ts:101:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:102:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:104:5 - (ae-undocumented) Missing documentation for "httpRouter".
|
||||
// src/next/services/mockServices.d.ts:105:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:106:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:108:5 - (ae-undocumented) Missing documentation for "rootHttpRouter".
|
||||
// src/next/services/mockServices.d.ts:109:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:110:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:112:5 - (ae-undocumented) Missing documentation for "lifecycle".
|
||||
// src/next/services/mockServices.d.ts:113:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:114:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:116:5 - (ae-undocumented) Missing documentation for "logger".
|
||||
// src/next/services/mockServices.d.ts:117:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:118:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:120:5 - (ae-undocumented) Missing documentation for "permissions".
|
||||
// src/next/services/mockServices.d.ts:121:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:122:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:124:5 - (ae-undocumented) Missing documentation for "rootLifecycle".
|
||||
// src/next/services/mockServices.d.ts:125:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:126:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:128:5 - (ae-undocumented) Missing documentation for "scheduler".
|
||||
// src/next/services/mockServices.d.ts:129:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:130:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:132:5 - (ae-undocumented) Missing documentation for "urlReader".
|
||||
// src/next/services/mockServices.d.ts:133:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:134:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:136:5 - (ae-undocumented) Missing documentation for "events".
|
||||
// src/next/services/mockServices.d.ts:137:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:138:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:53:5 - (ae-undocumented) Missing documentation for "rootConfig".
|
||||
// src/next/services/mockServices.d.ts:54:5 - (ae-undocumented) Missing documentation for "rootConfig".
|
||||
// src/next/services/mockServices.d.ts:55:9 - (ae-undocumented) Missing documentation for "Options".
|
||||
// src/next/services/mockServices.d.ts:58:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:59:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:61:5 - (ae-undocumented) Missing documentation for "rootLogger".
|
||||
// src/next/services/mockServices.d.ts:62:5 - (ae-undocumented) Missing documentation for "rootLogger".
|
||||
// src/next/services/mockServices.d.ts:63:9 - (ae-undocumented) Missing documentation for "Options".
|
||||
// src/next/services/mockServices.d.ts:66:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:67:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:69:5 - (ae-undocumented) Missing documentation for "auth".
|
||||
// src/next/services/mockServices.d.ts:73:5 - (ae-undocumented) Missing documentation for "auth".
|
||||
// src/next/services/mockServices.d.ts:74:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:75:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:77:5 - (ae-undocumented) Missing documentation for "discovery".
|
||||
// src/next/services/mockServices.d.ts:78:5 - (ae-undocumented) Missing documentation for "discovery".
|
||||
// src/next/services/mockServices.d.ts:79:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:80:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:100:5 - (ae-undocumented) Missing documentation for "httpAuth".
|
||||
// src/next/services/mockServices.d.ts:111:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:121:5 - (ae-undocumented) Missing documentation for "userInfo".
|
||||
// src/next/services/mockServices.d.ts:129:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:131:5 - (ae-undocumented) Missing documentation for "cache".
|
||||
// src/next/services/mockServices.d.ts:132:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:133:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:135:5 - (ae-undocumented) Missing documentation for "database".
|
||||
// src/next/services/mockServices.d.ts:136:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:137:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:139:5 - (ae-undocumented) Missing documentation for "rootHealth".
|
||||
// src/next/services/mockServices.d.ts:140:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:141:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:143:5 - (ae-undocumented) Missing documentation for "httpRouter".
|
||||
// src/next/services/mockServices.d.ts:144:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:145:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:147:5 - (ae-undocumented) Missing documentation for "rootHttpRouter".
|
||||
// src/next/services/mockServices.d.ts:148:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:149:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:151:5 - (ae-undocumented) Missing documentation for "lifecycle".
|
||||
// src/next/services/mockServices.d.ts:152:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:153:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:155:5 - (ae-undocumented) Missing documentation for "logger".
|
||||
// src/next/services/mockServices.d.ts:156:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:157:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:159:5 - (ae-undocumented) Missing documentation for "permissions".
|
||||
// src/next/services/mockServices.d.ts:160:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:161:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:163:5 - (ae-undocumented) Missing documentation for "rootLifecycle".
|
||||
// src/next/services/mockServices.d.ts:164:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:165:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:167:5 - (ae-undocumented) Missing documentation for "scheduler".
|
||||
// src/next/services/mockServices.d.ts:168:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:169:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:171:5 - (ae-undocumented) Missing documentation for "urlReader".
|
||||
// src/next/services/mockServices.d.ts:172:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:173:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/services/mockServices.d.ts:175:5 - (ae-undocumented) Missing documentation for "events".
|
||||
// src/next/services/mockServices.d.ts:176:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/next/services/mockServices.d.ts:177:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/next/wiring/TestBackend.d.ts:5:1 - (ae-undocumented) Missing documentation for "TestBackendOptions".
|
||||
// src/next/wiring/TestBackend.d.ts:6:5 - (ae-undocumented) Missing documentation for "extensionPoints".
|
||||
// src/next/wiring/TestBackend.d.ts:14:5 - (ae-undocumented) Missing documentation for "features".
|
||||
|
||||
@@ -128,7 +128,46 @@ function simpleMock<TService>(
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock implementations of the core services, to be used in tests.
|
||||
*
|
||||
* @public
|
||||
* @remarks
|
||||
*
|
||||
* There are some variations among the services depending on what needs tests
|
||||
* might have, but overall there are three main usage patterns:
|
||||
*
|
||||
* 1. Creating an actual fake service instance, often with a simplified version
|
||||
* of functionality, by calling the mock service itself as a function.
|
||||
*
|
||||
* ```ts
|
||||
* // The function often accepts parameters that control its behavior
|
||||
* const foo = mockServices.foo();
|
||||
* ```
|
||||
*
|
||||
* 2. Creating a mock service, where all methods are replaced with jest mocks, by
|
||||
* calling the service's `mock` function.
|
||||
*
|
||||
* ```ts
|
||||
* // You can optionally supply a subset of its methods to implement
|
||||
* const foo = mockServices.foo.mock({
|
||||
* someMethod: () => 'mocked result',
|
||||
* });
|
||||
* // After exercising your test, you can make assertions on the mock:
|
||||
* expect(foo.someMethod).toHaveBeenCalledTimes(2);
|
||||
* expect(foo.otherMethod).toHaveBeenCalledWith(testData);
|
||||
* ```
|
||||
*
|
||||
* 3. Creating a service factory that behaves similarly to the mock as per above.
|
||||
*
|
||||
* ```ts
|
||||
* await startTestBackend({
|
||||
* features: [
|
||||
* mockServices.foo.factory({
|
||||
* someMethod: () => 'mocked result',
|
||||
* })
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export namespace mockServices {
|
||||
export function rootConfig(options?: rootConfig.Options): RootConfigService {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
import BitbucketAuth from './BitbucketAuth';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const getSession = jest.fn();
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('BitbucketAuth', () => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
|
||||
it.each([
|
||||
['team api write_repository', ['team', 'api', 'write_repository']],
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
import BitbucketServerAuth from './BitbucketServerAuth';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const getSession = jest.fn();
|
||||
|
||||
@@ -41,7 +41,7 @@ describe('BitbucketServerAuth', () => {
|
||||
['PROJECT_ADMIN', 'REPO_READ', 'ACCOUNT_WRITE'],
|
||||
],
|
||||
])(`should normalize scopes correctly - %p`, (scope, scopes) => {
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
|
||||
const bitbucketServerAuth = BitbucketServerAuth.create({
|
||||
configApi: configApi,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import GithubAuth from './GithubAuth';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const getSession = jest.fn();
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('GithubAuth', () => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
|
||||
it('should forward access token request to session manager', async () => {
|
||||
const githubAuth = GithubAuth.create({
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
import GitlabAuth from './GitlabAuth';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const getSession = jest.fn();
|
||||
|
||||
@@ -40,7 +40,7 @@ describe('GitlabAuth', () => {
|
||||
],
|
||||
['read_repository sudo', ['read_repository', 'sudo']],
|
||||
])(`should normalize scopes correctly - %p`, (scope, scopes) => {
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
|
||||
const gitlabAuth = GitlabAuth.create({
|
||||
configApi: configApi,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import GoogleAuth from './GoogleAuth';
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const PREFIX = 'https://www.googleapis.com/auth/';
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('GoogleAuth', () => {
|
||||
[`${PREFIX}profile`, [`${PREFIX}profile`]],
|
||||
[`${PREFIX}openid`, [`${PREFIX}openid`]],
|
||||
])(`should normalize scopes correctly - %p`, (scope, scopes) => {
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
|
||||
const googleAuth = GoogleAuth.create({
|
||||
configApi: configApi,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import OAuth2 from './OAuth2';
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const theFuture = new Date(Date.now() + 3600000);
|
||||
const thePast = new Date(Date.now() - 10);
|
||||
@@ -35,7 +35,7 @@ jest.mock('../../../../lib/AuthSessionManager', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
|
||||
describe('OAuth2', () => {
|
||||
it('should get refreshed access token', async () => {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import OktaAuth from './OktaAuth';
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const PREFIX = 'okta.';
|
||||
|
||||
@@ -51,7 +51,7 @@ describe('OktaAuth', () => {
|
||||
[`${PREFIX}profile`, [`${PREFIX}profile`]],
|
||||
[`${PREFIX}openid`, [`${PREFIX}openid`]],
|
||||
])(`should normalize scopes correctly - %p`, (scope, scopes) => {
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
const auth = OktaAuth.create({
|
||||
configApi: configApi,
|
||||
oauthRequestApi: new MockOAuthApi(),
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
createRouteRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { collectRouteIds, resolveRouteBindings } from './resolveRouteBindings';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
describe('resolveRouteBindings', () => {
|
||||
it('runs happy path', () => {
|
||||
@@ -30,7 +30,7 @@ describe('resolveRouteBindings', () => {
|
||||
({ bind }) => {
|
||||
bind(external, { myRoute: ref });
|
||||
},
|
||||
new MockConfigApi({}),
|
||||
mockApis.config(),
|
||||
[],
|
||||
);
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('resolveRouteBindings', () => {
|
||||
({ bind }) => {
|
||||
bind(external, { someOtherRoute: ref } as any);
|
||||
},
|
||||
new MockConfigApi({}),
|
||||
mockApis.config(),
|
||||
[],
|
||||
),
|
||||
).toThrow('Key someOtherRoute is not an existing external route');
|
||||
@@ -56,8 +56,10 @@ describe('resolveRouteBindings', () => {
|
||||
const myTarget = createRouteRef({ id: 'test' });
|
||||
const result = resolveRouteBindings(
|
||||
() => {},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.mySource': 'test.myTarget' } } },
|
||||
mockApis.config({
|
||||
data: {
|
||||
app: { routes: { bindings: { 'test.mySource': 'test.myTarget' } } },
|
||||
},
|
||||
}),
|
||||
[
|
||||
createPlugin({
|
||||
@@ -84,8 +86,10 @@ describe('resolveRouteBindings', () => {
|
||||
({ bind }) => {
|
||||
bind({ mySource }, { mySource: false });
|
||||
},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.mySource': 'myTarget' } } },
|
||||
mockApis.config({
|
||||
data: {
|
||||
app: { routes: { bindings: { 'test.mySource': 'myTarget' } } },
|
||||
},
|
||||
}),
|
||||
[
|
||||
createPlugin({
|
||||
@@ -106,8 +110,8 @@ describe('resolveRouteBindings', () => {
|
||||
({ bind }) => {
|
||||
bind({ mySource }, { mySource: myTarget });
|
||||
},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.mySource': false } } },
|
||||
mockApis.config({
|
||||
data: { app: { routes: { bindings: { 'test.mySource': false } } } },
|
||||
}),
|
||||
[
|
||||
createPlugin({
|
||||
@@ -128,7 +132,7 @@ describe('resolveRouteBindings', () => {
|
||||
expect(() =>
|
||||
resolveRouteBindings(
|
||||
() => {},
|
||||
new MockConfigApi({ app: { routes: { bindings: 'derp' } } }),
|
||||
mockApis.config({ data: { app: { routes: { bindings: 'derp' } } } }),
|
||||
[],
|
||||
),
|
||||
).toThrow(
|
||||
@@ -138,8 +142,8 @@ describe('resolveRouteBindings', () => {
|
||||
expect(() =>
|
||||
resolveRouteBindings(
|
||||
() => {},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.mySource': true } } },
|
||||
mockApis.config({
|
||||
data: { app: { routes: { bindings: { 'test.mySource': true } } } },
|
||||
}),
|
||||
[],
|
||||
),
|
||||
@@ -150,8 +154,10 @@ describe('resolveRouteBindings', () => {
|
||||
expect(() =>
|
||||
resolveRouteBindings(
|
||||
() => {},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.mySource': 'test.myTarget' } } },
|
||||
mockApis.config({
|
||||
data: {
|
||||
app: { routes: { bindings: { 'test.mySource': 'test.myTarget' } } },
|
||||
},
|
||||
}),
|
||||
[],
|
||||
),
|
||||
@@ -162,8 +168,10 @@ describe('resolveRouteBindings', () => {
|
||||
expect(() =>
|
||||
resolveRouteBindings(
|
||||
() => {},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.mySource': 'test.myTarget' } } },
|
||||
mockApis.config({
|
||||
data: {
|
||||
app: { routes: { bindings: { 'test.mySource': 'test.myTarget' } } },
|
||||
},
|
||||
}),
|
||||
[
|
||||
createPlugin({
|
||||
@@ -198,17 +206,17 @@ describe('resolveRouteBindings', () => {
|
||||
});
|
||||
|
||||
// defaultTarget wins only if no bind or config matches
|
||||
let result = resolveRouteBindings(() => {}, new MockConfigApi({}), [
|
||||
plugin,
|
||||
]);
|
||||
let result = resolveRouteBindings(() => {}, mockApis.config(), [plugin]);
|
||||
|
||||
expect(result.get(source)).toBe(target1);
|
||||
|
||||
// config wins over defaultTarget
|
||||
result = resolveRouteBindings(
|
||||
() => {},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.source': 'test.target2' } } },
|
||||
mockApis.config({
|
||||
data: {
|
||||
app: { routes: { bindings: { 'test.source': 'test.target2' } } },
|
||||
},
|
||||
}),
|
||||
[plugin],
|
||||
);
|
||||
@@ -220,7 +228,7 @@ describe('resolveRouteBindings', () => {
|
||||
({ bind }) => {
|
||||
bind(plugin.externalRoutes, { source: plugin.routes.target2 });
|
||||
},
|
||||
new MockConfigApi({}),
|
||||
mockApis.config(),
|
||||
[plugin],
|
||||
);
|
||||
|
||||
@@ -257,17 +265,15 @@ describe('collectRouteIds', () => {
|
||||
});
|
||||
|
||||
// resolves normally with no config
|
||||
let result = resolveRouteBindings(() => {}, new MockConfigApi({}), [
|
||||
plugin,
|
||||
]);
|
||||
let result = resolveRouteBindings(() => {}, mockApis.config(), [plugin]);
|
||||
|
||||
expect(result.get(source)).toBe(target1);
|
||||
|
||||
// can be disabled
|
||||
result = resolveRouteBindings(
|
||||
() => {},
|
||||
new MockConfigApi({
|
||||
app: { routes: { bindings: { 'test.source': false } } },
|
||||
mockApis.config({
|
||||
data: { app: { routes: { bindings: { 'test.source': false } } } },
|
||||
}),
|
||||
[plugin],
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { configApiRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
MockConfigApi,
|
||||
mockApis,
|
||||
renderInTestApp,
|
||||
TestApiProvider,
|
||||
} from '@backstage/test-utils';
|
||||
@@ -24,17 +24,19 @@ import { act, fireEvent, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { SupportButton } from './SupportButton';
|
||||
|
||||
const configApi = new MockConfigApi({
|
||||
app: {
|
||||
support: {
|
||||
url: 'https://github.com',
|
||||
items: [
|
||||
{
|
||||
title: 'Github',
|
||||
icon: 'github',
|
||||
links: [{ title: 'Github Issues', url: '/issues' }],
|
||||
},
|
||||
],
|
||||
const configApi = mockApis.config({
|
||||
data: {
|
||||
app: {
|
||||
support: {
|
||||
url: 'https://github.com',
|
||||
items: [
|
||||
{
|
||||
title: 'Github',
|
||||
icon: 'github',
|
||||
links: [{ title: 'Github Issues', url: '/issues' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
createFrontendPlugin,
|
||||
createRouteRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { MockConfigApi, TestApiRegistry } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiRegistry } from '@backstage/test-utils';
|
||||
import appPlugin from '@backstage/plugin-app';
|
||||
|
||||
import { readAppExtensionsConfig } from '../tree/readAppExtensionsConfig';
|
||||
@@ -92,7 +92,7 @@ function routeInfoFromExtensions(extensions: ExtensionDefinition[]) {
|
||||
builtinExtensions: [
|
||||
resolveExtensionDefinition(Root, { namespace: 'root' }),
|
||||
],
|
||||
parameters: readAppExtensionsConfig(new MockConfigApi({})),
|
||||
parameters: readAppExtensionsConfig(mockApis.config()),
|
||||
forbidden: new Set(['root']),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { screen, render } from '@testing-library/react';
|
||||
import { createSpecializedApp } from './createSpecializedApp';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import {
|
||||
configApiRef,
|
||||
@@ -98,7 +98,7 @@ describe('createSpecializedApp', () => {
|
||||
|
||||
it('should forward config', () => {
|
||||
const app = createSpecializedApp({
|
||||
config: new MockConfigApi({ test: 'foo' }),
|
||||
config: mockApis.config({ data: { test: 'foo' } }),
|
||||
features: [
|
||||
createFrontendPlugin({
|
||||
id: 'test',
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { CreateAppFeatureLoader, createApp } from './createApp';
|
||||
import { MockConfigApi, renderWithEffects } from '@backstage/test-utils';
|
||||
import { mockApis, renderWithEffects } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api';
|
||||
import appPlugin from '@backstage/plugin-app';
|
||||
@@ -35,12 +35,14 @@ describe('createApp', () => {
|
||||
it('should allow themes to be installed', async () => {
|
||||
const app = createApp({
|
||||
configLoader: async () => ({
|
||||
config: new MockConfigApi({
|
||||
app: {
|
||||
extensions: [
|
||||
{ 'theme:app/light': false },
|
||||
{ 'theme:app/dark': false },
|
||||
],
|
||||
config: mockApis.config({
|
||||
data: {
|
||||
app: {
|
||||
extensions: [
|
||||
{ 'theme:app/light': false },
|
||||
{ 'theme:app/dark': false },
|
||||
],
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
@@ -72,7 +74,7 @@ describe('createApp', () => {
|
||||
it('should deduplicate features keeping the last received one', async () => {
|
||||
const duplicatedFeatureId = 'test';
|
||||
const app = createApp({
|
||||
configLoader: async () => ({ config: new MockConfigApi({}) }),
|
||||
configLoader: async () => ({ config: mockApis.config() }),
|
||||
features: [
|
||||
createFrontendPlugin({
|
||||
id: duplicatedFeatureId,
|
||||
@@ -135,7 +137,7 @@ describe('createApp', () => {
|
||||
|
||||
const app = createApp({
|
||||
configLoader: async () => ({
|
||||
config: new MockConfigApi({ key: 'config-value' }),
|
||||
config: mockApis.config({ data: { key: 'config-value' } }),
|
||||
}),
|
||||
features: [appPlugin, loader],
|
||||
});
|
||||
@@ -159,7 +161,7 @@ describe('createApp', () => {
|
||||
|
||||
const app = createApp({
|
||||
configLoader: async () => ({
|
||||
config: new MockConfigApi({}),
|
||||
config: mockApis.config(),
|
||||
}),
|
||||
features: [loader],
|
||||
});
|
||||
@@ -173,7 +175,7 @@ describe('createApp', () => {
|
||||
|
||||
it('should register feature flags', async () => {
|
||||
const app = createApp({
|
||||
configLoader: async () => ({ config: new MockConfigApi({}) }),
|
||||
configLoader: async () => ({ config: mockApis.config() }),
|
||||
features: [
|
||||
appPlugin.withOverrides({
|
||||
extensions: [
|
||||
@@ -227,7 +229,7 @@ describe('createApp', () => {
|
||||
let appTreeApi: AppTreeApi | undefined = undefined;
|
||||
|
||||
const app = createApp({
|
||||
configLoader: async () => ({ config: new MockConfigApi({}) }),
|
||||
configLoader: async () => ({ config: mockApis.config() }),
|
||||
features: [
|
||||
createFrontendPlugin({
|
||||
id: 'my-plugin',
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { createPublicSignInApp } from './createPublicSignInApp';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
describe('createPublicSignInApp', () => {
|
||||
beforeEach(() => {
|
||||
@@ -31,7 +31,7 @@ describe('createPublicSignInApp', () => {
|
||||
|
||||
it('should render a sign-in page', async () => {
|
||||
const app = createPublicSignInApp({
|
||||
configLoader: async () => ({ config: new MockConfigApi({}) }),
|
||||
configLoader: async () => ({ config: mockApis.config() }),
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
@@ -59,7 +59,7 @@ describe('createPublicSignInApp', () => {
|
||||
.mockReturnValue();
|
||||
|
||||
const app = createPublicSignInApp({
|
||||
configLoader: async () => ({ config: new MockConfigApi({}) }),
|
||||
configLoader: async () => ({ config: mockApis.config() }),
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
|
||||
@@ -23,7 +23,7 @@ import { JsonObject } from '@backstage/types';
|
||||
import { createExtension } from './createExtension';
|
||||
import { createExtensionDataRef } from './createExtensionDataRef';
|
||||
import { coreExtensionData } from './coreExtensionData';
|
||||
import { MockConfigApi, renderWithEffects } from '@backstage/test-utils';
|
||||
import { mockApis, renderWithEffects } from '@backstage/test-utils';
|
||||
import { createExtensionInput } from './createExtensionInput';
|
||||
|
||||
const nameExtensionDataRef = createExtensionDataRef<string>().with({
|
||||
@@ -128,7 +128,7 @@ function createTestAppRoot({
|
||||
}) {
|
||||
return createApp({
|
||||
features: [...features],
|
||||
configLoader: async () => ({ config: new MockConfigApi(config) }),
|
||||
configLoader: async () => ({ config: mockApis.config({ data: config }) }),
|
||||
}).createRoot();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@types/jest": "*",
|
||||
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
/// <reference types="jest" />
|
||||
/// <reference types="react" />
|
||||
|
||||
import { AnalyticsApi } from '@backstage/frontend-plugin-api';
|
||||
import { AnalyticsEvent } from '@backstage/frontend-plugin-api';
|
||||
import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api';
|
||||
import { ApiFactory } from '@backstage/frontend-plugin-api';
|
||||
import { ApiMock } from '@backstage/test-utils';
|
||||
import { AppNode } from '@backstage/frontend-plugin-api';
|
||||
import { AppNodeInstance } from '@backstage/frontend-plugin-api';
|
||||
import { ErrorWithContext } from '@backstage/test-utils';
|
||||
@@ -18,6 +17,7 @@ import { ExtensionDefinition } from '@backstage/frontend-plugin-api';
|
||||
import { ExtensionDefinitionParameters } from '@backstage/frontend-plugin-api';
|
||||
import { FrontendFeature } from '@backstage/frontend-app-api';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { MockErrorApi } from '@backstage/test-utils';
|
||||
import { MockErrorApiOptions } from '@backstage/test-utils';
|
||||
@@ -34,14 +34,7 @@ import { TestApiProviderProps } from '@backstage/test-utils';
|
||||
import { TestApiRegistry } from '@backstage/test-utils';
|
||||
import { withLogCollector } from '@backstage/test-utils';
|
||||
|
||||
// @public
|
||||
export type ApiMock<TApi> = {
|
||||
factory: ApiFactory<TApi, TApi, {}>;
|
||||
} & {
|
||||
[Key in keyof TApi]: TApi[Key] extends (...args: infer Args) => infer Return
|
||||
? TApi[Key] & jest.MockInstance<Return, Args>
|
||||
: TApi[Key];
|
||||
};
|
||||
export { ApiMock };
|
||||
|
||||
// @public (undocumented)
|
||||
export function createExtensionTester<T extends ExtensionDefinitionParameters>(
|
||||
@@ -103,6 +96,8 @@ export class MockAnalyticsApi implements AnalyticsApi {
|
||||
getEvents(): AnalyticsEvent[];
|
||||
}
|
||||
|
||||
export { mockApis };
|
||||
|
||||
export { MockConfigApi };
|
||||
|
||||
export { MockErrorApi };
|
||||
|
||||
@@ -24,7 +24,8 @@ export {
|
||||
MockPermissionApi,
|
||||
MockStorageApi,
|
||||
type MockStorageBucket,
|
||||
mockApis,
|
||||
type ApiMock,
|
||||
} from '@backstage/test-utils';
|
||||
|
||||
export { type ApiMock } from './ApiMock';
|
||||
export { MockAnalyticsApi } from './AnalyticsApi/MockAnalyticsApi';
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@testing-library/jest-dom": "^6.0.0",
|
||||
"@types/jest": "*",
|
||||
"@types/react": "^18.0.0",
|
||||
"msw": "^1.0.0",
|
||||
"react": "^18.0.2",
|
||||
@@ -73,12 +74,16 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@types/jest": "*",
|
||||
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
||||
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/jest": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
/// <reference types="jest" />
|
||||
|
||||
import { AnalyticsApi } from '@backstage/core-plugin-api';
|
||||
import { AnalyticsEvent } from '@backstage/core-plugin-api';
|
||||
import { ApiFactory } from '@backstage/core-plugin-api';
|
||||
import { ApiHolder } from '@backstage/core-plugin-api';
|
||||
import { ApiRef } from '@backstage/core-plugin-api';
|
||||
import { AppComponents } from '@backstage/core-plugin-api';
|
||||
@@ -39,6 +42,15 @@ import { RouteRef } from '@backstage/core-plugin-api';
|
||||
import { StorageApi } from '@backstage/core-plugin-api';
|
||||
import { StorageValueSnapshot } from '@backstage/core-plugin-api';
|
||||
|
||||
// @public
|
||||
export type ApiMock<TApi> = {
|
||||
factory: ApiFactory<TApi, TApi, {}>;
|
||||
} & {
|
||||
[Key in keyof TApi]: TApi[Key] extends (...args: infer Args) => infer Return
|
||||
? TApi[Key] & jest.MockInstance<Return, Args>
|
||||
: TApi[Key];
|
||||
};
|
||||
|
||||
// @public
|
||||
export type AsyncLogCollector = () => Promise<void>;
|
||||
|
||||
@@ -77,10 +89,27 @@ export class MockAnalyticsApi implements AnalyticsApi {
|
||||
getEvents(): AnalyticsEvent[];
|
||||
}
|
||||
|
||||
// @public
|
||||
export namespace mockApis {
|
||||
export function config(options?: { data?: JsonObject }): jest.Mocked<Config>;
|
||||
export namespace config {
|
||||
const factory: (
|
||||
options?:
|
||||
| {
|
||||
data?: JsonObject | undefined;
|
||||
}
|
||||
| undefined,
|
||||
) => ApiFactory<Config, Config, {}>;
|
||||
const mock: (partialImpl?: Partial<Config> | undefined) => ApiMock<Config>;
|
||||
}
|
||||
}
|
||||
|
||||
// @public @deprecated
|
||||
export function mockBreakpoint(options: { matches: boolean }): void;
|
||||
|
||||
// @public
|
||||
// Warning: (ae-unresolved-link) The @link reference could not be resolved: The reference is ambiguous because "config" has more than one declaration; you need to add a TSDoc member reference selector
|
||||
//
|
||||
// @public @deprecated
|
||||
export class MockConfigApi implements ConfigApi {
|
||||
constructor(data: JsonObject);
|
||||
get<T = JsonValue>(key?: string): T;
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ApiFactory } from '@backstage/frontend-plugin-api';
|
||||
import { ApiFactory } from '@backstage/core-plugin-api';
|
||||
|
||||
/**
|
||||
* Represents a mocked version of an API, where you automatically have access to
|
||||
@@ -23,6 +23,7 @@ import { ConfigApi } from '@backstage/core-plugin-api';
|
||||
* that can be used to mock configuration using a plain object.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Use {@link mockApis.config} instead
|
||||
* @example
|
||||
* ```tsx
|
||||
* const mockConfig = new MockConfigApi({
|
||||
|
||||
@@ -20,3 +20,5 @@ export * from './ErrorApi';
|
||||
export * from './FetchApi';
|
||||
export * from './PermissionApi';
|
||||
export * from './StorageApi';
|
||||
export { type ApiMock } from './ApiMock';
|
||||
export { mockApis } from './mockApis';
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { mockApis } from './mockApis';
|
||||
|
||||
describe('mockApis', () => {
|
||||
describe('config', () => {
|
||||
const data = { backend: { baseUrl: 'http://test.com' } };
|
||||
|
||||
it('can create an instance and make assertions on it', () => {
|
||||
const empty = mockApis.config();
|
||||
const notEmpty = mockApis.config({ data });
|
||||
expect(empty.getOptional('backend.baseUrl')).toBeUndefined();
|
||||
expect(empty.getOptional).toHaveBeenCalledTimes(1);
|
||||
expect(notEmpty.getOptional('backend.baseUrl')).toEqual(
|
||||
'http://test.com',
|
||||
);
|
||||
expect(notEmpty.getOptional).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('can create a mock and make assertions on it', async () => {
|
||||
const mock = mockApis.config.mock({ getString: () => 'replaced' });
|
||||
expect(mock.getString('a')).toEqual('replaced');
|
||||
expect(mock.getString).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import {
|
||||
ApiFactory,
|
||||
ApiRef,
|
||||
configApiRef,
|
||||
createApiFactory,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ApiMock } from './ApiMock';
|
||||
|
||||
/** @internal */
|
||||
function simpleInstance<TApi extends object>(
|
||||
_ref: ApiRef<TApi>,
|
||||
instance: TApi,
|
||||
mockSkeleton: () => jest.Mocked<TApi>,
|
||||
): jest.Mocked<TApi> {
|
||||
const mock = mockSkeleton();
|
||||
const result = Object.create(instance) as any;
|
||||
for (const [key, impl] of Object.entries(mock)) {
|
||||
result[key] = (impl as any).mockImplementation((instance as any)[key]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function simpleFactory<TApi, TArgs extends unknown[]>(
|
||||
ref: ApiRef<TApi>,
|
||||
factory: (...args: TArgs) => TApi,
|
||||
): (...args: TArgs) => ApiFactory<TApi, TApi, {}> {
|
||||
return (...args) =>
|
||||
createApiFactory({
|
||||
api: ref,
|
||||
deps: {},
|
||||
factory: () => factory(...args),
|
||||
});
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function simpleMock<TApi>(
|
||||
ref: ApiRef<TApi>,
|
||||
mockFactory: () => jest.Mocked<TApi>,
|
||||
): (partialImpl?: Partial<TApi>) => ApiMock<TApi> {
|
||||
return partialImpl => {
|
||||
const mock = mockFactory();
|
||||
if (partialImpl) {
|
||||
for (const [key, impl] of Object.entries(partialImpl)) {
|
||||
if (typeof impl === 'function') {
|
||||
(mock as any)[key].mockImplementation(impl);
|
||||
} else {
|
||||
(mock as any)[key] = impl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.assign(mock, {
|
||||
factory: createApiFactory({
|
||||
api: ref,
|
||||
deps: {},
|
||||
factory: () => mock,
|
||||
}),
|
||||
}) as ApiMock<TApi>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock implementations of the core utility APIs, to be used in tests.
|
||||
*
|
||||
* @public
|
||||
* @remarks
|
||||
*
|
||||
* There are some variations among the APIs depending on what needs tests
|
||||
* might have, but overall there are three main usage patterns:
|
||||
*
|
||||
* 1: Creating an actual fake API instance, often with a simplified version
|
||||
* of functionality, by calling the mock API itself as a function.
|
||||
*
|
||||
* ```ts
|
||||
* // The function often accepts parameters that control its behavior
|
||||
* const foo = mockApis.foo();
|
||||
* ```
|
||||
*
|
||||
* 2: Creating a mock API, where all methods are replaced with jest mocks, by
|
||||
* calling the API's `mock` function.
|
||||
*
|
||||
* ```ts
|
||||
* // You can optionally supply a subset of its methods to implement
|
||||
* const foo = mockApis.foo.mock({
|
||||
* someMethod: () => 'mocked result',
|
||||
* });
|
||||
* // After exercising your test, you can make assertions on the mock:
|
||||
* expect(foo.someMethod).toHaveBeenCalledTimes(2);
|
||||
* expect(foo.otherMethod).toHaveBeenCalledWith(testData);
|
||||
* ```
|
||||
*
|
||||
* 3: Creating an API factory that behaves similarly to the mock as per above.
|
||||
*
|
||||
* ```ts
|
||||
* const factory = mockApis.foo.factory({
|
||||
* someMethod: () => 'mocked result',
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export namespace mockApis {
|
||||
const configMockSkeleton = () => ({
|
||||
has: jest.fn(),
|
||||
keys: jest.fn(),
|
||||
get: jest.fn(),
|
||||
getOptional: jest.fn(),
|
||||
getConfig: jest.fn(),
|
||||
getOptionalConfig: jest.fn(),
|
||||
getConfigArray: jest.fn(),
|
||||
getOptionalConfigArray: jest.fn(),
|
||||
getNumber: jest.fn(),
|
||||
getOptionalNumber: jest.fn(),
|
||||
getBoolean: jest.fn(),
|
||||
getOptionalBoolean: jest.fn(),
|
||||
getString: jest.fn(),
|
||||
getOptionalString: jest.fn(),
|
||||
getStringArray: jest.fn(),
|
||||
getOptionalStringArray: jest.fn(),
|
||||
});
|
||||
/**
|
||||
* Fake implementation of {@link @backstage/frontend-plugin-api#ConfigApi}
|
||||
* with optional data supplied.
|
||||
*
|
||||
* @public
|
||||
* @example
|
||||
*
|
||||
* ```tsx
|
||||
* const config = mockApis.config({
|
||||
* data: { app: { baseUrl: 'https://example.com' } },
|
||||
* });
|
||||
*
|
||||
* const rendered = await renderInTestApp(
|
||||
* <TestApiProvider apis={[[configApiRef, config]]}>
|
||||
* <MyTestedComponent />
|
||||
* </TestApiProvider>,
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
export function config(options?: { data?: JsonObject }) {
|
||||
return simpleInstance(
|
||||
configApiRef,
|
||||
new ConfigReader(options?.data, 'mock-config'),
|
||||
configMockSkeleton,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Mock helpers for {@link @backstage/frontend-plugin-api#ConfigApi}.
|
||||
*
|
||||
* @see {@link @backstage/frontend-plugin-api#mockApis.config}
|
||||
* @public
|
||||
*/
|
||||
export namespace config {
|
||||
/**
|
||||
* Creates a factory for a fake implementation of
|
||||
* {@link @backstage/frontend-plugin-api#ConfigApi} with optional
|
||||
* configuration data supplied.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const factory = simpleFactory(configApiRef, config);
|
||||
/**
|
||||
* Creates a mock implementation of
|
||||
* {@link @backstage/frontend-plugin-api#ConfigApi}. All methods are
|
||||
* replaced with jest mock functions, and you can optionally pass in a
|
||||
* subset of methods with an explicit implementation.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const mock = simpleMock(configApiRef, configMockSkeleton);
|
||||
}
|
||||
}
|
||||
+8
-6
@@ -16,7 +16,7 @@
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { configApiRef } from '@backstage/core-plugin-api';
|
||||
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
@@ -46,7 +46,7 @@ const entities: Entity[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const mockConfigApi = new MockConfigApi({});
|
||||
const mockConfigApi = mockApis.config();
|
||||
const apis = [[configApiRef, mockConfigApi]] as const;
|
||||
|
||||
describe('<PreviewCatalogInfoComponent />', () => {
|
||||
@@ -122,10 +122,12 @@ describe('<PreviewCatalogInfoComponent />', () => {
|
||||
apis={[
|
||||
[
|
||||
configApiRef,
|
||||
new MockConfigApi({
|
||||
catalog: {
|
||||
import: {
|
||||
entityFilename: 'anvil.yaml',
|
||||
mockApis.config({
|
||||
data: {
|
||||
catalog: {
|
||||
import: {
|
||||
entityFilename: 'anvil.yaml',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
|
||||
import { configApiRef, errorApiRef } from '@backstage/core-plugin-api';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { TestApiProvider, MockConfigApi } from '@backstage/test-utils';
|
||||
import { TestApiProvider, mockApis } from '@backstage/test-utils';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
@@ -43,7 +43,7 @@ describe('<StepPrepareCreatePullRequest />', () => {
|
||||
post: jest.fn(),
|
||||
};
|
||||
|
||||
const configApi = new MockConfigApi({});
|
||||
const configApi = mockApis.config();
|
||||
|
||||
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
|
||||
<TestApiProvider
|
||||
|
||||
@@ -15,15 +15,17 @@
|
||||
*/
|
||||
|
||||
import { readFilterConfig, createFilterByQueryParamFromConfig } from './config';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
describe('config', () => {
|
||||
describe('readFilterConfig', () => {
|
||||
it('returns filter data', async () => {
|
||||
const mockConfig = new MockConfigApi({
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/home',
|
||||
const mockConfig = mockApis.config({
|
||||
data: {
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/home',
|
||||
},
|
||||
});
|
||||
const res = readFilterConfig(mockConfig);
|
||||
expect(res).toEqual({
|
||||
@@ -34,10 +36,12 @@ describe('config', () => {
|
||||
});
|
||||
|
||||
it('returns undefined for invalid filter', async () => {
|
||||
const mockInvalidConfig = new MockConfigApi({
|
||||
myField: 'pathname',
|
||||
operator: '==',
|
||||
value: '3',
|
||||
const mockInvalidConfig = mockApis.config({
|
||||
data: {
|
||||
myField: 'pathname',
|
||||
operator: '==',
|
||||
value: '3',
|
||||
},
|
||||
});
|
||||
const res = readFilterConfig(mockInvalidConfig);
|
||||
expect(res).toEqual(undefined);
|
||||
@@ -46,15 +50,19 @@ describe('config', () => {
|
||||
|
||||
describe('createFilterByQueryParamFromConfig', () => {
|
||||
it('returns filter data', async () => {
|
||||
const mockConfig1 = new MockConfigApi({
|
||||
field: 'id',
|
||||
operator: '==',
|
||||
value: '3',
|
||||
const mockConfig1 = mockApis.config({
|
||||
data: {
|
||||
field: 'id',
|
||||
operator: '==',
|
||||
value: '3',
|
||||
},
|
||||
});
|
||||
const mockConfig2 = new MockConfigApi({
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: 'path',
|
||||
const mockConfig2 = mockApis.config({
|
||||
data: {
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: 'path',
|
||||
},
|
||||
});
|
||||
const res = createFilterByQueryParamFromConfig([
|
||||
mockConfig1,
|
||||
@@ -67,15 +75,19 @@ describe('config', () => {
|
||||
});
|
||||
|
||||
it('returns only valid filters', async () => {
|
||||
const mockValidConfig = new MockConfigApi({
|
||||
field: 'id',
|
||||
operator: '==',
|
||||
value: 3,
|
||||
const mockValidConfig = mockApis.config({
|
||||
data: {
|
||||
field: 'id',
|
||||
operator: '==',
|
||||
value: 3,
|
||||
},
|
||||
});
|
||||
const mockInvalidConfig = new MockConfigApi({
|
||||
myField: 'pathname',
|
||||
operator: '==',
|
||||
value: 'path',
|
||||
const mockInvalidConfig = mockApis.config({
|
||||
data: {
|
||||
myField: 'pathname',
|
||||
operator: '==',
|
||||
value: 'path',
|
||||
},
|
||||
});
|
||||
const res = createFilterByQueryParamFromConfig([
|
||||
mockValidConfig,
|
||||
|
||||
@@ -19,7 +19,7 @@ import { Content } from './Content';
|
||||
import {
|
||||
TestApiProvider,
|
||||
renderInTestApp,
|
||||
MockConfigApi,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { visitsApiRef } from '../../api';
|
||||
import { ContextProvider } from './Context';
|
||||
@@ -138,16 +138,18 @@ describe('<Content kind="recent"/>', () => {
|
||||
});
|
||||
|
||||
it('allows recent items to be filtered using config', async () => {
|
||||
const configApiMock = new MockConfigApi({
|
||||
home: {
|
||||
recentVisits: {
|
||||
filterBy: [
|
||||
{
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/tech-radar',
|
||||
},
|
||||
],
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
home: {
|
||||
recentVisits: {
|
||||
filterBy: [
|
||||
{
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/tech-radar',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -206,20 +208,22 @@ describe('<Content kind="recent"/>', () => {
|
||||
});
|
||||
|
||||
it('allows recent items to have no filter if the filter config is not valid', async () => {
|
||||
const configApiMock = new MockConfigApi({
|
||||
home: {
|
||||
recentVisits: {
|
||||
filterBy: [
|
||||
{
|
||||
operator: '==',
|
||||
value: '/tech-radar',
|
||||
},
|
||||
{
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/explore',
|
||||
},
|
||||
],
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
home: {
|
||||
recentVisits: {
|
||||
filterBy: [
|
||||
{
|
||||
operator: '==',
|
||||
value: '/tech-radar',
|
||||
},
|
||||
{
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/explore',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -283,16 +287,18 @@ describe('<Content kind="top"/>', () => {
|
||||
});
|
||||
|
||||
it('allows top items to be filtered using config', async () => {
|
||||
const configApiMock = new MockConfigApi({
|
||||
home: {
|
||||
topVisits: {
|
||||
filterBy: [
|
||||
{
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/explore',
|
||||
},
|
||||
],
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
home: {
|
||||
topVisits: {
|
||||
filterBy: [
|
||||
{
|
||||
field: 'pathname',
|
||||
operator: '==',
|
||||
value: '/explore',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
import { screen, render, waitFor, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
@@ -35,10 +35,12 @@ const SearchContextFilterSpy = ({ name }: { name: string }) => {
|
||||
};
|
||||
|
||||
describe('SearchFilter.Autocomplete', () => {
|
||||
const configApiMock = new MockConfigApi({
|
||||
search: {
|
||||
query: {
|
||||
pageLimit: 100,
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
search: {
|
||||
query: {
|
||||
pageLimit: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import { configApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
import { SearchContextProvider } from '../../context';
|
||||
import { SearchFilter } from './SearchFilter';
|
||||
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
import { searchApiRef } from '../../api';
|
||||
|
||||
describe('SearchFilter', () => {
|
||||
@@ -37,10 +37,12 @@ describe('SearchFilter', () => {
|
||||
const values = ['value1', 'value2'];
|
||||
const filters = { unrelated: 'unrelated' };
|
||||
|
||||
const configApiMock = new MockConfigApi({
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import { MockConfigApi, TestApiRegistry } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiRegistry } from '@backstage/test-utils';
|
||||
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||
|
||||
import { searchApiRef } from '../../api';
|
||||
@@ -27,17 +28,19 @@ jest.useFakeTimers();
|
||||
|
||||
describe('SearchFilter.hooks', () => {
|
||||
describe('useDefaultFilterValue', () => {
|
||||
const configApiMock = new MockConfigApi({
|
||||
search: {
|
||||
query: {
|
||||
pageLimit: 100,
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
search: {
|
||||
query: {
|
||||
pageLimit: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const searchApiMock = {
|
||||
query: jest.fn().mockResolvedValue({ results: [] }),
|
||||
};
|
||||
const mockApis = TestApiRegistry.from(
|
||||
const apis = TestApiRegistry.from(
|
||||
[searchApiRef, searchApiMock],
|
||||
[configApiRef, configApiMock],
|
||||
);
|
||||
@@ -54,7 +57,7 @@ describe('SearchFilter.hooks', () => {
|
||||
filters: {},
|
||||
};
|
||||
return (
|
||||
<ApiProvider apis={mockApis}>
|
||||
<ApiProvider apis={apis}>
|
||||
<SearchContextProvider
|
||||
initialState={{ ...emptySearchContext, ...overrides }}
|
||||
>
|
||||
|
||||
@@ -19,7 +19,7 @@ import { screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import {
|
||||
MockConfigApi,
|
||||
mockApis,
|
||||
renderWithEffects,
|
||||
TestApiProvider,
|
||||
} from '@backstage/test-utils';
|
||||
@@ -31,10 +31,12 @@ import { SearchPagination } from './SearchPagination';
|
||||
import { configApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
describe('SearchPagination', () => {
|
||||
const configApiMock = new MockConfigApi({
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
act,
|
||||
renderHook,
|
||||
} from '@testing-library/react';
|
||||
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import {
|
||||
SearchContextProvider,
|
||||
@@ -37,7 +37,7 @@ describe('SearchContext', () => {
|
||||
} satisfies typeof searchApiRef.T;
|
||||
|
||||
const wrapper = ({ children, initialState, config = {} }: any) => {
|
||||
const configApiMock = new MockConfigApi(config);
|
||||
const configApiMock = mockApis.config({ data: config });
|
||||
return (
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
@@ -433,7 +433,7 @@ describe('SearchContext', () => {
|
||||
|
||||
const { result } = renderHook(() => useSearch(), {
|
||||
wrapper: ({ children }) => {
|
||||
const configApiMock = new MockConfigApi({});
|
||||
const configApiMock = mockApis.config();
|
||||
return (
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
@@ -491,7 +491,7 @@ describe('SearchContext', () => {
|
||||
|
||||
const { result } = renderHook(() => useSearch(), {
|
||||
wrapper: ({ children }) => {
|
||||
const configApiMock = new MockConfigApi({});
|
||||
const configApiMock = mockApis.config();
|
||||
return (
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
import { act, render, waitFor } from '@testing-library/react';
|
||||
import user from '@testing-library/user-event';
|
||||
import {
|
||||
@@ -41,10 +41,12 @@ jest.mock('@backstage/plugin-search-react', () => ({
|
||||
}));
|
||||
|
||||
describe('SearchType.Accordion', () => {
|
||||
const configApiMock = new MockConfigApi({
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import user from '@testing-library/user-event';
|
||||
import {
|
||||
@@ -40,10 +40,12 @@ jest.mock('@backstage/plugin-search-react', () => ({
|
||||
|
||||
describe('SearchType.Tabs', () => {
|
||||
const searchApiMock = { query: jest.fn().mockResolvedValue({ results: [] }) };
|
||||
const configApiMock = new MockConfigApi({
|
||||
search: {
|
||||
query: {
|
||||
pageLimit: 100,
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
search: {
|
||||
query: {
|
||||
pageLimit: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
searchApiRef,
|
||||
} from '@backstage/plugin-search-react';
|
||||
import { SearchType } from './SearchType';
|
||||
import { MockConfigApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
|
||||
describe('SearchType', () => {
|
||||
const initialState = {
|
||||
@@ -36,10 +36,12 @@ describe('SearchType', () => {
|
||||
const values = ['value1', 'value2'];
|
||||
const typeValues = ['preselected'];
|
||||
|
||||
const configApiMock = new MockConfigApi({
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
const configApiMock = mockApis.config({
|
||||
data: {
|
||||
search: {
|
||||
query: {
|
||||
pagelimit: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { renderHook, act, waitFor } from '@testing-library/react';
|
||||
|
||||
@@ -21,7 +22,7 @@ import { ThemeProvider } from '@material-ui/core/styles';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import {
|
||||
MockAnalyticsApi,
|
||||
MockConfigApi,
|
||||
mockApis,
|
||||
TestApiProvider,
|
||||
} from '@backstage/test-utils';
|
||||
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
@@ -84,7 +85,7 @@ const wrapper = ({
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
[analyticsApiRef, analyticsApiMock],
|
||||
[configApiRef, new MockConfigApi(config ?? {})],
|
||||
[configApiRef, mockApis.config({ data: config ?? {} })],
|
||||
[techdocsApiRef, techdocsApiMock],
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -18,7 +18,7 @@ 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,7 +34,7 @@ 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(),
|
||||
|
||||
+4
-5
@@ -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';
|
||||
@@ -106,10 +107,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 }) => {
|
||||
|
||||
+5
-31
@@ -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>,
|
||||
|
||||
@@ -4683,7 +4683,6 @@ __metadata:
|
||||
zod: ^3.22.4
|
||||
peerDependencies:
|
||||
"@testing-library/react": ^16.0.0
|
||||
"@types/jest": "*"
|
||||
"@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
@@ -8564,6 +8563,7 @@ __metadata:
|
||||
"@material-ui/core": ^4.12.2
|
||||
"@material-ui/icons": ^4.9.1
|
||||
"@testing-library/jest-dom": ^6.0.0
|
||||
"@types/jest": "*"
|
||||
"@types/react": ^18.0.0
|
||||
cross-fetch: ^4.0.0
|
||||
i18next: ^22.4.15
|
||||
@@ -8574,11 +8574,14 @@ __metadata:
|
||||
zen-observable: ^0.10.0
|
||||
peerDependencies:
|
||||
"@testing-library/react": ^16.0.0
|
||||
"@types/jest": "*"
|
||||
"@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
react-router-dom: 6.0.0-beta.0 || ^6.3.0
|
||||
peerDependenciesMeta:
|
||||
"@types/jest":
|
||||
optional: true
|
||||
"@types/react":
|
||||
optional: true
|
||||
languageName: unknown
|
||||
@@ -17912,7 +17915,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/jest@npm:^29.5.11":
|
||||
"@types/jest@npm:*, @types/jest@npm:^29.5.11":
|
||||
version: 29.5.13
|
||||
resolution: "@types/jest@npm:29.5.13"
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user