Josh HUmphrey
Josh HUmphrey

Reputation: 273

Rspec: How to properly make patch request

I've been searching all over for something that would explain the problem I'm having. I am probably missing something simple so I hope someone can catch my mistake.

Rails.application.routes.draw do

 get 'auth/:provider/callback', to: 'sessions#create', as: 'login'
 get 'auth/failure', to: redirect('/')
 get 'signout', to: 'sessions#destroy', as: 'signout'

 resources :sessions, only: [:create, :destroy]
 resources :home, only: [:show]
 resources :static_pages, only: [:show]
 resources :habits
 root to: "home#show"
 get '/started' => 'home#started'

end

Routes:

   habit GET    /habits/:id(.:format)              habits#show
         PATCH  /habits/:id(.:format)              habits#update
         PUT    /habits/:id(.:format)              habits#update
         DELETE /habits/:id(.:format)              habits#destroy

HabitsController:

def update
  if params[:name].present? && params[:description].present?
    Habit.habit_edit(@current_habit, form_params)
    flash[:success] = "Edited habit: " + @current_habit.name + '!'
    redirect_to habit_path(:id => session[:user_id])
  else
    flash[:notice] = "Habit must have a name and a description"
    redirect_to edit_habit_path(:id => @current_habit.id)
  end
end

HabitsControllerSpec:

describe "#update" do

it "should update the habit name/description" do
  form_params = {
    params: {
    name: "hello",
    description: "hello"
    }
  }
  post :create, form_params
  @current_habit = Habit.first
  form_params = {
    params: {
    name: "new",
    description: "shit"
    }
  }
  **patch "habits/1", form_params**


end

Problem:

1) HabitsController#update should update the habit name/description
 Failure/Error: patch "habits/1", form_params

 ActionController::UrlGenerationError:
   No route matches {:action=>"habits/1", :controller=>"habits", 
:description=>"shit", :name=>"new"}
 # ./spec/controllers/habits_controller_spec.rb:85:in `block (3 
levels) in <top (required)>'

I don't understand why this isn't working. I've tried lots of different methods to make a patch request and can't seem to figure out how to get this test to work. Again, I'm sure it is simple. If I left any important info out let me know. Thanks

Upvotes: 5

Views: 9403

Answers (3)

Marcelo Escobar
Marcelo Escobar

Reputation: 23

I've used resources to generate the routes, but to run update I did as below with rails 4.2

@current_habit = Habit.first

form_params = {
    name: "new",
    description: "shit",
  }

patch :update, {id: @current_habit.id, params: form_params}

Upvotes: 0

Josh HUmphrey
Josh HUmphrey

Reputation: 273

Okay figured it out. First I made a factory for the habit just to clear things up. I kept messing with the syntax and came to the correct answer.

form_params = {
  params: {
  name: "new",
  description: "shit"
  }
}
patch :update,id: 1, form_params

This was telling me wrong number of arguments and I eventually realized I needed to pass the id with my form_params. Like I said, small mistake.

Correct code:

form_params = {
    id: 1,
    name: "new",
    description: "shit",
  }
  patch :update, params: form_params

Upvotes: 9

Paulo Fidalgo
Paulo Fidalgo

Reputation: 22296

I've only used rack-test but I'm pretty sure it will be used or the syntax will be the same or similiar.

  context 'update fields' do
    let(:payload) {
      {
        field: value
      }
    }
    Given do
      repository.save(resource: resource_object)
    end
    When do
       patch('/resources/123', payload.to_json)
    end

    let(:result) { JSON.parse(last_response.body) }

    Then { expect(last_response.status).to eq(400) }
  end

So, first thing I noticed in your code, you're using a POST to create an object, where you should be saving directly.

Second, by the error, it seems you don't have a PATCH method for habits, can you please update your answer with the corresponding output of rails routes?

Upvotes: 1

Related Questions