diff --git a/src/main/wrapper/CxConstants.ts b/src/main/wrapper/CxConstants.ts index 7c40bc12..623f1946 100644 --- a/src/main/wrapper/CxConstants.ts +++ b/src/main/wrapper/CxConstants.ts @@ -116,6 +116,8 @@ export enum CxConstants { CMD_LEARN_MORE = "learn-more", IDE_SCANS_KEY = "scan.config.plugins.ideScans", AI_GUIDED_REMEDIATION_KEY = "scan.config.plugins.aiGuidedRemediation", + STANDALONE_KEY = "scan.config.plugins.standalone", + ASSIST_KEY = "scan.config.plugins.cxoneassist", AI_MCP_SERVER_KEY = "scan.config.plugins.aiMcpServer", TELEMETRY = "telemetry", SUB_CMD_TELEMETRY_AI = "ai", diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index 67ded66c..b487fca1 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -466,6 +466,27 @@ export class CxWrapper { return value?.toLowerCase() === "true"; } + async standaloneEnabled(): Promise { + const commands: string[] = [CxConstants.CMD_UTILS, CxConstants.SUB_CMD_TENANT]; + commands.push(...this.initializeCommands(false)); + + const exec = new ExecutionService(); + const output = await exec.executeMapTenantOutputCommands(this.config.pathToExecutable, commands); + + const value = getTrimmedMapValue(output, CxConstants.STANDALONE_KEY); + return value?.toLowerCase() === "true"; + } + + async cxOneAssistEnabled(): Promise { + const commands: string[] = [CxConstants.CMD_UTILS, CxConstants.SUB_CMD_TENANT]; + commands.push(...this.initializeCommands(false)); + + const exec = new ExecutionService(); + const output = await exec.executeMapTenantOutputCommands(this.config.pathToExecutable, commands); + + const value = getTrimmedMapValue(output, CxConstants.ASSIST_KEY); + return value?.toLowerCase() === "true"; + } async aiMcpServerEnabled(): Promise { const commands: string[] = [CxConstants.CMD_UTILS, CxConstants.SUB_CMD_TENANT]; diff --git a/src/tests/AssistEnabledTest.test.ts b/src/tests/AssistEnabledTest.test.ts new file mode 100644 index 00000000..00eb5cc7 --- /dev/null +++ b/src/tests/AssistEnabledTest.test.ts @@ -0,0 +1,52 @@ +import { CxWrapper } from '../main/wrapper/CxWrapper'; +import { BaseTest } from './BaseTest'; +import { ExecutionService } from '../main/wrapper/ExecutionService'; +import { CxConstants } from '../main/wrapper/CxConstants'; + +describe('cxOneAssistEnabled tenant setting', () => { + const baseConfig = new BaseTest(); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('returns true when assist key value is true (lowercase)', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.ASSIST_KEY, 'true']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.cxOneAssistEnabled(); + expect(enabled).toBe(true); + }); + + it('returns true when assist key value is TRUE (uppercase)', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.ASSIST_KEY, 'TRUE']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.cxOneAssistEnabled(); + expect(enabled).toBe(true); + }); + + it('returns false when assist key value is false', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.ASSIST_KEY, 'false']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.cxOneAssistEnabled(); + expect(enabled).toBe(false); + }); + + it('returns false when assist key is missing', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.IDE_SCANS_KEY, 'true']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.cxOneAssistEnabled(); + expect(enabled).toBe(false); + }); + + it('trims whitespace around key/value before evaluating', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[` ${CxConstants.ASSIST_KEY} `, ' true ']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.cxOneAssistEnabled(); + expect(enabled).toBe(true); + }); +}); diff --git a/src/tests/StandaloneEnabledTest.test.ts b/src/tests/StandaloneEnabledTest.test.ts new file mode 100644 index 00000000..0153d442 --- /dev/null +++ b/src/tests/StandaloneEnabledTest.test.ts @@ -0,0 +1,53 @@ +import { CxWrapper } from '../main/wrapper/CxWrapper'; +import { BaseTest } from './BaseTest'; +import { ExecutionService } from '../main/wrapper/ExecutionService'; +import { CxConstants } from '../main/wrapper/CxConstants'; + +describe('standaloneEnabled tenant setting', () => { + const baseConfig = new BaseTest(); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('returns true when standalone tenant flag is true (lowercase)', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.STANDALONE_KEY, 'true']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.standaloneEnabled(); + expect(enabled).toBe(true); + }); + + it('returns true when standalone tenant flag is TRUE (uppercase)', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.STANDALONE_KEY, 'TRUE']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.standaloneEnabled(); + expect(enabled).toBe(true); + }); + + it('returns false when standalone tenant flag is false', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.STANDALONE_KEY, 'false']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.standaloneEnabled(); + expect(enabled).toBe(false); + }); + + it('returns false when standalone tenant flag key is missing', async () => { + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[CxConstants.IDE_SCANS_KEY, 'true']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.standaloneEnabled(); + expect(enabled).toBe(false); + }); + + it('trims whitespace around key and value before evaluating', async () => { + // Simulate raw output map entries with leading/trailing spaces + jest.spyOn(ExecutionService.prototype, 'executeMapTenantOutputCommands') + .mockResolvedValue(new Map([[` ${CxConstants.STANDALONE_KEY} `, ' true ']])); + const wrapper = new CxWrapper(baseConfig); + const enabled = await wrapper.standaloneEnabled(); + expect(enabled).toBe(true); + }); +});