def test_day_interval(self): sign_up_action, person = self._create_events() person1 = person_factory(team_id=self.team.pk, distinct_ids=["person1"]) person_factory(team_id=self.team.pk, distinct_ids=["person2"]) event_factory( team=self.team, event="sign up", distinct_id="person1", timestamp="2020-01-04T12:00:00Z", ) event_factory( team=self.team, event="sign up", distinct_id="person2", timestamp="2020-01-05T12:00:00Z", ) calculate_actions_from_last_calculation() # test people action_response = self.client.get( "/api/action/people/", data={ "date_from": "2020-01-04", "date_to": "2020-01-04", ENTITY_TYPE: "actions", "interval": "day", ENTITY_ID: sign_up_action.id, }, ).json() event_response = self.client.get( "/api/action/people/", data={ "date_from": "2020-01-04", "date_to": "2020-01-04", ENTITY_TYPE: "events", ENTITY_ID: "sign up", "interval": "day", }, ).json() self.assertEqual(str(action_response["results"][0]["people"][0]["id"]), str(person1.pk)) self.assertEntityResponseEqual(action_response["results"], event_response["results"], remove=[])
def test_funnel_prop_filters(self): funnel = self._basic_funnel(properties={"$browser": "Safari"}) # events with_property = person_factory(distinct_ids=["with_property"], team_id=self.team.pk) self._signup_event(distinct_id="with_property", properties={"$browser": "Safari"}) self._pay_event(distinct_id="with_property", properties={"$browser": "Safari"}) # should not add a count without_property = person_factory( distinct_ids=["without_property"], team_id=self.team.pk) self._signup_event(distinct_id="without_property") self._pay_event(distinct_id="without_property") # will add to first step half_property = person_factory(distinct_ids=["half_property"], team_id=self.team.pk) self._signup_event(distinct_id="half_property", properties={"$browser": "Safari"}) self._pay_event(distinct_id="half_property") calculate_actions_from_last_calculation() result = funnel.run() self.assertEqual(result[0]["count"], 2) self.assertEqual(result[1]["count"], 1)
def test_funnel_events(self): funnel = self._basic_funnel() # events person_stopped_after_signup = person_factory(distinct_ids=["stopped_after_signup"], team_id=self.team.pk) self._signup_event(distinct_id="stopped_after_signup") person_stopped_after_pay = person_factory(distinct_ids=["stopped_after_pay"], team_id=self.team.pk) self._signup_event(distinct_id="stopped_after_pay") self._pay_event(distinct_id="stopped_after_pay") person_stopped_after_movie = person_factory( distinct_ids=["had_anonymous_id", "completed_movie"], team_id=self.team.pk ) self._signup_event(distinct_id="had_anonymous_id") self._pay_event(distinct_id="completed_movie") self._movie_event(distinct_id="completed_movie") person_that_just_did_movie = person_factory(distinct_ids=["just_did_movie"], team_id=self.team.pk) self._movie_event(distinct_id="just_did_movie") person_wrong_order = person_factory(distinct_ids=["wrong_order"], team_id=self.team.pk) self._pay_event(distinct_id="wrong_order") self._signup_event(distinct_id="wrong_order") self._movie_event(distinct_id="wrong_order") self._signup_event(distinct_id="a_user_that_got_deleted_or_doesnt_exist") calculate_actions_from_last_calculation() result = funnel.run() self.assertEqual(result[0]["name"], "user signed up") self.assertEqual(result[0]["count"], 4) self.assertEqual(result[1]["name"], "paid") self.assertEqual(result[1]["count"], 2) self.assertEqual(result[2]["name"], "watched movie") self.assertEqual(result[2]["count"], 1) # make sure it's O(n) person_wrong_order = person_factory(distinct_ids=["badalgo"], team_id=self.team.pk) self._signup_event(distinct_id="badalgo") with self.assertNumQueries(3): funnel.run() self._pay_event(distinct_id="badalgo") with self.assertNumQueries(3): funnel.run()
def test_send_to_slack(self, patch_post_to_slack): self.team.slack_incoming_webhook = "http://slack.com/hook" self.team.save() action_user_paid = Action.objects.create(team=self.team, name="user paid", post_to_slack=True) ActionStep.objects.create(action=action_user_paid, event="user paid") event = Event.objects.create(team=self.team, event="user paid", site_url="http://testserver") calculate_actions_from_last_calculation() calculate_actions_from_last_calculation( ) # intentionally twice to make sure the hook fires once self.assertEqual(patch_post_to_slack.call_count, 1) patch_post_to_slack.assert_has_calls([ call("posthog.tasks.webhooks.post_event_to_webhook", (event.pk, "http://testserver")) ])
def _create_people_interval_events(self): person1 = person_factory(team_id=self.team.pk, distinct_ids=["person1"]) person2 = person_factory(team_id=self.team.pk, distinct_ids=["person2"]) person3 = person_factory(team_id=self.team.pk, distinct_ids=["person3"]) person4 = person_factory(team_id=self.team.pk, distinct_ids=["person4"]) person5 = person_factory(team_id=self.team.pk, distinct_ids=["person5"]) person6 = person_factory(team_id=self.team.pk, distinct_ids=["person6"]) person7 = person_factory(team_id=self.team.pk, distinct_ids=["person7"]) # solo event_factory( team=self.team, event="sign up", distinct_id="person1", timestamp="2020-01-04T14:10:00Z", ) # group by hour event_factory( team=self.team, event="sign up", distinct_id="person2", timestamp="2020-01-04T16:30:00Z", ) # group by hour event_factory( team=self.team, event="sign up", distinct_id="person3", timestamp="2020-01-04T16:50:00Z", ) # group by min event_factory( team=self.team, event="sign up", distinct_id="person4", timestamp="2020-01-04T19:20:00Z", ) # group by min event_factory( team=self.team, event="sign up", distinct_id="person5", timestamp="2020-01-04T19:20:00Z", ) # group by week and month event_factory( team=self.team, event="sign up", distinct_id="person6", timestamp="2019-11-05T16:30:00Z", ) # group by week and month event_factory( team=self.team, event="sign up", distinct_id="person7", timestamp="2019-11-07T16:50:00Z", ) event_factory( team=self.team, event="sign up", distinct_id="person1", timestamp="2019-11-27T16:50:00Z", ) calculate_actions_from_last_calculation() return person1, person2, person3, person4, person5, person6, person7
def test_funnel_person_prop(self): action_credit_card = Action.objects.create(team_id=self.team.pk, name="paid") ActionStep.objects.create( action=action_credit_card, event="$autocapture", tag_name="button", text="Pay $10" ) action_play_movie = Action.objects.create(team_id=self.team.pk, name="watched movie") ActionStep.objects.create(action=action_play_movie, event="$autocapture", tag_name="a", href="/movie") filters = { "events": [ { "id": "user signed up", "type": "events", "order": 0, "properties": [{"key": "email", "value": "*****@*****.**", "type": "person"},], }, ], "actions": [ {"id": action_credit_card.pk, "type": "actions", "order": 1,}, {"id": action_play_movie.pk, "type": "actions", "order": 2,}, ], "funnel_window_days": 14, } funnel = self._basic_funnel(filters=filters) # events with_property = person_factory( distinct_ids=["with_property"], team_id=self.team.pk, properties={"email": "*****@*****.**"}, ) self._signup_event(distinct_id="with_property") self._pay_event(distinct_id="with_property") self._movie_event(distinct_id="with_property") calculate_actions_from_last_calculation() result = funnel.run() self.assertEqual(result[0]["count"], 1) self.assertEqual(result[1]["count"], 1) self.assertEqual(result[2]["count"], 1)
def create_test_data(self): with freeze_time("2012-01-14T03:21:34.000Z"): event_factory(team=self.team, event="$pageview", distinct_id="1") event_factory(team=self.team, event="$pageview", distinct_id="2") with freeze_time("2012-01-14T03:25:34.000Z"): event_factory(team=self.team, event="$pageview", distinct_id="1") event_factory(team=self.team, event="$pageview", distinct_id="2") with freeze_time("2012-01-15T03:59:34.000Z"): event_factory(team=self.team, event="$pageview", distinct_id="2") event_factory(team=self.team, event="custom-event", distinct_id="2", properties={"$os": "Windows 95"}) with freeze_time("2012-01-15T03:59:35.000Z"): event_factory(team=self.team, event="$pageview", distinct_id="1") event_factory(team=self.team, event="custom-event", distinct_id="2", properties={"$os": "Windows 95"}) with freeze_time("2012-01-15T04:01:34.000Z"): event_factory(team=self.team, event="custom-event", distinct_id="1", properties={"$os": "Mac OS X"}) event_factory(team=self.team, event="another-event", distinct_id="2", properties={"$os": "Windows 95"}) with freeze_time("2012-01-15T04:13:22.000Z"): event_factory(team=self.team, event="$pageview", distinct_id="2") team_2 = Organization.objects.bootstrap(None)[2] Person.objects.create(team=self.team, distinct_ids=["1", "3", "4"], properties={"email": "bla"}) # Test team leakage Person.objects.create(team=team_2, distinct_ids=["1", "3", "4"], properties={"email": "bla"}) calculate_actions_from_last_calculation()
def calculate_event_action_mappings(): from posthog.tasks.calculate_action import calculate_actions_from_last_calculation calculate_actions_from_last_calculation()
def test_day_interval_cumulative(self): sign_up_action, person = self._create_events() person1 = person_factory(team_id=self.team.pk, distinct_ids=["person1"]) person2 = person_factory(team_id=self.team.pk, distinct_ids=["person2"]) event_factory( team=self.team, event="sign up", distinct_id="person1", timestamp="2020-01-03T12:00:00Z", ) event_factory( team=self.team, event="sign up", distinct_id="person2", timestamp="2020-01-04T20:00:00Z", ) outside_range_person = person_factory( team_id=self.team.pk, distinct_ids=["outside_range"]) event_factory( team=self.team, event="sign up", distinct_id="outside_range", timestamp="2020-01-02T13:50:00Z", ) event_factory( team=self.team, event="sign up", distinct_id="outside_range", timestamp="2020-01-05T15:50:00Z", ) calculate_actions_from_last_calculation() # test people action_response = self.client.get( f"/api/projects/{self.team.id}/actions/people/", data={ "date_from": "2020-01-03", "date_to": "2020-01-04", ENTITY_TYPE: "actions", "interval": "day", ENTITY_ID: sign_up_action.id, "display": TRENDS_CUMULATIVE, }, ).json() event_response = self.client.get( f"/api/projects/{self.team.id}/actions/people/", data={ "date_from": "2020-01-03", "date_to": "2020-01-04", ENTITY_TYPE: "events", ENTITY_ID: "sign up", "interval": "day", "display": TRENDS_CUMULATIVE, }, ).json() self.assertEqual(len(action_response["results"][0]["people"]), 2) self.assertEqual( sorted([ p["id"] for p in action_response["results"][0]["people"] ]), sorted([person1.pk, person2.pk])) self.assertEntityResponseEqual(action_response["results"], event_response["results"], remove=[])
def test_funnel_prop_filters_per_entity(self): action_credit_card = Action.objects.create(team_id=self.team.pk, name="paid") ActionStep.objects.create(action=action_credit_card, event="$autocapture", tag_name="button", text="Pay $10") action_play_movie = Action.objects.create(team_id=self.team.pk, name="watched movie") ActionStep.objects.create(action=action_play_movie, event="$autocapture", tag_name="a", href="/movie") filters = { "events": [ { "id": "user signed up", "type": "events", "order": 0, "properties": [ { "key": "$browser", "value": "Safari" }, { "key": "$browser", "operator": "is_not", "value": "Chrome" }, ], }, ], "actions": [ { "id": action_credit_card.pk, "type": "actions", "order": 1, "properties": [{ "key": "$browser", "value": "Safari" }], }, { "id": action_play_movie.pk, "type": "actions", "order": 2, "properties": [{ "key": "$browser", "value": "Firefox" }], }, ], } funnel = self._basic_funnel(filters=filters) # events with_property = person_factory( distinct_ids=["with_property"], team_id=self.team.pk, properties={"$browser": "Safari"}, ) self._signup_event(distinct_id="with_property", properties={"$browser": "Safari"}) self._pay_event(distinct_id="with_property", properties={"$browser": "Safari"}) self._movie_event(distinct_id="with_property") # should not add a count without_property = person_factory( distinct_ids=["without_property"], team_id=self.team.pk) self._signup_event(distinct_id="without_property") self._pay_event(distinct_id="without_property", properties={"$browser": "Safari"}) # will add to first step half_property = person_factory(distinct_ids=["half_property"], team_id=self.team.pk) self._signup_event(distinct_id="half_property") self._pay_event(distinct_id="half_property") self._movie_event(distinct_id="half_property") calculate_actions_from_last_calculation() result = funnel.run() self.assertEqual(result[0]["count"], 1) self.assertEqual(result[1]["count"], 1) self.assertEqual(result[2]["count"], 0)