Skip to content

Commit

Permalink
fix: needed adjustments due to discovery
Browse files Browse the repository at this point in the history
@W-16507728@

Add ability to validate and correct instance name and parameters
  • Loading branch information
peternhale committed Aug 23, 2024
1 parent c6ab171 commit 4e7bba6
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 9 deletions.
33 changes: 26 additions & 7 deletions src/services/serviceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { ServiceParams, ServiceReturnType, ServiceType } from '../types';
import {
ServiceInstanceValidators,
ServiceParams,
ServiceReturnType,
ServiceType,
ServiceValidators
} from '../types';
import * as vscode from 'vscode';

/**
Expand All @@ -28,25 +34,30 @@ export class ServiceProvider {
*/
static async getService<T extends ServiceType>(
type: T,
instanceName: string,
instanceName?: string,
...rest: ServiceParams<T>[] // This does not make sense, so keep an eye on it
): Promise<ServiceReturnType<T>> {
let serviceInstance: ServiceReturnType<T> | undefined;

// Validate and correct instance name
const instanceValidator = ServiceInstanceValidators[type];
const correctedInstanceName =
instanceValidator.validateAndCorrect(instanceName);

if (ServiceProvider.serviceMap.has(type)) {
const serviceInstances = ServiceProvider.serviceMap.get(type);

if (serviceInstances?.has(instanceName)) {
if (serviceInstances?.has(correctedInstanceName)) {
serviceInstance = serviceInstances.get(
instanceName
correctedInstanceName
) as ServiceReturnType<T>;
}
}

if (!serviceInstance) {
serviceInstance = await ServiceProvider.materializeService<T>(
type,
instanceName,
correctedInstanceName,
...rest
);
}
Expand Down Expand Up @@ -165,20 +176,28 @@ export class ServiceProvider {
instanceName: string,
...rest: ServiceParams<T>[]
): Promise<ServiceReturnType<T>> {
const paramValidator = ServiceValidators[type];
const correctedParams = paramValidator.validateAndCorrect(
rest as ServiceParams<T>
);
let serviceInstance: ServiceReturnType<T> | undefined;

switch (type) {
case ServiceType.Logger:
// Call VSCode command to materialize service A
serviceInstance = await vscode.commands.executeCommand<
ServiceReturnType<T>
>('sf.vscode.core.logger.get.instance', instanceName, ...rest);
>(
'sf.vscode.core.logger.get.instance',
instanceName,
...correctedParams
);
break;
case ServiceType.Telemetry:
// Call VSCode command to materialize service A
serviceInstance = await vscode.commands.executeCommand<
ServiceReturnType<T>
>('sf.vscode.core.get.telemetry', instanceName, ...rest);
>('sf.vscode.core.get.telemetry', instanceName, ...correctedParams);
break;
default:
throw new Error(`Unsupported service type: ${type}`);
Expand Down
52 changes: 51 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import { LoggerInterface } from './logger/loggerTypes';
import { TelemetryServiceInterface } from './telemetry/telemetryTypes';

export const SFDX_CORE_EXTENSION_NAME = 'salesforcedx-vscode-core';

export enum ServiceType {
Logger = 'Logger',
Telemetry = 'Telemetry'
Expand All @@ -16,7 +18,7 @@ export enum ServiceType {
// Define a mapping from service types to their corresponding parameter types
interface ServiceParamsMap {
[ServiceType.Logger]: [string]; // Logger requires a string parameter
[ServiceType.Telemetry]: [string];
[ServiceType.Telemetry]: [string | undefined];
}

// Define a type that represents the parameter types for a given service type
Expand All @@ -31,5 +33,53 @@ export type ServiceReturnType<T extends ServiceType> =
? LoggerInterface
: never;

// Define a ServiceValidator interface
interface ServiceValidator<T extends ServiceType> {
validateAndCorrect(params: ServiceParams<T>): ServiceParams<T>;
}

// Create a ServiceValidators object to hold validators for each service type
export const ServiceValidators: {
[key in ServiceType]: ServiceValidator<key>;
} = {
[ServiceType.Logger]: {
validateAndCorrect(
params: ServiceParams<ServiceType.Logger>
): ServiceParams<ServiceType.Logger> {
return params;
}
},
[ServiceType.Telemetry]: {
validateAndCorrect(
params: ServiceParams<ServiceType.Telemetry>
): ServiceParams<ServiceType.Telemetry> {
return params;
}
}
// Add more validators as needed
};

// Define a ServiceInstanceValidator interface
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface ServiceInstanceValidator<T extends ServiceType> {
validateAndCorrect(instanceName: string): string;
}

// Create a ServiceInstanceValidators object to hold validators for each service type
export const ServiceInstanceValidators: {
[key in ServiceType]: ServiceInstanceValidator<key>;
} = {
[ServiceType.Logger]: {
validateAndCorrect(instanceName: string): string {
return instanceName || 'defaultLoggerInstance';
}
},
[ServiceType.Telemetry]: {
validateAndCorrect(instanceName: string): string {
return instanceName || SFDX_CORE_EXTENSION_NAME;
}
}
// Add more validators as needed
};
export * from './logger/loggerTypes';
export * from './telemetry/telemetryTypes';
19 changes: 18 additions & 1 deletion test/services/serviceProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
ActivationInfo,
Properties,
Measurements,
TelemetryData
TelemetryData,
SFDX_CORE_EXTENSION_NAME
} from '../../src';
import { ExtensionContext, ExtensionMode } from 'vscode';

Expand Down Expand Up @@ -115,6 +116,20 @@ describe('ServiceProvider', () => {
expect(service).toBe('mockService');
});

it('should get a service name that is a default', async () => {
(vscode.commands.executeCommand as jest.Mock).mockResolvedValue(
'mockService'
);

const service = await ServiceProvider.getService(ServiceType.Telemetry);
expect(service).toBe('mockService');
const hasService = ServiceProvider.has(
ServiceType.Telemetry,
SFDX_CORE_EXTENSION_NAME
);
expect(hasService).toBe(true);
});

it('should check if a service type exists', async () => {
(vscode.commands.executeCommand as jest.Mock).mockResolvedValue(
'mockService'
Expand All @@ -129,6 +144,7 @@ describe('ServiceProvider', () => {
const hasInstance = ServiceProvider.has(ServiceType.Telemetry, 'instance1');
expect(hasInstance).toBe(true);
});

it('should remove a service instance', async () => {
(vscode.commands.executeCommand as jest.Mock).mockResolvedValue(
'mockService'
Expand Down Expand Up @@ -159,6 +175,7 @@ describe('ServiceProvider', () => {
const hasService = ServiceProvider.hasService(ServiceType.Telemetry);
expect(hasService).toBe(false);
});

it('should set a new service instance successfully', () => {
const telemetryServiceInstance = new TelemetryService(); // create a real instance of TelemetryService
ServiceProvider.setService(
Expand Down

0 comments on commit 4e7bba6

Please sign in to comment.