-
Notifications
You must be signed in to change notification settings - Fork 3k
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
add “Report virtual card fraud” page and route #28312
Conversation
1be03aa
to
8cbb012
Compare
7533f27
to
1441d4c
Compare
1441d4c
to
0274f11
Compare
const submitReportFraud = () => { | ||
Card.reportDigitalExpensifyCardFraud(virtualCard.cardID); | ||
}; | ||
|
||
const onBackButtonPress = () => Navigation.goBack(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(domain)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB. Let's inline those functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, let me know if that's what you meant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant to pass the function directly to HeaderWithBackButton
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute(domain))}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
return; | ||
} | ||
|
||
FormActions.setErrors(ONYXKEYS.FORMS.REPORT_FRAUD_FORM, virtualCard.errors); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a pattern that we follow. The backend errors are not form errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 the errors should either come from the backend (in that case they are already there on the virtualCard
object) or the form itself should set them. In this case though, we have no form fields so there is no validation that could fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically the options are:
- Use the FormAlertWithSubmitButton directly (I think this might be the way I would go here) and then pass the errors that are on the card object.
- Use the Form - but don't manually set the errors. Just trust that the backend will set them if anything goes wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All right, so let's go with number 1! What exactly do you mean by "pass the errors that are on the card object."?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I get it now, let me know if that's what you meant 😄 CC: @marcaaron
This PR does not seem to be ready for test yet. The backend changes are not live yet, I'm getting 404 errors trying to access |
@s77rt I'm not sure that we need to wait BE |
@marcaaron can you confirm this and take a look at the Error handling? |
I am not the owner of this PR, so I can't edit the description, but I think the useEffect(() => {
window.Onyx.merge(`cardList`, {
'virtual': {
cardID: 234523452345,
state: 3,
bank: 'Expensify',
availableSpend:10000,
domainName: 'Expensify',
lastFourPAN: '',
isVirtual: true,
cardholderFirstName: "Test",
cardholderLastName: "Test",
}, 'physical': {
cardID: 234523452345,
state: 3,
bank: '1000',
availableSpend:10000,
domainName: 'Expensify',
lastFourPAN: '2345',
isVirtual: false,
},
});
Navigation.navigate(ROUTES.SETTINGS_WALLET_DOMAINCARDS.getRoute('expensify'));
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is looking great. I don't have many comments, but will ask for some annoying name changes.
@@ -141,6 +141,7 @@ const SettingsModalStackNavigator = createModalStackNavigator({ | |||
Settings_Lounge_Access: () => require('../../../pages/settings/Profile/LoungeAccessPage').default, | |||
Settings_Wallet: () => require('../../../pages/settings/Wallet/WalletPage').default, | |||
Settings_Wallet_DomainCards: () => require('../../../pages/settings/Wallet/ExpensifyCardPage').default, | |||
Settings_Report_Fraud: () => require('../../../pages/settings/Wallet/ReportFraudPage').default, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make this Settings_Wallet_ReportVirtualCardFraud
for consistency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, done!
src/libs/actions/Card.js
Outdated
/** | ||
* @param {Number} cardID | ||
*/ | ||
function reportDigitalExpensifyCardFraud(cardID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I am not mistaken, we decided to rebrand these as "virtual cards". Could we update that for consistency? So...
reportDigitalExpensifyCardFraud
->reportVirtualExpensifyCardFraud
ReportDigitalExpensifyCardFraud
->ReportVirtualExpensifyCardFraud
report-digital-fraud
->report-virtual-fraud
- etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
src/ONYXKEYS.ts
Outdated
@@ -291,6 +291,7 @@ const ONYXKEYS = { | |||
PRIVATE_NOTES_FORM: 'privateNotesForm', | |||
I_KNOW_A_TEACHER_FORM: 'iKnowTeacherForm', | |||
INTRO_SCHOOL_PRINCIPAL_FORM: 'introSchoolPrincipalForm', | |||
REPORT_FRAUD_FORM: 'reportFraudForm', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also could make this: REPORT_VIRTUAL_CARD_FRAUD
? Not sure if we will have other kinds of fraud reporting, but doesn't hurt to get specific here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
return; | ||
} | ||
|
||
FormActions.setErrors(ONYXKEYS.FORMS.REPORT_FRAUD_FORM, virtualCard.errors); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 the errors should either come from the backend (in that case they are already there on the virtualCard
object) or the form itself should set them. In this case though, we have no form fields so there is no validation that could fail.
I'm not sure I can test this well. Request to |
I pushed a couple commits, I think all comments have been addressed in some way, let me know if there is anything else you'd like me to change! CC: @marcaaron @s77rt |
PR updated CC: @marcaaron @s77rt |
@s77rt Test what you can. Like I said, I will verify that part. |
Reviewer Checklist
Screenshots/VideosWebweb.movMobile Web - Chromemweb-chrome.movMobile Web - Safarimweb-safari.movDesktopdesktop.moviOSios.movAndroidandroid.mov |
I think this one looks ready to merge now. As for testing... this isn't something that QA will be able to test as the flows aren't really accessible and I am not sure if they have Expensify Cards. I updated the test steps and I think either myself or @grgia should be able to do them on staging. |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/marcaaron in version: 1.3.81-0 🚀
|
This pretty much failed the internal QA for me, but since this flow isn't really "accessible" yet I think we can deploy anyway and continue testing as we go and create some follow up issues. We will want to E2E test everything before we release the changes to the wallet page. cc @grgia but this is what I ran into:
Expired physical card case First interesting thing is that it says I have no physical card. This is correct, mine has expired 😅 @kevinksullivan @joekaufmanexpensify what should the behavior be in this case? Error message says This comes from here. So it means we are taking the error message and assuming it is a translation key. Maybe something with this logic is off @fedirjh. Because it would not throw on staging if I am looking at it correctly 🤔 App/src/libs/Localize/index.js Lines 118 to 137 in cb883e8
I think on production this error would end up showing to the user But what do we want to say here? cc @kevinksullivan & @joekaufmanexpensify again here as it probably depends on what we decide on first issue. Separately, maybe someone with a physical + virtual card is daring enough to try this on NewDot staging? |
🚀 Deployed to staging by https://github.com/marcaaron in version: 1.3.83-0 🚀
|
@marcaaron I believe this is a regression from #28377, which appears to have altered the error-handling mechanism previously in use.
I expect that production will behave similarly to staging and also display I think prior to that PR it will display the server error: |
Hmm ok I am not really sure what the expected behavior is supposed to be here. Pretty confused on those changes overall actually. Maybe @mountiny can explain what we should do. |
This is bug in the form error, we are passing the message which wants to be translated into translate method which we should not be doing. That will be handled as a fix of the form component, dont have link right now, sorry |
ah so all error messages from the backend that the Form component was previously displaying are broken atm? |
If they are being passed as what should be a translate key to translate method, then yeah, this feels like incorrect usage of the translate utility. If we want to keep this behaviour in Form, ie get translated error if the key exist. Other option which I dont think we really want to do now, would be to catch the error in PHP and then pass down the translation key and have a nice and translated error. |
This was added as a futureproof concept for violations, which will be passed from a server and should be translated so the MISSING TRANSLATIONS is shown Only to Expensify emails account https://github.com/Expensify/App/pull/28377/files#diff-2f79c1e80b9fe28f0d8f5487095f8219dce80539b231f41190e509b8d5d3f8d4R93 So cutomers should still just see the Error from the server @marcaaron |
Interesting. I missed that convo. Still not sure what it means. So if someone with an "expensify email" sees the MISSING TRANSLATIONS then they should do what exactly? 😅 |
It should just be easier to spot that there is a bug and raise it as a bug 😄 we did not really expect this would be happening until violations come in wave9 but the current usage of the form validation error does not look ideal |
Details
Fixed Issues
$ #22880
Tests
Offline tests
QA Steps
/settings/wallet
and wait for all API commands to finish/settings/wallet/cards/expensify.com/
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
this
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Web
web.mov
Mobile Web - Chrome
android.web.webm
Mobile Web - Safari
ios-web.mp4
Desktop
desktop.app.mov
iOS
ios.native.mp4
Android
android.native.webm