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

Update layout_for_admin component to take custom asset filenames #3993

Merged
merged 1 commit into from
Apr 26, 2024

Conversation

davidgisbey
Copy link
Contributor

@davidgisbey davidgisbey commented Apr 24, 2024

What

Allow custom JS and CSS filenames to be passed to the layout_for_admin component.

Why

We're adding an admin interface to our application and want to use retain application.js & application.scss for the public interface.

This will allow us to pass admin.js and admin.scss in as args so we can retain only loading the required components for each so the page load time is fast.

Visual Changes

N/A

Testing

It was a bit awkward to test this as passing it a filename that doesn't exist causes exceptions. Using any_instance_of is a bit of a smell, but it's probs okay(ish) here to avoid additional complexity.

Trello card

https://trello.com/c/r6uafy2D/1354-basic-admin-area

@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 08:19 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 6949cf1 to 0b29cbc Compare April 24, 2024 08:35
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 08:35 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 0b29cbc to 35070cd Compare April 24, 2024 08:43
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 08:43 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 35070cd to 77e9db0 Compare April 24, 2024 08:45
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 08:46 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 77e9db0 to ba61613 Compare April 24, 2024 08:58
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 08:58 Inactive
@davidgisbey davidgisbey marked this pull request as ready for review April 24, 2024 08:58
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from ba61613 to 08f5ded Compare April 24, 2024 09:38
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 09:38 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 08f5ded to 4244ec3 Compare April 24, 2024 14:59
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 15:00 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 4244ec3 to 232d27b Compare April 24, 2024 15:00
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 15:01 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 232d27b to 66e2a21 Compare April 24, 2024 15:01
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 15:01 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 66e2a21 to fa4037c Compare April 24, 2024 15:09
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 15:09 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from c4ae73e to 3f29ecb Compare April 24, 2024 15:14
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 15:14 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 3f29ecb to caed1b4 Compare April 24, 2024 15:19
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 15:20 Inactive
@davidgisbey davidgisbey changed the title Allow custom filenames to be passed for JS and CS Allow custom JS and CS filenames to be passed to admin_for_layout component Apr 24, 2024
Copy link
Member

@kevindew kevindew left a comment

Choose a reason for hiding this comment

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

Great stuff David 👍

CHANGELOG.md Show resolved Hide resolved
spec/components/layout_for_admin_spec.rb Outdated Show resolved Hide resolved
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from caed1b4 to 2f39828 Compare April 24, 2024 16:19
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 16:19 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 2f39828 to d71638d Compare April 24, 2024 16:21
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 16:21 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from d71638d to 92649fb Compare April 24, 2024 16:22
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 16:22 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 92649fb to c413dca Compare April 24, 2024 16:38
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 24, 2024 16:39 Inactive
Copy link
Member

@kevindew kevindew left a comment

Choose a reason for hiding this comment

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

Great, all the changes look good to me. Only thing I remembered to suggest is that we should add some information in the commit message about how we ended up committing the sin of using (allow|expect)_any_instance_of and how we ended up stubbing ActiveView::Base - as there is quite opaque.

It'd be good to get a nod from @andysellick or one of the frontend devs on our team before merging though

@davidgisbey
Copy link
Contributor Author

Yea great shout. Sorry i was using CI to run my tests as i was having issues locally and forgot to update the commit message. I'll sort that now 👍

@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from c413dca to 8c76f06 Compare April 25, 2024 08:27
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 25, 2024 08:27 Inactive
Copy link
Contributor

@andysellick andysellick left a comment

Choose a reason for hiding this comment

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

Change looks good, just a few comments/questions 👍

CHANGELOG.md Show resolved Hide resolved
environment: production
product_name: Publishing
browser_title: 'A page title'
js_filename: "application"
Copy link
Contributor

Choose a reason for hiding this comment

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

These examples pass the default value, would it be clearer to show this functionality in action?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem with that is that i'd have to add a blank admin stylesheet, because it will actually try to compile the file. So it if update it to use "admin" it'll look for "admin.js" and blow up if it can't find it.

I figured this was the lesser of 2 evils, but let me know if you'd prefer another approach 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh I see that makes sense. Tricky! In that case maybe add a description to these examples to clarify? Something like:

description: An alternative JS filename can be used in place of the default `application.js` if required (note that this cannot easily be demonstrated here).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

great shout. Thanks Andy will sort that now

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, description needs to be added at the top level, underneath the example name, e.g.

with_custom_js_filename:
  description: etc.
  data:
    environment: production

It should appear in the component guide if you want to check it.

spec/components/layout_for_admin_spec.rb Show resolved Hide resolved
@@ -16,4 +16,25 @@ def component_name

assert_select 'meta[name="robots"][content="noindex,nofollow,noimageindex"]', visible: false
end

it "can receive a custom js filename" do
allow_any_instance_of(ActionView::Base).to receive(:javascript_include_tag)
Copy link
Contributor

Choose a reason for hiding this comment

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

Again just interested to know how this works - why does the JS test have allow_any_instance_of and expect_any_instance_of, but the CSS test only has expect_any_instance_of?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar to above, the reason we're unable to make an assertion on the page is that it will blow up while trying to render the component if it's unable to find the file based on filename passed into the component.

Due to that we have to stub out the method that handles the compilation of the assets. It feels like in this situation the thing we really care about is that the correct file is being included.

How allow and expect is that they stub out the method for the class passed in and return "" (by default).
So essentially what happens here is that the layout makes the call to compile admin.js and we intercept that call and return an empty string. Blocking it from actually trying to compile and blowing up.

The reason that we need allow_any_instance_of in the JS test is due to there being a second method call here

So two calls are made:

 <%= javascript_include_tag "govuk_publishing_components/vendor/modernizr" %>

then

 <%= javascript_include_tag "application" %>

Without the allow this line

 expect_any_instance_of(ActionView::Base).to receive(:javascript_include_tag).with("admin").once

blows up because the javascript_include_tag method has been stubbed, but only once with expectation that the argument will be "admin".

The output of the test is something similar to

expected  javascript_include_tag with the argument of "admin", but it was actually "govuk_publishing_components/vendor/modernizr"

The allow allows the method to be called with any argument any amount of times which ensures we don't see the error above. While the expect is checking that the call is made with "admin" once which is the desired out come

Hopefully that makes sense.

Maybe it's clearer if i update the allow to be more explicit and do

allow_any_instance_of(ActionView::Base).to receive(:javascript_include_tag).with("govuk_publishing_components/vendor/modernizr")
 expect_any_instance_of(ActionView::Base).to receive(:javascript_include_tag).with("admin").once

So it's clear that the allow is due to the method being called twice, once with a file we're not worried about with our change to the implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are other approaches we could use like dynamically creating an empty admin.js file before action before running the test, testing what's in the file, then deleting it after running the test, but that comes with it's own setbacks. Still complex, far slower etc.

But happy to chat it through if you'd like!

I'll go back and update the commit message with some of the above.

Copy link
Contributor

Choose a reason for hiding this comment

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

Really interesting stuff, thanks for taking the time to explain 👍

@davidgisbey davidgisbey changed the title Allow custom JS and CS filenames to be passed to admin_for_layout component Update layout_for_admin component to take custom asset filenames Apr 25, 2024
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 8c76f06 to 705bb9b Compare April 25, 2024 09:46
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 25, 2024 09:46 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 705bb9b to 2ac5402 Compare April 25, 2024 09:50
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 25, 2024 09:51 Inactive
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 2ac5402 to 98f1098 Compare April 25, 2024 09:51
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 25, 2024 09:52 Inactive
@davidgisbey
Copy link
Contributor Author

@andysellick i've made the requested changes. Hopefully the above explanation makes sense. Let me know if you not and/or you want any other changes 👍

We're adding an admin interface to our application and want to use
retain application.js & application.scss for the public interface.

This will allow us to pass admin.js and admin.scss in as args so we
can retain only loading the required components for each so the page
load time is fast.

There has been some added complexity in testing this as the #javascript_include_tag
and #stylesheet_link_tag methods being passed a filename that isn't present
in the assets directory will raise an error due to the file not being found
when it's during attempted compilation.

We have a few options here:

1. stub out the methods and return an empty string so there is no attempt to
compile the file. In this situation we would just want to check that the
methods receive the correct filename.
2. create the files dynamically prior to running the test, check the output
on the rendered page and then delete the files after the test has run.
3. skip the test entirely.

We've opted for option 1 as probably less complex and faster than option 2
and preferable to not testing at all.

Unfortunately we've had to use "allow_any_instance_of" and
"expect_any_instance_of" to stub the calls to check that the JS and CSS
filenames are being passed into the #javascript_include_tag and #stylesheet_link_tag
methods.

These are implemeneted in the ActionView::Helpers::AssetTagHelper helper
which is included in ActionView::Base which is particularly gnarly to
attempt to stub a single instance of.

While this isn't ideal, it's probably preferable to having to stub out a
series of objects for what is essentially a very simple test which checks
the correct filename is passed in.
@davidgisbey davidgisbey force-pushed the update-admin-layout-to-take-custom-assets branch from 98f1098 to 5ba7778 Compare April 25, 2024 15:25
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3993 April 25, 2024 15:25 Inactive
@davidgisbey
Copy link
Contributor Author

davidgisbey commented Apr 26, 2024

I've tested it's working as expected on the component guide so i'll merge if there's no objections

@davidgisbey davidgisbey merged commit db67015 into main Apr 26, 2024
13 checks passed
@davidgisbey davidgisbey deleted the update-admin-layout-to-take-custom-assets branch April 26, 2024 09:33
@davidgisbey davidgisbey mentioned this pull request Apr 30, 2024
davidgisbey added a commit that referenced this pull request Apr 30, 2024
- Update layout_for_admin component to take custom asset filenames ([PR #3993](#3993))
davidgisbey added a commit that referenced this pull request Apr 30, 2024
- Update layout_for_admin component to take custom asset filenames [PR #3993](#3993)
davidgisbey added a commit that referenced this pull request Apr 30, 2024
- Update layout_for_admin component to take custom asset filenames PR #3993
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.

None yet

4 participants