-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
v4.6.0 breaks rspec controller tests #5021
Comments
Hi @philayres, thanks for the issue. Could you provide more info about what is happening in your application? It could be an application that reproduces this issue in isolation or just the stacktrace. |
This is the rspec example:
The error is:
That error aligns with the rspec example. But in reality every similar example like this fails. As soon as I rolled back to 4.5.0 the error went away. |
Oh, and the method for logging in
I have both a user and admin entity working independently. |
Could you also send the backtrace? that would help find where it's breaking inside Devise. |
That's the strange thing. In the console you have the full error that I have in the comment above (which is strangely short). In the test log, despite having changed logging level to :debug it still doesn't give me the error or any stack trace. I'm assuming that there is something nasty happening low down the stack that is getting swallowed up without logging. I'll keep digging to see if I can find more info. |
I have stepped through in a debugger and have narrowed it down to:
This final line is where it dies. My guess, not knowing the internals of the code, is that this is forcing a redirection when a user is not logged in? But in previous versions my user would have been successfully logged in prior to this point. So I don't really understand either this error, or why I would have arrived here unauthenticated. Of course, it is possible that I'm not understanding what is going on here. |
Are you using Rails engine? The only this that I can think now that was released and could break the We came up with this solution to check if the
EDITI'm already able to reproduce the issue. |
Just to make sure, have you the |
…ent?` When an application does not define a `root`, the method will be undefined instead of returning a falsey value. This commit also includes a new test with fake objects that mimic this behavior. Related resources: * 1aab449#diff-c1be825bdb5f3160081e41432f83d0d7R278 * #5021
@philayres We were able to reproduce the issue with the following scenario: a Rails application that doesn't have a After the commit mentioned by @feliperenan, we started calling This is definitely a regression and we're going to push a fix as soon as we can. But, what concerns me the most about your report is that in your tests you're expecting the user to be logged in successfully, but right now the authentication is failing. Can you point your application to the let-fix-root-path branch and test it again? This way we can remove this error and see whether there's another issue happening there. |
Ok, I just checked out the branch you suggested. As you guessed, this helped, but did not solve all the problems. The following steps through where I have looked to identify the root cause. Sorry if some of it is irrelevant; I just want to make sure I don't miss something that could be meaningful. Running the spec again I'm now getting different errors:
Stepping through an authentication reveals an issue with the authentication. Where I call
and subsequently
... I spot a problem. The If I force a value with Something must have changed in this area, where the It feels to me that it is the test code that has changed, since human testing in development runs fine. I will keep digging to see if I can spot what has changed and where. |
OK, easier to find than I expected. Blame The reasoning for me clearing the plain text password after save in the user model is that I'm checking for actual password value change ( So from the point of view of Devise, the above change broke my tests (and maybe others will experience this). For now I'm going to dig some more to decide whether I adapt my code or propose a change in Devise. |
@tegon I didn't answer your previous question about the |
…ent` (#5022) When an application does not define a `root`, the method will be undefined instead of returning a falsey value. This commit also includes a new test with fake objects that mimic this behavior. Related resources: * 1aab449#diff-c1be825bdb5f3160081e41432f83d0d7R278 * #5021
@philayres The About the As for your concern of leaking the password, Rails already replaces it with the value "[FILTERED]" in the logs via the irb(main):007:0> u = User.first
User Load (0.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<User id: 2, email: "bruce@wayne.com", created_at: "2019-01-30 12:50:45", updated_at: "2019-01-30 13:03:57">
irb(main):008:0> u.password = '123'
=> "123"
irb(main):009:0> p u
#<User id: 2, email: "bruce@wayne.com", created_at: "2019-01-30 12:50:45", updated_at: "2019-01-30 13:03:57">
=> #<User id: 2, email: "bruce@wayne.com", created_at: "2019-01-30 12:50:45", updated_at: "2019-01-30 13:03:57">
irb(main):010:0> puts u
#<User:0x00007fe579b64f20>
=> nil Also, Rails 6 will come with a feature called I'm not sure if those cover the cases you're worried about. If they don't, please let me know the exceptions. Thanks. |
The actual challenge I had was that my model forces password changes after first sign in, and these were breaking specs. For example, if I am running a series of controller tests like this:
I have many combinations of these types of things to ensure the implementation in my application actually does both what Devise claims and what the auditors might check for. The challenge was that in these series of model tests was that holding the plain text password between the steps above wouldn't allow for sensible checking whether a new password had been provided for sign in or to update the record, etc. My model code never knew if the password had changed (possibly a convoluted set of checks going on in my implementation) and could not fire callbacks consistently. Basically having the ability to clear the plain text password attribute automatically on save allowed complex test sequences to run without having to constantly reload the user record at every step, or worry that the password was being extracted from the user record in some other unrelated chunk of code. This is the leakage I mean; the password was leaking from one mode of use (creating the user) to another (testing authentication, checking for password change, validating password age, viewing user details etc) Anyway, I can make the changes to allow my specs to run without clearing the password attribute after save, by reloading user records representing more how a series of web requests would actually run. It breaks things from previously, but maybe I can accept that. I'm still not happy that the controller tests fail so obscurely when password is set to nil. The controller Thoughts? |
By looking at this thread, I'm also having similar issues with v6.4.1
which points to this:
I don't have a root_path defined. Will having a root_path defined will be something necessary from now on? |
@rodrigo-puente Nope, that was fixed in version |
@philayres I don't get exactly what the issues were to create your specs - if you want to create a sample application I can take a look at them and see if I can think of another solution. But when you said:
I understood that this issue is only for your test environment - please correct me if I got it wrong - when you test it manually in a browser everything works correctly? If that's the case, I'd say it's better to keep the specs as close to the reality as possible. It's a bummer when the tests are failing but the system is working fine due to differences from environments.
I know this is bad but the reason we released this change in a minor version is that we consider the old behavior a bug. We fixed and thought it wouldn't have those kinds of issues but it's hard to know how the code is being used throughout applications out there. We are sorry it's going to cause you trouble to update but we think it's the best way to go. |
@tegon this is probably a good time for me to go back and DRY up my tests anyway. Things have got messy over time. Thanks for you thoughts and rapid response to this issue. I'll close it now. |
Regarding nilifying #encrypted_password, I may missing something, but if, when I load a user model, #password is blank(as it's defined merely by attr_reader), won't any subsequent save of the user model cause encrypted_password to be cleared and persisted? |
@erich-team Not sure if I understood correctly, is this what you mean? ❯ rails c
Running via Spring preloader in process 35300
Loading development environment (Rails 5.2.2)
irb(main):001:0> u = User.first
User Load (0.5ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<User id: 1, email: "bruce@wayne.com", created_at: "2019-02-21 19:05:54", updated_at: "2019-02-22 19:01:31">
irb(main):002:0> u.password
=> nil
irb(main):003:0> u.encrypted_password
=> "$2a$11$rHW3mrrB6nzBIjueG1rSgOy2Dt4vStVk.3QLA4yWJS8yR0/Y1Jjym"
irb(main):004:0> u.save # encrypted_password is not updated to nil here
(0.3ms) BEGIN
(0.3ms) COMMIT
=> true
irb(main):005:0> u.password
=> nil
irb(main):006:0> u.encrypted_password
=> "$2a$11$rHW3mrrB6nzBIjueG1rSgOy2Dt4vStVk.3QLA4yWJS8yR0/Y1Jjym"
irb(main):007:0> The |
The issue appears to be with strip_whitespace_keys. This...
... in Obviously, the simplest solution is to not include password and password_confirmation, but it seems like this might be less than ideal. I have a user base that isn't necessarily... adept ...adept at typing and have to do things like strip white-space from these attributes. |
@erich-team I see 🤔 I'm not familiar with your user base or your application at all, but it seems to me that it's dangerous to change the password input in any way. I mean, theoretically, one could choose to deliberately include a white space on their password. If you want to prevent them from including those spaces as mistakes, I think it would be better to add a validation for this and let them know that they've typed their password with an extra whitespace so that they can fix it. Does that make sense to you? |
My user base is truck drivers. :) Good people, not always the most
accomplished typists. That said, we do have a work around.
…On Thu, Feb 28, 2019 at 8:33 AM Leonardo Tegon ***@***.***> wrote:
@erich-team <https://github.com/erich-team> I see 🤔
I'm not familiar with your user base or your application at all, but it
seems to me that it's dangerous to change the password input in any way. I
mean, theoretically, one could choose to deliberately include a white space
on their password.
If you want to prevent them from including those spaces as mistakes, I
think it would be better to add a validation for this and let them know
that they've typed their password with an extra whitespace so that they can
fix it. Does that make sense to you?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#5021 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AfbsCZvV9sMEeZc8lBtSU6ZVzOFCXpqVks5vR-iygaJpZM4awdbL>
.
--
Erich L Timkar
|
@erich-team Since this broke a lot of existing applications like yours, we decided to roll back the original change. If you want to return to the original behavior you can update to version Thanks! |
Environment
Current behavior
I just updated to 4.6.0 (no other changes were made) and the rspec controller tests now return
undefined method root_path
after running a sign_in.4.5.0 does not exhibit this behaviour.
Expected behavior
root_path
should return a value.The text was updated successfully, but these errors were encountered: