diff --git a/lib/code_corps/analytics/segment_data_extractor.ex b/lib/code_corps/analytics/segment_data_extractor.ex index d5c0f724d..7d64678cb 100644 --- a/lib/code_corps/analytics/segment_data_extractor.ex +++ b/lib/code_corps/analytics/segment_data_extractor.ex @@ -7,6 +7,14 @@ defmodule CodeCorps.Analytics.SegmentDataExtractor do def get_action(%Plug.Conn{private: %{phoenix_action: action}}), do: action def get_action(_), do: nil + @doc """ + Tries to extract project id from given resource. + Returns `nil` if project id can't be extracted. + """ + @spec get_project_id(CodeCorps.ProjectUser.t) :: String.t | nil + def get_project_id(%CodeCorps.ProjectUser{project_id: id}), do: "project_#{id}" + def get_project_id(_), do: nil + @spec get_resource(Plug.Conn.t) :: struct def get_resource(%Plug.Conn{assigns: %{data: data}}), do: data # these are used for delete actions on records that support it diff --git a/lib/code_corps/analytics/segment_event_name_builder.ex b/lib/code_corps/analytics/segment_event_name_builder.ex index 00a89e161..f94cb875b 100644 --- a/lib/code_corps/analytics/segment_event_name_builder.ex +++ b/lib/code_corps/analytics/segment_event_name_builder.ex @@ -14,12 +14,6 @@ defmodule CodeCorps.Analytics.SegmentEventNameBuilder do defp get_event_name(:update, %CodeCorps.DonationGoal{}) do "Updated Donation Goal" end - defp get_event_name(:create, %CodeCorps.ProjectUser{}) do - "Requested Project Membership" - end - defp get_event_name(:update, %CodeCorps.ProjectUser{}) do - "Approved Project Membership" - end defp get_event_name(:payment_succeeded, %CodeCorps.StripeInvoice{}) do "Processed Subscription Payment" end diff --git a/lib/code_corps/analytics/segment_tracking_support.ex b/lib/code_corps/analytics/segment_tracking_support.ex index 301bfb01f..dcdface6a 100644 --- a/lib/code_corps/analytics/segment_tracking_support.ex +++ b/lib/code_corps/analytics/segment_tracking_support.ex @@ -11,8 +11,6 @@ defmodule CodeCorps.Analytics.SegmentTrackingSupport do def includes?(:update, %CodeCorps.Comment{}), do: true def includes?(:create, %CodeCorps.DonationGoal{}), do: true def includes?(:update, %CodeCorps.DonationGoal{}), do: true - def includes?(:create, %CodeCorps.ProjectUser{}), do: true - def includes?(:update, %CodeCorps.ProjectUser{}), do: true def includes?(:create, %CodeCorps.StripeConnectAccount{}), do: true def includes?(:create, %CodeCorps.StripeConnectCharge{}), do: true def includes?(:create, %CodeCorps.StripeConnectPlan{}), do: true diff --git a/lib/code_corps/analytics/segment_traits_builder.ex b/lib/code_corps/analytics/segment_traits_builder.ex index 3000ba5c0..41608817e 100644 --- a/lib/code_corps/analytics/segment_traits_builder.ex +++ b/lib/code_corps/analytics/segment_traits_builder.ex @@ -225,4 +225,9 @@ defmodule CodeCorps.Analytics.SegmentTraitsBuilder do } end defp traits(%{token: _, user_id: _}), do: %{} + defp traits(%{acceptor: user, project_user: project_user}) do + project_user + |> traits() + |> Map.merge(%{acceptor_id: user.id, acceptor: user.username}) + end end diff --git a/lib/code_corps_web/controllers/project_user_controller.ex b/lib/code_corps_web/controllers/project_user_controller.ex index 0e41f7861..fe8c05491 100644 --- a/lib/code_corps_web/controllers/project_user_controller.ex +++ b/lib/code_corps_web/controllers/project_user_controller.ex @@ -2,7 +2,15 @@ defmodule CodeCorpsWeb.ProjectUserController do @moduledoc false use CodeCorpsWeb, :controller - alias CodeCorps.{Emails, Helpers.Query, Mailer, ProjectUser, User} + alias CodeCorps.{ + Analytics.SegmentTracker, + Analytics.SegmentDataExtractor, + Emails, + Helpers.Query, + Mailer, + ProjectUser, + User + } action_fallback CodeCorpsWeb.FallbackController plug CodeCorpsWeb.Plug.DataToAttributes @@ -31,6 +39,7 @@ defmodule CodeCorpsWeb.ProjectUserController do {:ok, %ProjectUser{} = project_user} <- %ProjectUser{} |> ProjectUser.create_changeset(params) |> Repo.insert, _ <- maybe_send_create_email(project_user) do + track_created(current_user, project_user) conn |> put_status(:created) |> render("show.json-api", data: project_user) end end @@ -43,6 +52,7 @@ defmodule CodeCorpsWeb.ProjectUserController do {:ok, %ProjectUser{} = updated_project_user} <- project_user |> ProjectUser.update_changeset(params) |> Repo.update, _ <- maybe_send_update_email(updated_project_user, project_user) do + track_updated(current_user, project_user) conn |> render("show.json-api", data: updated_project_user) end end @@ -88,4 +98,33 @@ defmodule CodeCorpsWeb.ProjectUserController do |> Emails.ProjectUserAcceptanceEmail.create() |> Mailer.deliver_now() end + + @spec track_created(User.t, ProjectUser.t) :: any + def track_created( + %User{id: user_id}, + %ProjectUser{} = project_user) do + + SegmentTracker.track(user_id, "Requested Membership (User)", project_user) + + project_user + |> SegmentDataExtractor.get_project_id() + |> SegmentTracker.track("Membership Requested (Project)", project_user) + end + + @spec track_updated(User.t, ProjectUser.t) :: any + def track_updated( + %User{id: user_id} = user, + %ProjectUser{} = project_user) do + + data = %{ + acceptor: user, + project_user: project_user + } + + SegmentTracker.track(user_id, "Membership Approved (User)", data) + + project_user + |> SegmentDataExtractor.get_project_id() + |> SegmentTracker.track("Approved Membership (Project)", data) + end end diff --git a/test/lib/code_corps/analytics/segment_data_extractor_test.exs b/test/lib/code_corps/analytics/segment_data_extractor_test.exs new file mode 100644 index 000000000..097e65b99 --- /dev/null +++ b/test/lib/code_corps/analytics/segment_data_extractor_test.exs @@ -0,0 +1,23 @@ +defmodule CodeCorps.Analytics.SegmentDataExtractorTest do + @moduledoc false + + use ExUnit.Case, async: true + + import CodeCorps.Factories + + alias CodeCorps.Analytics.SegmentDataExtractor + + describe "get_project_id/1" do + test "should return correct id for project user" do + project_user = build(:project_user) + project_id = "project_#{project_user.project_id}" + + assert SegmentDataExtractor.get_project_id(project_user) == project_id + end + + test "should return nil for unknown resource" do + assert SegmentDataExtractor.get_project_id(%{}) == nil + end + end + +end diff --git a/test/lib/code_corps/analytics/segment_event_name_builder_test.exs b/test/lib/code_corps/analytics/segment_event_name_builder_test.exs index 053a071a3..a38eae821 100644 --- a/test/lib/code_corps/analytics/segment_event_name_builder_test.exs +++ b/test/lib/code_corps/analytics/segment_event_name_builder_test.exs @@ -13,11 +13,6 @@ defmodule CodeCorps.Analytics.SegmentEventNameBuilderTest do assert SegmentEventNameBuilder.build(:update, build(:comment)) == "Edited Comment" end - test "with project_user" do - assert SegmentEventNameBuilder.build(:create, build(:project_user)) == "Requested Project Membership" - assert SegmentEventNameBuilder.build(:update, build(:project_user)) == "Approved Project Membership" - end - test "with task" do assert SegmentEventNameBuilder.build(:create, build(:task)) == "Created Task" assert SegmentEventNameBuilder.build(:update, build(:task)) == "Edited Task" diff --git a/test/lib/code_corps/analytics/segment_traits_builder_test.exs b/test/lib/code_corps/analytics/segment_traits_builder_test.exs index 85e387db6..7931acc9c 100644 --- a/test/lib/code_corps/analytics/segment_traits_builder_test.exs +++ b/test/lib/code_corps/analytics/segment_traits_builder_test.exs @@ -23,6 +23,12 @@ defmodule CodeCorps.Analytics.SegmentTraitsBuilderTest do assert :project_skill |> insert |> SegmentTraitsBuilder.build assert :project_user |> insert |> SegmentTraitsBuilder.build + data = %{ + acceptor: insert(:user), + project_user: insert(:project_user) + } + assert SegmentTraitsBuilder.build(data) + assert :stripe_connect_account |> insert |> SegmentTraitsBuilder.build assert :stripe_connect_charge |> insert |> SegmentTraitsBuilder.build assert :stripe_connect_plan |> insert |> SegmentTraitsBuilder.build diff --git a/test/lib/code_corps_web/controllers/project_user_controller_test.exs b/test/lib/code_corps_web/controllers/project_user_controller_test.exs index b41da48e8..805d2dc81 100644 --- a/test/lib/code_corps_web/controllers/project_user_controller_test.exs +++ b/test/lib/code_corps_web/controllers/project_user_controller_test.exs @@ -49,6 +49,7 @@ defmodule CodeCorpsWeb.ProjectUserControllerTest do assert conn |> request_create(attrs) |> json_response(201) user_id = user.id + project_id = "project_#{project.id}" tracking_properties = %{ project: project.title, @@ -57,7 +58,8 @@ defmodule CodeCorpsWeb.ProjectUserControllerTest do member_id: user.id } - assert_received {:track, ^user_id, "Requested Project Membership", ^tracking_properties} + assert_received {:track, ^user_id, "Requested Membership (User)", ^tracking_properties} + assert_received {:track, ^project_id, "Membership Requested (Project)", ^tracking_properties} email = CodeCorps.ProjectUser @@ -106,15 +108,19 @@ defmodule CodeCorpsWeb.ProjectUserControllerTest do assert json["data"]["attributes"]["role"] == "contributor" user_id = current_user.id + project_id = "project_#{project.id}" tracking_properties = %{ project: project.title, project_id: project.id, member: record.user.username, - member_id: record.user.id + member_id: record.user.id, + acceptor: current_user.username, + acceptor_id: current_user.id } - assert_received {:track, ^user_id, "Approved Project Membership", ^tracking_properties} + assert_received {:track, ^user_id, "Membership Approved (User)", ^tracking_properties} + assert_received {:track, ^project_id, "Approved Membership (Project)", ^tracking_properties} email = CodeCorps.ProjectUser