From f1d6dbac62b01483f8a7ecb69780136dbbf3c3fd Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Sat, 8 Oct 2016 12:51:44 -0700 Subject: [PATCH 1/2] Add ja_resource Convert category controller Convert comment controller Convert organization controller Change to use filter helpers in some controllers Convert organization membership (except create and update) Convert preview controller Convert project category controller Convert part of project controller Convert project skill controller Convert role skill controller Convert skill except for index Convert user category controller except create Convert user controller except update Convert user role except create Convert user skill controller except create Refactor helpers Switch to analytics tracking alongside ja_resource to places that lost tracking Switch OrganizationMembership update to new tracking, fix some tracking code there Switch parts we already touched to new tracking completely Switch Task controller to ja_resource, except index Switch User controller completely to ja_resource Improve abstraction of segment service. Allows for better testing. Add documentation for analytics, rewrite functions some --- config/config.exs | 6 +- config/dev.exs | 2 +- config/prod.exs | 3 + config/staging.exs | 3 + config/test.exs | 2 +- lib/code_corps/analytics/in_memory.ex | 7 - lib/code_corps/analytics/in_memory_api.ex | 10 ++ lib/code_corps/analytics/segment.ex | 143 +++++++++++------- lib/code_corps/analytics/segment_api.ex | 13 ++ lib/code_corps/helpers/query.ex | 18 +++ lib/code_corps/helpers/slug.ex | 15 ++ .../code_corps/helpers/string.ex | 2 +- mix.exs | 2 + mix.lock | 1 + test/controllers/comment_controller_test.exs | 7 +- .../organization_controller_test.exs | 8 +- ...ganization_membership_controller_test.exs} | 23 ++- test/controllers/project_controller_test.exs | 4 +- .../role_skill_controller_test.exs | 8 +- test/controllers/skill_controller_test.exs | 7 +- test/controllers/task_controller_test.exs | 5 +- test/controllers/user_controller_test.exs | 7 +- .../lib/code_corps/analytics/segment_test.exs | 42 +++++ web/controllers/category_controller.ex | 41 +---- web/controllers/comment_controller.ex | 61 ++------ web/controllers/organization_controller.ex | 56 ++----- .../organization_membership_controller.ex | 59 +++----- web/controllers/preview_controller.ex | 18 +-- .../project_category_controller.ex | 32 +--- web/controllers/project_controller.ex | 40 +---- web/controllers/project_skill_controller.ex | 31 +--- web/controllers/role_controller.ex | 27 +--- web/controllers/role_skill_controller.ex | 27 +--- web/controllers/skill_controller.ex | 27 +--- web/controllers/task_controller.ex | 70 +++------ web/controllers/token_controller.ex | 4 +- web/controllers/user_category_controller.ex | 49 ++---- web/controllers/user_controller.ex | 68 +++------ web/controllers/user_role_controller.ex | 47 ++---- web/controllers/user_skill_controller.ex | 49 ++---- web/models/category.ex | 5 +- web/models/comment.ex | 6 +- web/models/model_helpers.ex | 25 +-- web/models/organization.ex | 6 +- web/models/organization_membership.ex | 8 - web/models/project.ex | 2 +- web/models/role_skill.ex | 5 - web/models/slugged_route.ex | 3 +- web/models/user.ex | 7 +- web/models/user_category.ex | 6 - web/models/user_role.ex | 6 - web/models/user_skill.ex | 6 - web/plugs/analytics_identify.ex | 6 +- 53 files changed, 422 insertions(+), 713 deletions(-) delete mode 100644 lib/code_corps/analytics/in_memory.ex create mode 100644 lib/code_corps/analytics/in_memory_api.ex create mode 100644 lib/code_corps/analytics/segment_api.ex create mode 100644 lib/code_corps/helpers/query.ex create mode 100644 lib/code_corps/helpers/slug.ex rename web/controllers/controller_helpers.ex => lib/code_corps/helpers/string.ex (82%) rename test/controllers/{organization_memberships_controller_test.exs => organization_membership_controller_test.exs} (94%) create mode 100644 test/lib/code_corps/analytics/segment_test.exs diff --git a/config/config.exs b/config/config.exs index 365fe7267..bf28f7826 100644 --- a/config/config.exs +++ b/config/config.exs @@ -52,9 +52,6 @@ config :arc, bucket: System.get_env("S3_BUCKET"), asset_host: System.get_env("CLOUDFRONT_DOMAIN") -# Configures Segment for analytics -config :code_corps, :analytics, CodeCorps.Analytics.Segment - config :segment, write_key: System.get_env("SEGMENT_WRITE_KEY") @@ -72,6 +69,9 @@ config :sentry, included_environments: ~w(prod staging)a, use_error_logger: true +config :ja_resource, + repo: CodeCorps.Repo + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env}.exs" diff --git a/config/dev.exs b/config/dev.exs index b4e39c318..3280eec4a 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -46,7 +46,7 @@ config :code_corps, allowed_origins: ["http://localhost:4200"] config :guardian, Guardian, secret_key: "e62fb6e2746f6b1bf8b5b735ba816c2eae1d5d76e64f18f3fc647e308b0c159e" -config :code_corps, :analytics, CodeCorps.Analytics.InMemory +config :code_corps, :analytics, CodeCorps.Analytics.InMemoryAPI config :sentry, environment_name: Mix.env || :dev diff --git a/config/prod.exs b/config/prod.exs index 1b614740b..a37b6fb28 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -38,6 +38,9 @@ config :guardian, Guardian, # Do not print debug messages in production config :logger, level: :info +# Configures Segment for analytics +config :code_corps, :analytics, CodeCorps.Analytics.SegmentAPI + config :sentry, environment_name: Mix.env || :prod diff --git a/config/staging.exs b/config/staging.exs index 3305af155..db716c579 100644 --- a/config/staging.exs +++ b/config/staging.exs @@ -37,6 +37,9 @@ config :guardian, Guardian, # Do not print debug messages in production config :logger, level: :info +# Configures Segment for analytics +config :code_corps, :analytics, CodeCorps.Analytics.SegmentAPI + config :sentry, environment_name: Mix.env || :staging diff --git a/config/test.exs b/config/test.exs index 4ad3b9166..0875da59e 100644 --- a/config/test.exs +++ b/config/test.exs @@ -28,7 +28,7 @@ config :code_corps, allowed_origins: ["http://localhost:4200"] config :guardian, Guardian, secret_key: "e62fb6e2746f6b1bf8b5b735ba816c2eae1d5d76e64f18f3fc647e308b0c159e" -config :code_corps, :analytics, CodeCorps.Analytics.InMemory +config :code_corps, :analytics, CodeCorps.Analytics.InMemoryAPI config :code_corps, :icon_color_generator, CodeCorps.RandomIconColor.TestGenerator diff --git a/lib/code_corps/analytics/in_memory.ex b/lib/code_corps/analytics/in_memory.ex deleted file mode 100644 index f4ad6880a..000000000 --- a/lib/code_corps/analytics/in_memory.ex +++ /dev/null @@ -1,7 +0,0 @@ -defmodule CodeCorps.Analytics.InMemory do - def identify(_user) do - end - - def track(conn, _event, _struct), do: conn - def track(conn, _event), do: conn -end diff --git a/lib/code_corps/analytics/in_memory_api.ex b/lib/code_corps/analytics/in_memory_api.ex new file mode 100644 index 000000000..5f7ee2358 --- /dev/null +++ b/lib/code_corps/analytics/in_memory_api.ex @@ -0,0 +1,10 @@ +defmodule CodeCorps.Analytics.InMemoryAPI do + @moduledoc """ + In-memory interface to simulate calling out to the Segment API. + + Each function should have the same signature as `CodeCorps.Analytics.SegmentAPI` and simply return `nil`. + """ + + def identify(_user_id, _traits), do: nil + def track(_user_id, _event_name, _properties), do: nil +end diff --git a/lib/code_corps/analytics/segment.ex b/lib/code_corps/analytics/segment.ex index 2748c6671..d84babad9 100644 --- a/lib/code_corps/analytics/segment.ex +++ b/lib/code_corps/analytics/segment.ex @@ -1,4 +1,20 @@ defmodule CodeCorps.Analytics.Segment do + @moduledoc """ + Provides analytics tracking for Segment.com with an interface for making [`identify`](https://github.com/stueccles/analytics-elixir#identify) and [`track`](https://github.com/stueccles/analytics-elixir#track) calls via the [`analytics-elixir` package](https://github.com/stueccles/analytics-elixir). + + You can read more about [`identify`](https://segment.com/docs/spec/identify/) and [`track`](https://segment.com/docs/spec/track/) in [Segment's documentation](https://segment.com/docs/). + + By default, in `dev` and `test` envrionments, this module will use `CodeCorps.Analytics.InMemoryAPI` which does not make a request to Segment's REST API. + + In `prod` and `staging` environments, the module will use `CodeCorps.Analytics.SegmentAPI` which _will_ make requests to Segment's REST API. + + In your `config/prod.exs` you might set this like so: + + ```elixir + config :code_corps, :analytics, CodeCorps.Analytics.SegmentAPI + ``` + """ + alias CodeCorps.Comment alias CodeCorps.OrganizationMembership alias CodeCorps.Task @@ -6,77 +22,94 @@ defmodule CodeCorps.Analytics.Segment do alias CodeCorps.UserCategory alias CodeCorps.UserRole alias CodeCorps.UserSkill + alias Ecto.Changeset - def identify(user = %User{}) do - Segment.Analytics.identify(user.id, traits(user)) - end + @api Application.get_env(:code_corps, :analytics) - def track(conn, :added, user_category = %UserCategory{}) do - conn |> do_track("Added User Category", properties(user_category)) - end - def track(conn, :added, user_role = %UserRole{}) do - conn |> do_track("Added User Role", properties(user_role)) - end - def track(conn, :added, user_skill = %UserSkill{}) do - conn |> do_track("Added User Skill", properties(user_skill)) - end - def track(conn, :created, comment = %Comment{}) do - conn |> do_track("Created Comment", properties(comment)) - end - def track(conn, :created, organization_membership = %OrganizationMembership{role: "pending"}) do - conn |> do_track("Requested Organization Membership", properties(organization_membership)) - end - def track(conn, :created, organization_membership = %OrganizationMembership{}) do - conn |> do_track("Created Organization Membership", properties(organization_membership)) - end - def track(conn, :created, task = %Task{}) do - conn |> do_track("Created Task", properties(task)) - end - def track(conn, :edited, comment = %Comment{}) do - conn |> do_track("Edited Comment", properties(comment)) - end - def track(conn, :edited, task = %Task{}) do - conn |> do_track("Edited Task", properties(task)) - end - def track(conn, :removed, user_category = %UserCategory{}) do - conn |> do_track("Removed User Category", properties(user_category)) - end - def track(conn, :removed, user_role = %UserRole{}) do - conn |> do_track("Removed User Role", properties(user_role)) - end - def track(conn, :removed, user_skill = %UserSkill{}) do - conn |> do_track("Removed User Skill", properties(user_skill)) - end - def track(conn, _event, _struct) do - conn # return conn without event to track + @actions_without_properties [:updated_profile, :signed_in, :signed_out, :signed_up] + + @doc """ + Uses the action on the record to determine the event name that should be passed in for the `track` call. + """ + @spec get_event_name(atom, struct) :: String.t + def get_event_name(action, _) when action in @actions_without_properties do + friendly_action_name(action) + end + def get_event_name(:created, %OrganizationMembership{}), do: "Requested Organization Membership" + def get_event_name(:edited, %OrganizationMembership{}), do: "Approved Organization Membership" + def get_event_name(:created, %UserCategory{}), do: "Added User Category" + def get_event_name(:created, %UserSkill{}), do: "Added User Skill" + def get_event_name(:created, %UserRole{}), do: "Added User Role" + def get_event_name(action, model) do + [friendly_action_name(action), friendly_model_name(model)] |> Enum.join(" ") end - def track(conn, :updated_profile) do - conn |> do_track("Updated Profile") + @doc """ + Calls `identify` in the configured API module. + """ + @spec identify(User.t) :: any + def identify(user = %User{}) do + @api.identify(user.id, traits(user)) end - def track(conn, :signed_in) do - conn |> do_track("Signed In") + + @doc """ + Calls `track` in the configured API module. + + Receives either an `:ok` or `:error` tuple from an attempted `Ecto.Repo` operation. + """ + @spec track({:ok, Ecto.Schema.t} | {:error, Ecto.Changeset.t}, atom, Plug.Conn.t) :: any + def track({:ok, record}, action, %Plug.Conn{} = conn) when action in @actions_without_properties do + action_name = get_event_name(action, record) + do_track(conn, action_name) + + {:ok, record} end - def track(conn, :signed_out) do - conn |> do_track("Signed Out") + def track({:ok, record}, action, %Plug.Conn{} = conn) do + action_name = get_event_name(action, record) + do_track(conn, action_name, properties(record)) + + {:ok, record} end - def track(conn, :signed_up) do - conn |> do_track("Signed Up") + def track({:error, %Changeset{} = changeset}, _action, _conn), do: {:error, changeset} + def track({:error, errors}, :deleted, _conn), do: {:error, errors} + + @doc """ + Calls `track` with the "Signed In" event in the configured API module. + """ + @spec track_sign_in(Plug.Conn.t) :: any + def track_sign_in(conn), do: conn |> do_track("Signed In") + + defp friendly_action_name(:deleted), do: "Removed" + defp friendly_action_name(action) do + action + |> Atom.to_string + |> String.split("_") + |> Enum.map(&String.capitalize/1) + |> Enum.join(" ") end - def track(conn, _event) do - conn # return conn without event to track + + defp friendly_model_name(model) do + model.__struct__ + |> Module.split + |> List.last + |> Macro.underscore + |> String.split("_") + |> Enum.map(&String.capitalize/1) + |> Enum.join(" ") end defp do_track(conn, event_name, properties) do - Segment.Analytics.track(conn.assigns[:current_user].id, event_name, properties) + @api.track(conn.assigns[:current_user].id, event_name, properties) conn end + defp do_track(conn, event_name) do - Segment.Analytics.track(conn.assigns[:current_user].id, event_name, %{}) + @api.track(conn.assigns[:current_user].id, event_name, %{}) conn end defp properties(comment = %Comment{}) do + comment = comment |> CodeCorps.Repo.preload(:task) %{ comment_id: comment.id, task: comment.task.title, @@ -86,6 +119,7 @@ defmodule CodeCorps.Analytics.Segment do } end defp properties(organization_membership = %OrganizationMembership{}) do + organization_membership = organization_membership |> CodeCorps.Repo.preload(:organization) %{ organization: organization_membership.organization.name, organization_id: organization_membership.organization.id @@ -100,18 +134,21 @@ defmodule CodeCorps.Analytics.Segment do } end defp properties(user_category = %UserCategory{}) do + user_category = user_category |> CodeCorps.Repo.preload(:category) %{ category: user_category.category.name, category_id: user_category.category.id } end defp properties(user_role = %UserRole{}) do + user_role = user_role |> CodeCorps.Repo.preload(:role) %{ role: user_role.role.name, role_id: user_role.role.id } end defp properties(user_skill = %UserSkill{}) do + user_skill = user_skill |> CodeCorps.Repo.preload(:skill) %{ skill: user_skill.skill.title, skill_id: user_skill.skill.id diff --git a/lib/code_corps/analytics/segment_api.ex b/lib/code_corps/analytics/segment_api.ex new file mode 100644 index 000000000..9d5d0b8ea --- /dev/null +++ b/lib/code_corps/analytics/segment_api.ex @@ -0,0 +1,13 @@ +defmodule CodeCorps.Analytics.SegmentAPI do + @moduledoc """ + Interface to the Segment API through the [`analytics-elixir` package](https://github.com/stueccles/analytics-elixir). + """ + + def identify(user_id, traits) do + Segment.Analytics.identify(user_id, traits) + end + + def track(user_id, event_name, properties) do + Segment.Analytics.track(user_id, event_name, properties) + end +end diff --git a/lib/code_corps/helpers/query.ex b/lib/code_corps/helpers/query.ex new file mode 100644 index 000000000..ed7534c68 --- /dev/null +++ b/lib/code_corps/helpers/query.ex @@ -0,0 +1,18 @@ +defmodule CodeCorps.Helpers.Query do + import CodeCorps.Helpers.String, only: [coalesce_id_string: 1, coalesce_string: 1] + import Ecto.Query, only: [where: 3] + + def id_filter(query, id_list) do + ids = id_list |> coalesce_id_string + query |> where([object], object.id in ^ids) + end + + def organization_filter(query, organization_id) do + query |> where([object], object.organization_id == ^organization_id) + end + + def role_filter(query, roles_list) do + roles = roles_list |> coalesce_string + query |> where([object], object.role in ^roles) + end +end diff --git a/lib/code_corps/helpers/slug.ex b/lib/code_corps/helpers/slug.ex new file mode 100644 index 000000000..eeb02ec66 --- /dev/null +++ b/lib/code_corps/helpers/slug.ex @@ -0,0 +1,15 @@ +defmodule CodeCorps.Helpers.Slug do + alias Ecto.Changeset + + def generate_slug(changeset, value_key, slug_key) do + case changeset do + %Changeset{valid?: true, changes: changes} -> + case Map.fetch(changes, value_key) do + {:ok, value} -> Changeset.put_change(changeset, slug_key, Inflex.parameterize(value)) + _ -> changeset + end + _ -> + changeset + end + end +end diff --git a/web/controllers/controller_helpers.ex b/lib/code_corps/helpers/string.ex similarity index 82% rename from web/controllers/controller_helpers.ex rename to lib/code_corps/helpers/string.ex index a40098404..244386dc7 100644 --- a/web/controllers/controller_helpers.ex +++ b/lib/code_corps/helpers/string.ex @@ -1,4 +1,4 @@ -defmodule CodeCorps.ControllerHelpers do +defmodule CodeCorps.Helpers.String do def coalesce_id_string(string) do string |> String.split(",") diff --git a/mix.exs b/mix.exs index ef1dd9e62..9c7dc8c18 100644 --- a/mix.exs +++ b/mix.exs @@ -35,6 +35,7 @@ defmodule CodeCorps.Mixfile do :earmark, :ex_aws, :httpoison, + :ja_resource, :scrivener_ecto, :segment, :sentry, @@ -75,6 +76,7 @@ defmodule CodeCorps.Mixfile do {:hackney, ">= 1.4.4", override: true}, {:inch_ex, "~> 0.5", only: [:dev, :test]}, # Inch CI {:inflex, "~> 1.7.0"}, + {:ja_resource, "~> 0.1.0"}, {:ja_serializer, "~> 0.11.0"}, # JSON API {:mix_test_watch, "~> 0.2", only: :dev}, # Test watcher {:poison, "~> 1.2 or ~> 2.0"}, diff --git a/mix.lock b/mix.lock index 2ea7262f0..f6ed26203 100644 --- a/mix.lock +++ b/mix.lock @@ -28,6 +28,7 @@ "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, "inch_ex": {:hex, :inch_ex, "0.5.4", "a2b032ad141a335a0a119f49b157b36326f5928d16a1d129b0f582398fdc25d2", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}]}, "inflex": {:hex, :inflex, "1.7.0", "4466a34b7d8e871d8164619ba0f3b8410ec782e900f0ae1d3d27a5875a29532e", [:mix], []}, + "ja_resource": {:hex, :ja_resource, "0.1.0", "eed6443e7337147264bf28badabad48eb0cc32493ff06a48ac19d4b3657f5029", [:mix], [{:ecto, "~> 2.0", [hex: :ecto, optional: false]}, {:ja_serializer, "~> 0.9", [hex: :ja_serializer, optional: false]}, {:phoenix, "~> 1.1", [hex: :phoenix, optional: false]}, {:plug, "~> 1.2", [hex: :plug, optional: false]}]}, "ja_serializer": {:hex, :ja_serializer, "0.11.0", "6c8ded7cfd4cd226812e97445bedd2f6d47e19c5d8b987f58cf552518c98fbd1", [:mix], [{:inflex, "~> 1.4", [hex: :inflex, optional: false]}, {:plug, "> 1.0.0", [hex: :plug, optional: false]}, {:poison, "~> 1.4 or ~> 2.0", [hex: :poison, optional: false]}, {:scrivener, "~> 1.2 or ~> 2.0", [hex: :scrivener, optional: true]}]}, "jose": {:hex, :jose, "1.8.0", "1ee027c5c0ff3922e3bfe58f7891509e8f87f771ba609ee859e623cc60237574", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, optional: false]}]}, "jsx": {:hex, :jsx, "2.6.2", "213721e058da0587a4bce3cc8a00ff6684ced229c8f9223245c6ff2c88fbaa5a", [:mix, :rebar], []}, diff --git a/test/controllers/comment_controller_test.exs b/test/controllers/comment_controller_test.exs index b1d8ae8c5..766239047 100644 --- a/test/controllers/comment_controller_test.exs +++ b/test/controllers/comment_controller_test.exs @@ -48,10 +48,9 @@ defmodule CodeCorps.CommentControllerTest do assert data["relationships"]["task"]["data"]["id"] == "#{comment.task_id}" end - test "does not show resource and instead throw error when id is nonexistent", %{conn: conn} do - assert_error_sent 404, fn -> - get conn, comment_path(conn, :show, -1) - end + test "renders 404 when id is nonexistent", %{conn: conn} do + path = conn |> comment_path(:show, -1) + assert conn |> get(path) |> json_response(404) end end diff --git a/test/controllers/organization_controller_test.exs b/test/controllers/organization_controller_test.exs index 49db2ddeb..766ed557e 100644 --- a/test/controllers/organization_controller_test.exs +++ b/test/controllers/organization_controller_test.exs @@ -53,11 +53,9 @@ defmodule CodeCorps.OrganizationControllerTest do assert data["attributes"]["slug"] == organization.slug end - test "does not show resource and instead throw error when id is nonexistent", %{conn: conn} do - assert_error_sent 404, fn -> - path = conn |> organization_path(:show, -1) - conn |> get(path) - end + test "renders 404 when id is nonexistent", %{conn: conn} do + path = conn |> organization_path(:show, -1) + assert conn |> get(path) |> json_response(404) end end diff --git a/test/controllers/organization_memberships_controller_test.exs b/test/controllers/organization_membership_controller_test.exs similarity index 94% rename from test/controllers/organization_memberships_controller_test.exs rename to test/controllers/organization_membership_controller_test.exs index 2a7d4b453..cfe366bd9 100644 --- a/test/controllers/organization_memberships_controller_test.exs +++ b/test/controllers/organization_membership_controller_test.exs @@ -66,7 +66,7 @@ defmodule CodeCorps.OrganizationMembershipControllerTest do [membership_1, membership_2] = insert_pair(:organization_membership, role: "admin") insert(:organization_membership, role: "owner") - params = %{"role" => "admin"} + params = %{"filter" => %{"role" => "admin"}} response = conn |> get(organization_membership_path(conn, :index, params)) @@ -79,7 +79,7 @@ defmodule CodeCorps.OrganizationMembershipControllerTest do [membership_1, _] = insert_pair(:organization_membership, role: "admin") insert(:organization_membership, role: "owner") - params = %{"role" => "admin", "filter" => %{"id" => "#{membership_1.id}"}} + params = %{"filter" => %{"id" => "#{membership_1.id}", "role" => "admin"}} path = conn |> organization_membership_path(:index, params) response = conn |> get(path) |> json_response(200) @@ -91,7 +91,7 @@ defmodule CodeCorps.OrganizationMembershipControllerTest do [membership_1, _] = insert_pair(:organization_membership, organization: organization, role: "admin") insert(:organization_membership, role: "owner") - params = %{"role" => "admin", "filter" => %{"id" => "#{membership_1.id}"}} + params = %{"filter" => %{"id" => "#{membership_1.id}", "role" => "admin"}} path = conn |> organization_organization_membership_path(:index, organization) response = conn |> get(path, params) |> json_response(200) @@ -105,15 +105,14 @@ defmodule CodeCorps.OrganizationMembershipControllerTest do path = conn |> organization_membership_path(:show, membership) - response = - conn - |> get(path) - |> 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") + conn + |> get(path) + |> 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 diff --git a/test/controllers/project_controller_test.exs b/test/controllers/project_controller_test.exs index 7330cd3a4..0db8096c5 100644 --- a/test/controllers/project_controller_test.exs +++ b/test/controllers/project_controller_test.exs @@ -189,7 +189,7 @@ defmodule CodeCorps.ProjectControllerTest do payload = build_payload |> put_id(project.id) |> put_attributes(@valid_attrs) path = conn |> project_path(:update, project) - json = conn |> put(path, payload) |> json_response(201) + json = conn |> put(path, payload) |> json_response(200) id = json["data"]["id"] assert id @@ -227,7 +227,7 @@ defmodule CodeCorps.ProjectControllerTest do payload = build_payload |> put_id(project.id) |> put_attributes(attrs) path = conn |> project_path(:update, project) - json = conn |> put(path, payload) |> json_response(201) + json = conn |> put(path, payload) |> json_response(200) data = json["data"] large_url = data["attributes"]["icon-large-url"] diff --git a/test/controllers/role_skill_controller_test.exs b/test/controllers/role_skill_controller_test.exs index 9819ebe53..70a2e9ed9 100644 --- a/test/controllers/role_skill_controller_test.exs +++ b/test/controllers/role_skill_controller_test.exs @@ -78,10 +78,10 @@ defmodule CodeCorps.RoleSkillControllerTest do assert data["relationships"]["skill"]["data"]["type"] == "skill" end - test "does not show resource and instead throw error when id is nonexistent", %{conn: conn} do - assert_error_sent 404, fn -> - get conn, role_skill_path(conn, :show, -1) - end + @tag :authenticated + test "renders 404 when id is nonexistent", %{conn: conn} do + path = conn |> role_skill_path(:delete, -1) + assert conn |> delete(path) |> json_response(404) end test "does not create resource and renders 401 when unauthenticated", %{conn: conn} do diff --git a/test/controllers/skill_controller_test.exs b/test/controllers/skill_controller_test.exs index 63f4de361..89b053513 100644 --- a/test/controllers/skill_controller_test.exs +++ b/test/controllers/skill_controller_test.exs @@ -83,10 +83,9 @@ defmodule CodeCorps.SkillControllerTest do assert data["attributes"]["description"] == skill.description end - test "does not show resource and instead throw error when id is nonexistent", %{conn: conn} do - assert_error_sent 404, fn -> - get conn, skill_path(conn, :show, -1) - end + test "renders 404 when id is nonexistent", %{conn: conn} do + path = conn |> comment_path(:show, -1) + assert conn |> get(path) |> json_response(404) end end diff --git a/test/controllers/task_controller_test.exs b/test/controllers/task_controller_test.exs index 3c005c9dd..81e0350e2 100644 --- a/test/controllers/task_controller_test.exs +++ b/test/controllers/task_controller_test.exs @@ -152,9 +152,8 @@ defmodule CodeCorps.TaskControllerTest do end test "does not show resource and instead throw error when id is nonexistent", %{conn: conn} do - assert_error_sent 404, fn -> - get conn, task_path(conn, :show, -1) - end + path = conn |> task_path(:show, -1) + assert conn |> get(path) |> json_response(:not_found) end end diff --git a/test/controllers/user_controller_test.exs b/test/controllers/user_controller_test.exs index 66ec94fa4..2adc5f75f 100644 --- a/test/controllers/user_controller_test.exs +++ b/test/controllers/user_controller_test.exs @@ -64,10 +64,9 @@ defmodule CodeCorps.UserControllerTest do assert json["data"]["attributes"]["email"] == user.email end - test "does not show resource and instead throw error when id is nonexistent", %{conn: conn} do - assert_error_sent 404, fn -> - get conn, user_path(conn, :show, -1) - end + test "renders 404 when id is nonexistent", %{conn: conn} do + path = conn |> user_path(:show, -1) + assert conn |> get(path) |> json_response(404) end end diff --git a/test/lib/code_corps/analytics/segment_test.exs b/test/lib/code_corps/analytics/segment_test.exs new file mode 100644 index 000000000..1ba76a4b1 --- /dev/null +++ b/test/lib/code_corps/analytics/segment_test.exs @@ -0,0 +1,42 @@ +defmodule CodeCorps.Analytics.SegmentTest do + use ExUnit.Case, async: true + + import CodeCorps.Analytics.Segment, only: [get_event_name: 2] + import CodeCorps.Factories + + describe "get_action_name/2" do + test "with comment" do + assert get_event_name(:created, build(:comment)) == "Created Comment" + assert get_event_name(:edited, build(:comment)) == "Edited Comment" + end + + test "with organization membership" do + assert get_event_name(:created, build(:organization_membership)) == "Requested Organization Membership" + assert get_event_name(:edited, build(:organization_membership)) == "Approved Organization Membership" + end + + test "with task" do + assert get_event_name(:created, build(:task)) == "Created Task" + assert get_event_name(:edited, build(:task)) == "Edited Task" + end + + test "with user" do + assert get_event_name(:signed_up, build(:user)) == "Signed Up" + end + + test "with user category" do + assert get_event_name(:created, build(:user_category)) == "Added User Category" + assert get_event_name(:deleted, build(:user_category)) == "Removed User Category" + end + + test "with user role" do + assert get_event_name(:created, build(:user_role)) == "Added User Role" + assert get_event_name(:deleted, build(:user_role)) == "Removed User Role" + end + + test "with user skill" do + assert get_event_name(:created, build(:user_skill)) == "Added User Skill" + assert get_event_name(:deleted, build(:user_skill)) == "Removed User Skill" + end + end +end diff --git a/web/controllers/category_controller.ex b/web/controllers/category_controller.ex index 4c0d55224..f968ec505 100644 --- a/web/controllers/category_controller.ex +++ b/web/controllers/category_controller.ex @@ -1,47 +1,14 @@ defmodule CodeCorps.CategoryController do use CodeCorps.Web, :controller + use JaResource alias CodeCorps.Category - alias JaSerializer.Params plug :load_resource, model: Category, only: [:show] plug :load_and_authorize_resource, model: Category, only: [:create, :update] + plug JaResource - def index(conn, _params) do - categories = Category |> Repo.all - render(conn, "index.json-api", data: categories) - end - - def create(conn, %{"data" => data = %{"type" => "category", "attributes" => _category_params}}) do - changeset = Category.create_changeset(%Category{}, Params.to_attributes(data)) - - case Repo.insert(changeset) do - {:ok, category} -> - conn - |> put_status(:created) - |> put_resp_header("location", category_path(conn, :show, category)) - |> render("show.json-api", data: category) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end - end - - def show(conn, %{"id" => _id}) do - render(conn, "show.json-api", data: conn.assigns.category) - end - - def update(conn, %{"id" => _id, "data" => data = %{"type" => "category", "attributes" => _category_params}}) do - changeset = conn.assigns.category |> Category.changeset(Params.to_attributes(data)) - - case Repo.update(changeset) do - {:ok, category} -> - render(conn, "show.json-api", data: category) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(_conn, attributes) do + Category.create_changeset(%Category{}, attributes) end end diff --git a/web/controllers/comment_controller.ex b/web/controllers/comment_controller.ex index ae79010de..6fed50bc9 100644 --- a/web/controllers/comment_controller.ex +++ b/web/controllers/comment_controller.ex @@ -1,60 +1,25 @@ defmodule CodeCorps.CommentController do use CodeCorps.Web, :controller - alias CodeCorps.Comment - alias JaSerializer.Params + use JaResource - @analytics Application.get_env(:code_corps, :analytics) + alias CodeCorps.Comment plug :load_and_authorize_changeset, model: Comment, only: [:create] plug :load_and_authorize_resource, model: Comment, only: [:update] - plug :scrub_params, "data" when action in [:create, :update] - - def index(conn, params = %{"task_id" => _}) do - comments = - Comment - |> Comment.index_filters(params) - |> Repo.all - - render(conn, "index.json-api", data: comments) - end - - def create(conn, %{"data" => data = %{"type" => "comment", "attributes" => _comment_params}}) do - changeset = Comment.create_changeset(%Comment{}, Params.to_attributes(data)) - case Repo.insert(changeset) do - {:ok, comment} -> - conn - |> @analytics.track(:created, comment) - |> put_status(:created) - |> put_resp_header("location", comment_path(conn, :show, comment)) - |> render("show.json-api", data: comment) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end - end + plug JaResource - def show(conn, %{"id" => id}) do - comment = Repo.get!(Comment, id, preload: [:task]) - render(conn, "show.json-api", data: comment) + def handle_create(conn, attributes) do + %Comment{} + |> Comment.create_changeset(attributes) + |> Repo.insert + |> CodeCorps.Analytics.Segment.track(:created, conn) end - def update(conn, %{"id" => id, "data" => data = %{"type" => "comment", "attributes" => _comment_params}}) do - changeset = - Comment - |> Repo.get!(id) - |> Comment.changeset(Params.to_attributes(data)) - - case Repo.update(changeset) do - {:ok, comment} -> - conn - |> @analytics.track(:edited, comment) - |> render("show.json-api", data: comment) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_update(conn, comment, attributes) do + comment + |> Comment.changeset(attributes) + |> Repo.update + |> CodeCorps.Analytics.Segment.track(:edited, conn) end end diff --git a/web/controllers/organization_controller.ex b/web/controllers/organization_controller.ex index 108b26f4e..d78bee821 100644 --- a/web/controllers/organization_controller.ex +++ b/web/controllers/organization_controller.ex @@ -1,57 +1,19 @@ defmodule CodeCorps.OrganizationController do use CodeCorps.Web, :controller - import CodeCorps.Organization, only: [changeset: 2] - alias CodeCorps.Organization - alias JaSerializer.Params - - plug :load_and_authorize_resource, model: Organization, only: [:create, :update] - plug :scrub_params, "data" when action in [:create, :update] + use JaResource - def index(conn, params) do - organizations = - Organization - |> Organization.index_filters(params) - |> Repo.all - - render(conn, "index.json-api", data: organizations) - end + import CodeCorps.Helpers.Query, only: [id_filter: 2] - def create(conn, %{"data" => data = %{"type" => "organization", "attributes" => _organization_params}}) do - changeset = Organization.create_changeset(%Organization{}, Params.to_attributes(data)) + alias CodeCorps.Organization - case Repo.insert(changeset) do - {:ok, organization} -> - conn - |> put_status(:created) - |> put_resp_header("location", organization_path(conn, :show, organization)) - |> render("show.json-api", data: organization) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end - end + plug :load_and_authorize_resource, model: Organization, only: [:create, :update] + plug JaResource - def show(conn, %{"id" => id}) do - organization = - Organization - |> Repo.get!(id) - render(conn, "show.json-api", data: organization) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end - def update(conn, %{"id" => id, "data" => data = %{"type" => "organization", "attributes" => _organization_params}}) do - changeset = - Organization - |> Repo.get!(id) - |> changeset(Params.to_attributes(data)) - - case Repo.update(changeset) do - {:ok, organization} -> - render(conn, "show.json-api", data: organization) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(_conn, attributes) do + Organization.create_changeset(%Organization{}, attributes) end end diff --git a/web/controllers/organization_membership_controller.ex b/web/controllers/organization_membership_controller.ex index 419939bed..457b45466 100644 --- a/web/controllers/organization_membership_controller.ex +++ b/web/controllers/organization_membership_controller.ex @@ -1,55 +1,40 @@ defmodule CodeCorps.OrganizationMembershipController do use CodeCorps.Web, :controller - alias CodeCorps.OrganizationMembership + use JaResource + + import CodeCorps.Helpers.Query, only: [id_filter: 2, organization_filter: 2, role_filter: 2] - @analytics Application.get_env(:code_corps, :analytics) + alias CodeCorps.OrganizationMembership plug :load_resource, model: OrganizationMembership, only: [:show], preload: [:organization, :member] plug :load_and_authorize_resource, model: OrganizationMembership, only: [:delete] plug :load_and_authorize_changeset, model: OrganizationMembership, only: [:create, :update], preload: [:organization, :member] - plug :scrub_params, "data" when action in [:create, :update] - - def index(conn, params) do - memberships = - OrganizationMembership - |> OrganizationMembership.index_filters(params) - |> Repo.all + plug JaResource - render(conn, "index.json-api", data: memberships) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end - def show(conn, %{"id" => _id}) do - render(conn, "show.json-api", data: conn.assigns.organization_membership) + def filter(_conn, query, "role", roles_list) do + query |> role_filter(roles_list) end - def create(conn, %{"data" => %{"type" => "organization-membership"}}) do - case Repo.insert(conn.assigns.changeset) do - {:ok, membership} -> - conn - |> @analytics.track(:created, membership) - |> put_status(:created) - |> put_resp_header("location", organization_membership_path(conn, :show, membership)) - |> render("show.json-api", data: membership) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_index(_conn, %{"organization_id" => organization_id}) do + OrganizationMembership |> organization_filter(organization_id) end + def handle_index(_conn, _params), do: OrganizationMembership - def update(conn, %{"id" => _id, "data" => %{"type" => "organization-membership", "attributes" => _params}}) do - case Repo.update(conn.assigns.changeset) do - {:ok, membership} -> - render(conn, "show.json-api", data: membership) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(conn, attributes) do + %OrganizationMembership{} + |> OrganizationMembership.create_changeset(attributes) + |> Repo.insert + |> CodeCorps.Analytics.Segment.track(:created, conn) end - def delete(conn, %{"id" => _id}) do - conn.assigns.organization_membership |> Repo.delete! - conn |> send_resp(:no_content, "") + def handle_update(conn, model, attributes) do + model + |> OrganizationMembership.update_changeset(attributes) + |> Repo.update + |> CodeCorps.Analytics.Segment.track(:edited, conn) end end diff --git a/web/controllers/preview_controller.ex b/web/controllers/preview_controller.ex index 71410e32d..6d277f026 100644 --- a/web/controllers/preview_controller.ex +++ b/web/controllers/preview_controller.ex @@ -1,23 +1,13 @@ defmodule CodeCorps.PreviewController do use CodeCorps.Web, :controller + use JaResource alias CodeCorps.Preview - alias JaSerializer.Params plug :load_and_authorize_changeset, model: Preview, only: [:create] + plug JaResource - def create(conn, %{"data" => data = %{"type" => "preview", "attributes" => _preview_params}}) do - changeset = Preview.create_changeset(%Preview{}, Params.to_attributes(data)) - - case Repo.insert(changeset) do - {:ok, preview} -> - conn - |> put_status(:created) - |> render("show.json-api", data: preview) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(_conn, attributes) do + Preview.create_changeset(%Preview{}, attributes) end end diff --git a/web/controllers/project_category_controller.ex b/web/controllers/project_category_controller.ex index 65dfb3e1d..62dfe2360 100644 --- a/web/controllers/project_category_controller.ex +++ b/web/controllers/project_category_controller.ex @@ -1,28 +1,18 @@ defmodule CodeCorps.ProjectCategoryController do use CodeCorps.Web, :controller - - import CodeCorps.ControllerHelpers + use JaResource alias CodeCorps.ProjectCategory + import CodeCorps.Helpers.Query, only: [id_filter: 2] + plug :load_resource, model: ProjectCategory, only: [:show], preload: [:project, :category] plug :load_and_authorize_changeset, model: ProjectCategory, only: [:create] plug :load_and_authorize_resource, model: ProjectCategory, only: [:delete] - plug :scrub_params, "data" when action in [:create] + plug JaResource, except: [:create] - def index(conn, params) do - project_categories = - case params do - %{"filter" => %{"id" => id_list}} -> - ids = id_list |> coalesce_id_string - ProjectCategory - |> where([p], p.id in ^ids) - |> Repo.all - %{} -> - ProjectCategory - |> Repo.all - end - render(conn, "index.json-api", data: project_categories) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end def create(conn, %{"data" => %{"type" => "project-category"}}) do @@ -37,14 +27,4 @@ defmodule CodeCorps.ProjectCategoryController do |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) end end - - def show(conn, %{"id" => _id}) do - render(conn, "show.json-api", data: conn.assigns.project_category) - end - - def delete(conn, %{"id" => _id}) do - conn.assigns.project_category |> Repo.delete! - - conn |> send_resp(:no_content, "") - end end diff --git a/web/controllers/project_controller.ex b/web/controllers/project_controller.ex index 0bd247550..aceb4cbeb 100644 --- a/web/controllers/project_controller.ex +++ b/web/controllers/project_controller.ex @@ -1,32 +1,22 @@ defmodule CodeCorps.ProjectController do use CodeCorps.Web, :controller + use JaResource alias CodeCorps.Project - alias JaSerializer.Params plug :load_and_authorize_changeset, model: Project, only: [:create] plug :load_and_authorize_resource, model: Project, only: [:update] - plug :scrub_params, "data" when action in [:create, :update] + plug JaResource, except: [:show, :create] - def index(conn, %{"slug" => slug}) do + def handle_index(_conn, %{"slug" => slug}) do slugged_route = CodeCorps.SluggedRoute |> CodeCorps.ModelHelpers.slug_finder(slug) - projects = - Project - |> Repo.all(organization_id: slugged_route.organization_id) - - render(conn, "index.json-api", data: projects) - end - - def index(conn, _params) do - projects = - Project - |> Repo.all - - render(conn, "index.json-api", data: projects) + Project + |> Repo.all(organization_id: slugged_route.organization_id) end + def handle_index(_conn, _params), do: Project def show(conn, %{"slug" => _slug, "project_slug" => project_slug}) do project = @@ -39,7 +29,7 @@ defmodule CodeCorps.ProjectController do def show(conn, %{"id" => id}) do project = Project - |> Repo.get!(id) + |> Repo.get(id) render(conn, "show.json-api", data: project) end @@ -57,20 +47,4 @@ defmodule CodeCorps.ProjectController do |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) end end - - def update(conn, %{"id" => _id, "data" => data = %{"type" => "project", "attributes" => _project_params}}) do - changeset = conn.assigns.project |> Project.update_changeset(Params.to_attributes(data)) - - case Repo.update(changeset) do - {:ok, project} -> - conn - |> put_status(:created) - |> put_resp_header("location", project_path(conn, :show, project)) - |> render("show.json-api", data: project) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end - end end diff --git a/web/controllers/project_skill_controller.ex b/web/controllers/project_skill_controller.ex index c1bb72f64..75343ea69 100644 --- a/web/controllers/project_skill_controller.ex +++ b/web/controllers/project_skill_controller.ex @@ -1,28 +1,18 @@ defmodule CodeCorps.ProjectSkillController do use CodeCorps.Web, :controller + use JaResource - import CodeCorps.ControllerHelpers + import CodeCorps.Helpers.Query, only: [id_filter: 2] alias CodeCorps.ProjectSkill plug :load_resource, model: ProjectSkill, only: [:show], preload: [:project, :skill] plug :load_and_authorize_changeset, model: ProjectSkill, only: [:create] plug :load_and_authorize_resource, model: ProjectSkill, only: [:delete] - plug :scrub_params, "data" when action in [:create, :update] + plug JaResource, except: [:create] - def index(conn, params) do - project_skills = - case params do - %{"filter" => %{"id" => id_list}} -> - ids = id_list |> coalesce_id_string - ProjectSkill - |> where([p], p.id in ^ids) - |> Repo.all - %{} -> - ProjectSkill - |> Repo.all - end - render(conn, "index.json-api", data: project_skills) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end def create(conn, %{"data" => %{"type" => "project-skill", "attributes" => _project_skill_params}}) do @@ -38,15 +28,4 @@ defmodule CodeCorps.ProjectSkillController do |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) end end - - def show(conn, %{"id" => _id}) do - render(conn, "show.json-api", data: conn.assigns.project_skill) - end - - def delete(conn, %{"id" => _id}) do - conn.assigns.project_skill |> Repo.delete! - - send_resp(conn, :no_content, "") - end - end diff --git a/web/controllers/role_controller.ex b/web/controllers/role_controller.ex index 6affa0cbb..52bf2e501 100644 --- a/web/controllers/role_controller.ex +++ b/web/controllers/role_controller.ex @@ -1,32 +1,9 @@ defmodule CodeCorps.RoleController do use CodeCorps.Web, :controller + use JaResource alias CodeCorps.Role - alias JaSerializer.Params plug :load_and_authorize_resource, model: Role, only: [:create] - plug :scrub_params, "data" when action in [:create] - - def index(conn, _params) do - roles = - Role - |> Repo.all - render(conn, "index.json-api", data: roles) - end - - def create(conn, %{"data" => data = %{"type" => "role", "attributes" => _role_params}}) do - changeset = Role.changeset(%Role{}, Params.to_attributes(data)) - - case Repo.insert(changeset) do - {:ok, role} -> - conn - |> put_status(:created) - |> put_resp_header("location", role_path(conn, :show, role)) - |> render("show.json-api", data: role) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end - end + plug JaResource end diff --git a/web/controllers/role_skill_controller.ex b/web/controllers/role_skill_controller.ex index ec024d8ce..222533a0a 100644 --- a/web/controllers/role_skill_controller.ex +++ b/web/controllers/role_skill_controller.ex @@ -1,18 +1,18 @@ defmodule CodeCorps.RoleSkillController do use CodeCorps.Web, :controller + use JaResource alias CodeCorps.RoleSkill alias JaSerializer.Params + import CodeCorps.Helpers.Query, only: [id_filter: 2] + plug :load_and_authorize_resource, model: RoleSkill, only: [:create, :delete] plug :scrub_params, "data" when action in [:create] + plug JaResource, except: [:create] - def index(conn, params) do - role_skills = - RoleSkill - |> RoleSkill.index_filters(params) - |> Repo.all - render(conn, "index.json-api", data: role_skills) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end def create(conn, %{"data" => data = %{"type" => "role-skill", "attributes" => _role_skill_params}}) do @@ -30,19 +30,4 @@ defmodule CodeCorps.RoleSkillController do |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) end end - - def show(conn, %{"id" => id}) do - role_skill = - RoleSkill - |> Repo.get!(id) - render(conn, "show.json-api", data: role_skill) - end - - def delete(conn, %{"id" => id}) do - role_skill = Repo.get!(RoleSkill, id) - Repo.delete!(role_skill) - - send_resp(conn, :no_content, "") - end - end diff --git a/web/controllers/skill_controller.ex b/web/controllers/skill_controller.ex index 0efcb344f..506df9890 100644 --- a/web/controllers/skill_controller.ex +++ b/web/controllers/skill_controller.ex @@ -1,11 +1,11 @@ defmodule CodeCorps.SkillController do use CodeCorps.Web, :controller + use JaResource alias CodeCorps.Skill - alias JaSerializer.Params plug :load_and_authorize_resource, model: Skill, only: [:create] - plug :scrub_params, "data" when action in [:create] + plug JaResource, except: [:index] def index(conn, params) do skills = @@ -15,27 +15,4 @@ defmodule CodeCorps.SkillController do render(conn, "index.json-api", data: skills) end - - def create(conn, %{"data" => data = %{"type" => "skill", "attributes" => _skill_params}}) do - changeset = Skill.changeset(%Skill{}, Params.to_attributes(data)) - - case Repo.insert(changeset) do - {:ok, skill} -> - conn - |> put_status(:created) - |> put_resp_header("location", skill_path(conn, :show, skill)) - |> render("show.json-api", data: skill) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end - end - - def show(conn, %{"id" => id}) do - skill = - Skill - |> Repo.get!(id) - render(conn, "show.json-api", data: skill) - end end diff --git a/web/controllers/task_controller.ex b/web/controllers/task_controller.ex index df2190e25..11c5c022b 100644 --- a/web/controllers/task_controller.ex +++ b/web/controllers/task_controller.ex @@ -1,13 +1,12 @@ defmodule CodeCorps.TaskController do use CodeCorps.Web, :controller - alias CodeCorps.Task - alias JaSerializer.Params + use JaResource - @analytics Application.get_env(:code_corps, :analytics) + alias CodeCorps.Task plug :load_and_authorize_changeset, model: Task, only: [:create] plug :load_and_authorize_resource, model: Task, only: [:update] - plug :scrub_params, "data" when action in [:create, :update] + plug JaResource, except: [:index] def index(conn, params) do tasks = @@ -27,55 +26,26 @@ defmodule CodeCorps.TaskController do render(conn, "index.json-api", data: tasks, opts: [meta: meta]) end - def create(conn, %{"data" => data = %{"type" => "task", "attributes" => _task_params}}) do - changeset = Task.create_changeset(%Task{}, Params.to_attributes(data)) - - case Repo.insert(changeset) do - {:ok, task} -> - # need to reload, due to number being added on database level - task = Task |> Repo.get(task.id) - - conn - |> @analytics.track(:created, task) - |> put_status(:created) - |> put_resp_header("location", task_path(conn, :show, task)) - |> render("show.json-api", data: task) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def record(%Plug.Conn{params: %{"project_id" => _project_id} = params}, _number_as_id) do + Task |> Task.show_project_task_filters(params) |> Repo.one end - - def show(conn, params = %{"project_id" => _project_id, "id" => _number}) do - task = - Task - |> Task.show_project_task_filters(params) - |> Repo.one! - render(conn, "show.json-api", data: task) - end - def show(conn, %{"id" => id}) do - task = - Task - |> Repo.get!(id) - render(conn, "show.json-api", data: task) + def record(_conn, id), do: Task |> Repo.get(id) + + def handle_create(conn, attributes) do + %Task{} + |> Task.create_changeset(attributes) + |> Repo.insert + |> reload_task # need to reload to get generated number + |> CodeCorps.Analytics.Segment.track(:created, conn) end - def update(conn, %{"id" => id, "data" => data = %{"type" => "task", "attributes" => _task_params}}) do - changeset = - Task - |> Repo.get!(id) - |> Task.update_changeset(Params.to_attributes(data)) + defp reload_task({:ok, new_task}), do: {:ok, Repo.get(Task, new_task.id)} + defp reload_task({:error, changeset}), do: {:error, changeset} - case Repo.update(changeset) do - {:ok, task} -> - conn - |> @analytics.track(:edited, task) - |> render("show.json-api", data: task) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_update(conn, task, attributes) do + task + |> Task.update_changeset(attributes) + |> Repo.update + |> CodeCorps.Analytics.Segment.track(:edited, conn) end end diff --git a/web/controllers/token_controller.ex b/web/controllers/token_controller.ex index 18a2c46fa..db4dd8e6d 100644 --- a/web/controllers/token_controller.ex +++ b/web/controllers/token_controller.ex @@ -5,8 +5,6 @@ defmodule CodeCorps.TokenController do alias CodeCorps.Repo alias CodeCorps.User - @analytics Application.get_env(:code_corps, :analytics) - def create(conn, params = %{"username" => _, "password" => _}) do case login_by_email_and_pass(params) do {:ok, user} -> @@ -14,7 +12,7 @@ defmodule CodeCorps.TokenController do conn |> Plug.Conn.assign(:current_user, user) - |> @analytics.track(:signed_in) + |> CodeCorps.Analytics.Segment.track_sign_in |> put_status(:created) |> render("show.json", token: token, user_id: user.id) diff --git a/web/controllers/user_category_controller.ex b/web/controllers/user_category_controller.ex index 14750d6b9..76f1e4018 100644 --- a/web/controllers/user_category_controller.ex +++ b/web/controllers/user_category_controller.ex @@ -1,47 +1,30 @@ defmodule CodeCorps.UserCategoryController do use CodeCorps.Web, :controller - alias CodeCorps.UserCategory + use JaResource + + import CodeCorps.Helpers.Query, only: [id_filter: 2] - @analytics Application.get_env(:code_corps, :analytics) + alias CodeCorps.UserCategory plug :load_resource, model: UserCategory, only: [:show], preload: [:user, :category] plug :load_and_authorize_changeset, model: UserCategory, only: [:create] plug :load_and_authorize_resource, model: UserCategory, only: [:delete] - plug :scrub_params, "data" when action in [:create] - - def index(conn, params) do - user_categories = - UserCategory - |> UserCategory.index_filters(params) - |> Repo.all + plug JaResource - render(conn, "index.json-api", data: user_categories) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end - def create(conn, %{"data" => %{"type" => "user-category"}}) do - case Repo.insert(conn.assigns.changeset) do - {:ok, user_category} -> - conn - |> @analytics.track(:added, user_category) - |> put_status(:created) - |> put_resp_header("location", user_category_path(conn, :show, user_category)) - |> render("show.json-api", data: user_category) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(conn, attributes) do + %UserCategory{} + |> UserCategory.create_changeset(attributes) + |> Repo.insert + |> CodeCorps.Analytics.Segment.track(:created, conn) end - def show(conn, %{"id" => _id}) do - render(conn, "show.json-api", data: conn.assigns.user_category) - end - - def delete(conn, %{"id" => _id}) do - conn.assigns.user_category |> Repo.delete! - - conn - |> @analytics.track(:removed, conn.assigns.user_category) - |> send_resp(:no_content, "") + def handle_delete(conn, record) do + record + |> Repo.delete + |> CodeCorps.Analytics.Segment.track(:deleted, conn) end end diff --git a/web/controllers/user_controller.ex b/web/controllers/user_controller.ex index 7b2e6c4b4..fcd27755c 100644 --- a/web/controllers/user_controller.ex +++ b/web/controllers/user_controller.ex @@ -1,69 +1,49 @@ defmodule CodeCorps.UserController do use CodeCorps.Web, :controller - alias CodeCorps.User - alias JaSerializer.Params + use JaResource - @analytics Application.get_env(:code_corps, :analytics) + import CodeCorps.Helpers.Query, only: [id_filter: 2] - plug :load_and_authorize_resource, model: User, only: [:update] - plug :scrub_params, "data" when action in [:create, :update] + alias CodeCorps.User - def index(conn, params) do - users = - User - |> User.index_filters(params) - |> Repo.all + plug :load_and_authorize_resource, model: User, only: [:update] + plug JaResource - render(conn, "index.json-api", data: users) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end - def create(conn, %{"data" => data = %{"type" => "user", "attributes" => _user_params}}) do - changeset = User.registration_changeset(%User{}, Params.to_attributes(data)) - - case Repo.insert(changeset) do - {:ok, user} -> - conn - |> Plug.Conn.assign(:current_user, user) - |> @analytics.track(:signed_up) - |> put_status(:created) - |> put_resp_header("location", user_path(conn, :show, user)) - |> render("show.json-api", data: user) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(conn, attributes) do + %User{} + |> User.registration_changeset(attributes) + |> Repo.insert + |> login(conn) + |> track_signup end - def show(conn, %{"id" => id}) do - user = User |> Repo.get!(id) - render(conn, "show.json-api", data: user) + defp login({:error, changeset}, conn), do: {:error, changeset, conn} + defp login({:ok, model}, conn) do + {:ok, model, conn |> Plug.Conn.assign(:current_user, model)} end - def update(conn, %{"id" => id, "data" => data = %{"type" => "user", "attributes" => _user_params}}) do - changeset = User |> Repo.get!(id) |> User.update_changeset(Params.to_attributes(data)) + defp track_signup({status, model_or_changeset, conn}) do + CodeCorps.Analytics.Segment.track({status, model_or_changeset}, :signed_up, conn) + end - case Repo.update(changeset) do - {:ok, user} -> - conn - |> @analytics.track(:updated_profile) - |> render("show.json-api", data: user) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_update(conn, model, attributes) do + model + |> User.update_changeset(attributes) + |> Repo.update + |> CodeCorps.Analytics.Segment.track(:updated_profile, conn) end def email_available(conn, %{"email" => email}) do hash = User.check_email_availability(email) - conn |> json(hash) end def username_available(conn, %{"username" => username}) do hash = User.check_username_availability(username) - conn |> json(hash) end end diff --git a/web/controllers/user_role_controller.ex b/web/controllers/user_role_controller.ex index 399b37426..7b1d2fdbe 100644 --- a/web/controllers/user_role_controller.ex +++ b/web/controllers/user_role_controller.ex @@ -1,45 +1,30 @@ defmodule CodeCorps.UserRoleController do use CodeCorps.Web, :controller - alias CodeCorps.UserRole + use JaResource + + import CodeCorps.Helpers.Query, only: [id_filter: 2] - @analytics Application.get_env(:code_corps, :analytics) + alias CodeCorps.UserRole plug :load_resource, model: UserRole, only: [:show], preload: [:user, :role] plug :load_and_authorize_changeset, model: UserRole, only: [:create] plug :load_and_authorize_resource, model: UserRole, only: [:delete] + plug JaResource - def index(conn, params) do - user_roles = - UserRole - |> UserRole.index_filters(params) - |> Repo.all - - render(conn, "index.json-api", data: user_roles) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end - def create(conn, %{"data" => %{"type" => "user-role"}}) do - case Repo.insert(conn.assigns.changeset) do - {:ok, user_role} -> - conn - |> @analytics.track(:added, user_role) - |> put_status(:created) - |> render("show.json-api", data: user_role) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(conn, attributes) do + %UserRole{} + |> UserRole.create_changeset(attributes) + |> Repo.insert + |> CodeCorps.Analytics.Segment.track(:created, conn) end - def show(conn, %{"id" => _id}) do - render(conn, "show.json-api", data: conn.assigns.user_role) - end - - def delete(conn, %{"id" => _id}) do - conn.assigns.user_role |> Repo.delete! - - conn - |> @analytics.track(:removed, conn.assigns.user_role) - |> send_resp(:no_content, "") + def handle_delete(conn, record) do + record + |> Repo.delete + |> CodeCorps.Analytics.Segment.track(:deleted, conn) end end diff --git a/web/controllers/user_skill_controller.ex b/web/controllers/user_skill_controller.ex index 6f02d55c6..bef3ead31 100644 --- a/web/controllers/user_skill_controller.ex +++ b/web/controllers/user_skill_controller.ex @@ -1,47 +1,30 @@ defmodule CodeCorps.UserSkillController do use CodeCorps.Web, :controller - alias CodeCorps.UserSkill + use JaResource + + import CodeCorps.Helpers.Query, only: [id_filter: 2] - @analytics Application.get_env(:code_corps, :analytics) + alias CodeCorps.UserSkill plug :load_resource, model: UserSkill, only: [:show], preload: [:user, :skill] plug :load_and_authorize_changeset, model: UserSkill, only: [:create] plug :load_and_authorize_resource, model: UserSkill, only: [:delete] - plug :scrub_params, "data" when action in [:create] - - def index(conn, params) do - user_skills = - UserSkill - |> UserSkill.index_filters(params) - |> Repo.all + plug JaResource - render(conn, "index.json-api", data: user_skills) + def filter(_conn, query, "id", id_list) do + query |> id_filter(id_list) end - def create(conn, %{"data" => %{"type" => "user-skill"}}) do - case Repo.insert(conn.assigns.changeset) do - {:ok, user_skill} -> - conn - |> @analytics.track(:added, user_skill) - |> put_status(:created) - |> put_resp_header("location", user_skill_path(conn, :show, user_skill)) - |> render("show.json-api", data: user_skill) - {:error, changeset} -> - conn - |> put_status(:unprocessable_entity) - |> render(CodeCorps.ChangesetView, "error.json-api", changeset: changeset) - end + def handle_create(conn, attributes) do + %UserSkill{} + |> UserSkill.create_changeset(attributes) + |> Repo.insert + |> CodeCorps.Analytics.Segment.track(:created, conn) end - def show(conn, %{"id" => _id}) do - render(conn, "show.json-api", data: conn.assigns.user_skill) - end - - def delete(conn, %{"id" => _id}) do - conn.assigns.user_skill |> Repo.delete! - - conn - |> @analytics.track(:removed, conn.assigns.user_skill) - |> send_resp(:no_content, "") + def handle_delete(conn, record) do + record + |> Repo.delete + |> CodeCorps.Analytics.Segment.track(:deleted, conn) end end diff --git a/web/models/category.ex b/web/models/category.ex index b1b05ac89..3330dc682 100644 --- a/web/models/category.ex +++ b/web/models/category.ex @@ -4,7 +4,8 @@ defmodule CodeCorps.Category do """ use CodeCorps.Web, :model - import CodeCorps.ModelHelpers + + import CodeCorps.Helpers.Slug schema "categories" do field :name, :string @@ -27,7 +28,7 @@ defmodule CodeCorps.Category do end @doc """ - Builds a changeset for creating an organization. + Builds a changeset for creating an category. """ def create_changeset(struct, params) do struct diff --git a/web/models/comment.ex b/web/models/comment.ex index d70eb3d26..f96c33981 100644 --- a/web/models/comment.ex +++ b/web/models/comment.ex @@ -1,6 +1,6 @@ defmodule CodeCorps.Comment do use CodeCorps.Web, :model - import CodeCorps.ModelHelpers + alias CodeCorps.MarkdownRenderer schema "comments" do @@ -31,8 +31,4 @@ defmodule CodeCorps.Comment do |> assoc_constraint(:task) |> assoc_constraint(:user) end - - def index_filters(query, params) do - query |> task_filter(params) - end end diff --git a/web/models/model_helpers.ex b/web/models/model_helpers.ex index eb9025b1f..902a74266 100644 --- a/web/models/model_helpers.ex +++ b/web/models/model_helpers.ex @@ -1,19 +1,7 @@ defmodule CodeCorps.ModelHelpers do use CodeCorps.Web, :model - import CodeCorps.ControllerHelpers - - def generate_slug(changeset, value_key, slug_key) do - case changeset do - %Ecto.Changeset{valid?: true, changes: changes} -> - case Map.fetch(changes, value_key) do - {:ok, value} -> put_change(changeset, slug_key, Inflex.parameterize(value)) - _ -> changeset - end - _ -> - changeset - end - end + import CodeCorps.Helpers.String, only: [coalesce_id_string: 1, coalesce_string: 1] # filters @@ -35,11 +23,6 @@ defmodule CodeCorps.ModelHelpers do end def number_as_id_filter(query, _), do: query - def organization_filter(query, %{"organization_id" => organization_id}) do - query |> where([object], object.organization_id == ^organization_id) - end - def organization_filter(query, _), do: query - def task_type_filter(query, %{"task_type" => task_type_list}) do task_types = task_type_list |> coalesce_string query |> where([object], object.task_type in ^task_types) @@ -61,12 +44,6 @@ defmodule CodeCorps.ModelHelpers do end def project_filter(query, _), do: query - def role_filter(query, %{"role" => roles}) do - roles = roles |> coalesce_string - query |> where([object], object.role in ^roles) - end - def role_filter(query, _), do: query - def title_filter(query, %{"query" => title}) do query |> where([object], ilike(object.title, ^"%#{title}%")) end diff --git a/web/models/organization.ex b/web/models/organization.ex index 165471cb3..1ff89c2fd 100644 --- a/web/models/organization.ex +++ b/web/models/organization.ex @@ -6,7 +6,7 @@ defmodule CodeCorps.Organization do use Arc.Ecto.Schema use CodeCorps.Web, :model import CodeCorps.Base64ImageUploader - import CodeCorps.ModelHelpers + import CodeCorps.Helpers.Slug import CodeCorps.Validators.SlugValidator alias CodeCorps.SluggedRoute @@ -49,10 +49,6 @@ defmodule CodeCorps.Organization do |> put_slugged_route() end - def index_filters(query, params) do - query |> id_filter(params) - end - defp put_slugged_route(changeset) do case changeset do %Ecto.Changeset{valid?: true, changes: %{slug: slug}} -> diff --git a/web/models/organization_membership.ex b/web/models/organization_membership.ex index 6155c5f3d..581adab05 100644 --- a/web/models/organization_membership.ex +++ b/web/models/organization_membership.ex @@ -4,7 +4,6 @@ defmodule CodeCorps.OrganizationMembership do """ use CodeCorps.Web, :model - import CodeCorps.ModelHelpers schema "organization_memberships" do field :role, :string @@ -38,13 +37,6 @@ defmodule CodeCorps.OrganizationMembership do |> validate_inclusion(:role, roles) end - def index_filters(query, params) do - query - |> id_filter(params) - |> organization_filter(params) - |> role_filter(params) - end - defp roles do ~w{ pending contributor admin owner } end diff --git a/web/models/project.ex b/web/models/project.ex index 7aece0696..8bf117d0a 100644 --- a/web/models/project.ex +++ b/web/models/project.ex @@ -6,7 +6,7 @@ defmodule CodeCorps.Project do use Arc.Ecto.Schema use CodeCorps.Web, :model import CodeCorps.Base64ImageUploader - import CodeCorps.ModelHelpers + import CodeCorps.Helpers.Slug import CodeCorps.Validators.SlugValidator alias CodeCorps.MarkdownRenderer diff --git a/web/models/role_skill.ex b/web/models/role_skill.ex index 01cf3ae5c..d8711f048 100644 --- a/web/models/role_skill.ex +++ b/web/models/role_skill.ex @@ -1,6 +1,5 @@ defmodule CodeCorps.RoleSkill do use CodeCorps.Web, :model - import CodeCorps.ModelHelpers schema "role_skills" do field :cat, :integer @@ -33,10 +32,6 @@ defmodule CodeCorps.RoleSkill do |> validate_inclusion(:cat, cats) end - def index_filters(query, params) do - query |> id_filter(params) - end - defp cats do [1, 2, 3, 4, 5, 6] end diff --git a/web/models/slugged_route.ex b/web/models/slugged_route.ex index bf248305e..5466f9033 100644 --- a/web/models/slugged_route.ex +++ b/web/models/slugged_route.ex @@ -5,7 +5,8 @@ defmodule CodeCorps.SluggedRoute do """ use CodeCorps.Web, :model - import CodeCorps.ModelHelpers + + import CodeCorps.Helpers.Slug import CodeCorps.Validators.SlugValidator schema "slugged_routes" do diff --git a/web/models/user.ex b/web/models/user.ex index 7a93ad9e6..c6f4fd5a1 100644 --- a/web/models/user.ex +++ b/web/models/user.ex @@ -5,9 +5,10 @@ defmodule CodeCorps.User do use Arc.Ecto.Schema use CodeCorps.Web, :model + import CodeCorps.Base64ImageUploader import CodeCorps.Validators.SlugValidator - import CodeCorps.ModelHelpers + alias CodeCorps.SluggedRoute alias Comeonin.Bcrypt alias Ecto.Changeset @@ -109,10 +110,6 @@ defmodule CodeCorps.User do |> check_used(:username, username) end - def index_filters(query, params) do - query |> id_filter(params) - end - defp put_pass_hash(changeset) do case changeset do %Changeset{valid?: true, changes: %{password: pass}} -> diff --git a/web/models/user_category.ex b/web/models/user_category.ex index d12a4b9d1..a7ad5afff 100644 --- a/web/models/user_category.ex +++ b/web/models/user_category.ex @@ -1,8 +1,6 @@ defmodule CodeCorps.UserCategory do use CodeCorps.Web, :model - import CodeCorps.ModelHelpers - schema "user_categories" do belongs_to :user, CodeCorps.User belongs_to :category, CodeCorps.Category @@ -21,8 +19,4 @@ defmodule CodeCorps.UserCategory do |> assoc_constraint(:category) |> unique_constraint(:user_id, name: :index_projects_on_user_id_category_id) end - - def index_filters(query, params) do - query |> id_filter(params) - end end diff --git a/web/models/user_role.ex b/web/models/user_role.ex index 349fc4d70..f6a763e44 100644 --- a/web/models/user_role.ex +++ b/web/models/user_role.ex @@ -1,8 +1,6 @@ defmodule CodeCorps.UserRole do use CodeCorps.Web, :model - import CodeCorps.ModelHelpers - schema "user_roles" do belongs_to :user, CodeCorps.User belongs_to :role, CodeCorps.Role @@ -21,8 +19,4 @@ defmodule CodeCorps.UserRole do |> assoc_constraint(:role) |> unique_constraint(:user_id, name: :index_projects_on_user_id_role_id) end - - def index_filters(query, params) do - query |> id_filter(params) - end end diff --git a/web/models/user_skill.ex b/web/models/user_skill.ex index 0a3c877f5..a486416b9 100644 --- a/web/models/user_skill.ex +++ b/web/models/user_skill.ex @@ -1,8 +1,6 @@ defmodule CodeCorps.UserSkill do use CodeCorps.Web, :model - import CodeCorps.ModelHelpers - schema "user_skills" do belongs_to :user, CodeCorps.User belongs_to :skill, CodeCorps.Skill @@ -21,8 +19,4 @@ defmodule CodeCorps.UserSkill do |> assoc_constraint(:skill) |> unique_constraint(:user_id, name: :index_projects_on_user_id_skill_id) end - - def index_filters(query, params) do - query |> id_filter(params) - end end diff --git a/web/plugs/analytics_identify.ex b/web/plugs/analytics_identify.ex index 911d4194f..c4e862252 100644 --- a/web/plugs/analytics_identify.ex +++ b/web/plugs/analytics_identify.ex @@ -1,11 +1,13 @@ defmodule CodeCorps.Plug.AnalyticsIdentify do - @analytics Application.get_env(:code_corps, :analytics) + @moduledoc """ + Plug used to identify the current user on Segment.com using `CodeCorps.Analytics.Segment`. + """ def init(opts), do: opts def call(conn, _opts) do if current_user = conn.assigns[:current_user] do - @analytics.identify(current_user) + CodeCorps.Analytics.Segment.identify(current_user) conn else conn From f6775e0147b3a0b6707a15e5fbf325279ec3b5ce Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Wed, 12 Oct 2016 18:15:19 -0700 Subject: [PATCH 2/2] Fix coveralls reporting in circle Update excoveralls --- circle.yml | 2 +- mix.lock | 6 +++--- test/controllers/preview_controller_test.exs | 4 ++-- test/controllers/project_skill_controller_test.exs | 2 +- test/controllers/role_skill_controller_test.exs | 2 +- test/controllers/user_category_controller_test.exs | 2 +- test/controllers/user_role_controller_test.exs | 2 +- test/controllers/user_skill_controller_test.exs | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/circle.yml b/circle.yml index 9f7476d1b..4ea389816 100644 --- a/circle.yml +++ b/circle.yml @@ -14,7 +14,7 @@ dependencies: test: override: - | - if [ ${CIRCLE_PR_USERNAME} ]; then MIX_ENV=test mix test --cover; else MIX_ENV=test mix test --include requires_env --cover; fi + if [ ${CIRCLE_PR_USERNAME} ]; then MIX_ENV=test mix coveralls.circle; else MIX_ENV=test mix coveralls.circle --include requires_env; fi post: - mix inch.report diff --git a/mix.lock b/mix.lock index f6ed26203..283512340 100644 --- a/mix.lock +++ b/mix.lock @@ -18,8 +18,8 @@ "ex_aws": {:hex, :ex_aws, "0.5.0", "6ca02f1e8fe8340aa2eee66d9f08efcd6ff1f9f4ef7264669d0756e0b3917218", [:mix], [{:httpoison, "~> 0.8", [hex: :httpoison, optional: true]}, {:jsx, "~> 2.5", [hex: :jsx, optional: true]}, {:poison, "~> 1.2 or ~> 2.0", [hex: :poison, optional: true]}, {:sweet_xml, "~> 0.5", [hex: :sweet_xml, optional: true]}]}, "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, "ex_machina": {:hex, :ex_machina, "1.0.2", "1cc49e1a09e3f7ab2ecb630c17f14c2872dc4ec145d6d05a9c3621936a63e34f", [:mix], [{:ecto, "~> 2.0", [hex: :ecto, optional: true]}]}, - "excoveralls": {:hex, :excoveralls, "0.5.6", "35a903f6f78619ee7f951448dddfbef094b3a0d8581657afaf66465bc930468e", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]}, - "exjsx": {:hex, :exjsx, "3.2.0", "7136cc739ace295fc74c378f33699e5145bead4fdc1b4799822d0287489136fb", [:mix], [{:jsx, "~> 2.6.2", [hex: :jsx, optional: false]}]}, + "excoveralls": {:hex, :excoveralls, "0.5.7", "5d26e4a7cdf08294217594a1b0643636accc2ad30e984d62f1d166f70629ff50", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]}, + "exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]}, "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []}, "gettext": {:hex, :gettext, "0.11.0", "80c1dd42d270482418fa158ec5ba073d2980e3718bacad86f3d4ad71d5667679", [:mix], []}, "guardian": {:hex, :guardian, "0.13.0", "37c5b5302617276093570ee938baca146f53e1d5de1f5c2b8effb1d2fea596d2", [:mix], [{:jose, "~> 1.8", [hex: :jose, optional: false]}, {:phoenix, "~> 1.2.0", [hex: :phoenix, optional: true]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}, {:poison, ">= 1.3.0", [hex: :poison, optional: false]}, {:uuid, ">=1.1.1", [hex: :uuid, optional: false]}]}, @@ -31,7 +31,7 @@ "ja_resource": {:hex, :ja_resource, "0.1.0", "eed6443e7337147264bf28badabad48eb0cc32493ff06a48ac19d4b3657f5029", [:mix], [{:ecto, "~> 2.0", [hex: :ecto, optional: false]}, {:ja_serializer, "~> 0.9", [hex: :ja_serializer, optional: false]}, {:phoenix, "~> 1.1", [hex: :phoenix, optional: false]}, {:plug, "~> 1.2", [hex: :plug, optional: false]}]}, "ja_serializer": {:hex, :ja_serializer, "0.11.0", "6c8ded7cfd4cd226812e97445bedd2f6d47e19c5d8b987f58cf552518c98fbd1", [:mix], [{:inflex, "~> 1.4", [hex: :inflex, optional: false]}, {:plug, "> 1.0.0", [hex: :plug, optional: false]}, {:poison, "~> 1.4 or ~> 2.0", [hex: :poison, optional: false]}, {:scrivener, "~> 1.2 or ~> 2.0", [hex: :scrivener, optional: true]}]}, "jose": {:hex, :jose, "1.8.0", "1ee027c5c0ff3922e3bfe58f7891509e8f87f771ba609ee859e623cc60237574", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, optional: false]}]}, - "jsx": {:hex, :jsx, "2.6.2", "213721e058da0587a4bce3cc8a00ff6684ced229c8f9223245c6ff2c88fbaa5a", [:mix, :rebar], []}, + "jsx": {:hex, :jsx, "2.8.0", "749bec6d205c694ae1786d62cea6cc45a390437e24835fd16d12d74f07097727", [:mix, :rebar], []}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, diff --git a/test/controllers/preview_controller_test.exs b/test/controllers/preview_controller_test.exs index bb8c28808..cb4c0d27d 100644 --- a/test/controllers/preview_controller_test.exs +++ b/test/controllers/preview_controller_test.exs @@ -32,7 +32,7 @@ defmodule CodeCorps.PreviewControllerTest do assert attributes["body"] == "

A strong element

\n" assert attributes["markdown"] == "A **strong** element" - preview = Preview |> Repo.get!(id) + preview = Preview |> Repo.get(id) assert preview.body == "

A strong element

\n" assert preview.markdown == "A **strong** element" @@ -47,7 +47,7 @@ defmodule CodeCorps.PreviewControllerTest do id = json["data"]["id"] |> String.to_integer - preview = Preview |> Repo.get!(id) + preview = Preview |> Repo.get(id) assert preview.user_id == current_user.id end diff --git a/test/controllers/project_skill_controller_test.exs b/test/controllers/project_skill_controller_test.exs index 694c3342c..30a3bc89d 100644 --- a/test/controllers/project_skill_controller_test.exs +++ b/test/controllers/project_skill_controller_test.exs @@ -92,7 +92,7 @@ defmodule CodeCorps.ProjectSkillControllerTest do json = conn |> post(path, payload) |> json_response(201) id = json["data"]["id"] |> String.to_integer - project_skill = ProjectSkill |> Repo.get!(id) + project_skill = ProjectSkill |> Repo.get(id) assert json["data"]["id"] == "#{project_skill.id}" assert json["data"]["type"] == "project-skill" diff --git a/test/controllers/role_skill_controller_test.exs b/test/controllers/role_skill_controller_test.exs index 70a2e9ed9..840ab0b53 100644 --- a/test/controllers/role_skill_controller_test.exs +++ b/test/controllers/role_skill_controller_test.exs @@ -108,7 +108,7 @@ defmodule CodeCorps.RoleSkillControllerTest do json = conn |> post(path, payload) |> json_response(201) id = json["data"]["id"] |> String.to_integer - role_skill = RoleSkill |> Repo.get!(id) + role_skill = RoleSkill |> Repo.get(id) assert json["data"]["id"] == "#{role_skill.id}" assert json["data"]["type"] == "role-skill" diff --git a/test/controllers/user_category_controller_test.exs b/test/controllers/user_category_controller_test.exs index 97bee026e..a480f7d69 100644 --- a/test/controllers/user_category_controller_test.exs +++ b/test/controllers/user_category_controller_test.exs @@ -80,7 +80,7 @@ defmodule CodeCorps.UserCategoryControllerTest do json = conn |> post(path, payload) |> json_response(201) id = json["data"]["id"] |> String.to_integer - user_category = UserCategory |> Repo.get!(id) + user_category = UserCategory |> Repo.get(id) assert json["data"]["id"] == "#{user_category.id}" assert json["data"]["type"] == "user-category" diff --git a/test/controllers/user_role_controller_test.exs b/test/controllers/user_role_controller_test.exs index 0133cd6ef..6e5cb5c48 100644 --- a/test/controllers/user_role_controller_test.exs +++ b/test/controllers/user_role_controller_test.exs @@ -77,7 +77,7 @@ defmodule CodeCorps.UserRoleControllerTest do json = conn |> post(path, payload) |> json_response(201) id = json["data"]["id"] |> String.to_integer - user_role = UserRole |> Repo.get!(id) + user_role = UserRole |> Repo.get(id) assert json["data"]["id"] == "#{user_role.id}" assert json["data"]["type"] == "user-role" diff --git a/test/controllers/user_skill_controller_test.exs b/test/controllers/user_skill_controller_test.exs index 0ae58ca86..b821a5780 100644 --- a/test/controllers/user_skill_controller_test.exs +++ b/test/controllers/user_skill_controller_test.exs @@ -77,7 +77,7 @@ defmodule CodeCorps.UserSkillControllerTest do json = conn |> post(path, payload) |> json_response(201) id = json["data"]["id"] |> String.to_integer - user_skill = UserSkill |> Repo.get!(id) + user_skill = UserSkill |> Repo.get(id) assert json["data"]["id"] == "#{user_skill.id}" assert json["data"]["type"] == "user-skill"