From 4e7bba64a19d9278dad1a96999e51ccf96fa2fa7 Mon Sep 17 00:00:00 2001 From: peternhale Date: Fri, 23 Aug 2024 10:07:04 -0600 Subject: [PATCH] fix: needed adjustments due to discovery @W-16507728@ Add ability to validate and correct instance name and parameters --- src/services/serviceProvider.ts | 33 +++++++++++++---- src/types/index.ts | 52 ++++++++++++++++++++++++++- test/services/serviceProvider.test.ts | 19 +++++++++- 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/services/serviceProvider.ts b/src/services/serviceProvider.ts index 3264956..3651d4b 100644 --- a/src/services/serviceProvider.ts +++ b/src/services/serviceProvider.ts @@ -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'; /** @@ -28,17 +34,22 @@ export class ServiceProvider { */ static async getService( type: T, - instanceName: string, + instanceName?: string, ...rest: ServiceParams[] // This does not make sense, so keep an eye on it ): Promise> { let serviceInstance: ServiceReturnType | 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; } } @@ -46,7 +57,7 @@ export class ServiceProvider { if (!serviceInstance) { serviceInstance = await ServiceProvider.materializeService( type, - instanceName, + correctedInstanceName, ...rest ); } @@ -165,6 +176,10 @@ export class ServiceProvider { instanceName: string, ...rest: ServiceParams[] ): Promise> { + const paramValidator = ServiceValidators[type]; + const correctedParams = paramValidator.validateAndCorrect( + rest as ServiceParams + ); let serviceInstance: ServiceReturnType | undefined; switch (type) { @@ -172,13 +187,17 @@ export class ServiceProvider { // Call VSCode command to materialize service A serviceInstance = await vscode.commands.executeCommand< ServiceReturnType - >('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 - >('sf.vscode.core.get.telemetry', instanceName, ...rest); + >('sf.vscode.core.get.telemetry', instanceName, ...correctedParams); break; default: throw new Error(`Unsupported service type: ${type}`); diff --git a/src/types/index.ts b/src/types/index.ts index 4f449f1..90011d5 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -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' @@ -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 @@ -31,5 +33,53 @@ export type ServiceReturnType = ? LoggerInterface : never; +// Define a ServiceValidator interface +interface ServiceValidator { + validateAndCorrect(params: ServiceParams): ServiceParams; +} + +// Create a ServiceValidators object to hold validators for each service type +export const ServiceValidators: { + [key in ServiceType]: ServiceValidator; +} = { + [ServiceType.Logger]: { + validateAndCorrect( + params: ServiceParams + ): ServiceParams { + return params; + } + }, + [ServiceType.Telemetry]: { + validateAndCorrect( + params: ServiceParams + ): ServiceParams { + return params; + } + } + // Add more validators as needed +}; + +// Define a ServiceInstanceValidator interface +// eslint-disable-next-line @typescript-eslint/no-unused-vars +interface ServiceInstanceValidator { + validateAndCorrect(instanceName: string): string; +} + +// Create a ServiceInstanceValidators object to hold validators for each service type +export const ServiceInstanceValidators: { + [key in ServiceType]: ServiceInstanceValidator; +} = { + [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'; diff --git a/test/services/serviceProvider.test.ts b/test/services/serviceProvider.test.ts index 3048a85..6f0bea5 100644 --- a/test/services/serviceProvider.test.ts +++ b/test/services/serviceProvider.test.ts @@ -13,7 +13,8 @@ import { ActivationInfo, Properties, Measurements, - TelemetryData + TelemetryData, + SFDX_CORE_EXTENSION_NAME } from '../../src'; import { ExtensionContext, ExtensionMode } from 'vscode'; @@ -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' @@ -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' @@ -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(