0
votes

I made a test to update the user changeset that should pass with invalid data, but the validation of the user aren't allowing it to pass , sorry if this is noob, im just starting at elixir

   test "renders errors when data is invalid", %{conn: conn, user: user} do
      assert conn = put(conn, Routes.api_user_path(conn, :update, user), user: @invalid_attrs)
      assert json_response(conn, 422)["errors"] != %{}
    end
  end

The output


** (Ecto.InvalidChangesetError) could not perform update because changeset is invalid.

     Errors

         %{
           email: [{"can't be blank", [validation: :required]}],
           name: [{"can't be blank", [validation: :required]}],
           password: [{"can't be blank", [validation: :required]}],
           password__confirmation: [{"can't be blank", [validation: :required]}]
         }

     Applied changes

         %{is_active: nil}

     Params

         %{
           "email" => nil,
           "is_active" => nil,
           "name" => nil,
           "password" => nil,
           "password__confirmation" => nil
         }

     Changeset
Thats all lines been used

         #Ecto.Changeset<
           action: :update,
           changes: %{is_active: nil},
           errors: [
             name: {"can't be blank", [validation: :required]},
             email: {"can't be blank", [validation: :required]},
             password: {"can't be blank", [validation: :required]},
             password__confirmation: {"can't be blank", [validation: :required]}
           ],
           data: #TrelloClone.Auth.User<>,
           valid?: false
   @invalid_attrs %{name: nil, email: nil, is_active: nil,password: nil,password__confirmation: nil}


def update(conn, %{"id" => id, "user" => user_params}) do
    user = Auth.get_user!(id)

    with {:ok, %User{} = user} <- Auth.update_user(user, user_params) do
      render(conn, "show.json", user: user)
    end
  end


  def update_user(%User{} = user, attrs) do
    user
    |> User.changeset(attrs)
    |> Repo.update!()
  end


 def get_user!(id), do: Repo.get!(User, id)

Thats all lines been used, obs: they are in different files, Auth is the context of User

1
Can you show what @invalid_attrs is as well as your code in the controller to update a user?sbacarob
i will put at the postudduu
Use update not update! in your update_user function.zwippie
Your @invalid_attrs map uses atom keys (e.g. %{id: nil}, but your update function requires pattern-matching on string keys, e.g. %{"id" => id}. Is that part of what's going on here? Can you paste in the changeset functions from your User module?Everett

1 Answers

1
votes

According to the documentation, Repo.update! you use in update_user/2

Same as Repo.update/2 but returns the struct or raises if the changeset is invalid.

The exception is raised on the invalid changeset and your test blows up. If you want to indeed raise on incorrect inputs, you might amend the test with ExUnit.Assertions.assert_raise/2

test "renders errors when data is invalid", %{conn: conn, user: user} do
  assert_raise  Ecto.InvalidChangesetError, fn ->
    put(conn, Routes.api_user_path(conn, :update, user), user: @invalid_attrs)
  end
end

But since you want to display 422, you’d better off with using Repo.update/2 in update_user/2

def update_user(%User{} = user, attrs) do
  user
  |> User.changeset(attrs)
  |> Repo.update() # not Repo.update!()
end