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

[HOLD for payment 2024-08-14] [$250] Tax-In tax name field, saving with code does not throw error #45887

Closed
2 of 6 tasks
izarutskaya opened this issue Jul 22, 2024 · 48 comments
Closed
2 of 6 tasks
Assignees
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor

Comments

@izarutskaya
Copy link

izarutskaya commented Jul 22, 2024

If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!


Version Number: 9.0.10
Reproducible in staging?: Y
Reproducible in production?: Y
Logs: https://stackoverflow.com/c/expensify/questions/4856
Issue reported by: Applause-Internal team

Action Performed:

Pre-condition:Have a workspace with tax enabled

  1. Go to expensify site in both mweb and android app
  2. Tap profile icon -- workspaces-- workspace
  3. Tap tax -- Add tax rate -- Name
    4.Paste and save it

Expected Result:

In tax name field, saving with code must throw error " invalid character " across site consistently in same way.

Actual Result:

In tax name field, saving with code throws error " invalid character " in android but error not shown in mweb.

Across the site in all input field on saving html code throws error except in tax & Report field name field.

Workaround:

Unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • Android: Native
  • Android: mWeb Chrome
  • iOS: Native
  • iOS: mWeb Safari
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

Bug6548631_1721565991865.Screenrecorder-2024-07-21-18-05-27-361_compress_1.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01e31e4849306c8612
  • Upwork Job ID: 1815518037392380725
  • Last Price Increase: 2024-07-29
  • Automatic offers:
    • dominictb | Contributor | 103327688
Issue OwnerCurrent Issue Owner: @RachCHopkins
@izarutskaya izarutskaya added Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels Jul 22, 2024
Copy link

melvin-bot bot commented Jul 22, 2024

Triggered auto assignment to @RachCHopkins (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

@izarutskaya
Copy link
Author

We think this issue might be related to the #vip-vsb

@Krishna2323
Copy link
Contributor

Krishna2323 commented Jul 22, 2024

Proposal

Please re-state the problem that we are trying to solve in this issue.

Tax-In tax name field, saving with code does not throw error

What is the root cause of that problem?

  • The form validation runs when the input value changes because shouldValidateOnChange is true by default in FormProvider, but we only want to run validation when user submits the form and then after once form is submitted we want to validate on value changes.

<FormProvider
style={[styles.flexGrow1, styles.mh5]}
formID={ONYXKEYS.FORMS.WORKSPACE_NEW_TAX_FORM}
onSubmit={submitForm}
validate={validateForm}
submitButtonText={translate('common.save')}
enabledWhenOffline
shouldValidateOnBlur={false}
disablePressOnEnter={false}
>

/** Should validate function be called when the value of the input is changed */
shouldValidateOnChange?: boolean;

What changes do you think we should make in order to solve the problem?

What alternative solutions did you explore? (Optional)

We can validate the value inside TextSelectorModal and AmountSelectorModal.

Code changes:

  1. Introduce a new prop in TextPicker and TextSelectorModal, we can name it validate. The function will accept a value and should return an error or empty string if no issues are found.
  2. We need to extract the validation for invalidCharacter and make it a util function so we can use it in the validation function for TextPicker & TextSelectorModal. We can also use invalidCharacter validation directly inside TextSelectorModal, this way we don't need to pass invalidCharacter validation when using TextSelectorModal.
    Object.entries(trimmedStringValues).forEach(([inputID, inputValue]) => {
    // If the input value is empty OR is non-string, we don't need to validate it for HTML tags
    if (!inputValue || typeof inputValue !== 'string') {
    return;
    }
    const foundHtmlTagIndex = inputValue.search(CONST.VALIDATE_FOR_HTML_TAG_REGEX);
    const leadingSpaceIndex = inputValue.search(CONST.VALIDATE_FOR_LEADINGSPACES_HTML_TAG_REGEX);
    // Return early if there are no HTML characters
    if (leadingSpaceIndex === -1 && foundHtmlTagIndex === -1) {
    return;
    }
    const matchedHtmlTags = inputValue.match(CONST.VALIDATE_FOR_HTML_TAG_REGEX);
    let isMatch = CONST.WHITELISTED_TAGS.some((regex) => regex.test(inputValue));
    // Check for any matches that the original regex (foundHtmlTagIndex) matched
    if (matchedHtmlTags) {
    // Check if any matched inputs does not match in WHITELISTED_TAGS list and return early if needed.
    for (const htmlTag of matchedHtmlTags) {
    isMatch = CONST.WHITELISTED_TAGS.some((regex) => regex.test(htmlTag));
    if (!isMatch) {
    break;
    }
    }
    }
    if (isMatch && leadingSpaceIndex === -1) {
    return;
    }
    // Add a validation error here because it is a string value that contains HTML characters
    validateErrors[inputID] = translate('common.error.invalidCharacter');
    });
  3. Pass validation function for TextPicker. This will check for invalid character also.
    validate={(value?: string) => {
        if (!policy) {
            return;
        }
        if (validateTaxName(policy, {[INPUT_IDS.NAME]: value ?? ''})?.[INPUT_IDS.NAME]) {
            return validateTaxName(policy, {[INPUT_IDS.NAME]: value ?? ''})?.[INPUT_IDS.NAME];
        }
        // This can also be directly used in `TextSelectorModal`, that way we don't need to pass this in validation callback
        if (ValidationUtils.validateInvalidCharacter(value)) {
            return ValidationUtils.validateInvalidCharacter(value);
        }
        return '';
    }}
  1. Create state named isTouched & error. isTouched will be responsible for checking if the input is already blurred or not and if it is then we will validate on every keystroke and error will be used to store the error string.
  2. Replace Button inside TextSelectorModal with FormAlertWithSubmitButton and validate the value before saving.
<FormAlertWithSubmitButton
    isAlertVisible={!!error}
    onSubmit={() => {
        if (validate && validate(currentValue)) {
            setError(validate(currentValue) ?? '');
            setIsTouched(true);
            return;
        }
        Keyboard.dismiss();
        onValueSelected?.(currentValue ?? '');
    }}
    onFixTheErrorsLinkPressed={() => {
        inputRef.current?.focus();
    }}
    buttonText={translate('common.save')}
/>
  1. Test branch

@RachCHopkins RachCHopkins added the External Added to denote the issue can be worked on by a contributor label Jul 22, 2024
@melvin-bot melvin-bot bot changed the title Tax-In tax name field, saving with code does not throw error [$250] Tax-In tax name field, saving with code does not throw error Jul 22, 2024
Copy link

melvin-bot bot commented Jul 22, 2024

Job added to Upwork: https://www.upwork.com/jobs/~01e31e4849306c8612

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Jul 22, 2024
Copy link

melvin-bot bot commented Jul 22, 2024

Triggered auto assignment to Contributor-plus team member for initial proposal review - @hungvu193 (External)

@dominictb
Copy link
Contributor

dominictb commented Jul 23, 2024

Proposal

Please re-state the problem that we are trying to solve in this issue.

In tax name field, saving with code throws error " invalid character " in android but error not shown in mweb.

What is the root cause of that problem?

We don't set shouldValidateOnBlur true for the form here, so when we come back from the TextPicker back to the WorkspaceCreateTaxPage, it does not validate the input but has to wait until the user clicks Save to see the issue with the input.

This is odd because the user comes all the way from clicking into the Name field, inputting the invalid name and come back, and do not see any error until they click Save, then they have to click all the way to the Name field again to edit it to the correct one. The feedback loop is too long.

What changes do you think we should make in order to solve the problem?

Update

shouldValidateOnBlur={false}
to

shouldValidateOnBlur

Then the user will see the error immediately after they come back from the Name TextPicker, in all platforms.

What alternative solutions did you explore? (Optional)

I think the best UX would be to validate right inside the Name input, so if the name is invalid, it the user will see it immediately after clicking Save or blurring in the Name TextPicker. This will make the feedback loop the shortest and takes the least amount of time for the user to correct any mistake they made.

We don't really need to duplicate the validation logic from FormProvider to TextPicker, we just need to use FormProvider itself inside TextSelectorModal, because TextSelectorModal itself can be considered a form (with proper validation logic, etc)

General steps:

  1. Replace this part with the FormProvider
<FormProvider
    formID={ONYXKEYS.FORMS.TEXT_PICKER_MODAL_FORM}
    onSubmit={(data) => {
        Keyboard.dismiss();
        onValueSelected?.(data[rest.inputID] ?? '');
    }}
    submitButtonText={translate('common.save')}
    validate={validate}
    style={[styles.mh5, styles.flex1]}
    enabledWhenOffline
>
    <InputWrapper
        ref={inputCallbackRef}
        InputComponent={TextInput}
        maxLength={CONST.CATEGORY_NAME_LIMIT}
        {...rest}
    />
</FormProvider>
  1. The inputCallbackRef above can be defined here as:
const inputCallbackRef = (ref) => {
    inputRef.current = ref;
};
  1. the TEXT_PICKER_MODAL_FORM used above will be a new key in ONYXKEYS.FORMS
  2. In
    onClose={hidePickerModal}
    we need to call onClose of the parent too (we'll need this later when we set the modal open state in WorkspaceCreateTaxPage
onClose={() => {
    onClose && onClose();
    hidePickerModal();
}}
  1. Same for onOpen here
onPress={() => {
    onOpen && onOpen();
    showPickerModal();
}}
  1. In define a state isModalOpen
const [isModalOpen, setIsModalOpen] = React.useState(false);
  1. Update
    disablePressOnEnter={false}
    to
disablePressOnEnter={isModalOpen}

Because we don't want the Enter key press to trigger submission in the create tax form, if the name text picker is opened, because Enter should trigger submission in the text picker there instead because it's focused.
8. Below

role={CONST.ROLE.PRESENTATION}
, add

onClose={() => setIsModalOpen(false)}
onOpen={() => setIsModalOpen(true)}
validate={(values) => {
    if (!policy) {
        return {};
    }
    return {
        ...validateTaxName(policy, values)
    };
}}

With those minimal changes, it works well now:
https://github.com/user-attachments/assets/dc2ddac5-c366-4f8f-9cf9-37dec0420249

Some further enhancements that could be done:

  • We need to pass currentValue as value of the name form's input, also call setValue when the form name change
  • Test thoroughly the TextPicker used in other places to make sure it works well and no regression caused
  • Rather than isModalOpen check above, there could be other ways to check that the modal is opened on top of current screen (ie. Onyx's modal key like here) we can explore that to reduce changes needed.

All those follow-ups can be done in the PR phase.

@hungvu193
Copy link
Contributor

Thanks for proposal everyone.
@Krishna2323 Can you please explain why do we need to create a new state called shouldValidateOnChange instead using shouldValidateOnChange=true directly?

@dominictb shouldValidateOnBlur={true} will make the form validate and showed errors even when we didn't select any value for them, I don't think that's a good way to handle such cases. Please see the video below.

Screen.Recording.2024-07-24.at.11.15.43.mov

@dominictb
Copy link
Contributor

@dominictb shouldValidateOnBlur={true} will make the form validate and showed errors even when we didn't select any value for them, I don't think that's a good way to handle such cases. Please see the video below.

@hungvu193 That's the correct behavior when the user focuses on a required field but then leave it empty, it's good to signify to the user that the value is required and they must fill it. It's the same UX for any other required field, please take a look at the example video below in the Manual bank account connection feature (all required fields in every bank account step behave the same):

Screen.Recording.2024-07-24.at.1.33.33.PM.mov

Another example when adding category:

Screen.Recording.2024-07-24.at.1.36.03.PM.mov

Let me know if you think that makes sense 👍

@hungvu193
Copy link
Contributor

That's different cases, these cases that you mentioned we validated on blur directly on that field, in this case we opened a new screen to do that so I'm still aligned with my opinion above.

@Krishna2323
Copy link
Contributor

Krishna2323 commented Jul 24, 2024

Can you please explain why do we need to create a new state called shouldValidateOnChange instead using shouldValidateOnChange=true directly?

  • shouldValidateOnChange is true by default, when we open the text picker or amount picker and save even without entering any value or blur the input, onBlur is called and the input is registered in touchedInputs.

    onBlur: (event) => {
    // Only run validation when user proactively blurs the input.
    if (Visibility.isVisible() && Visibility.hasFocus()) {
    const relatedTarget = event && 'relatedTarget' in event.nativeEvent && event?.nativeEvent?.relatedTarget;
    const relatedTargetId = relatedTarget && 'id' in relatedTarget && typeof relatedTarget.id === 'string' && relatedTarget.id;
    // We delay the validation in order to prevent Checkbox loss of focus when
    // the user is focusing a TextInput and proceeds to toggle a CheckBox in
    // web and mobile web platforms.
    setTimeout(() => {
    if (
    relatedTargetId === CONST.OVERLAY.BOTTOM_BUTTON_NATIVE_ID ||
    relatedTargetId === CONST.OVERLAY.TOP_BUTTON_NATIVE_ID ||
    relatedTargetId === CONST.BACK_BUTTON_NATIVE_ID
    ) {
    return;
    }
    setTouchedInput(inputID);
    if (shouldValidateOnBlur) {
    onValidate(inputValues, !hasServerError);
    }
    }, VALIDATE_DELAY);
    }
    inputProps.onBlur?.(event);
    },

  • The validation runs even when we save the value for the first time but we don't see the error because the input wasn't registered in touchedInputs.

    const touchedInputErrors = Object.fromEntries(Object.entries(validateErrors).filter(([inputID]) => touchedInputs.current[inputID]));
    if (!lodashIsEqual(errors, touchedInputErrors)) {
    setErrors(touchedInputErrors);
    }

  • When we open the modals for the second time and if the input was blurred before, then after saving the value, onValidate runs and we get the error.

    if (shouldValidateOnChange) {
    onValidate(newState);
    }

We have two options here:

  • We should be only start validating once user hits the submit button. For that we can create a new state and only pass true to shouldValidateOnChange when user has only submitted the form once. Explained in the proposal.

  • We can create a prop setInputTouchedOnChange in FormProvider (or we can introduce this in inputProps so it will be for a specific input), which will register the input in touchedInputs before calling onValidate inside onInputChange.

onInputChange: (value, key) => {
    const inputKey = key ?? inputID;
    setInputValues((prevState) => {
        const newState = {
            ...prevState,
            [inputKey]: value,
        };
        if (setInputTouchedOnChange) {
            setTouchedInput(inputID);
        }
        if (shouldValidateOnChange) {
            onValidate(newState);
        }
        return newState as Form;
    });
    if (inputProps.shouldSaveDraft && !formID.includes('Draft')) {
        FormActions.setDraftValues(formID, {[inputKey]: value});
    }
    inputProps.onValueChange?.(value, inputKey);
},
form_validation_add_rate.mp4

@dominictb
Copy link
Contributor

dominictb commented Jul 24, 2024

in this case we opened a new screen to do that so I'm still aligned with my opinion above.

@hungvu193 Curious how you think it is different? Isn't blurring the TextPicker in the new screen the same as blurring the text input itself?

I don't think that's a good way to handle such cases

@hungvu193 Could you give more details on why you think that's not a good way in terms of UX perspective, as far as I can see it's the same UX we've been using everywhere else, and it's better than not showing any error after the user blurs the required inputs.

@hungvu193
Copy link
Contributor

@hungvu193 Curious how you think it is different? Isn't blurring the TextPicker in the new screen the same as blurring the text input itself?

I think that's why we added shouldValidateOnBlur={false} everywhere we used TextPicker. If TextPicker is blurred, it should show error on TextPicker too.

@hungvu193 Could you give more details on why you think that's not a good way in terms of UX perspective, as far as I can see it's the same UX we've been using everywhere else, and it's better than not showing any error after the user blurs the required inputs.

It's not the same, if you're talking about validating on blur, it should show error on TextPicker screen when we blurred TextInput as well. There will be inconsistency here, we click back from TextPicker => no error, we blur the input from TextPicker and click back => error showed.

cc @shawnborton for more thoughts here.

@hungvu193
Copy link
Contributor

hungvu193 commented Jul 24, 2024

Can you please explain why do we need to create a new state called shouldValidateOnChange instead using shouldValidateOnChange=true directly?

  • shouldValidateOnChange is true by default, when we open the text picker or amount picker and save even without entering any value or blur the input, onBlur is called and the input is registered in touchedInputs.
    onBlur: (event) => {
    // Only run validation when user proactively blurs the input.
    if (Visibility.isVisible() && Visibility.hasFocus()) {
    const relatedTarget = event && 'relatedTarget' in event.nativeEvent && event?.nativeEvent?.relatedTarget;
    const relatedTargetId = relatedTarget && 'id' in relatedTarget && typeof relatedTarget.id === 'string' && relatedTarget.id;
    // We delay the validation in order to prevent Checkbox loss of focus when
    // the user is focusing a TextInput and proceeds to toggle a CheckBox in
    // web and mobile web platforms.
    setTimeout(() => {
    if (
    relatedTargetId === CONST.OVERLAY.BOTTOM_BUTTON_NATIVE_ID ||
    relatedTargetId === CONST.OVERLAY.TOP_BUTTON_NATIVE_ID ||
    relatedTargetId === CONST.BACK_BUTTON_NATIVE_ID
    ) {
    return;
    }
    setTouchedInput(inputID);
    if (shouldValidateOnBlur) {
    onValidate(inputValues, !hasServerError);
    }
    }, VALIDATE_DELAY);
    }
    inputProps.onBlur?.(event);
    },
  • The validation runs even when we save the value for the first time but we don't see the error because the input wasn't registered in touchedInputs.

Thanks for your explanation, I'll review after we have confirmation from design team 🙏

@shawnborton
Copy link
Contributor

I'm a little lost - can you explain in more detail?

Based on what I see from the bug report though, it seems like we shouldn't even allow you to save the tax rate name with the forbidden character. We should throw the error on that same "edit name" page and make the user fix the error before it saves.

@hungvu193
Copy link
Contributor

Based on what I see from the bug report though, it seems like we shouldn't even allow you to save the tax rate name with the forbidden character. We should throw the error on that same "edit name" page and make the user fix the error before it saves.

I agree with this one.

I'm a little lost - can you explain in more detail?

We're talking about the way we should show error on name (and value) field in WorkspaceCreateTaxPage. When we click on name field, we we will open TextPicker screen.
Should we:

  1. Show error on name field when TextPicker input is blurred
Example
Screen.Recording.2024-07-24.at.11.15.43.mov
  1. Show error on name filed only when we press save on TextPicker screen.
  2. Or like you said, we should validate the input on TextPicker screen ("edit screen").

@shawnborton
Copy link
Contributor

Oh interesting... part of me thinks we wouldn't show those errors until we hit the Save button to submit the form for the Add rate page.

@shawnborton
Copy link
Contributor

Also cc @Expensify/design for their input too.

@dominictb
Copy link
Contributor

Or like you said, we should validate the input on TextPicker screen ("edit screen").

@shawnborton I think this would be the best UX for the user, if there's invalid character, they'd know right away and not having to go back and forth to change it (because now they only see the error at the last step where they submit).

We're doing that for all other forms too.

@dannymcclain
Copy link
Contributor

I agree with Shawn. I don't think we would show those errors on the Add rate page until someone tries to hit Save.

But on the individual Name input page, I think we could also validate that when they click the Save button on that screen. So if they don't enter anything or enter an invalid character and try to hit the Save button for the name field, we'd show an error message.

Does that make sense / follow our other validation patterns?

@trjExpensify
Copy link
Contributor

I don't think we would show those errors on the Add rate page until someone tries to hit Save.

Agreed.

But on the individual Name input page, I think we could also validate that when they click the Save button on that screen. So if they don't enter anything or enter an invalid character and try to hit the Save button for the name field, we'd show an error message.

I agree here too, but I would also say if they blur the filed we should show the error like other forms, right?

@dominictb
Copy link
Contributor

But on the individual Name input page, I think we could also validate that when they click the Save button on that screen. So if they don't enter anything or enter an invalid character and try to hit the Save button for the name field, we'd show an error message.

@hungvu193 Looks like everyone agrees with this UX, that's also what I suggested and proposed a solution to in the alternative part here

Could you take a look to see if we can go with it? Thanks.

@hungvu193
Copy link
Contributor

@hungvu193 Looks like everyone agrees with this UX, that's also what I suggested and proposed a solution to in the alternative part here

Please make sure that you will post a comment to let everyone know you updated your proposal.

    - If you want to make an entirely new proposal or update an existing proposal, please go back and edit your original proposal, then post a new comment to the issue in this format to alert everyone that it has been updated:
    ```
    ## Proposal
    [Updated](link to proposal)
    ```

Could you take a look to see if we can go with it? Thanks.

I think it's looking good, but can you give it a little bit more details? Also an evidence video would be appreciated. Thank you 😄

Copy link

melvin-bot bot commented Jul 30, 2024

Triggered auto assignment to @yuwenmemon, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label Jul 30, 2024
Copy link

melvin-bot bot commented Jul 30, 2024

📣 @dominictb 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app!

Offer link
Upwork job
Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻
Keep in mind: Code of Conduct | Contributing 📖

@yuwenmemon
Copy link
Contributor

@hungvu193 Assigned. You may need to solicit another Engineer for merge as I'll be OOO until the 13th starting tomorrow.

@dominictb
Copy link
Contributor

PR will be ready by tomorrow.

@melvin-bot melvin-bot bot added Reviewing Has a PR in review Weekly KSv2 and removed Daily KSv2 labels Aug 1, 2024
@hungvu193
Copy link
Contributor

Requested internal engineer to take over this issue on Slack

@melvin-bot melvin-bot bot added Weekly KSv2 Awaiting Payment Auto-added when associated PR is deployed to production and removed Weekly KSv2 labels Aug 7, 2024
@melvin-bot melvin-bot bot changed the title [$250] Tax-In tax name field, saving with code does not throw error [HOLD for payment 2024-08-14] [$250] Tax-In tax name field, saving with code does not throw error Aug 7, 2024
Copy link

melvin-bot bot commented Aug 7, 2024

Reviewing label has been removed, please complete the "BugZero Checklist".

@melvin-bot melvin-bot bot removed the Reviewing Has a PR in review label Aug 7, 2024
Copy link

melvin-bot bot commented Aug 7, 2024

The solution for this issue has been 🚀 deployed to production 🚀 in version 9.0.17-2 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

If no regressions arise, payment will be issued on 2024-08-14. 🎊

For reference, here are some details about the assignees on this issue:

Copy link

melvin-bot bot commented Aug 7, 2024

BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:

  • [@hungvu193] The PR that introduced the bug has been identified. Link to the PR:
  • [@hungvu193] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:
  • [@hungvu193] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:
  • [@hungvu193] Determine if we should create a regression test for this bug.
  • [@hungvu193] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
  • [@RachCHopkins] Link the GH issue for creating/updating the regression test once above steps have been agreed upon:

@melvin-bot melvin-bot bot added Daily KSv2 and removed Weekly KSv2 labels Aug 14, 2024
@hungvu193
Copy link
Contributor

  • The PR that introduced the bug has been identified. Link to the PR: [Simplified Collect][Taxes] Creating new taxes #37967
  • The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment: N/A
  • A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion: N/A

Regression test:

  1. Login with any account.
  2. Go to Profile => workspaces => Open any workspace that has Tax feature enable.
  3. Go to tax => Add tax rate => Name.
  4. Enter or any invalid character in the name input.
  5. Press Save.
  6. Verify that: the name input should show error "Invalid character" after clicking on save button.

Do we 👍 or 👎 ?

@hungvu193
Copy link
Contributor

little bump @RachCHopkins for the payment 😄

@melvin-bot melvin-bot bot added the Overdue label Aug 16, 2024
@RachCHopkins
Copy link
Contributor

Sorry @hungvu193 I've been a little tied up! I'll get this organised tomorrow!

@melvin-bot melvin-bot bot removed the Overdue label Aug 19, 2024
@RachCHopkins
Copy link
Contributor

Payment Summary:

Contributor: @dominictb paid $250 via Upwork
Contributor+: @hungvu193 due $250 via NewDot

Upwork job here

@RachCHopkins
Copy link
Contributor

Contributor has been paid, the contract has been completed, and the Upwork post has been closed. @hungvu193 please go ahead and raise your NewDot Request!

@JmillsExpensify
Copy link

$250 approved for @hungvu193

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor
Projects
No open projects
Archived in project
Development

No branches or pull requests

10 participants