Skip to content

Commit

Permalink
fix: adding new environment when having a project with notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
lazpavel committed Jan 18, 2023
1 parent d535a3e commit 614a273
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 44 deletions.
27 changes: 23 additions & 4 deletions packages/amplify-category-analytics/src/analytics-resource-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,8 @@ export const analyticsPluginAPIPush = async (
pushResponse.reasonMsg = `No Resources of ${resourceProviderServiceName} found for ${AmplifyCategories.ANALYTICS} category`;
} else {
try {
context.parameters.options.yes = true;
context.exeInfo.inputParams = (context.exeInfo.inputParams) || {};
context.exeInfo.inputParams.yes = true;
await invokeAuthPush(context);
await analyticsPush(context);
await analyticsPushYes(context);
} catch (err) {
pushResponse.status = false;
pushResponse.errorCode = PluginAPIError.E_PUSH_FAILED;
Expand All @@ -146,6 +143,27 @@ export const analyticsPluginAPIPush = async (
return pushResponse;
};

/**
* Execute analytics push command with force yes
* @param {Object} context - The amplify context.
*/
export const analyticsPushYes = async (context: $TSContext): Promise<void> => {
const exeInfoClone = { ...context?.exeInfo };
const parametersClone = { ...context?.parameters };
try {
context.exeInfo = (context.exeInfo) || {};
context.exeInfo.inputParams = (context.exeInfo.inputParams) || {};
context.exeInfo.inputParams.yes = true; // force yes to avoid prompts
context.parameters = (context.parameters) || {};
context.parameters.options.yes = true;
context.parameters.first = undefined;
await analyticsPush(context);
} finally {
context.exeInfo = exeInfoClone;
context.parameters = parametersClone;
}
};

/**
* Invoke post push hook for all dependent plugins ( e.g. notifications )
*/
Expand All @@ -171,6 +189,7 @@ export const analyticsPluginAPIPostPush = async (context: $TSContext) : Promise<
pinpointNotificationsMeta.Id = analyticsResource.output.Id;
pinpointNotificationsMeta.Region = analyticsResource.output.Region;
// Update Notifications output and channel metadata
pinpointNotificationsMeta.output = pinpointNotificationsMeta.output || {};
pinpointNotificationsMeta.output.Id = analyticsResource.output.Id;
pinpointNotificationsMeta.output.regulatedResourceName = analyticsResource.resourceName; // without the env suffix
pinpointNotificationsMeta.output.region = analyticsResource.output.Region;
Expand Down
6 changes: 5 additions & 1 deletion packages/amplify-category-auth/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,17 +529,21 @@ async function isSMSWorkflowEnabled(context, resourceName) {
*/
const authPushYes = async context => {
const exeInfoClone = { ...context?.exeInfo };
const parametersClone = { ...context?.parameters };
try {
context.exeInfo = (context.exeInfo) || {};
context.exeInfo.inputParams = (context.exeInfo.inputParams) || {};
context.exeInfo.inputParams.yes = true; // force yes to avoid prompts
context.parameters = (context.parameters) || {};
context.parameters.options.yes = true;
context.parameters.first = undefined;
await authRunPush(context);
} finally {
context.exeInfo = exeInfoClone;
context.parameters = parametersClone;
}
};


module.exports = {
externalAuthEnable,
migrateAuthResource,
Expand Down
4 changes: 2 additions & 2 deletions packages/amplify-category-notifications/src/channel-sms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const enable = async (context:$TSContext):Promise<$TSAny> => {
return buildPinpointChannelResponseSuccess(ChannelAction.ENABLE, deploymentType, channelName, data.SMSChannelResponse);
} catch (e) {
spinner.stop();
throw new AmplifyFault('NotificationsChannelEmailFault', {
throw new AmplifyFault('NotificationsChannelSmsFault', {
message: `Failed to enable the ${channelName} channel.`,
}, e);
}
Expand Down Expand Up @@ -81,7 +81,7 @@ export const disable = async (context: $TSContext): Promise<$TSAny> => {
return buildPinpointChannelResponseSuccess(ChannelAction.DISABLE, deploymentType, channelName, data.SMSChannelResponse);
} catch (e) {
spinner.fail(`Failed to disable the ${channelName} channel.`);
throw new AmplifyFault('NotificationsChannelEmailFault', {
throw new AmplifyFault('NotificationsChannelSmsFault', {
message: `Failed to disable the ${channelName} channel.`,
}, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { $TSContext, AmplifyError } from 'amplify-cli-core';
import { printer, prompter } from 'amplify-prompts';
import {
ensurePinpointApp, isPinpointAppDeployed, isPinpointDeploymentRequired, pushAuthAndAnalyticsPinpointResources,
ensurePinpointApp, isPinpointAppDeployed,
} from '../../pinpoint-helper';
import { enableChannel } from '../../notifications-manager';

Expand All @@ -11,14 +11,12 @@ import { writeData } from '../../multi-env-manager-utils';
import {
viewShowAllChannelsEnabledWarning,
viewShowDeferredModeInstructions,
viewShowInlineModeInstructionsFail,
viewShowInlineModeInstructionsStart,
viewShowInlineModeInstructionsStop,
} from '../../display-utils';
import {
getChannelViewName, getChannelNameFromView, getAvailableChannels, isValidChannel, isChannelDeploymentDeferred,
} from '../../notifications-backend-cfg-channel-api';
import { checkMigratedFromMobileHub, getDisabledChannelsFromAmplifyMeta } from '../../notifications-amplify-meta-api';
import { checkAndCreatePinpointApp } from '../../multi-env-manager';

export const name = 'add';
export const alias = 'enable';
Expand Down Expand Up @@ -72,29 +70,11 @@ export const run = async (context: $TSContext): Promise<$TSContext> => {

channelName = await viewQuestionAskNotificationChannelToBeEnabled(availableChannels, disabledChannels, channelName);
if (isValidChannel(channelName)) {
let pinpointAppStatus = await ensurePinpointApp(context, undefined);
context = pinpointAppStatus.context;
// In-line deployment now requires an amplify-push to create the Pinpoint resource
if (isPinpointDeploymentRequired(channelName, pinpointAppStatus)) {
await viewShowInlineModeInstructionsStart(channelName);
try {
// updates the pinpoint app status
pinpointAppStatus = await pushAuthAndAnalyticsPinpointResources(context, pinpointAppStatus);
pinpointAppStatus = await ensurePinpointApp(context, pinpointAppStatus);
await viewShowInlineModeInstructionsStop(channelName);
} catch (err) {
// if the push fails, the user will be prompted to deploy the resource manually
await viewShowInlineModeInstructionsFail(channelName, err);
throw new AmplifyError('DeploymentError', {
message: 'Failed to deploy Auth and Pinpoint resources.',
resolution: 'Deploy the Auth and Pinpoint resources manually.',
}, err);
}
context = pinpointAppStatus.context;
}
const pinpointAppStatus = await checkAndCreatePinpointApp(context, channelName, await ensurePinpointApp(context, undefined));

// enable the channel
if (isPinpointAppDeployed(pinpointAppStatus.status) || isChannelDeploymentDeferred(channelName)) {
const channelAPIResponse : IChannelAPIResponse|undefined = await enableChannel(context, channelName);
const channelAPIResponse = await enableChannel(context, channelName);
await writeData(context, channelAPIResponse);
if (channelAPIResponse?.deploymentType === ChannelConfigDeploymentType.DEFERRED) {
viewShowDeferredModeInstructions();
Expand Down
26 changes: 14 additions & 12 deletions packages/amplify-category-notifications/src/multi-env-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
getPinpointAppFromAnalyticsOutput,
getPinpointAppStatus,
getPinpointClient,
isPinpointAppDeployed,
IPinpointAppStatus,
isPinpointDeploymentRequired,
pushAuthAndAnalyticsPinpointResources,
scanCategoryMetaForPinpoint,
Expand All @@ -21,7 +21,7 @@ import { ICategoryMeta } from './notifications-amplify-meta-types';
import { PinpointName } from './pinpoint-name';
import { writeData } from './multi-env-manager-utils';
import { viewShowInlineModeInstructionsFail, viewShowInlineModeInstructionsStart, viewShowInlineModeInstructionsStop } from './display-utils';
import { getAvailableChannels, isChannelDeploymentDeferred } from './notifications-backend-cfg-channel-api';
import { getAvailableChannels } from './notifications-backend-cfg-channel-api';

/**
* Create Pinpoint resource in Analytics, Create Pinpoint Meta for Notifications category and
Expand Down Expand Up @@ -338,15 +338,18 @@ const getEnabledDisabledChannelsFromConfigAndMeta = (
* @param channelName channel to be enabled
* @param pinpointAppStatus Deployment status of the Pinpoint resource
*/
export const checkAndCreatePinpointApp = async (context: $TSContext, channelName: string, pinpointAppStatus: $TSAny) : Promise<$TSAny> => {
export const checkAndCreatePinpointApp = async (
context: $TSContext,
channelName: string,
pinpointAppStatus: IPinpointAppStatus,
) : Promise<IPinpointAppStatus> => {
let updatedPinpointAppStatus = pinpointAppStatus;
if (isPinpointDeploymentRequired(channelName, pinpointAppStatus)) {
await viewShowInlineModeInstructionsStart(channelName);
try {
// updates the pinpoint app status
// eslint-disable-next-line no-param-reassign
pinpointAppStatus = await pushAuthAndAnalyticsPinpointResources(context, pinpointAppStatus);
// eslint-disable-next-line no-param-reassign
pinpointAppStatus = await ensurePinpointApp(context, pinpointAppStatus);
updatedPinpointAppStatus = await pushAuthAndAnalyticsPinpointResources(context, pinpointAppStatus);
updatedPinpointAppStatus = await ensurePinpointApp(context, updatedPinpointAppStatus);
await viewShowInlineModeInstructionsStop(channelName);
} catch (err) {
// if the push fails, the user will be prompted to deploy the resource manually
Expand All @@ -360,13 +363,10 @@ export const checkAndCreatePinpointApp = async (context: $TSContext, channelName
context = pinpointAppStatus.context;
}

if (isPinpointAppDeployed(pinpointAppStatus.status) || isChannelDeploymentDeferred(channelName)) {
const channelAPIResponse = await notificationManager.enableChannel(context, channelName);
await writeData(context, channelAPIResponse);
}
return updatedPinpointAppStatus;
};

const pushChanges = async (context: $TSContext, pinpointNotificationsMeta: $TSAny):Promise<Array<IChannelAPIResponse|undefined>> => {
const pushChanges = async (context: $TSContext, pinpointNotificationsMeta: $TSAny): Promise<Array<IChannelAPIResponse|undefined>> => {
let pinpointInputParams : $TSAny;

if (context?.exeInfo?.inputParams?.categories?.[AmplifyCategories.NOTIFICATIONS]?.[AmplifySupportedService.PINPOINT]
Expand Down Expand Up @@ -399,10 +399,12 @@ const pushChanges = async (context: $TSContext, pinpointNotificationsMeta: $TSAn
);

for (const channel of channelsToEnable) {
await checkAndCreatePinpointApp(context, channel, pinpointAppStatus);
results.push(await notificationManager.enableChannel(context, channel));
}

for (const channel of channelsToDisable) {
await checkAndCreatePinpointApp(context, channel, pinpointAppStatus);
results.push(await notificationManager.disableChannel(context, channel));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
addNotificationChannel,
amplifyStatus,
createNewProjectDir,
deleteProject,
deleteProjectDir,
getAppId,
initJSProjectWithProfile,
} from '@aws-amplify/amplify-e2e-core';
import { addEnvironment, listEnvironment } from '../environment/env';
import {
getShortId,
} from '../import-helpers';

describe('notification category test - SMS', () => {
const testChannel = 'SMS';
const testChannelSelection = 'SMS';
const projectPrefix = `notification${testChannel}`.substring(0, 19);
const projectSettings = {
name: projectPrefix,
disableAmplifyAppCreation: false,
};

let projectRoot: string;

beforeEach(async () => {
projectRoot = await createNewProjectDir(projectPrefix);
});

afterEach(async () => {
await deleteProject(projectRoot);
deleteProjectDir(projectRoot);
});

// inline channels
it(`should add and remove the ${testChannel} channel correctly when no pinpoint is configured`, async () => {
await initJSProjectWithProfile(projectRoot, projectSettings);

// add sms channel
const settings = { resourceName: `${projectPrefix}${getShortId()}` };
await addNotificationChannel(projectRoot, settings, testChannelSelection);

const appId = getAppId(projectRoot);
expect(appId).toBeDefined();

// expect that Notifications, Analytics, and Auth categories are shown
await amplifyStatus(projectRoot, 'Notifications');
await amplifyStatus(projectRoot, 'Analytics');
await amplifyStatus(projectRoot, 'Auth');

await addEnvironment(projectRoot, { envName: 'prod' });
await listEnvironment(projectRoot, { numEnv: 2 });

// expect that Notifications, Analytics, and Auth categories are shown in the new env
await amplifyStatus(projectRoot, 'Notifications');
await amplifyStatus(projectRoot, 'Analytics');
await amplifyStatus(projectRoot, 'Auth');
});
});

0 comments on commit 614a273

Please sign in to comment.