Repository navigation
Refactor Project Controller Tests #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,53 +1,31 @@ | ||
| defmodule CodeCorps.ProjectControllerTest do | ||
| use CodeCorps.ApiCase | ||
| use CodeCorps.ApiCase, resource_name: :project | ||
|
|
||
| alias CodeCorps.Project | ||
| @valid_attrs %{title: "Valid project"} | ||
| @invalid_attrs %{title: ""} | ||
|
|
||
| @valid_attrs %{ | ||
| title: "Valid project", | ||
| description: "Valid project description", | ||
| long_description_markdown: "Valid **markdown**" | ||
| } | ||
|
|
||
| @invalid_attrs %{ | ||
| title: "" | ||
| } | ||
|
|
||
| defp build_payload, do: %{ "data" => %{"type" => "project"}} | ||
|
|
||
| describe "#index" do | ||
| describe "index" do | ||
| test "lists all entries on index", %{conn: conn} do | ||
| path = conn |> project_path(:index) | ||
| json = conn |> get(path) |> json_response(200) | ||
| [project_1, project_2] = insert_pair(:project) | ||
|
|
||
| assert json["data"] == [] | ||
| conn | ||
| |> request_index | ||
| |> json_response(200) | ||
| |> assert_ids_from_response([project_1.id, project_2.id]) | ||
| end | ||
|
|
||
| test "lists all entries for organization specified by slug", %{conn: conn} do | ||
| organization_slug = "test-organization" | ||
| organization = insert(:organization, name: "Test Organization", slug: organization_slug) | ||
| insert(:slugged_route, organization: organization, slug: organization_slug) | ||
| project_1 = insert(:project, title: "Test Project 1", organization: organization) | ||
| project_2 = insert(:project, title: "Test Project 2", organization: organization) | ||
|
|
||
| conn = conn |> get("/#{organization_slug}/projects") | ||
|
|
||
| data = conn |> json_response(200) |> Map.get("data") | ||
|
|
||
| assert Enum.count(data) == 2 | ||
| [project_1, project_2] = insert_pair(:project) | ||
|
|
||
| actual_ids = | ||
| data | ||
| |> Enum.map(& &1["id"]) | ||
| |> Enum.map(&Integer.parse(&1) |> elem(0)) | ||
| |> Enum.sort | ||
| path = ("/#{organization_slug}/projects") | ||
|
|
||
| expected_ids = | ||
| [project_1, project_2] | ||
| |> Enum.map(& &1.id) | ||
| |> Enum.sort | ||
|
|
||
| assert expected_ids == actual_ids | ||
| conn | ||
| |> get(path) | ||
| |> json_response(200) | ||
| |> assert_ids_from_response([project_1.id, project_2.id]) | ||
| end | ||
|
|
||
| test "listing by organization slug is case insensitive", %{conn: conn} do | ||
|
|
@@ -58,43 +36,28 @@ defmodule CodeCorps.ProjectControllerTest do | |
| end | ||
| end | ||
|
|
||
| describe "#show" do | ||
| describe "show" do | ||
| test "shows chosen resource", %{conn: conn} do | ||
| project = insert(:project, | ||
| title: "Test project", | ||
| description: "Test project description", | ||
| long_description_markdown: "A markdown **description**") | ||
| project = insert(:project) | ||
|
|
||
| conn = get conn, project_path(conn, :show, project) | ||
| data = json_response(conn, 200)["data"] | ||
| assert data["id"] == "#{project.id}" | ||
| assert data["type"] == "project" | ||
| assert data["attributes"]["title"] == "Test project" | ||
| assert data["attributes"]["description"] == "Test project description" | ||
| assert data["attributes"]["long-description-markdown"] == "A markdown **description**" | ||
| assert data["relationships"]["organization"]["data"]["id"] == Integer.to_string(project.organization_id) | ||
| conn | ||
| |> request_show(project) | ||
| |> json_response(200) | ||
| |> Map.get("data") | ||
| |> assert_result_id(project.id) | ||
| end | ||
|
|
||
| test "shows chosen resource retrieved by slug", %{conn: conn} do | ||
| project = insert(:project, | ||
| title: "Test project", | ||
| description: "Test project description", | ||
| long_description_markdown: "A markdown **description**", | ||
| slug: "test-project") | ||
|
|
||
| conn = get conn, "/test-organization/test-project" | ||
| organization = insert(:organization) | ||
| project = insert(:project, organization: organization) | ||
|
|
||
| data = | ||
| conn | ||
| |> json_response(200) | ||
| |> Map.get("data") | ||
| path = "#{organization.slug}/#{project.slug}" | ||
|
|
||
| assert data["id"] == "#{project.id}" | ||
| assert data["type"] == "project" | ||
| assert data["attributes"]["title"] == "Test project" | ||
| assert data["attributes"]["description"] == "Test project description" | ||
| assert data["attributes"]["long-description-markdown"] == "A markdown **description**" | ||
| assert data["relationships"]["organization"]["data"]["id"] == Integer.to_string(project.organization_id) | ||
| conn | ||
| |> get(path) | ||
| |> json_response(200) | ||
| |> Map.get("data") | ||
| |> assert_result_id(project.id) | ||
| end | ||
|
|
||
| test "retrieval by slug is case insensitive", %{conn: conn} do | ||
|
|
@@ -110,138 +73,62 @@ defmodule CodeCorps.ProjectControllerTest do | |
| test "creates and renders resource when attributes are valid", %{conn: conn, current_user: current_user} do | ||
| organization = insert(:organization) | ||
| insert(:organization_membership, role: "admin", member: current_user, organization: organization) | ||
|
|
||
| payload = | ||
| build_payload | ||
| |> put_attributes(@valid_attrs) | ||
| |> put_relationships(organization) | ||
|
|
||
| path = conn |> project_path(:create) | ||
|
|
||
| json = conn |> post(path, payload) |> json_response(201) | ||
|
|
||
| id = json["data"]["id"] | ||
| assert id | ||
| project = Project |> Repo.get(id) | ||
|
|
||
| assert project | ||
| assert project.title == "Valid project" | ||
| assert project.description == "Valid project description" | ||
| assert project.long_description_markdown == "Valid **markdown**" | ||
| assert project.long_description_body == "<p>Valid <strong>markdown</strong></p>\n" | ||
| assert project.organization_id == organization.id | ||
| attrs = @valid_attrs |> Map.merge(%{organization: organization}) | ||
| assert conn |> request_create(attrs) |> json_response(201) | ||
| end | ||
|
|
||
| @tag :authenticated | ||
| test "does not create resource and renders errors when attributes are invalid", %{conn: conn, current_user: current_user} do | ||
| organization = insert(:organization) | ||
| insert(:organization_membership, role: "admin", member: current_user, organization: organization) | ||
|
|
||
| payload = | ||
| build_payload | ||
| |> put_attributes(@invalid_attrs) | ||
| |> put_relationships(organization) | ||
|
|
||
| path = conn |> project_path(:create) | ||
|
|
||
| errors = conn |> post(path, payload) |> json_response(422) |> Map.get("errors") | ||
|
|
||
| assert errors != %{} | ||
| @tag authenticated: :admin | ||
| test "renders 422 when attributes are invalid", %{conn: conn} do | ||
| assert conn |> request_create(@invalid_attrs) |> json_response(422) | ||
| end | ||
|
|
||
| test "does not create resource and renders 401 when unauthenticated", %{conn: conn} do | ||
| path = conn |> project_path(:create) | ||
| assert conn |> post(path) |> json_response(401) | ||
| test "renders 401 when unauthenticated", %{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, current_user: current_user} do | ||
| organization = insert(:organization) | ||
| insert(:organization_membership, role: "contributor", member: current_user, organization: organization) | ||
|
|
||
| payload = | ||
| build_payload | ||
| |> put_attributes(@valid_attrs) | ||
| |> put_relationships(organization) | ||
|
|
||
| path = conn |> project_path(:create) | ||
| assert conn |> post(path, payload) |> json_response(403) | ||
| test "renders 403 when not authorized", %{conn: conn} do | ||
| # Need the organization in order to access membership in the project policy | ||
| attrs = %{organization: insert(:organization)} | ||
| assert conn |> request_create(attrs) |> json_response(403) | ||
| end | ||
| end | ||
|
|
||
| describe "update" do | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks so much better 👏
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| @tag authenticated: :admin | ||
| test "updates and renders resource when attributes are valid", %{conn: conn} do | ||
| project = insert(:project) | ||
|
|
||
| payload = build_payload |> put_id(project.id) |> put_attributes(@valid_attrs) | ||
| path = conn |> project_path(:update, project) | ||
|
|
||
| json = conn |> put(path, payload) |> json_response(200) | ||
|
|
||
| id = json["data"]["id"] | ||
| assert id | ||
|
|
||
| project = Project |> Repo.get(id) | ||
|
|
||
| assert project | ||
| assert project.title == "Valid project" | ||
| assert project.description == "Valid project description" | ||
| assert project.long_description_markdown == "Valid **markdown**" | ||
| assert project.long_description_body == "<p>Valid <strong>markdown</strong></p>\n" | ||
| assert project.organization_id | ||
| assert conn |> request_update(@valid_attrs) |> json_response(200) | ||
| end | ||
|
|
||
| @tag authenticated: :admin | ||
| test "renders errors when attributes are invalid", %{conn: conn} do | ||
| project = insert(:project) | ||
|
|
||
| payload = build_payload |> put_id(project.id) |> put_attributes(@invalid_attrs) | ||
| path = conn |> project_path(:update, project) | ||
|
|
||
| errors = conn |> put(path, payload) |> json_response(422) |> Map.get("errors") | ||
|
|
||
| assert errors != %{} | ||
| assert conn |> request_update(@invalid_attrs) |> json_response(422) | ||
| end | ||
|
|
||
| @tag :requires_env | ||
| @tag authenticated: :admin | ||
| test "uploads a icon to S3", %{conn: conn} do | ||
| project = insert(:project) | ||
|
|
||
| organization = insert(:organization) | ||
| icon_data = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=" | ||
| attrs = Map.put(@valid_attrs, :base64_icon_data, icon_data) | ||
| attrs = @valid_attrs |> Map.merge(%{base64_icon_data: icon_data, organization: organization}) | ||
|
|
||
| payload = build_payload |> put_id(project.id) |> put_attributes(attrs) | ||
| path = conn |> project_path(:update, project) | ||
|
|
||
| json = conn |> put(path, payload) |> json_response(200) | ||
|
|
||
| data = json["data"] | ||
| large_url = data["attributes"]["icon-large-url"] | ||
| assert large_url | ||
| assert String.contains? large_url, "/projects/#{project.id}/large" | ||
| thumb_url = data["attributes"]["icon-thumb-url"] | ||
| assert thumb_url | ||
| assert String.contains? thumb_url, "/projects/#{project.id}/thumb" | ||
| assert conn |> request_create(attrs) |> json_response(201) | ||
| end | ||
|
|
||
| test "does not create resource and renders 401 when unauthenticated", %{conn: conn} do | ||
| path = conn |> project_path(:update, "id not important") | ||
| assert conn |> put(path) |> json_response(401) | ||
| test "renders 401 when unauthenticated", %{conn: conn} do | ||
| assert conn |> request_update |> json_response(401) | ||
| end | ||
|
|
||
| @tag :authenticated | ||
| test "does not create resource and renders 403 when not authorized", %{conn: conn} do | ||
| project = insert(:project) | ||
| path = conn |> project_path(:update, project) | ||
| assert conn |> put(path) |> json_response(403) | ||
| test "renders 403 when not authorized", %{conn: conn} do | ||
| # Need the organization in order to access membership in the project policy | ||
| attrs = %{organization: insert(:organization)} | ||
| assert conn |> request_update(attrs) |> json_response(403) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, why not just |
||
| end | ||
|
|
||
| @tag :authenticated | ||
| test "does not update resource and renders 404 when not found", %{conn: conn} do | ||
| path = conn |> project_path(:update, -1) | ||
| assert conn |> put(path) |> json_response(404) | ||
| @tag authenticated: :admin | ||
| test "renders 404 when not found", %{conn: conn} do | ||
| assert conn |> request_update(:not_found) |> json_response(404) | ||
| end | ||
| end | ||
| end | ||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you doing this extra work here? Would
request_createon its own not work?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was having trouble getting this test to pass and this was the only solution that worked. I couldn't figure out why the usual request_create wasn't working so I just included the attributes. I'll look at it again today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the error I'm getting: ** (FunctionClauseError) no function clause matching in CodeCorps.Helpers.Policy.get_membership/2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay we'll dig into it when we pair.