HI,
I suppose solution is pretty easy, but for many hours I cant find it and I am struggling now with controller tests that need authenticated user to move on. I tried few solutions from forum and actually I still get failed tests.
Long story short: I have separated user authentication with user profile/data. I dont know if there is better solution but I let auth user create only one user profile with his data (first name, country etc.). Its only allowed to authenticated and confirmed user.
Here are my functions:
Profile_controller.ex
def show_me(conn, _params) do
user = conn.assigns.current_user
profile = Accounts.get_profile_by_user_id(user.id)
render(conn, "show_me.json", profile: profile)
end
def create(conn, profile_params) do
user = conn.assigns.current_user
if Accounts.get_profile_by_user_id(user.id) do
conn
|> put_status(:forbidden)
|> json(%{message: "You are allowed to have only one profile"})
else
with {:ok, %Profile{} = profile} <- Accounts.create_profile(user, profile_params) do
conn
|> put_status(:created)
|> json(%{username: profile.username, message: "Profile created"})
end
end
end
Profile_controller_test.exs
setup %{conn: conn} do
{:ok, conn: put_req_header(conn, "accept", "application/json")}
end
describe "show_me profile" do
setup do
%{user: AccountsFixtures.confirmed_user_fixture()}
end
test "renders profile when data is valid", %{conn: conn, user: user} do
token = Bookshare.Auth.generate_user_session_token(user)
conn = conn |> Plug.Conn.put_req_header("authorization", "Token #{token}")
profile = AccountsFixtures.profile_fixture(user)
conn = get(conn, Routes.profile_path(conn, :show_me))
assert json_response(conn, 200)
end
test "renders errors when data is invalid", %{conn: conn, user: user} do
profile = AccountsFixtures.profile_fixture(user)
conn = get(conn, Routes.profile_path(conn, :show_me))
assert json_response(conn, 401)
end
end
Accounts_fixtures.exs
def confirmed_user_fixture(attrs \\ %{}) do
{:ok, user} =
attrs
|> valid_user_attributes()
|> Bookshare.Auth.register_user()
user = Map.put(user, :is_confirmed, true)
user
end
def profile_fixture(user, _attrs \\ %{}) do
attrs = %{
username: unique_profile_username()
}
{:ok, profile} = Bookshare.Accounts.create_profile(user, attrs)
profile
end
Basis on show_me test I would do easily create/update tests, but everytime I get 401 Unauthorized error
1) test show_me profile renders profile when data is valid (BookshareWeb.ProfileControllerTest)
test/bookshare_web/controllers/profile_controller_test.exs:98
** (RuntimeError) expected response with status 200, got: 401, with body:
"{\"errors\":{\"detail\":\"Unauthorized\"}}"
code: assert json_response(conn, 200)
stacktrace:
(phoenix 1.6.14) lib/phoenix/test/conn_test.ex:369: Phoenix.ConnTest.response/2
(phoenix 1.6.14) lib/phoenix/test/conn_test.ex:415: Phoenix.ConnTest.json_response/2
test/bookshare_web/controllers/profile_controller_test.exs:105: (test)