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

Turbo compatibility: return status unprocessable_entity #1880

Merged
merged 1 commit into from
Feb 11, 2021
Merged

Turbo compatibility: return status unprocessable_entity #1880

merged 1 commit into from
Feb 11, 2021

Conversation

jankeesvw
Copy link
Contributor

We are using Administrate quite a lot in our project, and a few weeks ago we upgraded from Turbolinks to Turbo. I noticed that our validations weren't triggering anymore in Administrate.

Then I noticed that the Administrate base class doesn't return the right status code when the record can't be saved.

From the Hotwire docs:

Redirecting After a Form Submission

After a stateful request from a form submission, Turbo Drive expects the server to return an HTTP 303 redirect response, which it will then follow and use to navigate and update the page without reloading.

The exception to this rule is when the response is rendered with either a 4xx or 5xx status code. This allows form validation errors to be rendered by having the server respond with 422 Unprocessable Entity and a broken server to display a “Something Went Wrong” screen on a 500 Internal Server Error.

This pull request returns the correct status codes when saving a record.

@jankeesvw jankeesvw changed the title Turbo compatibly: return status unprocessable_entity Turbo compatibility: return status unprocessable_entity Jan 29, 2021
@pablobm
Copy link
Collaborator

pablobm commented Feb 4, 2021

Thank you for that PR @jankeesvw! Would you be able to add spec examples for both create and update? Currently our controller specs are a bit disorganised, but I think that https://github.com/thoughtbot/administrate/blob/master/spec/controllers/admin/log_entries_controller_spec.rb would be a good place to put them

@jankeesvw
Copy link
Contributor Author

Thank you for that PR @jankeesvw! Would you be able to add spec examples for both create and update? Currently our controller specs are a bit disorganised, but I think that https://github.com/thoughtbot/administrate/blob/master/spec/controllers/admin/log_entries_controller_spec.rb would be a good place to put them

I tried adding a spec, but my expectation is failing. Not sure why, because it works in practice. @pablobm do you have some time to help me?

This is my current .patch with a failing spec:

diff --git a/spec/controllers/admin/log_entries_controller_spec.rb b/spec/controllers/admin/log_entries_controller_spec.rb
index 729fbef..162eefb 100644
--- a/spec/controllers/admin/log_entries_controller_spec.rb
+++ b/spec/controllers/admin/log_entries_controller_spec.rb
@@ -135,6 +135,7 @@ describe Admin::LogEntriesController, type: :controller do
         expect(page).to be_instance_of(Administrate::Page::Form)
         expect(page.resource).to eq(log_entry)
         expect(page.resource.action).to eq(new_action)
+        expect(response).to have_http_status(:unprocessable_entity)
       end
     end
   end

@pablobm
Copy link
Collaborator

pablobm commented Feb 9, 2021

Uh, you are right. For some strange reason, it tries to render the template for :update, instead of for :edit as it's told, and it returns 204 No Content. This is not what it does in development mode. Rails is doing something weird, so let me look into it, hopefully this week.

@jankeesvw
Copy link
Contributor Author

Uh, you are right. For some strange reason, it tries to render the template for :update, instead of for :edit as it's told, and it returns 204 No Content. This is not what it does in development mode. Rails is doing something weird, so let me look into it, hopefully this week.

Are you willing to merge before we improved the tests, now people won't see errors when using Turbo.

@pablobm
Copy link
Collaborator

pablobm commented Feb 11, 2021

I looked into this today. After some head scratching, I realised what was going on. This controller test doesn't actually run Rails's test rendering code. Instead it captures the call to render with a mock, extracts the value of :locals, and runs expectations on that. As a result, nothing is actually rendered, and Rails tells us that the result was a :no_content.

The capture is done with capture_view_locals, which can be seen at https://github.com/thoughtbot/administrate/blob/e1ae45cf44a6b7fce13865175bb5e596ad448ba9/spec/support/controller_helpers.rb

To compound the problem, I don't think there is a standard way of achieving this. It's possible to test :locals, but only in a very limited way, by comparing exact values. See:

https://github.com/rails/rails-controller-testing/blob/4b15c86e82ee380f2a7cc009e470368f7520560a/lib/rails/controller/testing/template_assertions.rb#L104-L108

For now, I'm going to accept this MR, as it fixes the problem at hand and its intent I think is obvious enough. Meanwhile I'll file a separate issue to see how we can address this problem properly and provide better tests.

@pablobm pablobm merged commit c8c413d into thoughtbot:master Feb 11, 2021
@jankeesvw jankeesvw deleted the patch-1 branch February 11, 2021 18:40
@jankeesvw
Copy link
Contributor Author

For now, I'm going to accept this MR, as it fixes the problem at hand and its intent I think is obvious enough. Meanwhile I'll file a separate issue to see how we can address this problem properly and provide better tests.

Thanks for looking into this!

@jankeesvw
Copy link
Contributor Author

@pablobm can you make a new gem release with this change, would be great to get this out.

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.

2 participants