I'm writing some controllers tests, however, every controller test, even without authentication, fails because the conn is redirect to somewhere else. The strange is that in my code I never redirect or return such status (307), only CRUD: 200,201, 400 and 500, without redirecting.
Here is one of my controller test:
defmodule SysbovApiWeb.Animals.AnimalsControllerTest do
use SysbovApiWeb.ConnCase, async: true
import SysbovApi.Factory
setup_all :login_and_farm_id
defp login_and_farm_id(_context) do
conn = build_conn()
user = insert(:user)
%{id: farm_id} = insert(:farm, user_id: user.id)
session =
post(conn, "/api/v1/users/sessions", %{
"email" => user.email,
"password" => "123456"
})
assert %{"token" => token, "user" => _} = json_response(session, 201)
conn_with_token = conn |> put_req_header("Authorization", "Bearer #{token}")
%{conn: conn_with_token, farm_id: farm_id}
end
describe "create/2" do
test "returns 201 when all params are correct", %{conn: conn, farm_id: farm_id} do
conn =
post(conn, "/api/v1/farms/animals", %{
"name" => "Macabeuzinho",
"father" => "Macabeus",
"mother" => "Macabeia",
"breed" => "raro",
"color" => "brown",
"weight" => Decimal.new("10.10"),
"farm_id" => farm_id
})
assert %{
"animal" => %{
"breed" => _,
"color" => _,
"farm_id" => _,
"father" => _,
"id" => _,
"mother" => _,
"name" => _,
"weight" => _
}
} = json_response(conn, 201)
end
end
describe "index/2" do
test "returns all animals given a farm", %{conn: conn, farm_id: farm_id} do
insert_list(2, :animal, farm_id: farm_id)
conn = get(conn, "/api/v1/farms/#{farm_id}/animals")
%{animals: animals} = json_response(conn, 200)
assert is_list(animals)
assert length(animals) == 2
end
end
describe "show/2" do
test "returns a specific animal given a farm", %{conn: conn, farm_id: farm_id} do
animal = insert(:animal, farm_id: farm_id)
conn = get(conn, "/api/v1/farms/#{farm_id}/animals/#{animal.id}")
assert %{
"animal" => %{
"breed" => _,
"color" => _,
"farm_id" => _,
"father" => _,
"id" => _,
"mother" => _,
"name" => _,
"weight" => _
}
} = json_response(conn, 200)
end
end
describe "delete/2" do
test "correctly deletes an animal given a id", %{conn: conn, farm_id: farm_id} do
animal = insert(:animal, farm_id: farm_id)
conn = delete(conn, "/api/v1/farms/animals/#{animal.id}")
assert %{deleted: true} = json_response(conn, 200)
end
end
end
My controller:
defmodule SysbovApiWeb.Animals.AnimalsController do
use SysbovApiWeb, :controller
alias SysbovApi.CreateAnimals
alias SysbovApi.Farm.AnimalsRepo
alias SysbovApi.Animals.AnimalsRepo
def create(conn, params) do
case CreateAnimals.run(params) do
{:ok, animal} ->
conn
|> put_status(201)
|> render("create.json", %{animal: animal})
{:error, changeset} ->
conn
|> put_status(400)
|> render(SysbovApiWeb.ErrorView, "400.json", %{changeset: changeset})
end
end
def index(conn, %{"farm_id" => farm_id}) do
case AnimalsRepo.get_animals(farm_id) do
{:ok, animals} ->
render(conn, "index.json", %{animals: animals})
_ ->
conn
|> put_status(400)
|> render(SysbovApiWeb.ErrorView, "400.json")
end
end
def show(conn, %{"animal_id" => animal_id}) do
case AnimalsRepo.get_animal(animal_id) do
{:ok, animal} ->
render(conn, "show.json", %{animal: animal})
{:error, error} ->
conn
|> put_status(500)
|> render("500.json", %{error: error})
end
end
def delete(conn, %{"animal_id" => animal_id}) do
case AnimalsRepo.delete_animal(animal_id) do
{:ok, _deleted} ->
render(conn, "delete.json", %{deleted: true})
{:error, error} ->
conn
|> put_status(500)
|> render(SysbovApiWeb.ErrorView, "500.json", %{error: error})
end
end
end
and my conn case:
defmodule SysbovApiWeb.ConnCase do
@moduledoc """
This module defines the test case to be used by
tests that require setting up a connection.
Such tests rely on `Phoenix.ConnTest` and also
import other functionality to make it easier
to build common data structures and query the data layer.
Finally, if the test case interacts with the database,
we enable the SQL sandbox, so changes done to the database
are reverted at the end of every test. If you are using
PostgreSQL, you can even run database tests asynchronously
by setting `use SysbovApiWeb.ConnCase, async: true`, although
this option is not recommended for other databases.
"""
alias Ecto.Adapters.SQL.Sandbox
use ExUnit.CaseTemplate
using do
quote do
# Import conveniences for testing with connections
import Plug.Conn
import Phoenix.ConnTest
import SysbovApiWeb.ConnCase
alias SysbovApiWeb.Router.Helpers, as: Routes
# The default endpoint for testing
@endpoint SysbovApiWeb.Endpoint
end
end
setup tags do
:ok = Sandbox.checkout(SysbovApi.Repo)
unless tags[:async] do
Sandbox.mode(SysbovApi.Repo, {:shared, self()})
end
{:ok, conn: Phoenix.ConnTest.build_conn()}
end
end
the really strange part is that the conn is only redirected when running all tests, if I test each route, manually, all works fine.
What I'm doing wrong?
Aucun commentaire:
Enregistrer un commentaire