Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: in app messaging notification #11067

Merged
merged 29 commits into from
Oct 13, 2022
Merged

feat: in app messaging notification #11067

merged 29 commits into from
Oct 13, 2022

Conversation

lazpavel
Copy link
Contributor

@lazpavel lazpavel commented Sep 26, 2022

Description of changes

  • in app messaging feature
    -- adds a new channel for in app messaging
    -- changes the place for pinpoint resource to always stay in the analytics category
    -- ensures auth and analytics are added as a pre-requirement for the notifications channels
    -- notification channels re-use the pinpoint resource from the analytics category

Description of how you validated changes

  • manual tests
  • cloud-e2e pass
  • e2e tests and unit test added for in-app-messaging channel

Checklist

  • PR description included
  • yarn test passes
  • Tests are changed or added
  • Relevant documentation is changed or added (and PR referenced)
  • New AWS SDK calls or CloudFormation actions have been added to relevant test and service IAM policies

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@lgtm-com
Copy link

lgtm-com bot commented Sep 26, 2022

This pull request introduces 7 alerts when merging eb3c10e into 6f287b1 - view on LGTM.com

new alerts:

  • 4 for Unused variable, import, function or class
  • 3 for Useless conditional

@lgtm-com
Copy link

lgtm-com bot commented Sep 26, 2022

This pull request introduces 7 alerts when merging de2a2d7 into 6f287b1 - view on LGTM.com

new alerts:

  • 4 for Unused variable, import, function or class
  • 3 for Useless conditional

@lazpavel lazpavel changed the title feat: in app messaging initial commit feat: in app messaging notification Sep 26, 2022
@lgtm-com
Copy link

lgtm-com bot commented Sep 26, 2022

This pull request introduces 4 alerts when merging de5d49b into f06c821 - view on LGTM.com

new alerts:

  • 3 for Useless conditional
  • 1 for Unused variable, import, function or class

@lazpavel lazpavel marked this pull request as ready for review September 26, 2022 20:44
@lazpavel lazpavel requested a review from a team as a code owner September 26, 2022 20:44
@lgtm-com
Copy link

lgtm-com bot commented Sep 27, 2022

This pull request introduces 1 alert when merging a77f14c into f06c821 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Sep 27, 2022

This pull request introduces 1 alert when merging addef6b into f06c821 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Sep 27, 2022

This pull request introduces 1 alert when merging 46a1675 into f06c821 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

Copy link
Member

@edwardfoyle edwardfoyle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't go through this in depth enough to really get the bigger picture so most of my comments are relatively localized

"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should scope this policy better

packages/amplify-category-analytics/src/index.ts Outdated Show resolved Hide resolved
packages/amplify-category-analytics/src/index.ts Outdated Show resolved Hide resolved
packages/amplify-category-auth/src/index.js Outdated Show resolved Hide resolved
@@ -29,7 +29,8 @@
"inquirer": "^7.3.3",
"lodash": "^4.17.21",
"ora": "^4.0.3",
"promise-sequential": "^1.1.1"
"promise-sequential": "^1.1.1",
"chalk": "^4.1.1"
},
"devDependencies": {
"mockirer": "^2.0.1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: see if we can replace this : https://www.npmjs.com/package/mockirer . package seems not maintained

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably should have a separate task to get rid of all inquirer references, this will allow us to remove the mockirer in the same step

import {
addSMSNotification,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the only e2e test we have for notifications? if so, what concepts do you think should be verified (what's a good e2e test for this PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only one, it used to test just SMS channel and now was changed to do a push/pull for SMS and In-App Messaging channels.
not sure what can we do with a e2e test, but we should test that creating resources with older version and then upgrading to the new implementation and updating/adding new channels work as expected. One of the main changes in this PR is that notifications and analytics no longer create 2 distinct pinpoint resources but whoever will share the same resource, also pinpont resource is always managed by the analytics category so adding a notification category will also add a analytics category with the pinpoint resource.

For the above we should test various combinations for when adding/updating analytics/notifications channgels are mixed and matched with old and new implementation

Other things that could be tested are update and delete for the notifications channels (this tests only tests add)

@lgtm-com
Copy link

lgtm-com bot commented Sep 29, 2022

This pull request introduces 2 alerts when merging 915acd1 into e4593c4 - view on LGTM.com

new alerts:

  • 2 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Sep 30, 2022

This pull request introduces 2 alerts when merging 50fa878 into e4593c4 - view on LGTM.com

new alerts:

  • 2 for Unused variable, import, function or class

@codecov-commenter
Copy link

codecov-commenter commented Sep 30, 2022

Codecov Report

Merging #11067 (84444b7) into dev (4a4fee8) will decrease coverage by 0.31%.
The diff coverage is 47.90%.

@@            Coverage Diff             @@
##              dev   #11067      +/-   ##
==========================================
- Coverage   49.64%   49.32%   -0.32%     
==========================================
  Files         666      676      +10     
  Lines       31923    32628     +705     
  Branches     6500     6664     +164     
==========================================
+ Hits        15848    16094     +246     
- Misses      14595    15051     +456     
- Partials     1480     1483       +3     
Impacted Files Coverage Δ
...s/amplify-cli-core/src/errors/amplify-exception.ts 65.21% <ø> (ø)
packages/amplify-category-auth/src/index.js 16.27% <14.28%> (-0.05%) ⬇️
...otifications/src/notifications-amplify-meta-api.ts 16.66% <16.66%> (ø)
.../amplify-category-notifications/src/auth-helper.ts 21.83% <20.00%> (ø)
...y-provider-awscloudformation/src/push-resources.ts 19.58% <20.00%> (+<0.01%) ⬆️
...notifications/src/notifications-backend-cfg-api.ts 20.58% <20.58%> (ø)
...lify-category-notifications/src/pinpoint-helper.ts 18.51% <21.51%> (ø)
...category-notifications/src/apns-cert-p12decoder.ts 16.66% <25.00%> (+1.74%) ⬆️
...tions/src/notifications-backend-cfg-channel-api.ts 29.34% <29.34%> (ø)
...amplify-cli-core/src/state-manager/stateManager.ts 37.56% <37.50%> (-0.01%) ⬇️
... and 22 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@lgtm-com
Copy link

lgtm-com bot commented Sep 30, 2022

This pull request introduces 1 alert when merging 104a409 into e4593c4 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Oct 5, 2022

This pull request introduces 3 alerts when merging 6c65379 into 85696bd - view on LGTM.com

new alerts:

  • 3 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Oct 6, 2022

This pull request introduces 3 alerts when merging c6a1ac6 into c454ae7 - view on LGTM.com

new alerts:

  • 3 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Oct 6, 2022

This pull request introduces 1 alert when merging 6cf7029 into c09e541 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Oct 6, 2022

This pull request introduces 1 alert when merging 95c47e3 into 9f3bba7 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

Copy link
Member

@edwardfoyle edwardfoyle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added some comments but I don't think any of them are merge blockers

* @returns push command response
*/
export const authPush = async (context: $TSContext): Promise<$TSAny> => {
const { run } = await import(path.join('.', name, 'push'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we turn this into a normal import?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in follow-up PR: #11158

* Execute auth Push command with force yes
* @param {Object} context - The amplify context.
*/
const authPush = async context => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to authPushYes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in follow-up PR: #11158

Comment on lines +529 to +530
const commandPath = path.normalize(path.join(__dirname, 'commands', category, 'push'));
const commandModule = await import(commandPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static import?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in follow-up PR: #11158

const commandModule = await import(commandPath);
context.exeInfo = (context.exeInfo) || {};
context.exeInfo.inputParams = (context.exeInfo.inputParams) || {};
context.exeInfo.inputParams.yes = true; // force yes to avoid prompts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this have any downstream impact on other prompts in the original flow? It could also lead to some inconsistencies because amplify-prompter looks for the --yes flag in process.argv not in context

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not in this particular case, but it is injecting side-effects that could affect future implementation that look at this parameters after this call

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed restoring the original value after push

Comment on lines +27 to +30
export const run = async (context: $TSContext): Promise<$TSAny> => {
try {
const { run } = await import(path.join('.', name, context.parameters.first));
return run(context);
const { run: authRun } = await import(path.join('.', name, context.parameters.first));
return authRun(context);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about leaving this as the only function exported by this file and add an optional second parameter to override the action:

export const run = async (context: $TSContext, actionOverride?: 'push'): Promise<$TSAny> => {
  try {
    const { run: authRun } = await import(path.join('.', name, actionOverride ?? context.parameters.first));
    return authRun(context);

Comment on lines +63 to +66
updateApnsChannel: jest.fn(() => ({
promise: () => new Promise((resolve, __) => {
resolve(mockPinpointResponseData);
}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit all of these could simplify to:

Suggested change
updateApnsChannel: jest.fn(() => ({
promise: () => new Promise((resolve, __) => {
resolve(mockPinpointResponseData);
}),
updateApnsChannel: jest.fn().mockReturnValue({
promise: jest.fn().mockResolvedValue(mockPinpointResponseData),
}),

Comment on lines +12 to +22
const mockInquirer = (answers : $TSAny): $TSAny => {
(inquirer as any).prompt = async (prompts:$TSAny):Promise<$TSAny> => {
[].concat(prompts).forEach(prompt => {
if (!((prompt as unknown as any).name in answers) && typeof (prompt as unknown as any).default !== 'undefined') {
// eslint-disable-next-line no-param-reassign
answers[(prompt as unknown as any).name] = (prompt as unknown as any).default;
}
});
return answers;
};
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use jest mocks instead of all this reassigning and type asserting?

* Display status that Auth and Pinpoint resources are being deployed to the cloud
*/
export const viewShowInlineModeInstructionsStart = async (channelName: string): Promise<void> => {
spinner.start(`Channel ${channelName} requires a Pinpoint resource in the cloud. Proceeding to deploy Auth and Pinpoint resources...`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably not worth a bunch of rework at this point but maybe a TODO or backlog item is appropriate

return buildPinpointChannelResponseSuccess(ChannelAction.ENABLE, deploymentType, channelName, data.SMSChannelResponse);
} catch (e) {
spinner.stop();
throw amplifyFaultWithTroubleshootingLink('NotificationsChannelEmailFault', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should pass the underlying stack into the amplfiy fault as well (applies to lots of places). Not sure how feasible it is to update all of them

Copy link
Contributor

@akshbhu akshbhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits otherwise LGTM!!

Region: pinpointMeta.Region,
}
: undefined;
stateManager.setTeamProviderInfo(projectPath, teamProviderInfo);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use envManager here to populate tpi data

break;
}
default: {
throw Error(`Channel ${notificationChannel} is not supported on Analytics resource`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw Error(`Channel ${notificationChannel} is not supported on Analytics resource`);
throw new AmplifyError('ConfigurationError', {
message: `Channel ${notificationChannel} is not supported on Analytics resource`,
resolution: 'Use one of the supported channels',

@@ -79,7 +88,7 @@ export const getPermissionPolicies = async (context: $TSContext, resourceOpsMapp
printer.warn(`Could not get policies for ${category}: ${resourceName}`);
throw e;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We can throw Amplify Error here

* @returns Resource in Notifications category (IAmplifyResource type)
*/
export const invokeAuthPush = async (context: $TSContext): Promise<void> => {
await context.amplify.invokePluginMethod(context, AmplifyCategories.AUTH, undefined, 'authPluginAPIPush', [context]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think we can directly call context.amplify directly

context.exeInfo.amplifyMeta = await toggleNotificationsChannelAppMeta(channelAPIResponse.channel, false,
context.exeInfo.amplifyMeta);
break;
case ChannelAction.CONFIGURE:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can remove the case if the operation is noop

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should break out instead of printing an error

try {
deployedBackendConfig = (stateManager.getCurrentBackendConfig()) || undefined;
} catch (e) {
appInitialized = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to throw error here if file operation fails ?

@@ -445,6 +447,13 @@ export const run = async (context: $TSContext, resourceDefinition: $TSObject, re
await context.amplify.updateamplifyMetaAfterPush(resources);
}

// Generate frontend resources for any notifications channels enabled on analytics resources.
const analyticsResources = resourcesToBeCreated.filter((r: { category: string; }) => r.category === AmplifyCategories.ANALYTICS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const analyticsResources = resourcesToBeCreated.filter((r: { category: string; }) => r.category === AmplifyCategories.ANALYTICS);
const analyticsResources = resourcesToBeCreated.filter((resource: { category: string; }) => r.category === AmplifyCategories.ANALYTICS);

@lazpavel
Copy link
Contributor Author

going to address the remaining nits as part of the analytics migration PR: #11158

@lazpavel lazpavel merged commit 0c70a05 into aws-amplify:dev Oct 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants