Skip to content

Commit 3c04141

Browse files
committed
feat: add tests for protected routes
1 parent c37e67a commit 3c04141

5 files changed

Lines changed: 67 additions & 37 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
defmodule ApiEcommerce.AuthErrorHandler do
2+
import Plug.Conn
3+
4+
@behaviour Guardian.Plug.ErrorHandler
5+
6+
@impl Guardian.Plug.ErrorHandler
7+
def auth_error(conn, {type, _reason}, _opts) do
8+
conn
9+
|> put_resp_content_type("application/json")
10+
|> send_resp(401, '')
11+
end
12+
13+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
defmodule ApiEcommerce.Guardian.AuthPipeline do
2+
use Guardian.Plug.Pipeline, otp_app: :api_ecommerce,
3+
module: ApiEcommerce.Guardian,
4+
error_handler: ApiEcommerce.AuthErrorHandler
5+
6+
plug Guardian.Plug.VerifyHeader, realm: "Bearer"
7+
plug Guardian.Plug.EnsureAuthenticated
8+
plug Guardian.Plug.LoadResource
9+
end

lib/api_ecommerce_web/router.ex

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,26 @@
11
defmodule ApiEcommerceWeb.Router do
22
use ApiEcommerceWeb, :router
33

4+
alias ApiEcommerce.Guardian
5+
46
pipeline :api do
57
plug :accepts, ["json"]
6-
plug :fetch_session
78
end
89

910
pipeline :auth do
10-
plug :verify_auth
11+
plug Guardian.AuthPipeline
1112
end
1213

1314
scope "/v1", ApiEcommerceWeb do
1415
pipe_through :api
16+
1517
post "/users/sign_in", UserController, :sign_in
18+
post "/users/sign_up", UserController, :create
1619
end
1720

1821
scope "/v1", ApiEcommerceWeb do
19-
pipe_through [:api]
20-
resources "/users", UserController, except: [:new, :edit]
21-
end
22-
23-
# Plug function
24-
defp verify_auth(conn, _opts) do
25-
current_user_id = get_session(conn, :current_user_id)
22+
pipe_through [:api, :auth]
2623

27-
if current_user_id do
28-
conn
29-
else
30-
conn
31-
|> put_status(:unauthorized)
32-
|> put_view(MyAppWeb.ErrorView)
33-
|> render("401.json", message: "Unauthenticated user")
34-
|> halt()
35-
end
24+
resources "/users", UserController, except: [:new, :create, :edit]
3625
end
3726
end

lib/guardian.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ defmodule ApiEcommerce.Guardian do
1212

1313
def resource_from_claims(claims) do
1414
id = claims["sub"]
15-
resource = MyApi.Accounts.get_user!(id)
15+
resource = ApiEcommerce.Auth.get_user!(id)
1616
{:ok, resource}
1717
end
1818

test/api_ecommerce_web/controllers/user_controller_test.exs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ defmodule ApiEcommerceWeb.UserControllerTest do
3434

3535
setup %{conn: conn} do
3636
{:ok, conn: conn, current_user: current_user} = setup_current_user(conn)
37-
{:ok, conn: put_req_header(conn, "accept", "application/json"), current_user: current_user}
37+
{:ok, token, _} = Guardian.encode_and_sign(current_user)
38+
{:ok, conn: put_req_header(conn, "accept", "application/json"), current_user: current_user, token: token}
3839
end
3940

4041
describe "index" do
41-
test "lists all users", %{conn: conn, current_user: current_user} do
42-
conn = get(conn, Routes.user_path(conn, :index))
42+
test "lists all users", %{conn: conn, current_user: current_user, token: token} do
43+
44+
conn = conn
45+
|> put_req_header("authorization", "bearer: " <> token)
46+
|> get(Routes.user_path(conn, :index))
47+
4348
assert json_response(conn, 200)["data"] == [
4449
%{
4550
"id" => current_user.id,
@@ -52,13 +57,15 @@ defmodule ApiEcommerceWeb.UserControllerTest do
5257
end
5358

5459
describe "create user" do
55-
test "renders user when data is valid", %{conn: conn} do
56-
conn = post(conn, Routes.user_path(conn, :create), user: @create_attrs)
57-
assert %{"id" => id} = json_response(conn, 201)["data"]
60+
test "renders user when data is valid", %{conn: conn, token: token} do
61+
request1 = post(conn, Routes.user_path(conn, :create), user: @create_attrs)
62+
assert %{"id" => id} = json_response(request1, 201)["data"]
5863

59-
conn = get(conn, Routes.user_path(conn, :show, id))
64+
request2 = conn
65+
|> put_req_header("authorization", "bearer: " <> token)
66+
|> get(Routes.user_path(conn, :show, id))
6067

61-
assert json_response(conn, 200)["data"] == %{
68+
assert json_response(request2, 200)["data"] == %{
6269
"id" => id,
6370
"email" => @create_attrs.email,
6471
"status" => "active",
@@ -75,31 +82,40 @@ defmodule ApiEcommerceWeb.UserControllerTest do
7582
describe "update user" do
7683
setup [:create_user]
7784

78-
test "renders user when data is valid", %{conn: conn, user: %User{id: id} = user} do
79-
conn = put(conn, Routes.user_path(conn, :update, user), user: @update_attrs)
80-
assert %{"id" => ^id} = json_response(conn, 200)["data"]
85+
test "renders user when data is valid", %{conn: conn, user: %User{id: id} = user, token: token} do
86+
request1 = conn
87+
|> put_req_header("authorization", "bearer: " <> token)
88+
|> put(Routes.user_path(conn, :update, user), user: @update_attrs)
89+
90+
assert %{"id" => ^id} = json_response(request1, 200)["data"]
8191

82-
conn = get(conn, Routes.user_path(conn, :show, id))
92+
request2 = conn
93+
|> put_req_header("authorization", "bearer: " <> token)
94+
|> get(Routes.user_path(conn, :show, id))
8395

84-
assert json_response(conn, 200)["data"] == %{
96+
assert json_response(request2, 200)["data"] == %{
8597
"id" => id,
8698
"email" => @update_attrs.email,
8799
"status" => user.status |> Atom.to_string(),
88100
"role" => user.role |> Atom.to_string()
89101
}
90102
end
91103

92-
test "renders errors when data is invalid", %{conn: conn, user: user} do
93-
conn = put(conn, Routes.user_path(conn, :update, user), user: @invalid_attrs)
104+
test "renders errors when data is invalid", %{conn: conn, user: user, token: token} do
105+
conn = conn
106+
|> put_req_header("authorization", "bearer: " <> token)
107+
|> put(Routes.user_path(conn, :update, user), user: @invalid_attrs)
94108
assert json_response(conn, 422)["errors"] != %{}
95109
end
96110
end
97111

98112
describe "delete user" do
99113
setup [:create_user]
100114

101-
test "deletes chosen user", %{conn: conn, user: user} do
102-
conn = delete(conn, Routes.user_path(conn, :delete, user))
115+
test "deletes chosen user", %{conn: conn, user: user, token: token} do
116+
conn = conn
117+
|> put_req_header("authorization", "bearer: " <> token)
118+
|> delete(Routes.user_path(conn, :delete, user))
103119
assert response(conn, 204)
104120

105121
assert_error_sent 404, fn ->
@@ -111,7 +127,10 @@ defmodule ApiEcommerceWeb.UserControllerTest do
111127
describe "sign_in user" do
112128
test "renders user when user credentials are good", %{conn: conn, current_user: current_user} do
113129
conn =
114-
post(conn, Routes.user_path(conn, :sign_in, %{ email: current_user.email, password: @current_user_attrs.password}))
130+
post(
131+
conn,
132+
Routes.user_path(conn, :sign_in, %{email: current_user.email, password: @current_user_attrs.password})
133+
)
115134

116135
assert json_response(conn, 200)["data"]["id"] == current_user.id
117136
assert json_response(conn, 200)["data"]["email"] == current_user.email

0 commit comments

Comments
 (0)