implement identity too
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
+6
-11
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { IdentityApi } from '@backstage/core-plugin-api';
|
||||
import { IdentityAuthInjectorFetchMiddleware } from './IdentityAuthInjectorFetchMiddleware';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
describe('IdentityAuthInjectorFetchMiddleware', () => {
|
||||
it('creates using defaults', async () => {
|
||||
@@ -58,10 +58,7 @@ describe('IdentityAuthInjectorFetchMiddleware', () => {
|
||||
});
|
||||
|
||||
it('injects the header only when a token is available', async () => {
|
||||
const tokenFunction = jest.fn();
|
||||
const identityApi = {
|
||||
getCredentials: tokenFunction,
|
||||
} as unknown as IdentityApi;
|
||||
const identityApi = mockApis.identity();
|
||||
|
||||
const middleware = new IdentityAuthInjectorFetchMiddleware(
|
||||
identityApi,
|
||||
@@ -73,27 +70,25 @@ describe('IdentityAuthInjectorFetchMiddleware', () => {
|
||||
const outer = middleware.apply(inner);
|
||||
|
||||
// No token available
|
||||
tokenFunction.mockResolvedValueOnce({ token: undefined });
|
||||
identityApi.getCredentials.mockResolvedValueOnce({ token: undefined });
|
||||
await outer(new Request('https://example.com'));
|
||||
expect([...inner.mock.calls[0][0].headers.entries()]).toEqual([]);
|
||||
|
||||
// Supply a token, header gets added
|
||||
tokenFunction.mockResolvedValueOnce({ token: 'token' });
|
||||
identityApi.getCredentials.mockResolvedValueOnce({ token: 'token' });
|
||||
await outer(new Request('https://example.com'));
|
||||
expect([...inner.mock.calls[1][0].headers.entries()]).toEqual([
|
||||
['authorization', 'Bearer token'],
|
||||
]);
|
||||
|
||||
// Token no longer available
|
||||
tokenFunction.mockResolvedValueOnce({ token: undefined });
|
||||
identityApi.getCredentials.mockResolvedValueOnce({ token: undefined });
|
||||
await outer(new Request('https://example.com'));
|
||||
expect([...inner.mock.calls[2][0].headers.entries()]).toEqual([]);
|
||||
});
|
||||
|
||||
it('does not overwrite an existing header with the same name', async () => {
|
||||
const identityApi = {
|
||||
getCredentials: () => ({ token: 'token' }),
|
||||
} as unknown as IdentityApi;
|
||||
const identityApi = mockApis.identity({ token: 'token' });
|
||||
|
||||
const middleware = new IdentityAuthInjectorFetchMiddleware(
|
||||
identityApi,
|
||||
|
||||
@@ -18,7 +18,6 @@ import React from 'react';
|
||||
import {
|
||||
AppComponents,
|
||||
configApiRef,
|
||||
IdentityApi,
|
||||
identityApiRef,
|
||||
SignInPageProps,
|
||||
useApi,
|
||||
@@ -30,7 +29,7 @@ import { render, screen } from '@testing-library/react';
|
||||
import { AppRouter } from './AppRouter';
|
||||
import useAsync from 'react-use/esm/useAsync';
|
||||
import { AppContextProvider } from './AppContext';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { mockApis, TestApiProvider } from '@backstage/test-utils';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
|
||||
function UserRefDisplay() {
|
||||
@@ -78,13 +77,7 @@ describe('AppRouter', () => {
|
||||
const appIdentityProxy = new AppIdentityProxy();
|
||||
|
||||
const SignInPage = (props: SignInPageProps) => {
|
||||
props.onSignInSuccess({
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/test',
|
||||
ownershipEntityRefs: ['user:default/test'],
|
||||
}),
|
||||
} as IdentityApi);
|
||||
props.onSignInSuccess(mockApis.identity());
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,23 +13,23 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createMocks } from 'react-idle-timer';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { MessageChannel } from 'worker_threads';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import { identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils';
|
||||
import {
|
||||
TestApiRegistry,
|
||||
renderInTestApp,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
|
||||
import { AutoLogout } from './AutoLogout';
|
||||
import { cleanup } from '@testing-library/react';
|
||||
|
||||
// Mock the signOut function of identityApiRef
|
||||
const mockSignOut = jest.fn();
|
||||
const mockIdentityApi = {
|
||||
signOut: mockSignOut,
|
||||
getCredentials: jest.fn().mockReturnValue({ token: 'xxx' }),
|
||||
};
|
||||
const mockIdentityApi = mockApis.identity({ token: 'xxx' });
|
||||
const apis = TestApiRegistry.from([identityApiRef, mockIdentityApi]);
|
||||
|
||||
describe('AutoLogout', () => {
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
IdentityApi,
|
||||
SignInPageBlueprint,
|
||||
createFrontendModule,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
@@ -70,9 +69,9 @@ describe('createPublicSignInApp', () => {
|
||||
async () =>
|
||||
({ onSignInSuccess }) => {
|
||||
useEffect(() => {
|
||||
onSignInSuccess({
|
||||
getCredentials: async () => ({ token: 'mock-token' }),
|
||||
} as IdentityApi);
|
||||
onSignInSuccess(
|
||||
mockApis.identity({ token: 'mock-token' }),
|
||||
);
|
||||
}, [onSignInSuccess]);
|
||||
return <div />;
|
||||
},
|
||||
|
||||
@@ -100,7 +100,9 @@ export namespace mockApis {
|
||||
const // (undocumented)
|
||||
factory: () => ApiFactory<AnalyticsApi, AnalyticsApi, {}>;
|
||||
const // (undocumented)
|
||||
mock: () => jest.Mocked<AnalyticsApi>;
|
||||
mock: (
|
||||
partialImpl?: Partial<AnalyticsApi> | undefined,
|
||||
) => ApiMock<AnalyticsApi>;
|
||||
}
|
||||
export function config(options?: { data?: JsonObject }): ConfigApi;
|
||||
export namespace config {
|
||||
@@ -113,6 +115,35 @@ export namespace mockApis {
|
||||
) => ApiFactory<Config, Config, {}>;
|
||||
const mock: (partialImpl?: Partial<Config> | undefined) => ApiMock<Config>;
|
||||
}
|
||||
// (undocumented)
|
||||
export function identity(options?: {
|
||||
userEntityRef?: string;
|
||||
ownershipEntityRefs?: string[];
|
||||
token?: string;
|
||||
email?: string;
|
||||
displayName?: string;
|
||||
picture?: string;
|
||||
}): jest.Mocked<IdentityApi>;
|
||||
// (undocumented)
|
||||
export namespace identity {
|
||||
const // (undocumented)
|
||||
factory: (
|
||||
options?:
|
||||
| {
|
||||
userEntityRef?: string | undefined;
|
||||
ownershipEntityRefs?: string[] | undefined;
|
||||
token?: string | undefined;
|
||||
email?: string | undefined;
|
||||
displayName?: string | undefined;
|
||||
picture?: string | undefined;
|
||||
}
|
||||
| undefined,
|
||||
) => ApiFactory<IdentityApi, IdentityApi, {}>;
|
||||
const // (undocumented)
|
||||
mock: (
|
||||
partialImpl?: Partial<IdentityApi> | undefined,
|
||||
) => ApiMock<IdentityApi>;
|
||||
}
|
||||
}
|
||||
|
||||
// @public @deprecated
|
||||
@@ -331,4 +362,8 @@ export function wrapInTestApp(
|
||||
// src/testUtils/apis/mockApis.d.ts:45:5 - (ae-undocumented) Missing documentation for "analytics".
|
||||
// src/testUtils/apis/mockApis.d.ts:46:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:47:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
// src/testUtils/apis/mockApis.d.ts:98:5 - (ae-undocumented) Missing documentation for "identity".
|
||||
// src/testUtils/apis/mockApis.d.ts:106:5 - (ae-undocumented) Missing documentation for "identity".
|
||||
// src/testUtils/apis/mockApis.d.ts:107:15 - (ae-undocumented) Missing documentation for "factory".
|
||||
// src/testUtils/apis/mockApis.d.ts:115:15 - (ae-undocumented) Missing documentation for "mock".
|
||||
```
|
||||
|
||||
@@ -17,13 +17,49 @@
|
||||
import { mockApis } from './mockApis';
|
||||
|
||||
describe('mockApis', () => {
|
||||
describe('analytics', () => {
|
||||
it('can create an instance and make assertions on it', () => {
|
||||
const analytics = mockApis.analytics();
|
||||
expect(
|
||||
analytics.captureEvent({
|
||||
action: 'a',
|
||||
subject: 'b',
|
||||
context: { pluginId: 'c', extension: 'd', routeRef: 'e' },
|
||||
}),
|
||||
).toBeUndefined();
|
||||
expect(analytics.captureEvent).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('can create a mock and make assertions on it', async () => {
|
||||
expect.assertions(3);
|
||||
const analytics = mockApis.analytics.mock({
|
||||
captureEvent: event => {
|
||||
expect(event).toEqual({
|
||||
action: 'a',
|
||||
subject: 'b',
|
||||
context: { pluginId: 'c', extension: 'd', routeRef: 'e' },
|
||||
});
|
||||
},
|
||||
});
|
||||
expect(
|
||||
analytics.captureEvent({
|
||||
action: 'a',
|
||||
subject: 'b',
|
||||
context: { pluginId: 'c', extension: 'd', routeRef: 'e' },
|
||||
}),
|
||||
).toBeUndefined();
|
||||
expect(analytics.captureEvent).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('config', () => {
|
||||
const data = { backend: { baseUrl: 'http://test.com' } };
|
||||
|
||||
it('can create an instance', () => {
|
||||
const empty = mockApis.config();
|
||||
const notEmpty = mockApis.config({ data });
|
||||
expect(empty.getOptional('backend.baseUrl')).toBeUndefined();
|
||||
|
||||
const notEmpty = mockApis.config({ data });
|
||||
expect(notEmpty.getOptional('backend.baseUrl')).toEqual(
|
||||
'http://test.com',
|
||||
);
|
||||
@@ -35,4 +71,90 @@ describe('mockApis', () => {
|
||||
expect(mock.getString).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('identity', () => {
|
||||
it('can create an instance and make assertions on it', async () => {
|
||||
const empty = mockApis.identity();
|
||||
await expect(empty.getBackstageIdentity()).resolves.toEqual({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/test',
|
||||
ownershipEntityRefs: ['user:default/test'],
|
||||
});
|
||||
await expect(empty.getCredentials()).resolves.toEqual({});
|
||||
await expect(empty.getProfileInfo()).resolves.toEqual({});
|
||||
await expect(empty.signOut()).resolves.toBeUndefined();
|
||||
expect(empty.getBackstageIdentity).toHaveBeenCalledTimes(1);
|
||||
expect(empty.getCredentials).toHaveBeenCalledTimes(1);
|
||||
expect(empty.getProfileInfo).toHaveBeenCalledTimes(1);
|
||||
expect(empty.signOut).toHaveBeenCalledTimes(1);
|
||||
|
||||
const notEmpty = mockApis.identity({
|
||||
userEntityRef: 'a',
|
||||
ownershipEntityRefs: ['b'],
|
||||
token: 'c',
|
||||
email: 'd',
|
||||
displayName: 'e',
|
||||
picture: 'f',
|
||||
});
|
||||
await expect(notEmpty.getBackstageIdentity()).resolves.toEqual({
|
||||
type: 'user',
|
||||
userEntityRef: 'a',
|
||||
ownershipEntityRefs: ['b'],
|
||||
});
|
||||
await expect(notEmpty.getCredentials()).resolves.toEqual({ token: 'c' });
|
||||
await expect(notEmpty.getProfileInfo()).resolves.toEqual({
|
||||
email: 'd',
|
||||
displayName: 'e',
|
||||
picture: 'f',
|
||||
});
|
||||
await expect(notEmpty.signOut()).resolves.toBeUndefined();
|
||||
expect(notEmpty.getBackstageIdentity).toHaveBeenCalledTimes(1);
|
||||
expect(notEmpty.getCredentials).toHaveBeenCalledTimes(1);
|
||||
expect(notEmpty.getProfileInfo).toHaveBeenCalledTimes(1);
|
||||
expect(notEmpty.signOut).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('can create a mock and make assertions on it', async () => {
|
||||
const empty = mockApis.identity.mock();
|
||||
expect(empty.getBackstageIdentity()).toBeUndefined();
|
||||
expect(empty.getCredentials()).toBeUndefined();
|
||||
expect(empty.getProfileInfo()).toBeUndefined();
|
||||
expect(empty.signOut()).toBeUndefined();
|
||||
expect(empty.getBackstageIdentity).toHaveBeenCalledTimes(1);
|
||||
expect(empty.getCredentials).toHaveBeenCalledTimes(1);
|
||||
expect(empty.getProfileInfo).toHaveBeenCalledTimes(1);
|
||||
expect(empty.signOut).toHaveBeenCalledTimes(1);
|
||||
|
||||
const notEmpty = mockApis.identity.mock({
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'a',
|
||||
ownershipEntityRefs: ['b'],
|
||||
}),
|
||||
getCredentials: async () => ({ token: 'c' }),
|
||||
getProfileInfo: async () => ({
|
||||
email: 'd',
|
||||
displayName: 'e',
|
||||
picture: 'f',
|
||||
}),
|
||||
signOut: async () => undefined,
|
||||
});
|
||||
await expect(notEmpty.getBackstageIdentity()).resolves.toEqual({
|
||||
type: 'user',
|
||||
userEntityRef: 'a',
|
||||
ownershipEntityRefs: ['b'],
|
||||
});
|
||||
await expect(notEmpty.getCredentials()).resolves.toEqual({ token: 'c' });
|
||||
await expect(notEmpty.getProfileInfo()).resolves.toEqual({
|
||||
email: 'd',
|
||||
displayName: 'e',
|
||||
picture: 'f',
|
||||
});
|
||||
await expect(notEmpty.signOut()).resolves.toBeUndefined();
|
||||
expect(notEmpty.getBackstageIdentity).toHaveBeenCalledTimes(1);
|
||||
expect(notEmpty.getCredentials).toHaveBeenCalledTimes(1);
|
||||
expect(notEmpty.getProfileInfo).toHaveBeenCalledTimes(1);
|
||||
expect(notEmpty.signOut).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,9 +20,11 @@ import {
|
||||
ApiFactory,
|
||||
ApiRef,
|
||||
ConfigApi,
|
||||
IdentityApi,
|
||||
analyticsApiRef,
|
||||
configApiRef,
|
||||
createApiFactory,
|
||||
identityApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ApiMock } from './ApiMock';
|
||||
@@ -113,7 +115,7 @@ export namespace mockApis {
|
||||
}
|
||||
export namespace analytics {
|
||||
export const factory = simpleFactory(analyticsApiRef, analytics);
|
||||
export const mock = analyticsMockSkeleton;
|
||||
export const mock = simpleMock(analyticsApiRef, analyticsMockSkeleton);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,4 +182,48 @@ export namespace mockApis {
|
||||
getOptionalStringArray: jest.fn(),
|
||||
}));
|
||||
}
|
||||
|
||||
const identityMockSkeleton = (): jest.Mocked<IdentityApi> => ({
|
||||
getBackstageIdentity: jest.fn(),
|
||||
getCredentials: jest.fn(),
|
||||
getProfileInfo: jest.fn(),
|
||||
signOut: jest.fn(),
|
||||
});
|
||||
export function identity(options?: {
|
||||
userEntityRef?: string;
|
||||
ownershipEntityRefs?: string[];
|
||||
token?: string;
|
||||
email?: string;
|
||||
displayName?: string;
|
||||
picture?: string;
|
||||
}) {
|
||||
const {
|
||||
userEntityRef = 'user:default/test',
|
||||
ownershipEntityRefs = ['user:default/test'],
|
||||
token,
|
||||
email,
|
||||
displayName,
|
||||
picture,
|
||||
} = options ?? {};
|
||||
return simpleInstance(
|
||||
identityApiRef,
|
||||
{
|
||||
async getBackstageIdentity() {
|
||||
return { type: 'user', ownershipEntityRefs, userEntityRef };
|
||||
},
|
||||
async getCredentials() {
|
||||
return { token };
|
||||
},
|
||||
async getProfileInfo() {
|
||||
return { email, displayName, picture };
|
||||
},
|
||||
async signOut() {},
|
||||
},
|
||||
identityMockSkeleton,
|
||||
);
|
||||
}
|
||||
export namespace identity {
|
||||
export const factory = simpleFactory(identityApiRef, identity);
|
||||
export const mock = simpleMock(identityApiRef, identityMockSkeleton);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
import React from 'react';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
|
||||
import {
|
||||
TestApiProvider,
|
||||
renderInTestApp,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { CookieAuthRedirect } from './CookieAuthRedirect';
|
||||
|
||||
describe('CookieAuthRedirect', () => {
|
||||
const identityApiMock = { getCredentials: jest.fn() };
|
||||
const identityApiMock = mockApis.identity.mock();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
@@ -36,13 +36,12 @@ import { catalogApiRef } from '../../api';
|
||||
import {
|
||||
MockStorageApi,
|
||||
TestApiRegistry,
|
||||
mockApis,
|
||||
renderInTestApp,
|
||||
} from '@backstage/test-utils';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import {
|
||||
ConfigApi,
|
||||
configApiRef,
|
||||
IdentityApi,
|
||||
identityApiRef,
|
||||
storageApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
@@ -61,15 +60,18 @@ const mockUser: UserEntity = {
|
||||
},
|
||||
};
|
||||
|
||||
const mockConfigApi = {
|
||||
getOptionalString: () => 'Test Company',
|
||||
} as Partial<ConfigApi>;
|
||||
const ownershipEntityRefs = ['user:default/testuser'];
|
||||
|
||||
const mockConfigApi = mockApis.config({
|
||||
data: { organization: { name: 'Test Company' } },
|
||||
});
|
||||
|
||||
const mockCatalogApi = catalogApiMock.mock();
|
||||
|
||||
const mockIdentityApi = {
|
||||
getBackstageIdentity: jest.fn(),
|
||||
} as Partial<jest.Mocked<IdentityApi>>;
|
||||
const mockIdentityApi = mockApis.identity({
|
||||
userEntityRef: ownershipEntityRefs[0],
|
||||
ownershipEntityRefs,
|
||||
});
|
||||
|
||||
const mockStarredEntitiesApi = new MockStarredEntitiesApi();
|
||||
|
||||
@@ -81,7 +83,6 @@ const apis = TestApiRegistry.from(
|
||||
[starredEntitiesApiRef, mockStarredEntitiesApi],
|
||||
);
|
||||
|
||||
const ownershipEntityRefs = ['user:default/testuser'];
|
||||
describe('<UserListPicker />', () => {
|
||||
const mockQueryEntitiesImplementation: CatalogApi['queryEntities'] =
|
||||
async request => {
|
||||
|
||||
+20
-25
@@ -23,11 +23,7 @@ import {
|
||||
useEntityList,
|
||||
} from '../../hooks';
|
||||
import { catalogApiRef } from '../../api';
|
||||
import {
|
||||
ApiRef,
|
||||
IdentityApi,
|
||||
identityApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { ApiRef, identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { useOwnedEntitiesCount } from './useOwnedEntitiesCount';
|
||||
import {
|
||||
@@ -36,12 +32,13 @@ import {
|
||||
EntityUserFilter,
|
||||
} from '../../filters';
|
||||
import { useMountEffect } from '@react-hookz/web';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
|
||||
const mockCatalogApi = catalogApiMock.mock();
|
||||
|
||||
const mockGetBackstageIdentity: jest.MockedFn<
|
||||
IdentityApi['getBackstageIdentity']
|
||||
> = jest.fn();
|
||||
const mockIdentityApi = mockApis.identity({
|
||||
ownershipEntityRefs: ['user:default/spiderman', 'user:group/a-group'],
|
||||
userEntityRef: 'user:default/spiderman',
|
||||
});
|
||||
|
||||
jest.mock('@backstage/core-plugin-api', () => {
|
||||
const actual = jest.requireActual('@backstage/core-plugin-api');
|
||||
@@ -50,13 +47,9 @@ jest.mock('@backstage/core-plugin-api', () => {
|
||||
useApi: (ref: ApiRef<any>) => {
|
||||
if (ref === catalogApiRef) {
|
||||
return mockCatalogApi;
|
||||
} else if (ref === identityApiRef) {
|
||||
return mockIdentityApi;
|
||||
}
|
||||
if (ref === identityApiRef) {
|
||||
return {
|
||||
getBackstageIdentity: mockGetBackstageIdentity,
|
||||
};
|
||||
}
|
||||
|
||||
return actual.useApi(ref);
|
||||
},
|
||||
};
|
||||
@@ -65,12 +58,6 @@ jest.mock('@backstage/core-plugin-api', () => {
|
||||
describe('useOwnedEntitiesCount', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
mockGetBackstageIdentity.mockResolvedValue({
|
||||
ownershipEntityRefs: ['user:default/spiderman', 'user:group/a-group'],
|
||||
userEntityRef: 'user:default/spiderman',
|
||||
type: 'user',
|
||||
});
|
||||
});
|
||||
|
||||
it(`shouldn't invoke queryEntities when filters are loading`, async () => {
|
||||
@@ -84,7 +71,9 @@ describe('useOwnedEntitiesCount', () => {
|
||||
wrapper: createWrapperWithInitialFilters({}),
|
||||
});
|
||||
|
||||
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
|
||||
await waitFor(() =>
|
||||
expect(mockIdentityApi.getBackstageIdentity).toHaveBeenCalled(),
|
||||
);
|
||||
|
||||
await expect(
|
||||
waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled()),
|
||||
@@ -114,7 +103,9 @@ describe('useOwnedEntitiesCount', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
|
||||
await waitFor(() =>
|
||||
expect(mockIdentityApi.getBackstageIdentity).toHaveBeenCalled(),
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
@@ -151,7 +142,9 @@ describe('useOwnedEntitiesCount', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
|
||||
await waitFor(() =>
|
||||
expect(mockIdentityApi.getBackstageIdentity).toHaveBeenCalled(),
|
||||
);
|
||||
|
||||
await expect(
|
||||
waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled()),
|
||||
@@ -185,7 +178,9 @@ describe('useOwnedEntitiesCount', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
await waitFor(() => expect(mockGetBackstageIdentity).toHaveBeenCalled());
|
||||
await waitFor(() =>
|
||||
expect(mockIdentityApi.getBackstageIdentity).toHaveBeenCalled(),
|
||||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
|
||||
@@ -18,14 +18,16 @@ import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import {
|
||||
alertApiRef,
|
||||
ConfigApi,
|
||||
configApiRef,
|
||||
errorApiRef,
|
||||
IdentityApi,
|
||||
identityApiRef,
|
||||
storageApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { MockStorageApi, TestApiProvider } from '@backstage/test-utils';
|
||||
import {
|
||||
MockStorageApi,
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||
import qs from 'qs';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
@@ -67,20 +69,14 @@ const entities: Entity[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const mockConfigApi = {
|
||||
getOptionalString: () => '',
|
||||
} as Partial<ConfigApi>;
|
||||
const mockConfigApi = mockApis.config();
|
||||
|
||||
const ownershipEntityRefs = ['user:default/guest'];
|
||||
|
||||
const mockIdentityApi: Partial<IdentityApi> = {
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs,
|
||||
}),
|
||||
getCredentials: async () => ({ token: undefined }),
|
||||
};
|
||||
const mockIdentityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs,
|
||||
});
|
||||
const mockCatalogApi = catalogApiMock.mock({
|
||||
getEntities: jest.fn().mockResolvedValue({ items: entities }),
|
||||
queryEntities: jest.fn().mockResolvedValue({
|
||||
|
||||
@@ -15,20 +15,17 @@
|
||||
*/
|
||||
|
||||
import { ComponentEntity, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
||||
import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { TestApiProvider, mockApis } from '@backstage/test-utils';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { useEntityOwnership } from './useEntityOwnership';
|
||||
|
||||
describe('useEntityOwnership', () => {
|
||||
type MockIdentityApi = jest.Mocked<Pick<IdentityApi, 'getBackstageIdentity'>>;
|
||||
|
||||
const mockIdentityApi: MockIdentityApi = {
|
||||
getBackstageIdentity: jest.fn(),
|
||||
};
|
||||
|
||||
const identityApi = mockIdentityApi as unknown as IdentityApi;
|
||||
const identityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/user1',
|
||||
ownershipEntityRefs: ['user:default/user1', 'group:default/group1'],
|
||||
});
|
||||
|
||||
const Wrapper = (props: { children?: React.ReactNode }) => (
|
||||
<TestApiProvider apis={[[identityApiRef, identityApi]]}>
|
||||
@@ -64,12 +61,6 @@ describe('useEntityOwnership', () => {
|
||||
|
||||
describe('useEntityOwnership', () => {
|
||||
it('matches ownership via ownership entity refs', async () => {
|
||||
mockIdentityApi.getBackstageIdentity.mockResolvedValue({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/user1',
|
||||
ownershipEntityRefs: ['user:default/user1', 'group:default/group1'],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useEntityOwnership(), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
|
||||
@@ -17,12 +17,7 @@
|
||||
import { QueryEntitiesInitialRequest } from '@backstage/catalog-client';
|
||||
import { RELATION_OWNED_BY } from '@backstage/catalog-model';
|
||||
import { TableColumn, TableProps } from '@backstage/core-components';
|
||||
import {
|
||||
IdentityApi,
|
||||
identityApiRef,
|
||||
ProfileInfo,
|
||||
storageApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { identityApiRef, storageApiRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
catalogApiRef,
|
||||
entityRouteRef,
|
||||
@@ -34,6 +29,7 @@ import {
|
||||
MockPermissionApi,
|
||||
MockStorageApi,
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
renderInTestApp,
|
||||
} from '@backstage/test-utils';
|
||||
import DashboardIcon from '@material-ui/icons/Dashboard';
|
||||
@@ -166,18 +162,11 @@ describe('DefaultCatalogPage', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
const testProfile: Partial<ProfileInfo> = {
|
||||
const identityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest', 'group:default/tools'],
|
||||
displayName: 'Display Name',
|
||||
};
|
||||
const identityApi: Partial<IdentityApi> = {
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest', 'group:default/tools'],
|
||||
}),
|
||||
getCredentials: async () => ({ token: undefined }),
|
||||
getProfileInfo: async () => testProfile,
|
||||
};
|
||||
});
|
||||
const storageApi = MockStorageApi.create();
|
||||
|
||||
const renderWrapped = (children: React.ReactNode) =>
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BackstageUserIdentity, IdentityApi } from '@backstage/core-plugin-api';
|
||||
import { VisitsStorageApi } from './VisitsStorageApi';
|
||||
import { MockStorageApi } from '@backstage/test-utils';
|
||||
import { MockStorageApi, mockApis } from '@backstage/test-utils';
|
||||
import { Visit, VisitsApi } from './VisitsApi';
|
||||
|
||||
describe('VisitsStorageApi.create', () => {
|
||||
@@ -26,13 +25,9 @@ describe('VisitsStorageApi.create', () => {
|
||||
() => Math.floor(Math.random() * 16).toString(16), // 0x0 to 0xf
|
||||
) as `${string}-${string}-${string}-${string}-${string}`;
|
||||
|
||||
const mockIdentityApi: IdentityApi = {
|
||||
signOut: jest.fn(),
|
||||
getProfileInfo: jest.fn(),
|
||||
getBackstageIdentity: async () =>
|
||||
({ userEntityRef: 'user:default/guest' } as BackstageUserIdentity),
|
||||
getCredentials: jest.fn(),
|
||||
};
|
||||
const mockIdentityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/guest',
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
window.crypto.randomUUID = mockRandomUUID;
|
||||
@@ -40,7 +35,7 @@ describe('VisitsStorageApi.create', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
jest.useRealTimers();
|
||||
window.localStorage.clear();
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BackstageUserIdentity, IdentityApi } from '@backstage/core-plugin-api';
|
||||
import { mockApis } from '@backstage/test-utils';
|
||||
import { VisitsWebStorageApi } from './VisitsWebStorageApi';
|
||||
|
||||
describe('VisitsWebStorageApi.create()', () => {
|
||||
@@ -24,13 +24,9 @@ describe('VisitsWebStorageApi.create()', () => {
|
||||
() => Math.floor(Math.random() * 16).toString(16), // 0x0 to 0xf
|
||||
) as `${string}-${string}-${string}-${string}-${string}`;
|
||||
|
||||
const mockIdentityApi: IdentityApi = {
|
||||
signOut: jest.fn(),
|
||||
getProfileInfo: jest.fn(),
|
||||
getBackstageIdentity: async () =>
|
||||
({ userEntityRef: 'user:default/guest' } as BackstageUserIdentity),
|
||||
getCredentials: jest.fn(),
|
||||
};
|
||||
const mockIdentityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/guest',
|
||||
});
|
||||
|
||||
const mockErrorApi = { post: jest.fn(), error$: jest.fn() };
|
||||
|
||||
@@ -40,7 +36,7 @@ describe('VisitsWebStorageApi.create()', () => {
|
||||
|
||||
afterEach(() => {
|
||||
window.localStorage.clear();
|
||||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('instantiates with only identitiyApi', () => {
|
||||
|
||||
@@ -14,11 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import {
|
||||
renderInTestApp,
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { MyGroupsSidebarItem } from './MyGroupsSidebarItem';
|
||||
import GroupIcon from '@material-ui/icons/People';
|
||||
import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
@@ -26,13 +30,10 @@ import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
describe('MyGroupsSidebarItem Test', () => {
|
||||
describe('For guests or users with no groups', () => {
|
||||
it('MyGroupsSidebarItem should be empty', async () => {
|
||||
const identityApi: Partial<IdentityApi> = {
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest'],
|
||||
}),
|
||||
};
|
||||
const identityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest'],
|
||||
});
|
||||
const catalogApi = catalogApiMock();
|
||||
const rendered = await renderInTestApp(
|
||||
<TestApiProvider
|
||||
@@ -59,13 +60,10 @@ describe('MyGroupsSidebarItem Test', () => {
|
||||
|
||||
describe('For users that are members of a single group', () => {
|
||||
it('MyGroupsSidebarItem should display a single item that links to their group', async () => {
|
||||
const identityApi: Partial<IdentityApi> = {
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/nigel.manning',
|
||||
ownershipEntityRefs: ['user:default/nigel.manning'],
|
||||
}),
|
||||
};
|
||||
const identityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/nigel.manning',
|
||||
ownershipEntityRefs: ['user:default/nigel.manning'],
|
||||
});
|
||||
const catalogApi = catalogApiMock.mock({
|
||||
getEntities: async () => ({
|
||||
items: [
|
||||
@@ -114,13 +112,10 @@ describe('MyGroupsSidebarItem Test', () => {
|
||||
|
||||
describe('For users that are members of multiple groups', () => {
|
||||
it('MyGroupsSidebarItem should display a sub-menu with all their groups and a link to each group', async () => {
|
||||
const identityApi: Partial<IdentityApi> = {
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/nigel.manning',
|
||||
ownershipEntityRefs: ['user:default/nigel.manning'],
|
||||
}),
|
||||
};
|
||||
const identityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/nigel.manning',
|
||||
ownershipEntityRefs: ['user:default/nigel.manning'],
|
||||
});
|
||||
const catalogApi = catalogApiMock.mock({
|
||||
getEntities: async () => ({
|
||||
items: [
|
||||
@@ -192,13 +187,10 @@ describe('MyGroupsSidebarItem Test', () => {
|
||||
|
||||
describe('When an additional filter is not provided', () => {
|
||||
it('catalogApi.getEntities() should be called with the default filter', async () => {
|
||||
const identityApi: Partial<IdentityApi> = {
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest'],
|
||||
}),
|
||||
};
|
||||
const identityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest'],
|
||||
});
|
||||
const mockCatalogApi = catalogApiMock.mock();
|
||||
await renderInTestApp(
|
||||
<TestApiProvider
|
||||
@@ -233,13 +225,10 @@ describe('MyGroupsSidebarItem Test', () => {
|
||||
|
||||
describe('When an additional filter is provided', () => {
|
||||
it('catalogApi.getEntities() should be called with an additional filter item', async () => {
|
||||
const identityApi: Partial<IdentityApi> = {
|
||||
getBackstageIdentity: async () => ({
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest'],
|
||||
}),
|
||||
};
|
||||
const identityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/guest',
|
||||
ownershipEntityRefs: ['user:default/guest'],
|
||||
});
|
||||
const mockCatalogApi = catalogApiMock.mock();
|
||||
await renderInTestApp(
|
||||
<TestApiProvider
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import {
|
||||
renderInTestApp,
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import React from 'react';
|
||||
@@ -31,12 +35,7 @@ import { rootRouteRef } from '../../routes';
|
||||
describe('<ListTasksPage />', () => {
|
||||
const catalogApi = catalogApiMock.mock();
|
||||
|
||||
const identityApi = {
|
||||
getBackstageIdentity: jest.fn(),
|
||||
getProfileInfo: jest.fn(),
|
||||
getCredentials: jest.fn(),
|
||||
signOut: jest.fn(),
|
||||
};
|
||||
const identityApi = mockApis.identity();
|
||||
|
||||
const scaffolderApiMock: jest.Mocked<Required<ScaffolderApi>> = {
|
||||
scaffold: jest.fn(),
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import {
|
||||
renderInTestApp,
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import React from 'react';
|
||||
@@ -24,13 +28,7 @@ import { identityApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
describe('<OwnerEntityColumn />', () => {
|
||||
const catalogApi = catalogApiMock.mock();
|
||||
|
||||
const identityApi = {
|
||||
getBackstageIdentity: jest.fn(),
|
||||
getProfileInfo: jest.fn(),
|
||||
getCredentials: jest.fn(),
|
||||
signOut: jest.fn(),
|
||||
};
|
||||
const identityApi = mockApis.identity();
|
||||
|
||||
it('should render the column with the user', async () => {
|
||||
const props = {
|
||||
|
||||
@@ -18,7 +18,11 @@ import React from 'react';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { MyGroupsPicker } from './MyGroupsPicker';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import {
|
||||
renderInTestApp,
|
||||
TestApiProvider,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import {
|
||||
catalogApiRef,
|
||||
entityPresentationApiRef,
|
||||
@@ -26,7 +30,6 @@ import {
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import {
|
||||
ErrorApi,
|
||||
IdentityApi,
|
||||
errorApiRef,
|
||||
identityApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
@@ -34,25 +37,9 @@ import userEvent from '@testing-library/user-event';
|
||||
import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffolder-react';
|
||||
import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog';
|
||||
|
||||
// Create a mock IdentityApi
|
||||
const mockIdentityApi: IdentityApi = {
|
||||
getProfileInfo: () =>
|
||||
Promise.resolve({
|
||||
displayName: 'Bob',
|
||||
email: 'bob@example.com',
|
||||
picture: 'https://example.com/picture.jpg',
|
||||
}),
|
||||
getBackstageIdentity: () =>
|
||||
Promise.resolve({
|
||||
id: 'Bob',
|
||||
idToken: 'token',
|
||||
type: 'user',
|
||||
userEntityRef: 'user:default/bob',
|
||||
ownershipEntityRefs: ['group:default/group1', 'group:default/group2'],
|
||||
}),
|
||||
getCredentials: () => Promise.resolve({ token: 'token' }),
|
||||
signOut: () => Promise.resolve(),
|
||||
};
|
||||
const mockIdentityApi = mockApis.identity({
|
||||
userEntityRef: 'user:default/bob',
|
||||
});
|
||||
|
||||
describe('<MyGroupsPicker />', () => {
|
||||
let entities: Entity[];
|
||||
@@ -96,7 +83,7 @@ describe('<MyGroupsPicker />', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should only return the groups a user is part of and not the groups a user is not part of', async () => {
|
||||
|
||||
@@ -14,16 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
|
||||
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 tokenFunction = jest.fn();
|
||||
const baseUrlFunction = jest.fn();
|
||||
const identity = {
|
||||
getCredentials: tokenFunction,
|
||||
} as unknown as IdentityApi;
|
||||
const identity = mockApis.identity({ token: '12345' });
|
||||
const discoveryApi = {
|
||||
getBaseUrl: baseUrlFunction,
|
||||
} as unknown as DiscoveryApi;
|
||||
@@ -31,8 +29,7 @@ describe('SignalsClient', () => {
|
||||
let server: WS;
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.resetAllMocks();
|
||||
tokenFunction.mockResolvedValue({ token: '12345' });
|
||||
jest.clearAllMocks();
|
||||
baseUrlFunction.mockResolvedValue('http://localhost:1234');
|
||||
server = new WS('ws://localhost:1234', { jsonProtocol: true });
|
||||
});
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
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 { mockApis, MockFetchApi } from '@backstage/test-utils';
|
||||
@@ -36,9 +35,7 @@ describe('TechDocsStorageClient', () => {
|
||||
const mockBaseUrl = 'http://backstage:9191/api/techdocs';
|
||||
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(() => {
|
||||
|
||||
@@ -18,10 +18,13 @@ import {
|
||||
DiscoveryApi,
|
||||
ErrorApi,
|
||||
FetchApi,
|
||||
IdentityApi,
|
||||
StorageApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { MockFetchApi, registerMswTestHooks } from '@backstage/test-utils';
|
||||
import {
|
||||
MockFetchApi,
|
||||
mockApis,
|
||||
registerMswTestHooks,
|
||||
} from '@backstage/test-utils';
|
||||
import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { UserSettingsStorage } from './UserSettingsStorage';
|
||||
@@ -35,13 +38,8 @@ describe('Persistent Storage API', () => {
|
||||
const mockDiscoveryApi = {
|
||||
getBaseUrl: async () => mockBaseUrl,
|
||||
};
|
||||
const mockIdentityApi: Partial<IdentityApi> = {
|
||||
getCredentials: async () => ({ token: 'a-token' }),
|
||||
};
|
||||
const mockIdentityApiFallback: Partial<IdentityApi> = {
|
||||
// This API recreates the guest mode, where the WebStorage is used as fallback
|
||||
getCredentials: async () => ({}),
|
||||
};
|
||||
const mockIdentityApi = mockApis.identity({ token: 'a-token' });
|
||||
const mockIdentityApiFallback = mockApis.identity();
|
||||
|
||||
const createPersistentStorage = (
|
||||
args?: Partial<{
|
||||
@@ -55,7 +53,7 @@ describe('Persistent Storage API', () => {
|
||||
errorApi: mockErrorApi,
|
||||
fetchApi: new MockFetchApi(),
|
||||
discoveryApi: mockDiscoveryApi,
|
||||
identityApi: mockIdentityApi as IdentityApi,
|
||||
identityApi: mockIdentityApi,
|
||||
...args,
|
||||
});
|
||||
};
|
||||
@@ -72,13 +70,13 @@ describe('Persistent Storage API', () => {
|
||||
errorApi: mockErrorApi,
|
||||
fetchApi: new MockFetchApi(),
|
||||
discoveryApi: mockDiscoveryApi,
|
||||
identityApi: mockIdentityApiFallback as IdentityApi,
|
||||
identityApi: mockIdentityApiFallback,
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should return undefined for values which are unset', async () => {
|
||||
|
||||
+6
-7
@@ -20,16 +20,15 @@ import { DefaultSettingsPage } from './DefaultSettingsPage';
|
||||
import { UserSettingsTab } from '../UserSettingsTab';
|
||||
import { useOutlet } from 'react-router-dom';
|
||||
import { SettingsLayout } from '../SettingsLayout';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useOutlet: jest.fn().mockReturnValue(undefined),
|
||||
}));
|
||||
|
||||
const catalogApiMock: jest.Mocked<CatalogApi> = {
|
||||
getEntityByRef: jest.fn(),
|
||||
} as any;
|
||||
const catalogApi = catalogApiMock();
|
||||
|
||||
describe('<DefaultSettingsPage />', () => {
|
||||
beforeEach(() => {
|
||||
@@ -38,7 +37,7 @@ describe('<DefaultSettingsPage />', () => {
|
||||
|
||||
it('should render the settings page with 3 tabs', async () => {
|
||||
const { container } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApiMock]]}>
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<DefaultSettingsPage />
|
||||
</TestApiProvider>,
|
||||
);
|
||||
@@ -54,7 +53,7 @@ describe('<DefaultSettingsPage />', () => {
|
||||
</UserSettingsTab>
|
||||
);
|
||||
const { container } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApiMock]]}>
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<DefaultSettingsPage tabs={[advancedTabRoute]} />
|
||||
</TestApiProvider>,
|
||||
);
|
||||
@@ -71,7 +70,7 @@ describe('<DefaultSettingsPage />', () => {
|
||||
</SettingsLayout.Route>
|
||||
);
|
||||
const { container } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApiMock]]}>
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<DefaultSettingsPage tabs={[advancedTabRoute]} />
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
@@ -14,32 +14,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
|
||||
import {
|
||||
renderInTestApp,
|
||||
TestApiRegistry,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { UserSettingsIdentityCard } from './UserSettingsIdentityCard';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import { identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
const apiRegistry = TestApiRegistry.from(
|
||||
[
|
||||
identityApiRef,
|
||||
{
|
||||
getProfileInfo: jest.fn(async () => ({})),
|
||||
getBackstageIdentity: jest.fn(async () => ({
|
||||
type: 'user' as const,
|
||||
userEntityRef: 'foo:bar/foobar',
|
||||
ownershipEntityRefs: ['user:default/test-ownership'],
|
||||
})),
|
||||
},
|
||||
],
|
||||
[
|
||||
catalogApiRef,
|
||||
{
|
||||
getEntityByRef: jest.fn(),
|
||||
},
|
||||
mockApis.identity({
|
||||
userEntityRef: 'foo:bar/foobar',
|
||||
ownershipEntityRefs: ['user:default/test-ownership'],
|
||||
}),
|
||||
],
|
||||
[catalogApiRef, catalogApiMock.mock()],
|
||||
);
|
||||
|
||||
describe('<UserSettingsIdentityCard />', () => {
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
MockErrorApi,
|
||||
TestApiProvider,
|
||||
renderInTestApp,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { errorApiRef, identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { fireEvent, waitFor, screen } from '@testing-library/react';
|
||||
@@ -35,9 +36,9 @@ describe('<UserSettingsMenu />', () => {
|
||||
});
|
||||
|
||||
it('handles errors that occur when signing out', async () => {
|
||||
const failingIdentityApi = {
|
||||
signOut: jest.fn().mockRejectedValue(new Error('Logout error')),
|
||||
};
|
||||
const failingIdentityApi = mockApis.identity.mock({
|
||||
signOut: () => Promise.reject(new Error('Logout error')),
|
||||
});
|
||||
const mockErrorApi = new MockErrorApi({ collect: true });
|
||||
await renderInTestApp(
|
||||
<TestApiProvider
|
||||
|
||||
@@ -14,35 +14,30 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils';
|
||||
import {
|
||||
renderInTestApp,
|
||||
TestApiRegistry,
|
||||
mockApis,
|
||||
} from '@backstage/test-utils';
|
||||
import { screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { identityApiRef } from '@backstage/core-plugin-api';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
import { ApiProvider } from '@backstage/core-app-api';
|
||||
import { UserSettingsProfileCard } from './UserSettingsProfileCard';
|
||||
|
||||
const apiRegistry = TestApiRegistry.from(
|
||||
[
|
||||
identityApiRef,
|
||||
{
|
||||
getProfileInfo: jest.fn(async () => ({})),
|
||||
getBackstageIdentity: jest.fn(async () => ({
|
||||
type: 'user' as const,
|
||||
userEntityRef: 'foo:bar/foobar',
|
||||
ownershipEntityRefs: ['user:default/test-ownership'],
|
||||
})),
|
||||
},
|
||||
],
|
||||
[identityApiRef, mockApis.identity()],
|
||||
[
|
||||
catalogApiRef,
|
||||
{
|
||||
getEntityByRef: jest.fn(async () => {
|
||||
return {
|
||||
catalogApiMock({
|
||||
entities: [
|
||||
{
|
||||
apiVersion: 'backstage.io/v1beta1',
|
||||
kind: 'User',
|
||||
metadata: {
|
||||
name: 'Guest',
|
||||
name: 'test',
|
||||
annotations: {},
|
||||
},
|
||||
spec: {
|
||||
@@ -50,9 +45,9 @@ const apiRegistry = TestApiRegistry.from(
|
||||
picture: 'https://example.com/avatar.png',
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@@ -22,20 +22,15 @@ import { useOutlet } from 'react-router-dom';
|
||||
import { SettingsLayout } from '../SettingsLayout';
|
||||
import { screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import {
|
||||
CatalogApi,
|
||||
catalogApiRef,
|
||||
entityRouteRef,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useOutlet: jest.fn().mockReturnValue(undefined),
|
||||
}));
|
||||
|
||||
const catalogApiMock: jest.Mocked<CatalogApi> = {
|
||||
getEntityByRef: jest.fn(),
|
||||
} as any;
|
||||
const catalogApi = catalogApiMock();
|
||||
|
||||
describe('<SettingsPage />', () => {
|
||||
beforeEach(() => {
|
||||
@@ -44,7 +39,7 @@ describe('<SettingsPage />', () => {
|
||||
|
||||
it('should render the default settings page with 3 tabs', async () => {
|
||||
const { container } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApiMock]]}>
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<SettingsPage />
|
||||
</TestApiProvider>,
|
||||
{
|
||||
@@ -64,7 +59,7 @@ describe('<SettingsPage />', () => {
|
||||
);
|
||||
(useOutlet as jest.Mock).mockReturnValue(advancedTabRoute);
|
||||
const { container } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApiMock]]}>
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<SettingsPage />
|
||||
</TestApiProvider>,
|
||||
{
|
||||
@@ -85,7 +80,7 @@ describe('<SettingsPage />', () => {
|
||||
);
|
||||
(useOutlet as jest.Mock).mockReturnValue(advancedTabRoute);
|
||||
const { container } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApiMock]]}>
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<SettingsPage />
|
||||
</TestApiProvider>,
|
||||
{
|
||||
@@ -115,7 +110,7 @@ describe('<SettingsPage />', () => {
|
||||
);
|
||||
(useOutlet as jest.Mock).mockReturnValue(customLayout);
|
||||
const { container } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApiMock]]}>
|
||||
<TestApiProvider apis={[[catalogApiRef, catalogApi]]}>
|
||||
<SettingsPage />
|
||||
</TestApiProvider>,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user