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/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..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]}]}, @@ -28,9 +28,10 @@ "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], []}, + "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/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/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_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/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 9819ebe53..840ab0b53 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 @@ -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/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_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_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/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" 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