Merge pull request #25588 from backstage/rugvip/manual-options

backend-test-utils: refactor mock service factories to define options on its own
This commit is contained in:
Patrik Oldsberg
2024-07-16 10:47:21 +02:00
committed by GitHub
3 changed files with 68 additions and 41 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-test-utils': patch
---
Internal refactor of `mockServices.httpAuth.factory` to allow it to still be constructed with options, but without declaring options via `createServiceFactory`.
+14 -15
View File
@@ -206,13 +206,10 @@ export namespace mockServices {
}): HttpAuthService;
// (undocumented)
export namespace httpAuth {
const factory: ServiceFactoryCompat<
HttpAuthService,
'plugin',
{
defaultCredentials?: BackstageCredentials | undefined;
}
>;
const factory: ((options?: {
defaultCredentials?: BackstageCredentials;
}) => ServiceFactory<HttpAuthService, 'plugin'>) &
ServiceFactory<HttpAuthService, 'plugin'>;
const // (undocumented)
mock: (
partialImpl?: Partial<HttpAuthService> | undefined,
@@ -232,7 +229,7 @@ export namespace mockServices {
// (undocumented)
export namespace identity {
const // (undocumented)
factory: () => ServiceFactory<IdentityService, 'plugin'>;
factory: ServiceFactoryCompat<IdentityService, 'plugin', undefined>;
const // (undocumented)
mock: (
partialImpl?: Partial<IdentityService> | undefined,
@@ -274,9 +271,10 @@ export namespace mockServices {
data?: JsonObject;
};
const // (undocumented)
factory: (
options?: Options | undefined,
) => ServiceFactory<RootConfigService, 'root'>;
factory: ServiceFactory<RootConfigService, 'root'> &
((
options?: Options | undefined,
) => ServiceFactory<RootConfigService, 'root'>);
}
// (undocumented)
export namespace rootHealth {
@@ -318,9 +316,10 @@ export namespace mockServices {
level?: 'none' | 'error' | 'warn' | 'info' | 'debug';
};
const // (undocumented)
factory: (
options?: Options | undefined,
) => ServiceFactory<LoggerService, 'root'>;
factory: ServiceFactory<LoggerService, 'root'> &
((
options?: Options | undefined,
) => ServiceFactory<LoggerService, 'root'>);
const // (undocumented)
mock: (
partialImpl?: Partial<RootLoggerService> | undefined,
@@ -340,7 +339,7 @@ export namespace mockServices {
// (undocumented)
export namespace tokenManager {
const // (undocumented)
factory: () => ServiceFactory<TokenManagerService, 'plugin'>;
factory: ServiceFactoryCompat<TokenManagerService, 'plugin', undefined>;
const // (undocumented)
mock: (
partialImpl?: Partial<TokenManagerService> | undefined,
@@ -70,21 +70,28 @@ function createLoggerMock() {
}
/** @internal */
function simpleFactory<
function simpleFactoryWithOptions<
TService,
TScope extends 'root' | 'plugin',
TOptions extends [options?: object] = [],
>(
ref: ServiceRef<TService, TScope>,
factory: (...options: TOptions) => TService,
): (...options: TOptions) => ServiceFactory<TService, TScope> {
return createServiceFactory((options: unknown) => ({
service: ref as ServiceRef<TService, any>,
deps: {},
async factory() {
return (factory as any)(options);
},
})) as (...options: TOptions) => ServiceFactory<TService, any>;
): ServiceFactory<TService, TScope> &
((...options: TOptions) => ServiceFactory<TService, TScope>) {
const factoryWithOptions = (...options: TOptions) =>
createServiceFactory({
service: ref as ServiceRef<TService, any>,
deps: {},
async factory() {
return factory(...options);
},
})();
return Object.assign(
factoryWithOptions,
factoryWithOptions(...([undefined] as unknown as TOptions)),
) as ServiceFactory<TService, TScope> &
((...options: TOptions) => ServiceFactory<TService, TScope>);
}
/** @public */
@@ -134,7 +141,10 @@ export namespace mockServices {
export namespace rootConfig {
export type Options = { data?: JsonObject };
export const factory = simpleFactory(coreServices.rootConfig, rootConfig);
export const factory = simpleFactoryWithOptions(
coreServices.rootConfig,
rootConfig,
);
}
export function rootLogger(options?: rootLogger.Options): LoggerService {
@@ -145,7 +155,10 @@ export namespace mockServices {
level?: 'none' | 'error' | 'warn' | 'info' | 'debug';
};
export const factory = simpleFactory(coreServices.rootLogger, rootLogger);
export const factory = simpleFactoryWithOptions(
coreServices.rootLogger,
rootLogger,
);
export const mock = simpleMock(coreServices.rootLogger, () => ({
child: jest.fn(),
debug: jest.fn(),
@@ -168,10 +181,11 @@ export namespace mockServices {
};
}
export namespace tokenManager {
export const factory = simpleFactory(
coreServices.tokenManager,
tokenManager,
);
export const factory = createServiceFactory({
service: coreServices.tokenManager,
deps: {},
factory: () => tokenManager(),
});
export const mock = simpleMock(coreServices.tokenManager, () => ({
authenticate: jest.fn(),
getToken: jest.fn(),
@@ -182,7 +196,11 @@ export namespace mockServices {
return new MockIdentityService();
}
export namespace identity {
export const factory = simpleFactory(coreServices.identity, identity);
export const factory = createServiceFactory({
service: coreServices.identity,
deps: {},
factory: () => identity(),
});
export const mock = simpleMock(coreServices.identity, () => ({
getIdentity: jest.fn(),
}));
@@ -270,15 +288,10 @@ export namespace mockServices {
);
}
export namespace httpAuth {
/**
* Creates a mock service factory for the `HttpAuthService`.
*
* By default all requests without credentials are treated as requests from
* the default mock user principal. This behavior can be configured with the
* `defaultCredentials` option.
*/
export const factory = createServiceFactory(
(options?: { defaultCredentials?: BackstageCredentials }) => ({
const factoryWithOptions = (options?: {
defaultCredentials?: BackstageCredentials;
}) =>
createServiceFactory({
service: coreServices.httpAuth,
deps: { plugin: coreServices.pluginMetadata },
factory: ({ plugin }) =>
@@ -286,7 +299,17 @@ export namespace mockServices {
plugin.getId(),
options?.defaultCredentials ?? mockCredentials.user(),
),
}),
})();
/**
* Creates a mock service factory for the `HttpAuthService`.
*
* By default all requests without credentials are treated as requests from
* the default mock user principal. This behavior can be configured with the
* `defaultCredentials` option.
*/
export const factory = Object.assign(
factoryWithOptions,
factoryWithOptions(),
);
export const mock = simpleMock(coreServices.httpAuth, () => ({
credentials: jest.fn(),