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

Open external links in product description in a new page #11761

Conversation

binarygit
Copy link
Contributor

What? Why?

What should we test?

  • Add a link in a product description
  • Open the link from the modal that opens when you click the product name from the shopfront page (http://localhost:3000/<shop-name>/shop)
  • Ensure that the link opens in a new tab instead of the same tab

Release notes

Changelog Category (reviewers may add a label for the release notes):

  • User facing changes
  • API changes (V0, V1, DFC or Webhook)
  • Technical changes only
  • Feature toggled

Note: Trix does not have an API to toggle links as external which is why the stimulus controller is needed. See: basecamp/trix#55

Copy link
Collaborator

@rioug rioug left a comment

Choose a reason for hiding this comment

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

Nice one !
I was bit confused has to why you needed a Stimulus controller, but then I realised you don't have access to the link directly in the template.
richtext is a bit of a generic name, I think we should use something more specific like : add_blank_to_link . What do you think ?

Copy link
Member

@mkllnk mkllnk left a comment

Choose a reason for hiding this comment

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

Nice one!

I agree that the name is very generic. Were you planning to add other things to it?

We could also be more precise and only select a tags with href but it shouldn't really matter in this context.

@binarygit
Copy link
Contributor Author

Will change the name and write specs for this. Give me till tomorrow. I'll re-request review!

@binarygit binarygit force-pushed the open-external-links-in-new-page branch 3 times, most recently from fdc4546 to 1ff6517 Compare November 10, 2023 11:50
@binarygit binarygit requested review from mkllnk and rioug November 10, 2023 11:51
@binarygit
Copy link
Contributor Author

I can see rubocop complaining:

 Assignment Branch Condition size for expect_product_description_html_to_be_displayed is too high.

I don't think there's a straightforward way to lower the branch condition size without splitting up that method. Do you think I should?

@binarygit binarygit force-pushed the open-external-links-in-new-page branch from 1ff6517 to 73c68df Compare November 12, 2023 07:10
Copy link
Collaborator

@rioug rioug left a comment

Choose a reason for hiding this comment

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

Thanks for adding the Javascript spec !

I don't think there's a straightforward way to lower the branch condition size without splitting up that method. Do you think I should?

It's due to the extra expect .. if blah, but yes short of breaking up expect_product_description_html_to_be_displayed there isn't a quick way to fix it. I don't think it's too hard to understand, so I would be happy with ignoring the warning here. @mkllnk what do you think ?
You can disable the warning by adding something like :

# rubocop:disable Metrics/AbcSize
def expect_product_description_html_to_be_displayed
...
end
# rubocop:enable Metrics/AbcSize

Copy link
Member

@mkllnk mkllnk left a comment

Choose a reason for hiding this comment

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

Let's improve the existing code while working on this.

@@ -157,6 +157,7 @@ def expect_product_description_html_to_be_displayed(product, html, not_include =
expect(page).to have_selector '.reveal-modal'
modal_should_be_open_for product
within(".reveal-modal") do
expect(find_link('external site')[:target]).to eq('_blank') if href
expect(html).to include(html)
expect(html).not_to include(not_include) if not_include
end
Copy link
Member

Choose a reason for hiding this comment

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

Why not split this up? There are two distinct chunks of tests here. One is about the product list and the other about the modal. Boolean flags are often a code smell as well. There are some strange things in this method. This line is self-fulfilling:

      expect(html).to include(html)

This line also seems unnecessary:

    expect(page).to have_selector '.reveal-modal'

The next line should test the same thing.

Copy link
Contributor Author

@binarygit binarygit Nov 13, 2023

Choose a reason for hiding this comment

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

I have removed those redundant assertions.

I tried to make the other assertions better but have not found a clear way to do so. I think the intention is to check whether in the rendered HTML the html passed into the method exists but I couldn't come up with a solution that can make the assertion.
Also the spec right after this,

     it "does not show unsecure HTML" do
        product.description = "<script>alert('Dangerous!');</script><p>Safe</p>"
        product.save!

        visit shop_path
        expect(page).to have_content product.name

        expect_product_description_html_to_be_displayed(
          product, "<p>Safe</p>", "<script>alert('Dangerous!');</script>", truncate: false
        )
     end

says that unsecure html should not be displayed but is calling the same method at the end, I don't know what the actual behaviour should be but what's currently happening is that the unsecure HTML does show up (as text) in the page.

@binarygit binarygit force-pushed the open-external-links-in-new-page branch 6 times, most recently from fbcdca6 to d20ffb5 Compare November 13, 2023 15:36
@binarygit binarygit force-pushed the open-external-links-in-new-page branch from d20ffb5 to 249c002 Compare November 13, 2023 15:46
@@ -147,14 +147,12 @@ def expect_product_description_html_to_be_displayed(product, html, not_include =
truncate: false, href: false)
# check inside list of products
within "#product-#{product.id} .product-description" do
expect(html).to include(html)
Copy link
Member

Choose a reason for hiding this comment

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

I now realise that html was supposed to refer to the page html but it got accidentally overridden by a parameter named the same. So I added more commits to show you how I would write it. It's maybe not as DRY but much simpler to read. And it makes it easier to fix up all the little mistakes of the previous code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice. Thanks @mkllnk. This was a good learning experience 🙏
and I understand what you mean, readability is more important than being pedantically DRY 😄


# It truncates a long product description.
within_product_description(product) do
expect(html).to include product.description
Copy link
Member

Choose a reason for hiding this comment

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

I brought this line back but it's actually wrong because we want to see only part of the description with ... at the end. It'll be fixed in a later commit.

@@ -105,10 +105,12 @@
within_product_description(product) do
expect(html).to include "<p>Safe</p>"
expect(html).not_to include "<script>alert('Dangerous!');</script>"
expect(page).to have_content "alert('Dangerous!'); Safe"
Copy link
Member

Choose a reason for hiding this comment

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

This is what the user sees.

Copy link
Collaborator

@rioug rioug left a comment

Choose a reason for hiding this comment

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

Thanks both for fixing the complexity !

@filipefurtad0 filipefurtad0 added the pr-staged-uk staging.openfoodnetwork.org.uk label Nov 16, 2023
@filipefurtad0 filipefurtad0 self-assigned this Nov 16, 2023
@filipefurtad0
Copy link
Contributor

Thanks @binarygit,

I've checked the behavior before staging the PR: indeed, clicking a hyperlink on a product description will not open a new tab, forcing the user to navigate back.

After staging this PR:
Hum... I can't observer the new behavior. Staging seems to have worked fine, but if I click the hyperlink then the behavior is the same as before: navigating to the URL, within the same browser window. You can see this in the console, which displays Navigated to:

image

This occurred after hard-reload, re-setting the URL... Not sure what to try next. Any advice?

@filipefurtad0 filipefurtad0 added feedback-needed pr-staged-uk staging.openfoodnetwork.org.uk and removed pr-staged-uk staging.openfoodnetwork.org.uk labels Nov 16, 2023
@binarygit
Copy link
Contributor Author

@filipefurtad0 I just logged into staging-uk and checked the rendered HTML. The stimulus data-controller which is responsible for adding the target='_blank' attribute is not rendered in staging!

Are you sure that this PR's code is merged with the uk-staging code?

Local:

local

Staging:

staging

Locally, I have rebased with the latest changes in master so, I know that it's not because of some new code in master that this is not working in staging.

@filipefurtad0
Copy link
Contributor

Thanks for double checking @binarygit !

Are you sure that this PR's code is merged with the uk-staging code?

Uff - I was fully trusting the deployment workflow... (well, not fully, I think I've deployed twice, just to be sure :-D ). I'll just try again and/or other staging servers and check if your code changes are there.

@filipefurtad0 filipefurtad0 added pr-staged-au staging.openfoodnetwork.org.au pr-staged-uk staging.openfoodnetwork.org.uk and removed feedback-needed pr-staged-uk staging.openfoodnetwork.org.uk pr-staged-au staging.openfoodnetwork.org.au labels Nov 17, 2023
@filipefurtad0
Copy link
Contributor

Ok, I see what's happening - there are two ways to access the product description:

  1. "directly", over the shop's page - and clicking the link, if it is visible - a new window is not opened ❌

image

  1. by opening a separate modal, and clicking the link - a new window is opened ✔️

This is the improvement this PR adds:
image

So, I'll merge this PR, leaving issue #11721 open and adding a note so scenario 1) is covered as well.

Thanks for your help @binarygit !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Hyperlinks in product description open in same window instead of opening in a new browser window
4 participants