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

Fix: move autoEmail to before mentions #550

Merged
merged 10 commits into from
Jul 12, 2023

Conversation

tienifr
Copy link
Contributor

@tienifr tienifr commented Jun 16, 2023

Fixed Issues

$ Expensify/App#20085

Tests

  1. Login to NewDot
  2. Click on any chat
  3. Send test@here@gmail.com
  4. Send test+1@here@gmail.com
  5. Verify the texts as emails are displayed
  6. Click on the emails
  7. Verify that it opens the mail sender
  8. Send @test@gmail.com
  9. Send @test+1@gmail.com
  10. Verify the texts as mentions are displayed
  11. Click on the mentions
  12. Verify that it opens the user detail page of the user that was mentioned

QA

  1. Login to NewDot
  2. Click on any chat
  3. Send test@here@gmail.com
  4. Send test+1@here@gmail.com
  5. Verify the texts as emails are displayed
  6. Click on the emails
  7. Verify that it opens the mail sender
  8. Send @test@gmail.com
  9. Send @test+1@gmail.com
  10. Verify the texts as mentions are displayed
  11. Click on the mentions
  12. Verify that it opens the user detail page of the user that was mentioned

Screenshots/Videos

Web
550-web-03.mp4
Mobile Web - Chrome
550-mweb-chrome.mov
Mobile Web - Safari
550-mweb-safari-02.mov
Desktop
Screen.Recording.2023-06-16.at.12.27.44.mov
iOS
550-ios-02.1.mov
Android
550-android.1.mov

@tienifr tienifr marked this pull request as ready for review June 16, 2023 06:28
@tienifr tienifr requested a review from a team as a code owner June 16, 2023 06:28
@melvin-bot melvin-bot bot requested review from cead22 and removed request for a team June 16, 2023 06:28
@cead22 cead22 changed the title fix: move autoEmail to before mentions Fix: move autoEmail to before mentions Jun 16, 2023
@cead22
Copy link
Contributor

cead22 commented Jun 16, 2023

Verify the texts as emails are displayed

Can you explain precisely what this means for each of the cases? For instance, is this one below correct?

image

What about this one? Should @here be highlighted in the case that it's highlighted? What about the others (and particularly the last one which looks identical to the one with the highlight, but isn't highlighted)?

image

Copy link
Contributor

@cead22 cead22 left a comment

Choose a reason for hiding this comment

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

With this change, how does one mention a user by email?

@@ -896,7 +896,7 @@ test('Test for user mention without space or supported styling character', () =>

test('Test for user mention with user email includes underscores', () => {
const testString = '@_concierge_@expensify.com';
const resultString = '<mention-user>@_concierge_@expensify.com</mention-user>';
const resultString = '@_<a href=\"mailto:concierge_@expensify.com\">concierge_@expensify.com</a>';
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible the first _ should be part of the email?
image

Copy link
Contributor Author

@tienifr tienifr Jun 19, 2023

Choose a reason for hiding this comment

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

@cead22 I agree that this should be changed. We can resolve it simply by addding a _ character in the beginning part of the regular expression for MARKDOWN_EMAIL here

-        MARKDOWN_EMAIL: "([a-zA-Z0-9.!#$%&'+/=?^`{|}-][a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]*@[a-zA-Z0-9-]+?(\\.[a-zA-Z]+)+)",
+        MARKDOWN_EMAIL: "([a-zA-Z0-9.!#$%&'+/=?^_`{|}-][a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]*@[a-zA-Z0-9-]+?(\\.[a-zA-Z]+)+)",

However, I think this is not related to the current issue that is being resolved (which is dealing with the inconsistency rather than the correctness of the email validation). Furthermore, the current regular expression for email is also capturing many invalid emails, for example .abc@gmail.com (emails cannot start with dot character) and abc..def@gmail.com (emails cannot have consecutive dot characters). IMO, we should resolve this in a seperated issue, something like Update email regular expression to remove matches of invalid emails.

Thoughts?

@tienifr
Copy link
Contributor Author

tienifr commented Jun 19, 2023

Verify the texts as emails are displayed

Can you explain precisely what this means for each of the cases? For instance, is this one below correct?

image What about this one? Should `@here` be highlighted in the case that it's highlighted? What about the others (and particularly the last one which looks identical to the one with the highlight, but isn't highlighted)? image

Sorry for the confusion. The difference you are seeing is the result before I apply the changes in this PR. The expected behavior is that those texts should be rendered as email like what was shown when the texts are typed and sent. I have updated the new video recordings in the PR description with a brand new account to avoid this confusion.

@eVoloshchak
Copy link
Contributor

@tienifr, could you take a look at @cead22's concern here?

With this change, how does one mention a user by email?

Screen.Recording.2023-06-19.at.17.59.06.mov

@tienifr
Copy link
Contributor Author

tienifr commented Jun 20, 2023

@eVoloshchak Thanks for pointing that out.

After some more digging, I'm having these 2 solutions for this, please let me know what you think.

  • Solution 1: The first way we could address this is modifying the autoEmail regex, then implement a replacement function which would only replace it as email if the first character is not @. It would be similar to the mention replacement logic here. Something like this would work

Change the autoEmail regex

- (?![^<]*>|[^<>]*<\\/)${CONST.REG_EXP.MARKDOWN_EMAIL}(?![^<]*(<\\/pre>|<\\/code>|<\\/a>))
+ (?![^<]*>|[^<>]*<\\/)([a-zA-Z0-9.!#$%&'*+/=?^_\`{|}~-]*?@?)(${CONST.REG_EXP.MARKDOWN_EMAIL})(?![^<]*(<\\/pre>|<\\/code>|<\\/a>))

Change the replacement function

-                replacement: '<a href="mailto:$1">$1</a>',
+                replacement: (match, g1, g2) => {
+                    if (match.startsWith('@')) {
+                        return match;
+                    }
+                    return `${g1}<a href="mailto:${g2}">${g2}</a>`;
+                },
  • Solution 2: After digging a little bit, I notice that the current mention rule is not replacing the match with mention if the match starts with [`.a-zA-Z]. We can revert all the previous changes (keep the original menntion -> autoEmail order), and modify the hereMentions and userMentions regex so that it also ignore other email valid characters (digit, special characters...). We should modify their prefix from [`.a-zA-Z]? to [a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]?

IMO, solution 2 should be better, since it provide the least change which will fix the mention issue, which wouldn't affect other cases that we may not yet thought about. Here is the recording of the cases that both solution will solve.
Screenshot 2023-06-20 at 10 24 41

@eVoloshchak
Copy link
Contributor

Solution 2: After digging a little bit, I notice that the current mention rule is not replacing the match with mention if the match starts with [.a-zA-Z]. We can revert all the previous changes (keep the original menntion -> autoEmail order), and modify the hereMentionsanduserMentionsregex so that it also ignore other email valid characters (digit, special characters...). We should modify their prefix from[.a-zA-Z]?to[a-zA-Z0-9.!#$%&'*+/=?^_{|}~-]?`

Shouldn't it be the other way around? I.e. "replace the match with mention only if it starts with @"?

@tienifr
Copy link
Contributor Author

tienifr commented Jun 20, 2023

Shouldn't it be the other way around? I.e. "replace the match with mention only if it starts with @"?

Yes, that's what the current logic is doing, and we are not changing that. My suggestion is that we change the mention regex so that it also cover other characters. Currently, with the email test@here@gmail.com, the current regex match t@here -> text would not be replaced by mentionn since it doesn't start with @. However, with the email test+1@here@gmail.com, the current regex match @here -> text would be replaced by mention.

The main point is that the current regex (intentionally matching text before @ character then check it later in the replacement function) does not cover enough characters. So I'm suggesting covering all email-valid characters by the change in Solution 2.

@tienifr
Copy link
Contributor Author

tienifr commented Jun 21, 2023

@eVoloshchak friendly bump. What do you think should be our next step here? Thanks.

@eVoloshchak
Copy link
Contributor

Sorry for the delay, for some reason there's no review request showing up for me for this PR.
Let's proceed with solution 2
Is there an alternative to [a-zA-Z0-9.!#$%&*+/=?^_{|}~-]? Something like \S?

@tienifr
Copy link
Contributor Author

tienifr commented Jun 22, 2023

Is there an alternative to [a-zA-Z0-9.!#$%&*+/=?^_{|}~-]? Something like \S?

I don't think so. You can notice that regex does not contain some invalid email username characters i.e @. I copied it from the MARKDOWN_EMAIL constant in Const.jsx.

@tienifr
Copy link
Contributor Author

tienifr commented Jun 22, 2023

Ok, so here's what I have done

  • Revert the old tests from ExpensiMark-HTML-test.js tests
  • Revert the order of mention and email to previous order (mention -> autoEmail)
  • Modify userMentions and hereMentions regex so that it also includes digits and special characters. These would be filtered out later by the isValidMention function. Also, I exclude some markdown characters (~_#@), so that these would not be included in the mention.

For the email starting with _, I believe that this should not be treated as a valid email, per this link.

cc @cead22 @eVoloshchak

@eVoloshchak
Copy link
Contributor

eVoloshchak commented Jun 22, 2023

Looks good except one test case

image

dfgjl+-=32@gmail.com is invalid email (hence not displayed as mention), but is still displayed as email
The same happens without this PR, is that expected?

@tienifr
Copy link
Contributor Author

tienifr commented Jun 23, 2023

@eVoloshchak I think the current email regex is not totally correct. Should we fix it in other PR?

@eVoloshchak
Copy link
Contributor

Yeah, I'll just report tt=hat on Slack, it's not caused by this PR

Copy link
Contributor

@eVoloshchak eVoloshchak left a comment

Choose a reason for hiding this comment

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

LGTM
cc: @cead22

cead22
cead22 previously approved these changes Jun 23, 2023
Copy link
Contributor

@cead22 cead22 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. @tienifr can you add more manual tests to the PR description to test (and QA)

  • Some cases of mentions to make sure those are still working
  • Tapping on a mention and making sure it works
  • Tapping on one of those emails you're sending, and make sure the behavior is correct

If there are more edge cases that aren't covered in the automated tests that you can think of, those would be good to add as well

@cead22
Copy link
Contributor

cead22 commented Jun 23, 2023

Also, I noticed the iOS videos are showing an app that looks broken, without a header. I know that's not related to these changes but if you can update those so the app doesn't look broken (since we're trying to show in these videos that the app works well), and if you know how to reproduce that, can you comment here?

@tienifr
Copy link
Contributor Author

tienifr commented Jun 26, 2023

@cead22 Tests and IOS videos are updated, please have a look!

Also, I would like to bring attention to this edge case. It's appearing in both staging and this PR, and although I think we should resolve this in another PR, it's worth mentioning and the expected behavior should be agreed upon:

  • When sending test@here@gmail.com, the here@gmail.com part is displayed as email address.
  • When sending @here@gmail.com or @here_@gmail.com, the @here part is displayed as a mention.

I think it probably would be confusing for the users when they try to mention another user that has email named here. The root cause should be addressed somewhere in the email regex.

cc @cead22 @eVoloshchak for thoughts.

@tienifr
Copy link
Contributor Author

tienifr commented Jun 26, 2023

and if you know how to reproduce that, can you comment here?

Weird enough, at the moment it's not reproducible on my side 😬

@eVoloshchak
Copy link
Contributor

eVoloshchak commented Jun 26, 2023

Also, I would like to bring attention to this edge case. It's appearing in both staging and this PR, and although I think we should resolve this in another PR, it's worth mentioning and the expected behavior should be agreed upon:

When sending test@here@gmail.com, the here@gmail.com part is displayed as email address.
When sending @here@gmail.com or @here_@gmail.com, the @here part is displayed as a mention.

My understanding is, both @here@gmail.com and @here_@gmail.com are not valid emails, so @here part being displayed as a mention is correct I think, but curious what others think

UPD: Notice how GitHub also doesn't render them as emails

@cead22
Copy link
Contributor

cead22 commented Jun 26, 2023

It's appearing in both staging and this PR, and although I think we should resolve this in another PR

Why not resolve here? Is it happening in production? That seems very related to this PR

both @here@gmail.com and @here_@gmail.com are not valid emails, so @here part being displayed as a mention is correct I think, but curious what others think

I don't know if I missed something, but I think both these statements are wrong. Those are valid emails and GH markdown renders them as such

@cead22
Copy link
Contributor

cead22 commented Jun 26, 2023

@tienifr

  • Please update tests & QA to test tapping on an email
  • Please update one of the videos to show tapping on an email, and tapping on a mention works

@tienifr
Copy link
Contributor Author

tienifr commented Jun 27, 2023

@cead22

Why not resolve here? Is it happening in production? That seems very related to this PR

Because it's more about the correctness of the regex, instead of the inconsistency issue. If we all agree that it's a bug and should be fixed in this PR then we can fix it by modifying the user mention regex so that it exclude the @here mention when it follows with a domain.

- regex: /[a-zA-Z0-9.!$%&+/=?^`{|}-]?@here(?=_\b|\b)(?!((?:(?!<a).)+)?<\/a>|[^<]*(<\/pre>|<\/code>))/gm,
+ regex: /[a-zA-Z0-9.!$%&+/=?^`{|}-]?@here(?=_\b|\b)(?!(@[a-zA-Z0-9-]+?(.[a-zA-Z]+)+)|((?:(?!<a).)+)?<\/a>|[^<]*(<\/pre>|<\/code>))/gm,

What do you think about this change?
image

@tienifr
Copy link
Contributor Author

tienifr commented Jun 27, 2023

  • Please update tests & QA to test tapping on an email

Please correct me if i'm wrong, the expected behavior for tapping on an email is that the app would open the mailbox? Since we are using mailto: href for emails. Personally, I don't see any relevance of that test in this PR.

  • Please update one of the videos to show tapping on an email, and tapping on a mention works

I will update it once we agree on the expected behavior of the email/mention @here@gmail.com above.

@eVoloshchak
Copy link
Contributor

I don't know if I missed something, but I think both these statements are wrong. Those are valid emails and GH markdown renders them as such

Ah, my bad, I missed that they're supposed to be rendered as mentions instead of as emails

image

This looks like the correct behavior to me

@cead22
Copy link
Contributor

cead22 commented Jun 30, 2023

@tienifr whatever the behavior is today, it should be the same with this change. The reason I think the test is relevant is because we're modifying some code that's involved in rendering emails, so imo we should test that this isn't breaking what we have

@tienifr
Copy link
Contributor Author

tienifr commented Jul 1, 2023

@cead22 @eVoloshchak

Okay, so I added a few other edge cases that worth testing. Those test cases require some additional modification. Here are the latest changes:

  • The isValidMention function now return true only if the text starts with @, or if it starts and ends with a same markdown character *~_#’”.
  • I removed the #@username@expensify.com test case for isValidMention, since currently it is not rendered as markdown, and should not be treated as a valid mention
  • I modified the hereMentions regular expression and replacement logic so that it could replace the mention more efficiently. The matching regex will also match the prefix and suffix markdown character, and those shall be added in the replacement function
  • I added some addition test cases ExpensiMark-HTML-test.js
    @here@here.com -> rendered as an user mention
    @abc_@here.com -> rendered as an user mention
    @here_@here.com -> rendered as an user mention
    @here_@here_.com -> rendered as a @here mention and an italic @here mention, since here_.com is an invalid domain
    @here@ -> rendered as a mention @here and a @ character
    @here@here -> rendered as 2 @here mentions

Can you please check that out?

@tienifr
Copy link
Contributor Author

tienifr commented Jul 1, 2023

Also @cead22 , can you please clarify what you mean by update tests & QA to test tapping on an email? Would the expected behavior be that the machine will open up email app so that the user could send an email to that address? I'm confused about the relationship of that to this issue. Also, I believe this is complicated when recording on some emulator, since we have to install additional mailing app on that.

Screen.Recording.2023-07-01.at.11.49.13.mov

@tienifr tienifr requested a review from cead22 July 2, 2023 08:58
@tienifr
Copy link
Contributor Author

tienifr commented Jul 4, 2023

@cead22 Friendly bump. Can you take a look?

@cead22
Copy link
Contributor

cead22 commented Jul 6, 2023

The updates in this comment make sense to me 👍

Would the expected behavior be that the machine will open up email app so that the user could send an email to that address?

This should be the same behavior we have today. We're just testing that we're not breaking the existing behavior since we're changing some code related to how we render emails

Also, I believe this is complicated when recording on some emulator, since we have to install additional mailing app on that.

That's fine, we don't need this in the recordings, but we should test and QA the behavior didn't break

@cead22
Copy link
Contributor

cead22 commented Jul 6, 2023

  • Please update one of the videos to show tapping on an email, and tapping on a mention works

Looks like this was missed again. I still think it'd be good to show this in a video, but at least it's in the QA steps

lib/str.js Outdated
// A valid mention starts with a space, *, _, #, ', ", or @ (with no preceding characters).
return /[\s*~_#'"@]/g.test(mention.charAt(0));
// A valid mention starts with a space or @, or
// starts and ends with a *, _, #, ', or " (with no preceding characters).
Copy link
Contributor

Choose a reason for hiding this comment

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

Is # supposed to be here? I thought # was used for headings like so # heading 1, ie, with a # before the text but without a # after the text

Copy link
Contributor

Choose a reason for hiding this comment

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

A valid mention starts with a space or @ or starts and ends with a *, _, #, ', or " (with no preceding characters)

Is this correct?
I think I'm missing something, can mention start and end with *, _, #, ', or "?

Copy link
Contributor

Choose a reason for hiding this comment

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

@eVoloshchak it can "start" with * in the sense that the mention can be within two *, so it'll still technically start with an @, but this is saying it can start with * becasue it can be like let's ask *@carlos@expensify.com*.

This is why I asked about #, cause that one is only a leading character unlike *, _, ', ", and ~.

Incidentally @tienifr, the ~ is missing from the comment starts and ends with a *, _, #, ', or "...

Copy link
Contributor Author

@tienifr tienifr Jul 11, 2023

Choose a reason for hiding this comment

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

Incidentally @tienifr, the ~ is missing from the comment starts and ends with a *, _, #, ', or "...

I missed that. Thanks for pointing it out.

This is why I asked about #, cause that one is only a leading character unlike *, _, ', ", and ~.

I agree that # is redundant here since it is only a leading character, and we can get rid of it. It also does not affect the current behavior of either this PR or the current staging version
image

@cead22 cead22 requested a review from eVoloshchak July 6, 2023 23:59
@cead22
Copy link
Contributor

cead22 commented Jul 6, 2023

@eVoloshchak since there were code changes after you approved, can you please re-review? Thanks!

@tienifr
Copy link
Contributor Author

tienifr commented Jul 11, 2023

  • Please update one of the videos to show tapping on an email, and tapping on a mention works

@cead22 This has been updated in the Web video. Please have a look!

Copy link
Contributor

@eVoloshchak eVoloshchak left a comment

Choose a reason for hiding this comment

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

Looks good

Shouldn't we have the PR reviewer checklist in these repositories too?
You still have to go through it to test the PR

Copy link
Contributor

@cead22 cead22 left a comment

Choose a reason for hiding this comment

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

Minor change request, but the comment was still wrong because it said it could start and end with # and didn't mention ~

// starts and ends with a *, _, #, ', or " (with no preceding characters).

lib/str.js Outdated Show resolved Hide resolved
@cead22
Copy link
Contributor

cead22 commented Jul 12, 2023

Shouldn't we have the PR reviewer checklist in these repositories too?

@eVoloshchak that seems like a good idea, can you start a convo in #expensify-open-source?

@tienifr
Copy link
Contributor Author

tienifr commented Jul 12, 2023

@cead22 I've resolved that.

@cead22 cead22 merged commit d7e4249 into Expensify:main Jul 12, 2023
3 checks passed
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.

3 participants