From 952602eaf3ed3c4ead28a542c119710a8adcb919 Mon Sep 17 00:00:00 2001 From: Nick Pendery Date: Wed, 24 Aug 2016 18:25:22 -0400 Subject: [PATCH] Add role search to organization memberships --- ...ganization_memberships_controller_test.exs | 130 +++++++++++++----- web/controllers/controller_helpers.ex | 5 + .../organization_membership_controller.ex | 17 +-- web/models/model_helpers.ex | 21 ++- web/models/organization_membership.ex | 9 ++ 5 files changed, 134 insertions(+), 48 deletions(-) diff --git a/test/controllers/organization_memberships_controller_test.exs b/test/controllers/organization_memberships_controller_test.exs index dbfb0ac97..007058f41 100644 --- a/test/controllers/organization_memberships_controller_test.exs +++ b/test/controllers/organization_memberships_controller_test.exs @@ -5,15 +5,6 @@ defmodule CodeCorps.OrganizationMembershipControllerTest do alias CodeCorps.Organization alias CodeCorps.User - def filter_params(records) do - ids = - records - |> Enum.map(fn(r) -> r.id end) - |> Enum.join(",") - - %{filter: %{id: ids}} - end - setup do conn = %{build_conn | host: "api."} @@ -23,36 +14,111 @@ defmodule CodeCorps.OrganizationMembershipControllerTest do {:ok, conn: conn} end - test "filters resources on index", %{conn: conn} do - membership_1 = insert(:organization_membership) - membership_2 = insert(:organization_membership) - insert(:organization_membership) + describe "index" do + test "lists all resources", %{conn: conn} do + membership_1 = insert(:organization_membership) + membership_2 = insert(:organization_membership) - params = filter_params([membership_1, membership_2]) - path = conn |> organization_membership_path(:index) + path = conn |> organization_membership_path(:index) - data = conn |> get(path, params) |> json_response(200) |> Map.get("data") - assert data |> length == 2 + data = conn |> get(path) |> json_response(200) |> Map.get("data") + assert data |> length == 2 - [first_result, second_result] = data - assert first_result["id"] == "#{membership_1.id}" - assert second_result["id"] == "#{membership_2.id}" - end + [first_result, second_result] = data + assert first_result["id"] == "#{membership_1.id}" + assert second_result["id"] == "#{membership_2.id}" + end - test "lists all resources for specified organization", %{conn: conn} do - organization = insert(:organization) - membership_1 = insert(:organization_membership, organization: organization) - membership_2 = insert(:organization_membership, organization: organization) - insert(:organization_membership) + test "lists all resources for specified organization", %{conn: conn} do + organization = insert(:organization) + membership_1 = insert(:organization_membership, organization: organization) + membership_2 = insert(:organization_membership, organization: organization) + insert(:organization_membership) - path = conn |> organization_organization_membership_path(:index, organization) + path = conn |> organization_organization_membership_path(:index, organization) - data = conn |> get(path) |> json_response(200) |> Map.get("data") - assert data |> length == 2 + data = conn |> get(path) |> json_response(200) |> Map.get("data") + assert data |> length == 2 + + [first_result, second_result] = data + assert first_result["id"] == "#{membership_1.id}" + assert second_result["id"] == "#{membership_2.id}" + end + + test "filters resources by member id", %{conn: conn} do + member_1 = insert(:user) + member_2 = insert(:user) + member_3 = insert(:user) + membership_1 = insert(:organization_membership, member: member_1) + membership_2 = insert(:organization_membership, member: member_2) + insert(:organization_membership, member: member_3) + + params = %{"filter" => %{"id" => "#{member_1.id},#{member_2.id}"}} + path = conn |> organization_membership_path(:index, params) + data = conn |> get(URI.decode(path)) |> json_response(200) |> Map.get("data") + assert data |> length == 2 + + [first_result, second_result] = data + assert first_result["id"] == "#{membership_1.id}" + assert second_result["id"] == "#{membership_2.id}" + end + + test "filters resources by role", %{conn: conn} do + membership_1 = insert(:organization_membership, role: "admin") + membership_2 = insert(:organization_membership, role: "admin") + insert(:organization_membership, role: "owner") - [first_result, second_result] = data - assert first_result["id"] == "#{membership_1.id}" - assert second_result["id"] == "#{membership_2.id}" + params = %{"role" => "admin"} + path = conn |> organization_membership_path(:index, params) + + data = conn |> get(path) |> json_response(200) |> Map.get("data") + assert data |> length == 2 + + [first_result, second_result] = data + assert first_result["id"] == "#{membership_1.id}" + assert second_result["id"] == "#{membership_2.id}" + end + + test "filters resources by role and id", %{conn: conn} do + member_1 = insert(:user) + member_2 = insert(:user) + membership_1 = insert(:organization_membership, role: "admin", member: member_1) + insert(:organization_membership, role: "admin", member: member_2) + insert(:organization_membership, role: "owner") + + params = %{"role" => "admin", "filter" => %{"id" => "#{member_1.id}"}} + path = conn |> organization_membership_path(:index, params) + + data = conn |> get(path) |> json_response(200) |> Map.get("data") + + assert data |> length == 1 + + [only_result] = data + assert only_result["id"] == "#{membership_1.id}" + end + + test "filters resources by role and id on specific organization", %{conn: conn} do + member_1 = insert(:user) + organization = insert(:organization) + membership_1 = + insert( + :organization_membership, + organization: organization, + role: "admin", + member: member_1 + ) + insert(:organization_membership, organization: organization, role: "admin") + insert(:organization_membership, role: "owner") + + params = %{"role" => "admin", "filter" => %{"id" => "#{member_1.id}"}} + path = conn |> organization_organization_membership_path(:index, organization) + + data = conn |> get(path, params) |> json_response(200) |> Map.get("data") + assert data |> length == 1 + + [only_result] = data + assert only_result["id"] == "#{membership_1.id}" + end end test "shows chosen resource", %{conn: conn} do diff --git a/web/controllers/controller_helpers.ex b/web/controllers/controller_helpers.ex index 2324fafa8..a40098404 100644 --- a/web/controllers/controller_helpers.ex +++ b/web/controllers/controller_helpers.ex @@ -4,4 +4,9 @@ defmodule CodeCorps.ControllerHelpers do |> String.split(",") |> Enum.map(&String.to_integer(&1)) end + + def coalesce_string(string) do + string + |> String.split(",") + end end diff --git a/web/controllers/organization_membership_controller.ex b/web/controllers/organization_membership_controller.ex index 3309f0288..3f00df2af 100644 --- a/web/controllers/organization_membership_controller.ex +++ b/web/controllers/organization_membership_controller.ex @@ -1,34 +1,21 @@ defmodule CodeCorps.OrganizationMembershipController do use CodeCorps.Web, :controller - import CodeCorps.ControllerHelpers - alias JaSerializer.Params alias CodeCorps.OrganizationMembership plug :scrub_params, "data" when action in [:create, :update] - def index(conn, %{"filter" => %{"id" => id_list}}) do - ids = id_list |> coalesce_id_string + def index(conn, params) do memberships = OrganizationMembership + |> OrganizationMembership.index_filters(params) |> preload([:organization, :member]) - |> where([p], p.id in ^ids) |> Repo.all render(conn, "index.json-api", data: memberships) end - def index(conn, %{"organization_id" => organization_id}) do - memberships = - OrganizationMembership - |> preload([:organization, :member]) - |> where([m], m.organization_id == ^organization_id) - |> Repo.all - - render(conn, "index.json-api", data: memberships) - end - def show(conn, %{"id" => id}) do membership = OrganizationMembership diff --git a/web/models/model_helpers.ex b/web/models/model_helpers.ex index 2b2161d56..19f1ac233 100644 --- a/web/models/model_helpers.ex +++ b/web/models/model_helpers.ex @@ -1,5 +1,7 @@ defmodule CodeCorps.ModelHelpers do - import Ecto.Changeset + use CodeCorps.Web, :model + + import CodeCorps.ControllerHelpers def generate_slug(changeset, value_key, slug_key) do case changeset do @@ -10,4 +12,21 @@ defmodule CodeCorps.ModelHelpers do changeset end end + + def member_filter(query, %{"filter" => %{"id" => id_list}}) do + ids = id_list |> coalesce_id_string + query |> where([om], om.member_id in ^ids) + end + def member_filter(query, _), do: query + + def organization_filter(query, %{"organization_id" => organization_id}) do + query |> where([om], om.organization_id == ^organization_id) + end + def organization_filter(query, _), do: query + + def role_filter(query, %{"role" => roles}) do + roles = roles |> coalesce_string + query |> where([om], om.role in ^roles) + end + def role_filter(query, _), do: query end diff --git a/web/models/organization_membership.ex b/web/models/organization_membership.ex index 65c910505..4416701d9 100644 --- a/web/models/organization_membership.ex +++ b/web/models/organization_membership.ex @@ -5,6 +5,8 @@ defmodule CodeCorps.OrganizationMembership do use CodeCorps.Web, :model + import CodeCorps.ModelHelpers + alias CodeCorps.Organization alias CodeCorps.User @@ -47,6 +49,13 @@ defmodule CodeCorps.OrganizationMembership do |> changeset(params) end + def index_filters(query, params) do + query + |> organization_filter(params) + |> role_filter(params) + |> member_filter(params) + end + defp roles do ~w{ pending contributor admin owner } end