Skip to content

Commit

Permalink
fix(odata-service-inquirer): Apply additional messages to service s…
Browse files Browse the repository at this point in the history
…election prompt (#2693)

* Apply additional messages to service selection prompt

#2692

* Linting auto fix commit

* Adds tests to cover `additionalMessages` option

* Adds cset

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
IainSAP and github-actions[bot] authored Dec 12, 2024
1 parent 3d5933b commit ec1dc17
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/swift-impalas-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sap-ux/odata-service-inquirer': patch
---

Fix `additionalMessages` option not applied for system service prompt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ export function getAbapOnBTPSystemQuestions(
}

// Service selection prompt
questions.push(...getSystemServiceQuestion(connectValidator, abapOnBtpPromptNamespace, promptOptions));
questions.push(
...getSystemServiceQuestion(connectValidator, abapOnBtpPromptNamespace, promptOptions?.serviceSelection)
);
return questions;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ export function getAbapOnPremQuestions(
requiredOdataVersion
);

questions.push(...getSystemServiceQuestion(connectValidator, abapOnPremPromptNamespace, promptOptions));
questions.push(
...getSystemServiceQuestion(connectValidator, abapOnPremPromptNamespace, promptOptions?.serviceSelection)
);

return questions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import type { CatalogService, ODataVersion } from '@sap-ux/axios-extension';
import type { Destination } from '@sap-ux/btp-utils';
import { hostEnvironment } from '@sap-ux/fiori-generator-shared';
import {
type CommonPromptOptions,
ERROR_TYPE,
ErrorHandler,
extendWithOptions,
searchChoices,
type ListQuestion,
type ValidationLink
type ValidationLink,
type YUIQuestion
} from '@sap-ux/inquirer-common';
import { OdataVersion } from '@sap-ux/odata-service-writer';
import type { Answers, ListChoiceOptions, Question } from 'inquirer';
import { t } from '../../../../i18n';
import type { OdataServicePromptOptions } from '../../../../types';
import type { OdataServicePromptOptions, ServiceSelectionPromptOptions } from '../../../../types';
import { promptNames } from '../../../../types';
import { getDefaultChoiceIndex, getPromptHostEnvironment } from '../../../../utils';
import { getDefaultChoiceIndex, getPromptHostEnvironment, PromptState } from '../../../../utils';
import type { ConnectionValidator } from '../../../connectionValidator';
import LoggerHelper from '../../../logger-helper';
import { errorHandler } from '../../../prompt-helpers';
Expand Down Expand Up @@ -45,20 +47,21 @@ const cliServicePromptName = 'cliServiceSelection';
export function getSystemServiceQuestion(
connectValidator: ConnectionValidator,
promptNamespace: string,
promptOptions?: OdataServicePromptOptions
promptOptions?: ServiceSelectionPromptOptions
): Question<ServiceAnswer>[] {
let serviceChoices: ListChoiceOptions<ServiceAnswer>[] = [];
// Prevent re-requesting services repeatedly by only requesting them once and when the system or client is changed
let previousSystemUrl: string | undefined;
let previousClient: string | undefined;
let previousService: ServiceAnswer | undefined;
const requiredOdataVersion = promptOptions?.serviceSelection?.requiredOdataVersion;
const requiredOdataVersion = promptOptions?.requiredOdataVersion;
const serviceSelectionPromptName = `${promptNamespace}:${promptNames.serviceSelection}`;

const systemServiceQuestion = {
let systemServiceQuestion = {
when: (): boolean =>
connectValidator.validity.authenticated || connectValidator.validity.authRequired === false,
name: `${promptNamespace}:${promptNames.serviceSelection}`,
type: promptOptions?.serviceSelection?.useAutoComplete ? 'autocomplete' : 'list',
name: serviceSelectionPromptName,
type: promptOptions?.useAutoComplete ? 'autocomplete' : 'list',
message: () => getSelectedServiceLabel(connectValidator.connectedUserName),
guiOptions: {
breadcrumb: t('prompts.systemService.breadcrumb'),
Expand Down Expand Up @@ -124,7 +127,7 @@ export function getSystemServiceQuestion(
): Promise<string | boolean | ValidationLink> => {
let serviceAnswer = service as ServiceAnswer;
// Autocomplete passes the entire choice object as the answer, so we need to extract the value
if (promptOptions?.serviceSelection?.useAutoComplete && (service as ListChoiceOptions).value) {
if (promptOptions?.useAutoComplete && (service as ListChoiceOptions).value) {
serviceAnswer = (service as ListChoiceOptions).value;
}

Expand All @@ -142,12 +145,24 @@ export function getSystemServiceQuestion(
}
return true;
}
} as ListQuestion<ServiceAnswer>;
} as Question<ServiceAnswer>;

// Add additional messages to prompts if specified in the prompt options
if (promptOptions?.additionalMessages) {
const promptOptsToApply: Record<string, CommonPromptOptions> = {
[serviceSelectionPromptName]: { additionalMessages: promptOptions.additionalMessages }
};
systemServiceQuestion = extendWithOptions(
[systemServiceQuestion] as YUIQuestion[],
promptOptsToApply,
PromptState.odataService
)[0];
}

const questions: Question<ServiceAnswer>[] = [systemServiceQuestion];

// Only for CLI use as `list` prompt validation does not run on CLI unless autocomplete plugin is used
if (getPromptHostEnvironment() === hostEnvironment.cli && !promptOptions?.serviceSelection?.useAutoComplete) {
if (getPromptHostEnvironment() === hostEnvironment.cli && !promptOptions?.useAutoComplete) {
questions.push({
when: async (answers: Answers): Promise<boolean> => {
const selectedService = answers?.[`${promptNamespace}:${promptNames.serviceSelection}`];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export async function getServiceDetails(
PromptState.odataService.annotations = serviceResult?.annotations;
PromptState.odataService.metadata = serviceResult?.metadata;
PromptState.odataService.odataVersion =
version ?? service.serviceODataVersion === ODataVersion.v2 ? OdataVersion.v2 : OdataVersion.v4;
version ?? (service.serviceODataVersion === ODataVersion.v2 ? OdataVersion.v2 : OdataVersion.v4);
PromptState.odataService.servicePath = service.servicePath;
PromptState.odataService.origin = origin;
PromptState.odataService.sapClient = connectionValidator.validatedClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ export async function getSystemSelectionQuestions(
// In future, make the service prompt optional by wrapping in condition `[promptOptions?.serviceSelection?.hide]`
questions.push(
...withCondition(
getSystemServiceQuestion(connectValidator, systemSelectionPromptNamespace, promptOptions) as Question[],
getSystemServiceQuestion(
connectValidator,
systemSelectionPromptNamespace,
promptOptions?.serviceSelection
) as Question[],
(answers: Answers) => (answers as SystemSelectionAnswers).systemSelection?.type !== 'newSystemChoice'
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import type {
V4CatalogService
} from '@sap-ux/axios-extension';
import { ODataVersion, ServiceType } from '@sap-ux/axios-extension';
import type { ListQuestion } from '@sap-ux/inquirer-common';
import type { ListQuestion, PromptSeverityMessage } from '@sap-ux/inquirer-common';
import { OdataVersion } from '@sap-ux/odata-service-writer';
import type { ChoiceOptions } from 'inquirer';
import type { Answers, ChoiceOptions } from 'inquirer';
import type { AutocompleteQuestionOptions } from 'inquirer-autocomplete-prompt';
import { initI18nOdataServiceInquirer, t } from '../../../../../src/i18n';
import { ConnectionValidator } from '../../../../../src/prompts/connectionValidator';
import type { ServiceAnswer } from '../../../../../src/prompts/datasources/sap-system/service-selection';
import { getSystemServiceQuestion } from '../../../../../src/prompts/datasources/sap-system/service-selection';
import * as serviceHelpers from '../../../../../src/prompts/datasources/sap-system/service-selection/service-helper';
import LoggerHelper from '../../../../../src/prompts/logger-helper';
import { promptNames } from '../../../../../src/types';
import { OdataServiceAnswers, promptNames } from '../../../../../src/types';
import * as utils from '../../../../../src/utils';
import { PromptState } from '../../../../../src/utils';
import { hostEnvironment } from '@sap-ux/fiori-generator-shared';
Expand Down Expand Up @@ -181,7 +181,7 @@ describe('Test new system prompt', () => {

// The services choices should be restricted to the specified required odata version
systemServiceQuestions = getSystemServiceQuestion(connectValidator, promptNamespace, {
serviceSelection: { requiredOdataVersion: OdataVersion.v2 }
requiredOdataVersion: OdataVersion.v2
});
serviceSelectionPrompt = systemServiceQuestions.find(
(question) => question.name === `${promptNamespace}:${promptNames.serviceSelection}`
Expand Down Expand Up @@ -219,7 +219,7 @@ describe('Test new system prompt', () => {

// No odata version specific (`requiredOdataVersion`) service available
systemServiceQuestions = getSystemServiceQuestion(connectValidator, promptNamespace, {
serviceSelection: { requiredOdataVersion: OdataVersion.v2 }
requiredOdataVersion: OdataVersion.v2
});
serviceSelectionPrompt = systemServiceQuestions.find(
(question) => question.name === `${promptNamespace}:${promptNames.serviceSelection}`
Expand Down Expand Up @@ -474,7 +474,7 @@ describe('Test new system prompt', () => {
}
};
const systemServiceQuestions = getSystemServiceQuestion(connectValidator, promptNamespace, {
serviceSelection: { useAutoComplete: true }
useAutoComplete: true
});
const serviceSelectionPrompt = systemServiceQuestions.find(
(question) => question.name === `${promptNamespace}:${promptNames.serviceSelection}`
Expand Down Expand Up @@ -505,6 +505,34 @@ describe('Test new system prompt', () => {
expect(getServiceDetailsSpy).toHaveBeenCalledWith(flightChoice?.value, connectionValidatorMock, undefined);
});

test('Should apply `additionalMessages` prompt option', async () => {
const connectValidator = new ConnectionValidator();
connectionValidatorMock.catalogs = {
[ODataVersion.v2]: {
listServices: jest.fn().mockResolvedValue([serviceV2a])
},
[ODataVersion.v4]: {
listServices: jest.fn().mockResolvedValue([])
}
};
const customAdditionalMsgs: PromptSeverityMessage = (input: unknown, answers: Answers | undefined) => {
return { message: 'Custom message', severity: Severity.information };
};
const serviceSelectionPromptOptions = { additionalMessages: customAdditionalMsgs };
const systemServiceQuestions = getSystemServiceQuestion(
connectValidator,
promptNamespace,
serviceSelectionPromptOptions
);
const serviceSelectionPrompt = systemServiceQuestions.find(
(question) => question.name === `${promptNamespace}:${promptNames.serviceSelection}`
);
expect(await ((serviceSelectionPrompt as ListQuestion)?.additionalMessages as Function)()).toEqual({
message: 'Custom message',
severity: Severity.information
});
});

test('Should show and log error message when service validation fails', async () => {
const connectValidator = new ConnectionValidator();
connectionValidatorMock.catalogs = {
Expand Down

0 comments on commit ec1dc17

Please sign in to comment.