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

Refactor AddPersonalBankAccount to use Form #11076

Merged
merged 8 commits into from
Oct 7, 2022

Conversation

youssef-lr
Copy link
Contributor

@youssef-lr youssef-lr commented Sep 17, 2022

Details

cc @luacmartins

Fixed Issues

$ #9577

Tests and QA

  • Navigate to Settings -> Payments -> Add Payment Method -> Bank Account
  • Go through the Plaid process to add an account
  • Select an account from the dropdown
  • Keep password field empty and submit the form: verify Password is a required field error is show.
  • Enter an invalid password: Verify that an Incorrect password is shown above the submit button.
  • Enter your valid password and verify the account gets added succesfully.

PR Review Checklist

Contributor (PR Author) Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR.

PR Reviewer Checklist

The Contributor+ will copy/paste it into a new comment and complete it after the author checklist is completed

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

QA Steps

  • Verify that no errors appear in the JS console

Screenshots

Web

Screen.Recording.2022-09-22.at.22.38.24.mov

Mobile Web

Desktop

iOS

Android

@melvin-bot
Copy link

melvin-bot bot commented Sep 17, 2022

Hey! I see that you made changes to our Form component. Make sure to update the docs in FORMS.md accordingly. Cheers!

@youssef-lr youssef-lr self-assigned this Sep 18, 2022
@youssef-lr youssef-lr marked this pull request as ready for review September 22, 2022 21:40
@youssef-lr youssef-lr requested a review from a team as a code owner September 22, 2022 21:40
@melvin-bot melvin-bot bot requested review from dangrous and removed request for a team September 22, 2022 21:41
@@ -163,7 +122,14 @@ class AddPersonalBankAccountPage extends React.Component {
</FixedFooter>
</>
) : (
<FormScrollView>
<Form
formID={ONYXKEYS.PERSONAL_BANK_ACCOUNT}
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this already exists, but I'm hazy on how the form IDs work - would it make more sense to add a new ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT to separate it out from the key for the value itself?

Otherwise this is looking good when I skimmed; I will look closer and also test tomorrow!

Copy link
Contributor Author

@youssef-lr youssef-lr Sep 23, 2022

Choose a reason for hiding this comment

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

Yes one of the reasons I didn't wanna move the key under FORMS is that there are other external PRs ongoing that touch the same keys so we figured out that we'll keep keys as they are now and then once everything is merged we'll move the keys under the FORMS key. But I'm gonna double check in case this specific key is only used here then I can move it under FORMS. Good eye!

@youssef-lr youssef-lr mentioned this pull request Sep 23, 2022
93 tasks
@dangrous
Copy link
Contributor

Hey so I tested this on web and it seems good EXCEPT when I put in an incorrect password, there's no feedback - the button acts as if it's clicked but immediately returns to the same text, no error visible. Putting in the correct password works as expected.

Is there any other branch I need to check out locally other than this one (e.g. something in Web-E or otherwise) to make this work? Let me know!

@youssef-lr
Copy link
Contributor Author

Oh it looks like I need to refactor Form.js in this PR to take into account the new errors key that gets returned from the API, previously we returned error.

@luacmartins luacmartins self-requested a review September 26, 2022 15:03
@youssef-lr
Copy link
Contributor Author

Updated!

dangrous
dangrous previously approved these changes Sep 29, 2022
Copy link
Contributor

@dangrous dangrous left a comment

Choose a reason for hiding this comment

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

This looks good, and errors work now! Can you add testing steps into the overview (just write out what the video shows)? Then I can fill out that other checklist and get this merged, unless @luacmartins has any further notes.

Thanks!

Copy link
Contributor

@luacmartins luacmartins left a comment

Choose a reason for hiding this comment

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

Looking good. Couple of minor comments.

*/
validate() {
validate(values) {
const errors = {};
if (_.isUndefined(this.state.selectedPlaidBankAccount)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to validate selectedPlaidBankAccount if it doesn't have an inputID and we hide the submit button if no value is selected?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, I'll remove it.

const errors = {};
if (_.isUndefined(this.state.selectedPlaidBankAccount)) {
errors.selectedBank = true;
}

if (this.props.isPasswordRequired && _.isEmpty(this.state.password)) {
if (this.props.isPasswordRequired && _.isEmpty(values.password)) {
errors.password = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to convert this error to a translated error string instead of bool

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like isPasswordRequired is undefined, so code inside will never run. I think we only wanna show an error if the pasword is empty? Display something like "This field is required"? Or is the backend error enough?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh if we don't require a password to add a personal bank account, we don't need to validate it in the front-end either. We could just remove this check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it is required to add a personal bank account. But for some reason we never set isPasswordRequired to true. Because if you send an empty password the backend sends back an "invalid password" error. I can either remove the check and rely on the backend, or add a check to validate the field is not empty.

Copy link
Contributor

Choose a reason for hiding this comment

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

The password field is required, so I think that we can remove mentions to that prop and:

  1. Add a check for empty password
  2. Add check for invalid password

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Add check for [invalid password]

I think we're asking the user there to input their existing password? So it should already be valid, unless it's incorrect then the backend will handle that case. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that's fine too. I don't have strong feelings about 2. We should still update the validate method to account for an empty password and remove the check for selectedPlaidBankAccount

Copy link
Contributor

Choose a reason for hiding this comment

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

@youssef-lr any updates regarding my comment above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On it, sorry! Was OOO (sick).

@luacmartins
Copy link
Contributor

luacmartins commented Sep 29, 2022

Also the PR title and linked issue mention AddPlaidBankAccount, but the refactored page is AddPersonalBankAccount page 😬

@youssef-lr
Copy link
Contributor Author

Also the PR title and linked issue mention AddPlaidBankAccount, but the refactored page is AddPersonalBankAccount page 😬

Yes I realize this 😁 I'm not really sue what to refactor inside of AddPlaidBankAccount, any insights? As for AddPersonalBankAccount, I refactored it because you mentioned it in this comment. Let me know what needs to be done in AddPlaidBankAccount.

Should I change this issue title? Or create separate issue for it and link to it here?

@luacmartins
Copy link
Contributor

I think just changing the issue title and mentioning that comment in the original post is enough. As for the refactor in AddPlaidBankAccount, that comment points to this part

@youssef-lr youssef-lr changed the title Refactor AddPlaidBankAccount to use Form Refactor AddPersonalBankAccount to use Form Sep 30, 2022
@youssef-lr
Copy link
Contributor Author

Updated and added tests!

Copy link
Contributor

@luacmartins luacmartins left a comment

Choose a reason for hiding this comment

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

Almost there! Just a few minor style changes that I noticed while testing, we are adding extra margins around the form. I suggested changes that fix that.

Screen Shot 2022-10-07 at 9 12 31 AM

onSubmit={this.submit}
validate={this.validate}
style={[styles.mh5, styles.mb5, styles.flex1]}
>
<View style={[styles.mh5, styles.mb5, styles.flex1]}>
Copy link
Contributor

Choose a reason for hiding this comment

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

This View is duplicating the styles applied by Form. I think we should just make it a fragment.

Suggested change
<View style={[styles.mh5, styles.mb5, styles.flex1]}>
<>

autoCompleteType="password"
textContentType="password"
autoCapitalize="none"
autoFocus={canFocusInputOnScreenFocus()}
onChangeText={text => this.setState({password: text})}
errorText={this.getErrorText('password')}
hasError={this.getErrors().password}
/>
</View>
)}
</View>
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
</View>
</>

@@ -177,30 +140,18 @@ class AddPersonalBankAccountPage extends React.Component {
{!_.isUndefined(this.state.selectedPlaidBankAccount) && (
<View style={[styles.mb5]}>
Copy link
Contributor

Choose a reason for hiding this comment

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

We can remove this view

Suggested change
<View style={[styles.mb5]}>

autoCompleteType="password"
textContentType="password"
autoCapitalize="none"
autoFocus={canFocusInputOnScreenFocus()}
onChangeText={text => this.setState({password: text})}
errorText={this.getErrorText('password')}
hasError={this.getErrors().password}
/>
</View>
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
</View>

submitButtonText={this.props.translate('common.saveAndContinue')}
onSubmit={this.submit}
validate={this.validate}
style={[styles.mh5, styles.mb5, styles.flex1]}
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need the extra bottom margin

Suggested change
style={[styles.mh5, styles.mb5, styles.flex1]}
style={[styles.mh5, styles.flex1]}

@youssef-lr
Copy link
Contributor Author

Updated!

Copy link
Contributor

@luacmartins luacmartins left a comment

Choose a reason for hiding this comment

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

LGTM

@luacmartins luacmartins merged commit 73c6279 into main Oct 7, 2022
@luacmartins luacmartins deleted the youssef_refactor_addplaidaccount_form branch October 7, 2022 16:10
@OSBotify
Copy link
Contributor

OSBotify commented Oct 7, 2022

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @luacmartins in version: 1.2.13-0 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@yuwenmemon
Copy link
Contributor

Tested, it works! Checking off ✅

@OSBotify
Copy link
Contributor

🚀 Deployed to production by @yuwenmemon in version: 1.2.13-5 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

smrutiparida pushed a commit to autosave-app/App that referenced this pull request Oct 13, 2022
…dplaidaccount_form

Refactor AddPersonalBankAccount to use Form
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.

5 participants