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
New #stub_user controller macro #10243
Conversation
# TODO: remove these stubs | ||
allow(controller).to receive(:check_privileges).and_return(true) | ||
login_as user | ||
allow_any_instance_of(User).to receive(:role_allows?).and_return(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why it's wrong: it accepts custom user with features as input but blindly says "yeah", you can do whatever you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new stub_user
, on the other hand, allows you to create an (features: :all)
"permitted" or "denied"(features: :none)
user. This accounts for the majority of test cases. When you want to test specific features, you should use login_as user_with_feature(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could potentially do stubbing of specific features (that's why the API here is so explicit, so if we run into a reason to do so someday...), but that's not something we're interested in doing quite yet.
@gtanzillo @dclarizio this is what was required in the tests for us to funnel the AppHelper#role_allows, User#role_allows, etc. through one Rbac class. |
@@ -95,7 +95,7 @@ | |||
end | |||
|
|||
it "renders explorer based on RBAC access to feature 'provider_foreman_add_provider'" do | |||
set_user_privileges user_with_feature %w(provider_foreman_add_provider) | |||
login_as user_with_feature %w(provider_foreman_add_provider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should now use login_as
user_with_feature
to test specific features. We don't want to stub things when we're testing specific features as OTHER features would get that stubbed response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other terms, we should use login_as
when you want a real user model, saved to the db, and stub_user
when you want a user object with stubbed responses (stub_user
currently creates a real user model but I'd soon like to try using an RSpec test double or a FactoryGirl object (build, not create))
This is a distinction I'd really like to push, as we can avoid people doing db writes for everything just for a sake of a user object when they can just stub it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added what I mention above here in 9af8717 - see the commit message there for details.
9af8717
to
9f48a19
Compare
The previous build error (that is now green, re-running it) came from an unrelated issue recently merged to master |
We need to add TargetRubyVersion to the .rubocop.yml to avoid the crash boom bang ... Can you do it in this PR, and set it to Ruby 2.2? AllCops:
TargetRubyVersion: "2.2" |
@@ -1,7 +1,7 @@ | |||
describe MiqAeCustomizationController, "ApplicationController::Automate" do | |||
context "#resolve" do | |||
before(:each) do | |||
set_user_privileges | |||
stub_user(features: :all) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at you trying to sneak in the non hash-rockets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kwargs to the rescue!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In all honesty though, these should all be hash rockets...from the caller side, it's a regular hash, not kwargs. kwargs syntax at the signature level, which is what it was designed for, is required: def stub_user(features:)
is required syntax (vs def stub_user(:features =>)
which is invalid syntax)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh I forgot that's true. Ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And yes, I know you have a handy script and are just trolling me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall 👍 LGTM except the minor comments above. |
12d350f
to
d203594
Compare
Replaces #set_user_privileges This consolidates the stubbing of users in controllers specs to a single, flexible, more controlled spot. It enables easier integration of forthcoming tenancy changes (multiple entitlements/roles)
With the addition of #stub_user, this [very janky, barely works] method can be removed.
This changes stub_user to use a non-persisted user object and changes the :user_with_group factory to use a non-persisted group object. This increases test performance as stub_user is called over 1,000 times in controller specs, writing a user and group record to the database every time. Automation specs also make heavy use of :user_with_group, so each group write there is avoided. As expected, stubbing is more performant but loses a little bit of true parity with actual code testing. For example, because the user and group are empty objects and have no primary keys, code that utilizes IDs directly MUST use a real record. For that, one should use create an actual user/group and use 'login_as'. Given that I needed to change only a *single* spec because of this, it seems well worth it in 99% of cases (the spec I have changed here uses current_user.miq_groups.ids in a query for groups added to a report) In short, stub_user vs. login_as should be used as most people are told to use FactoryGirl's create vs. build - Use build as much as you can, but create if you really need to.
d203594
to
2b8420a
Compare
Avoids the 💣 💥 🔥 🚒
2b8420a
to
fbdabcf
Compare
Checked commits chrisarcand/manageiq@5e91d1d~...fbdabcf with ruby 2.2.5, rubocop 0.37.2, and haml-lint 0.16.1 spec/helpers/application_helper_spec.rb
spec/support/auth_helper.rb
|
This replaces the old #set_user_privileges method.
Besides being awesome that you don't need to remember how to spell 'privileges', this replacement method is much more flexible and correct than the previous one.
It is the groundwork for forthcoming role checking changes and reduces the diff substantially.
@miq-bot add_labels tenancy, core, darga/no
@miq-bot assign @Fryguy
cc/ @gtanzillo @dclarizio