diff --git a/lib/bokken/guards.ex b/lib/bokken/guards.ex index 189eff5f..57477e27 100644 --- a/lib/bokken/guards.ex +++ b/lib/bokken/guards.ex @@ -18,6 +18,20 @@ defmodule Bokken.Guards do defguard is_guardian(conn) when conn.assigns.current_user.role === :guardian defguard is_registered(conn) when conn.assigns.current_user.registered + @doc """ + Defines the way to proceed in specific roles situations. + + ## Examples + + defguard is_ninja_guardian(user, ninja) when user.role == :guardian and user.guardian.id == ninja.guardian.id + Means to return True when a user is the ninja's guardian. + + """ + defguard is_ninja_guardian(user, ninja) + when user.role == :guardian and user.guardian.id == ninja.guardian.id + + defguard is_ninja_user(user, ninja) when user.role == :ninja and user.id == ninja.user_id + @doc """ Defines the way to proceed in specific error situations. diff --git a/lib/bokken_web/controllers/ninja/ninja_controller.ex b/lib/bokken_web/controllers/ninja/ninja_controller.ex index e6e3bd78..be7cd3c9 100644 --- a/lib/bokken_web/controllers/ninja/ninja_controller.ex +++ b/lib/bokken_web/controllers/ninja/ninja_controller.ex @@ -14,20 +14,25 @@ defmodule BokkenWeb.NinjaController do when is_map_key(params, "badge_id") when is_map_key(params, "event_id") do ninjas = Accounts.list_ninjas() - render(conn, :index, ninjas: ninjas) + render(conn, :index, %{ninjas: ninjas, current_user: conn.assigns.current_user}) end - def index(conn, _params) when is_guardian(conn) or is_organizer(conn) do - guardian_id = conn.assigns.current_user.guardian.id + def index(conn, _params) when is_guardian(conn) do + current_user = Accounts.get_user!(conn.assigns.current_user.id, [:guardian]) + guardian_id = current_user.guardian.id guardian = Accounts.get_guardian!(guardian_id, [:ninjas]) - render(conn, :index, ninjas: guardian.ninjas) + + render(conn, :index, %{ + ninjas: guardian.ninjas, + current_user: current_user + }) end def create(conn, %{"event_id" => event_id, "ninja_id" => ninja_id}) when is_guardian(conn) or is_organizer(conn) do with {:ok, %Event{} = event, %Lecture{} = _lecture} <- Accounts.register_ninja_in_event(event_id, ninja_id) do - render(conn, :index, ninjas: event.ninjas) + render(conn, :index, %{ninjas: event.ninjas, current_user: conn.assigns.current_user}) end end @@ -39,7 +44,7 @@ defmodule BokkenWeb.NinjaController do conn |> put_status(:created) |> put_resp_header("location", ~p"/api/teams/#{ninja}") - |> render(:show, ninja: ninja) + |> render(:show, %{ninja: ninja, current_user: conn.assigns.current_user}) end end @@ -52,18 +57,18 @@ defmodule BokkenWeb.NinjaController do conn |> put_status(:created) |> put_resp_header("location", ~p"/api/ninjas/#{ninja}") - |> render(:show, ninja: ninja) + |> render(:show, %{ninja: ninja, current_user: conn.assigns.current_user}) end end def show(conn, %{"id" => id}) do - ninja = Accounts.get_ninja!(id, [:skills]) - render(conn, :show, ninja: ninja) + ninja = Accounts.get_ninja!(id, [:skills, :guardian]) + render(conn, :show, %{ninja: ninja, current_user: conn.assigns.current_user}) end def show(conn, %{"discord_id" => discord_id}) do with {:ok, %Ninja{} = ninja} <- Accounts.get_ninja_by_discord(discord_id) do - render(conn, :show, ninja: ninja) + render(conn, :show, %{ninja: ninja, current_user: conn.assigns.current_user}) end end @@ -72,14 +77,14 @@ defmodule BokkenWeb.NinjaController do ninja = Accounts.get_ninja!(id) with {:ok, %Ninja{} = ninja} <- Accounts.update_ninja(ninja, ninja_params) do - render(conn, :show, ninja: ninja) + render(conn, :show, %{ninja: ninja, current_user: conn.assigns.current_user}) end end def update(conn, %{"discord_id" => discord_id, "ninja" => ninja_params}) do with {:ok, %Ninja{} = ninja} <- Accounts.get_ninja_by_discord(discord_id), {:ok, %Ninja{} = ninja} <- Accounts.update_ninja(ninja, ninja_params) do - render(conn, :show, ninja: ninja) + render(conn, :show, %{ninja: ninja, current_user: conn.assigns.current_user}) end end diff --git a/lib/bokken_web/controllers/ninja/ninja_json.ex b/lib/bokken_web/controllers/ninja/ninja_json.ex index 80dcb9b4..f1eaea38 100644 --- a/lib/bokken_web/controllers/ninja/ninja_json.ex +++ b/lib/bokken_web/controllers/ninja/ninja_json.ex @@ -2,21 +2,17 @@ defmodule BokkenWeb.NinjaJSON do alias Bokken.Uploaders.Avatar alias BokkenWeb.SkillJSON - def index(%{ninjas: ninjas}) do - %{data: for(ninja <- ninjas, do: data(ninja))} - end + import Bokken.Guards, only: [is_ninja_guardian: 2, is_ninja_user: 2] - def show(%{ninja: ninja}) do - %{data: data(ninja)} + def index(%{ninjas: ninjas, current_user: current_user}) do + %{data: for(ninja <- ninjas, do: data(ninja, current_user))} end - def ninja(%{ninja: ninja, current_user: current_user}) do - data(ninja) - |> Map.merge(personal(ninja, current_user)) - |> Map.merge(sensitive(ninja, current_user)) + def show(%{ninja: ninja, current_user: current_user}) do + %{data: data(ninja, current_user)} end - def data(ninja) do + def data(ninja, current_user) do %{ id: ninja.id, photo: Avatar.url({ninja.photo, ninja}, :thumb), @@ -27,11 +23,15 @@ defmodule BokkenWeb.NinjaJSON do since: ninja.inserted_at, guardian_id: ninja.guardian_id } + |> Map.merge(personal(ninja, current_user)) + |> Map.merge(sensitive(ninja, current_user)) |> Map.merge(skills(ninja)) end defp personal(ninja, current_user) - when current_user.role == :organizer or current_user.id == ninja.id do + when current_user.role == :organizer or + is_ninja_guardian(current_user, ninja) or + is_ninja_user(current_user, ninja) do %{ birthday: ninja.birthday } diff --git a/lib/bokken_web/views/auth_view.ex b/lib/bokken_web/views/auth_view.ex index 56b7d32e..5a3ee124 100644 --- a/lib/bokken_web/views/auth_view.ex +++ b/lib/bokken_web/views/auth_view.ex @@ -24,7 +24,7 @@ defmodule BokkenWeb.AuthView do end def render("me.json", %{user: %{role: :ninja, ninja: ninja} = user}) do - NinjaJSON.ninja(%{ninja: ninja, current_user: user}) + NinjaJSON.data(ninja, user) |> Map.merge(render_one(user, AuthView, "user.json")) |> Map.put(:ninja_id, ninja.id) end diff --git a/lib/bokken_web/views/enrollment_view.ex b/lib/bokken_web/views/enrollment_view.ex index 919492ed..b571ee28 100644 --- a/lib/bokken_web/views/enrollment_view.ex +++ b/lib/bokken_web/views/enrollment_view.ex @@ -39,7 +39,7 @@ defmodule BokkenWeb.EnrollmentView do defp ninja(enrollment, current_user) do if Ecto.assoc_loaded?(enrollment.ninja) do - %{ninja: NinjaJSON.ninja(%{ninja: enrollment.ninja, current_user: current_user})} + %{ninja: NinjaJSON.data(enrollment.ninja, current_user)} else %{ninja_id: enrollment.ninja_id} end diff --git a/lib/bokken_web/views/lecture_view.ex b/lib/bokken_web/views/lecture_view.ex index a2324756..82123371 100644 --- a/lib/bokken_web/views/lecture_view.ex +++ b/lib/bokken_web/views/lecture_view.ex @@ -35,7 +35,7 @@ defmodule BokkenWeb.LectureView do defp ninja(lecture, current_user) do if Ecto.assoc_loaded?(lecture.ninja) do - %{ninja: NinjaJSON.ninja(%{ninja: lecture.ninja, current_user: current_user})} + %{ninja: NinjaJSON.data(lecture.ninja, current_user)} else %{ninja_id: lecture.ninja_id} end diff --git a/test/bokken_web/controllers/ninja_json_test.exs b/test/bokken_web/controllers/ninja_json_test.exs index 2ae7e248..8afd90c8 100644 --- a/test/bokken_web/controllers/ninja_json_test.exs +++ b/test/bokken_web/controllers/ninja_json_test.exs @@ -5,37 +5,142 @@ defmodule Bokken.NinjaJSONTest do alias Bokken.Uploaders.Avatar alias BokkenWeb.NinjaJSON - test "data" do - ninja = build(:ninja) - rendered_ninja = NinjaJSON.data(ninja) - - assert rendered_ninja == %{ - id: ninja.id, - photo: Avatar.url({ninja.photo, ninja}), - first_name: ninja.first_name, - last_name: ninja.last_name, - belt: ninja.belt, - socials: ninja.socials, - since: ninja.inserted_at, - guardian_id: ninja.guardian_id - } + describe "render as guardian" do + setup do + guardian = insert(:guardian) + user = insert(:user, role: :guardian, guardian: guardian) + ninja = insert(:ninja, guardian: guardian) + + {:ok, ninja: ninja, current_user: user} + end + + test "show", %{ninja: ninja, current_user: user} do + rendered_ninja = NinjaJSON.show(%{ninja: ninja, current_user: user}) + + assert rendered_ninja == + %{ + data: %{ + id: ninja.id, + photo: Avatar.url({ninja.photo, ninja}), + first_name: ninja.first_name, + last_name: ninja.last_name, + belt: ninja.belt, + socials: ninja.socials, + since: ninja.inserted_at, + birthday: ninja.birthday, + guardian_id: ninja.guardian_id + } + } + end + + test "index", %{ninja: ninja, current_user: user} do + ninjas = insert_list(5, :ninja, guardian: ninja.guardian) + rendered_ninjas = NinjaJSON.index(%{ninjas: ninjas, current_user: user}) + + assert 5 == Enum.count(rendered_ninjas[:data]) + end + end + + describe "render as not ninja's guardian" do + setup do + guardian = insert(:guardian) + user = insert(:user, role: :guardian) + ninja = insert(:ninja, guardian: guardian) + + {:ok, ninja: ninja, current_user: user} + end + + test "show", %{ninja: ninja, current_user: user} do + rendered_ninja = NinjaJSON.show(%{ninja: ninja, current_user: user}) + + assert rendered_ninja == + %{ + data: %{ + id: ninja.id, + photo: Avatar.url({ninja.photo, ninja}), + first_name: ninja.first_name, + last_name: ninja.last_name, + belt: ninja.belt, + socials: ninja.socials, + since: ninja.inserted_at, + guardian_id: ninja.guardian_id + } + } + end + + test "index", %{ninja: ninja, current_user: user} do + ninjas = insert_list(5, :ninja, guardian: ninja.guardian) + rendered_ninjas = NinjaJSON.index(%{ninjas: ninjas, current_user: user}) + + assert 5 == Enum.count(rendered_ninjas[:data]) + end end - test "show" do - ninja = build(:ninja) - rendered_ninja = NinjaJSON.show(%{ninja: ninja}) + describe "render as mentor" do + setup do + user = insert(:user, role: :mentor) + ninja = insert(:ninja) + {:ok, ninja: ninja, current_user: user} + end + + test "show", %{ninja: ninja, current_user: user} do + rendered_ninja = NinjaJSON.show(%{ninja: ninja, current_user: user}) + + assert rendered_ninja == + %{ + data: %{ + id: ninja.id, + photo: Avatar.url({ninja.photo, ninja}), + first_name: ninja.first_name, + last_name: ninja.last_name, + belt: ninja.belt, + socials: ninja.socials, + since: ninja.inserted_at, + notes: nil, + guardian_id: ninja.guardian_id + } + } + end - assert rendered_ninja == %{ - data: NinjaJSON.data(ninja) - } + test "index", %{ninja: ninja, current_user: user} do + ninjas = insert_list(5, :ninja, guardian: ninja.guardian) + rendered_ninjas = NinjaJSON.index(%{ninjas: ninjas, current_user: user}) + + assert 5 == Enum.count(rendered_ninjas[:data]) + end end - test "index" do - ninjas = build_list(5, :ninja) - rendered_ninjas = NinjaJSON.index(%{ninjas: ninjas}) + describe "render as ninja" do + setup do + user = insert(:user, role: :ninja) + ninja = insert(:ninja, user: user) + {:ok, ninja: ninja, current_user: user} + end + + test "show", %{ninja: ninja, current_user: user} do + rendered_ninja = NinjaJSON.show(%{ninja: ninja, current_user: user}) + + assert rendered_ninja == + %{ + data: %{ + id: ninja.id, + photo: Avatar.url({ninja.photo, ninja}), + first_name: ninja.first_name, + last_name: ninja.last_name, + belt: ninja.belt, + socials: ninja.socials, + since: ninja.inserted_at, + birthday: ninja.birthday, + guardian_id: ninja.guardian_id + } + } + end + + test "index", %{ninja: ninja, current_user: user} do + ninjas = insert_list(5, :ninja, guardian: ninja.guardian) + rendered_ninjas = NinjaJSON.index(%{ninjas: ninjas, current_user: user}) - assert rendered_ninjas == %{ - data: Enum.map(ninjas, &NinjaJSON.data(&1)) - } + assert 5 == Enum.count(rendered_ninjas[:data]) + end end end