0
votes

My user#update method appears to be working as anticipated. When performing this method as requested from my front-end, a successful update occurs. The test for the method, however, fails.

For my test, I'm logging the user in, then attaching the returned auth_token in the request headers.

Here is the test:

test "should successfully update valid email" do
    old = @user.auth_token
    post api_login_url, params: { session: @credentials }
    @user.reload
    assert_not_equal old, @user.auth_token
    old_user = @user
    @request.headers["Authorization"] = @user.auth_token
    patch "/api/users/" + @user.id.to_s, params: { email: "[email protected]", password: "testtest" }, headers: @request.headers
    assert_response 201
    assert_equal "[email protected]", User.find(@user.id).email
  end

The error:

Expected: "[email protected]"
Actual: "[email protected]"

In my controller (@user is already set): before_action :authenticate_with_token!, only: [:update, :destroy] before_action :set_user, only: [:show, :update, :destroy, :confirm, :posts, :comments] wrap_parameters :user, include: [:username, :email, :password, :password_confirmation]

def update
   if @user.update(user_params)
     render json: @user
   else
     render json: @user.errors, status: :unprocessable_entity
   end
end

def user_params
   params.require(:user).permit(:username, :email, :password, :password_confirmation, :confirmation_code, :confirmed)
end

The user model:

require 'json_web_token'

class User < ApplicationRecord
  before_save { email.downcase! }
  before_create :generate_authentication_token!
  before_update :reset_confirmed!, :if => :email_changed?
  has_secure_password
  has_many :posts
  has_many :comments
  has_many :votes
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
  validates :username, presence: true, length: { maximum: 24 }, uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 8 }
  validates :auth_token, uniqueness: true

  def generate_authentication_token!
    begin
      self.auth_token = JsonWebToken.encode('id' => self.id, 'username' => self.username)
    end while self.class.exists?(auth_token: auth_token)
  end

  def destroy_token!
    self.auth_token = nil
  end

  def reset_confirmed!
    self.confirmed = false
  end
end

In case anyone will ask, I've tried removing the before_update :reset_confirmed! call.

I've tried rewriting the tests many different ways. The assert_response 201 does not fail.

Rails version: 5.0.0.beta2

Ruby version: 2.2.3 (x86_64-darwin15)

1
use a debugger, and set a breakpoint in the update method - Meier

1 Answers

1
votes

You need to wrap your params:

patch "/api/users/" + @user.id.to_s,
      params: { user: { email: "[email protected]", password: "testtest" }},
      headers: @request.headers

I am however quite surprised you are not getting an exception (require(:user) should raise one when params[:user] is missing), so let me know if it is working.