Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add specs from config refactor #139

Merged
merged 6 commits into from
Oct 27, 2024
Merged

Conversation

bknoles
Copy link
Collaborator

@bknoles bknoles commented Oct 22, 2024

The back and forth on #121 revealed a couple places where we lacked test coverage. I created them locally as I reviewed.

This PR adds them in so Future Us have them available.

@@ -1,6 +1,7 @@
class InertiaShareTestController < ApplicationController
inertia_share name: 'Brandon'
inertia_share sport: -> { 'hockey' }
inertia_share({a_hash: 'also works'})
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@skryukov pointed this one out in #121

end
end

context "when there is conditional data shared via before_action" do
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Freezing the shared data prevents the before_action conditional sharing hack I cooked up! It's a really nice guard rail.

@@ -154,4 +154,12 @@
end
end
end

describe 'a non existent route' do
it 'raises a 404 exception' do
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Arguably this is just testing Rails instead of InertiaRails, but I wrote this to reproduce a possible bug that @skryukov found in the middleware, so I'm leaving it in.

protected

def conditionally_share_a_prop
self.class.inertia_share incorrectly_conditionally_shared_prop: 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

genuine question: Why are we explicitly testing that this fails as opposed to just not testing it if it's undocumented behavior?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

When I first wrote a variation of this test, it didn't fail. It actually passed. Before #121 , this code would not conditionally share that prop. Because the inertia_share store is a class instance variable, it would be included on all subsequent requests after the first time it ran.

It's not very elegant code, but I think the use case is valid. If I can share data per-controller, why not per action? I wrote the original spec just to document the behavior.

However, @ElMassimo 's refactor actually prevents this from occurring at all because it freezes the shared data structure once the controller class is loaded into memory. And that is (part of) the intended behavior of his change. So, the spec now documents/ensures you can't even try the contrived workaround for per-action data sharing. To me, this is a nice guardrail that fails loudly, and since I was surprised by the new behavior when I added the spec back, I think it's worth keeping!

it "raises an error because it is frozen" do
expect {
get conditional_share_show_with_a_problem_path, headers: {'X-Inertia' => true}
}.to raise_error(FrozenError)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Does anyone by chance know why Rails 7.0 and lower doesn't raise an error here while Rails 7.1 does?

My guess is that maybe there was a change in the way Rails loads the code in 7.1, and previous versions don't actually load/freeze the data in the controller before this line gets called?

Copy link
Contributor

Choose a reason for hiding this comment

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

We use Rails 7.1 config.action_dispatch.show_exceptions = :none config option for the dummy app, which evaluates to just truthy in Rails < 7.1 and acts like the :all option:
https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-ways-to-handle-exceptions-in-controller-tests-integration-tests-and-system-tests

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yea, that was part of it but there was a second subtler bug. Because the shared data is frozen the first time you access the shared data, if the first request to a controller has one of these (contrived) conditionally shared data examples, then it won't raise an error.

So, in the test suite, the failure (to raise a FrozenArray exception) was intermittent, depending on which spec in that file ran first.

It's an edge case of an edge case, so I don't feel we need to prevent it; and I still like having a spec to document the frozen data behavior.

In any case, thanks for #140 , it gave me a headstart tonight once I got back to looking at this one!

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, good catch. What do you think about marking inertia_share and inertia_config as protected? This way, calling them from action will raise an error, which might be a clear signal to users that they're doing something wrong.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yea, that might be cleaner. I'm not super worried about it either way now. It'll raise the FrozenArray error the second time you try to call the conditional action, so the failure I was seeing was just one of those test suite not quite matching reality quirks.

The per-action use case isn't actually officially supported at the moment, so we're being helpfully defensive enough already, IMO.

@bknoles bknoles merged commit 56dfc76 into master Oct 27, 2024
18 checks passed
@bknoles bknoles deleted the add-specs-from-config-refactor branch October 27, 2024 00:28
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
spec.name = "inertia_rails"
spec.version = InertiaRails::VERSION
spec.authors = ["Brian Knoles", "Brandon Shar", "Eugene Granovsky"]
spec.email = ["brain@bellawatt.com", "brandon@bellawatt.com", "eugene@bellawatt.com"]
spec.email = ["brian@bellawatt.com", "brandon@bellawatt.com", "eugene@bellawatt.com"]
Copy link
Contributor

Choose a reason for hiding this comment

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

It was a cool email, though 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Maybe it should be my cooler alter ago 😅!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants