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

Prevent "have_http_status" from using deprecated methods in Rails 5.2+ #1951

Merged
merged 10 commits into from
Feb 22, 2018
Merged

Prevent "have_http_status" from using deprecated methods in Rails 5.2+ #1951

merged 10 commits into from
Feb 22, 2018

Conversation

wbreeze
Copy link
Contributor

@wbreeze wbreeze commented Jan 31, 2018

This alternative PR (to #1945) Provides a minimum change to solve the problem of response status methods deprecated in Rails 5.2, as raised by issue #1857

This does so without deprecating or changing any status matchers in RSpec, so a Rails 5.2 upgrade will be transparent, at least with respect to not causing deprecation warnings for the :success, :error, and :missing values of has_http_status.

A major or minor release that eliminates the version check will either require Rails 5.2 and map :success to the successful call, or require everyone to change their tests.

@JonRowe
Copy link
Member

JonRowe commented Feb 1, 2018

You'll need to rebase this so you don't bring across a load of 3-7-maintenance commits across to master

@wbreeze
Copy link
Contributor Author

wbreeze commented Feb 1, 2018

Thank you for prompting that, Jon. Agreed and done. The commit history looked terrible, but the diff was okay. With your prompting, I rebased, squashed, and force pushed. Now you have one commit to backport if you want it.

My view of the migration strategy is:

  • Now: Patch or minor release with the version check
  • With Rails 6 or someday: major release that requires 5.2 (or later), eliminates the version check, and maps the old syntax to the new method.

With that, no-one has to port forty tests when they upgrade. (I can only guess the number of extant has_http_status :success tests, but doubt that it's a trivial count.)

@@ -18,7 +18,12 @@ module HaveHttpStatus
# @return response matcher instance
def self.matcher_for_status(target)
if GenericStatus.valid_statuses.include?(target)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rather than check valid statuses and then doing the mapping, this could do the mapping, then check valid statuses. status_method = GenericStatus.map_status(target); if (status_method) ... Then GenericStatus encapsulates all of the logic. I'm willing to make that change.

Copy link
Member

Choose a reason for hiding this comment

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

I'd still like to see this class done away with, and the lookup method defined depending on the version of rails. See below.

Copy link
Member

@JonRowe JonRowe left a comment

Choose a reason for hiding this comment

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

Looking good but I'd still like to see a refactor here.

Also we'd be releasing this in the next minor version as we class it an enhancement, rather than a patch.

We're also unlikely to drop the old functionality for some time. We like to work with as many rails versions as possible.

@@ -255,12 +260,11 @@ def initialize(type)
@invalid_response = nil
end

# @return [Boolean] `true` if Rack's associated numeric HTTP code matched
# the `response` code
# @return [Boolean] value of response status method
Copy link
Member

Choose a reason for hiding this comment

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

I'd like to see the original doc restored, with maybe an additional " or the named response status matches"

@@ -18,7 +18,12 @@ module HaveHttpStatus
# @return response matcher instance
def self.matcher_for_status(target)
if GenericStatus.valid_statuses.include?(target)
Copy link
Member

Choose a reason for hiding this comment

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

I'd still like to see this class done away with, and the lookup method defined depending on the version of rails. See below.


def check_expected_status(test_response, expected)
test_response.send("#{expected}?")
end
Copy link
Member

Choose a reason for hiding this comment

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

Basically this would become something like:

if if 5 < ::Rails::VERSION::MAJOR || (::Rails::VERSION::MAJOR == 5 && 2 <= ::Rails::VERSION::MINOR)
  def check_expected_status(test_response, expected)
    test_response.send("#{expected}?")
  end
else
  RESPONSE_METHODS = {
    success: 'successful',
    error: 'server_error',
    missing: 'not_found'
  }.freeze

  def check_expected_status(test_response, expected)
     test_response.send("#{RESPONSE_METHODS.fetch(response_symbol, response_symbol)}?")
  end
end

@@ -327,6 +337,33 @@ def type_codes
end
end
end

class GenericStatusWithLookup < GenericStatus
Copy link
Member

Choose a reason for hiding this comment

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

And this would go away.

Document the newly added internal method, "response_method"

Add the Rails 5.2 beta as a test environment for travis

Avoid defining tests specific to rails 5.2+ when not relevant

Conditionally define method lookup for Rails 5.2 deprecated response status methods

Add context for Rails 5.2 http status deprecation tests

Remove stray print statement left in have_http_status_spec
@wbreeze
Copy link
Contributor Author

wbreeze commented Feb 19, 2018

Jon:

Thank you for the further guidance on the change that you would like to see.

I'm afraid I went a little further, and made the change forward compatible as well as backward compatible. Allowing the new syntax for any version didn't seem right unless it worked for any version.

The two variants failing on Travis are failing in build.

[
:error, :success, :missing,
:server_error, :successful, :not_found,
:redirect
Copy link
Member

Choose a reason for hiding this comment

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

Almost there! Can we just get some specs covering the usage of the extra methods, these should run on all versions of Rails to show they're being mapped correctly on older versions. Thank you so much for your patience!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for prompting those additional tests. What could go wrong? It turns out that the type codes came back empty in the messages for those new generic methods.

I couldn't resist drying up the tests with a shared_examples block. They were very repetitive.

to(negated_message)
end
end

Copy link
Contributor Author

@wbreeze wbreeze Feb 20, 2018

Choose a reason for hiding this comment

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

The diff from here down looks terrible. All that happened is:

  • the repeated code in this shared example was replaced with invocation of this shared example
  • new tests using the shared example were added for :not_found, :server_error, and :successful

it "raises an ArgumentError" do
expect{ have_http_status(nil) }.to raise_error ArgumentError
end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Everything from here on is actually new, not changed lines.

@wbreeze
Copy link
Contributor Author

wbreeze commented Feb 21, 2018

@JonRowe The two failing combinations are gem dependency errors from bundler. If you hate the refactoring, I'll redo it copy-paste.

Let me know if you would like any further changes.

@JonRowe JonRowe merged commit 9bb089a into rspec:master Feb 22, 2018
@JonRowe
Copy link
Member

JonRowe commented Feb 22, 2018

Thanks for the effort getting this over the line!

JonRowe added a commit that referenced this pull request Feb 22, 2018
@jesperronn
Copy link

In my opinion, this calls for a release, since the deprecation warning is REALLY annoying when upgrading rails projects.

I would suggest a minor version bump, since it's an added feature for Rails 5.2 and it doesn't break existing behaviour.

@JonRowe
Copy link
Member

JonRowe commented Mar 3, 2018 via email

benoittgt pushed a commit to benoittgt/rspec-rails that referenced this pull request Mar 4, 2018
@jonekdahl
Copy link

jonekdahl commented Apr 13, 2018

I second @jesperronn's suggestion for a point release. Now that Rails 5.2 is out, it would be neat if there was a released version of rspec-rails that doesn't not trigger deprecation warnings.

@jfi
Copy link

jfi commented Apr 19, 2018

Any news on a release for this?

sihugh added a commit to alphagov/local-links-manager that referenced this pull request Jun 1, 2018
This resolves the deprecation warning:

> The success? predicate is deprecated and will be removed in Rails 6.0. Please use successful? as provided by Rack::Response::Helpers.

There is a [fix for this that has been merged](rspec/rspec-rails#1951)
for rspec-rails, but is [not yet released](https://github.com/rspec/rspec-rails/blob/678b313cf3cc3bdb2c59149ee3e290fd590460d1/Changelog.md).
We could revert it back afterwards if we're worried, but we expect this to be
a `200` response at the moment, not a `202` or anything so this is fine I think.
sihugh added a commit to alphagov/local-links-manager that referenced this pull request Jun 4, 2018
This resolves the deprecation warning:

> The success? predicate is deprecated and will be removed in Rails 6.0. Please use successful? as provided by Rack::Response::Helpers.

There is a [fix for this that has been merged](rspec/rspec-rails#1951)
for rspec-rails, but is [not yet released](https://github.com/rspec/rspec-rails/blob/678b313cf3cc3bdb2c59149ee3e290fd590460d1/Changelog.md).
We could revert it back afterwards if we're worried, but we expect this to be
a `200` response at the moment, not a `202` or anything so this is fine I think.
@Aesthetikx
Copy link

@samphippen Sorry to bump but I would also appreciate a point release including this for our Rails 5.2 upgrade ❤️

Aesthetikx pushed a commit to Revela/rspec-rails that referenced this pull request Jun 18, 2018
Prevent "have_http_status" from using deprecated methods in Rails 5.2+
@LeeXGreen
Copy link

I would also really appreciate a point release with this fix.

We're currently pointing to 3.8.pre via Git SHAs, but it would be much nicer to just pull this from Rubygems.

sebjacobs pushed a commit to futurelearn/rspec-rails that referenced this pull request Mar 15, 2019
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

7 participants