 defmodule CodeCorps.OrganizationMembershipControllerTest do
-  use CodeCorps.ApiCase
-
-  alias CodeCorps.OrganizationMembership
-  alias CodeCorps.Organization
-  alias CodeCorps.User
+  use CodeCorps.ApiCase, resource_name: :organization_membership
 
   @valid_attrs %{role: "contributor"}
-  @invalid_attrs %{role: "invalid_role"}
-
-  defp build_payload, do: %{ "data" => %{"type" => "organization-membership"}}
-  defp put_relationships_with_member(payload, organization, member) do
-    relationships = build_relationships(organization, member)
-    payload |> put_in(["data", "relationships"], relationships)
-  end
-
-  defp build_relationships(organization, member) do
-    %{
-      organization: %{data: %{id: organization.id}},
-      member: %{data: %{id: member.id}}
-    }
-  end
-
-  defp assert_role(data, role) do
-    assert data["attributes"]["role"] == role
-    data
-  end
 
   describe "index" do
     test "lists all resources", %{conn: conn} do
       [membership_1, membership_2] = insert_pair(:organization_membership)
 
-      path = conn |> organization_membership_path(:index)
-      response = conn |> get(path) |> json_response(200)
-
-      assert ids_from_response(response) == [membership_1.id, membership_2.id]
+      conn
+      |> request_index
+      |> json_response(200)
+      |> assert_ids_from_response([membership_1.id, membership_2.id])
     end
 
     test "filters resources by membership id", %{conn: conn} do
-      [membership_1, membership_2] = insert_pair(:organization_membership)
-      insert(:organization_membership)
+      [membership_1, membership_2 | _] = insert_list(3, :organization_membership)
 
-      params = %{"filter" => %{"id" => "#{membership_1.id},#{membership_2.id}"}}
-      response =
-        conn
-        |> get(organization_membership_path(conn, :index, params))
-        |> json_response(200)
+      path = "organization-memberships/?filter[id]=#{membership_1.id},#{membership_2.id}"
 
-      assert ids_from_response(response) == [membership_1.id, membership_2.id]
+      conn
+      |> get(path)
+      |> json_response(200)
+      |> assert_ids_from_response([membership_1.id, membership_2.id])
     end
   end
 
   describe "show" do
     test "shows chosen resource", %{conn: conn} do
-      membership = insert(:organization_membership, role: "admin")
-
-      path = conn |> organization_membership_path(:show, membership)
-
+      membership = insert(:organization_membership)
       conn
-      |> get(path)
+      |> request_show(membership)
       |> json_response(200)
-      |> assert_jsonapi_relationship("organization", membership.organization.id)
-      |> assert_jsonapi_relationship("member", membership.member.id)
       |> Map.get("data")
       |> assert_result_id(membership.id)
-      |> assert_role("admin")
     end
 
-    test "renders page not found when id is nonexistent", %{conn: conn} do
-      path = conn |> organization_membership_path(:show, -1)
-      assert conn |> get(path) |> json_response(:not_found)
+    test "renders 404 when id is nonexistent", %{conn: conn} do
+      assert conn |> request_show(:not_found) |> json_response(404)
     end
   end
 

    @tag :authenticated
    test "creates and renders resource when data is valid", %{conn: conn, current_user: member} do
      organization = insert(:organization)

      payload = build_payload |> put_relationships_with_member(organization, member)

      path = conn |> organization_membership_path(:create)
      response =
        conn
        |> post(path, payload)
        |> json_response(201)
        |> assert_jsonapi_relationship("organization", organization.id)
        |> assert_jsonapi_relationship("member", member.id)

      data = response |> Map.get("data") |> assert_role("pending")

      membership = OrganizationMembership |> Repo.get(data["id"])
      assert membership
      assert membership.role == "pending"
      assert membership.organization_id == organization.id
      assert membership.member_id == member.id
    end

    @tag :authenticated

      # only way to trigger a validation error is to provide a non-existant organization
      # anything else will fail on authorization level
      organization = build(:organization)
      attrs = @valid_attrs |> Map.merge(%{organization: organization, member: member})
      assert conn |> request_create(attrs) |> json_response(422)
    end

    test "does not create resource and renders 401 when not authenticated", %{conn: conn} do
      assert conn |> request_create |> json_response(401)
    end

    @tag :authenticated
    test "does not create resource and renders 403 when not authorized", %{conn: conn} do
      assert conn |> request_create |> json_response(403)
    end
  end

