0
0
mirror of https://github.com/PostHog/posthog.git synced 2024-11-28 09:16:49 +01:00
posthog/ee/clickhouse/test/test_journeys.py

108 lines
3.3 KiB
Python
Raw Normal View History

import dataclasses
import json
Multi property breakdown for person and event queries on Funnels (#7074) * implement multi property breakdown as an array from the spike * correct type hint on method * really resolve the conflict * don't break groups * refactor test assertions for breakdown cases * adds a test to prove that funnels can receive a string and not an array * protect saved dashboards from multi property changeover * WIP * multi breakdown working with funnel step breakdown * prove funnel step person breakdown works with multi property breakdown * don't need to protect cached dashboards from multi property breakdowns when they can't be set from the UI * capitalise keywords in SQL * convert a single test to journey helper * wip * account for funnel step breakdown sometimes being an array sent as a string * safer handling of funnel step breakdown * convert a test * revert commits that made things worse * simpler handling of funnel step breakdown * no need to change funnel step breakdown type hint * update imports * guard against integer properties * compare funnel step breakdown differently now there are arrays involved * look for strict intersection for funnel step breakdown * update test snapshots * need to set breakdown_values earlier in processing * remove tests that cover speculative functionality * update snapshot * move setup of breakdown values back out of update_filters * update snapshots * remove a sql parameter that was never assigned to * Update ee/clickhouse/models/test/test_property.py Co-authored-by: Harry Waye <harry@posthog.com> * Update ee/clickhouse/queries/funnels/base.py Co-authored-by: Harry Waye <harry@posthog.com> * address review comment to simplify reading json expressions for breakdown * clarify why some uses of get_property_string_expr escape params before passing * add keyword arguments for calls to getting property string expressions in funnels * switch to keyword arguments in test helper method * fix parameterised test * add multi property materialized column tests * introduce the shim to allow new API for breakdown properties * can't remove the naive funnel step breakdown list detection * move funnel step breakdown list handling * better handling of numeric funnel step breakdown values * update snapshots Co-authored-by: Harry Waye <harry@posthog.com>
2021-11-22 12:20:01 +01:00
from datetime import datetime
from typing import Any, Dict, List
from uuid import uuid4
from django.utils import timezone
from ee.clickhouse.client import sync_execute
from posthog.models import Person, PersonDistinctId, Team
2022-01-18 08:52:49 +01:00
def journeys_for(
events_by_person: Dict[str, List[Dict[str, Any]]], team: Team, create_people: bool = True
) -> Dict[str, Person]:
"""
Helper for creating specific events for a team.
Allows tests to be written in a declarative style
# these things happened in the past for these people
events_by_person = {
"person1": [{"some": "events}],
"person2": [{"some": "more events}],
}
journeys_for(events_by_person, team)
# then the application receives them
actual = system_under_test.runs()
# and we can assert on the results of that
...
Writing tests in this way reduces duplication in test setup
And clarifies the preconditions of the test
"""
people = {}
events_to_create = []
for distinct_id, events in events_by_person.items():
2022-01-18 08:52:49 +01:00
if create_people:
people[distinct_id] = update_or_create_person(distinct_ids=[distinct_id], team_id=team.pk)
Multi property breakdown for person and event queries on Funnels (#7074) * implement multi property breakdown as an array from the spike * correct type hint on method * really resolve the conflict * don't break groups * refactor test assertions for breakdown cases * adds a test to prove that funnels can receive a string and not an array * protect saved dashboards from multi property changeover * WIP * multi breakdown working with funnel step breakdown * prove funnel step person breakdown works with multi property breakdown * don't need to protect cached dashboards from multi property breakdowns when they can't be set from the UI * capitalise keywords in SQL * convert a single test to journey helper * wip * account for funnel step breakdown sometimes being an array sent as a string * safer handling of funnel step breakdown * convert a test * revert commits that made things worse * simpler handling of funnel step breakdown * no need to change funnel step breakdown type hint * update imports * guard against integer properties * compare funnel step breakdown differently now there are arrays involved * look for strict intersection for funnel step breakdown * update test snapshots * need to set breakdown_values earlier in processing * remove tests that cover speculative functionality * update snapshot * move setup of breakdown values back out of update_filters * update snapshots * remove a sql parameter that was never assigned to * Update ee/clickhouse/models/test/test_property.py Co-authored-by: Harry Waye <harry@posthog.com> * Update ee/clickhouse/queries/funnels/base.py Co-authored-by: Harry Waye <harry@posthog.com> * address review comment to simplify reading json expressions for breakdown * clarify why some uses of get_property_string_expr escape params before passing * add keyword arguments for calls to getting property string expressions in funnels * switch to keyword arguments in test helper method * fix parameterised test * add multi property materialized column tests * introduce the shim to allow new API for breakdown properties * can't remove the naive funnel step breakdown list detection * move funnel step breakdown list handling * better handling of numeric funnel step breakdown values * update snapshots Co-authored-by: Harry Waye <harry@posthog.com>
2021-11-22 12:20:01 +01:00
for event in events:
Multi property breakdown for person and event queries on Funnels (#7074) * implement multi property breakdown as an array from the spike * correct type hint on method * really resolve the conflict * don't break groups * refactor test assertions for breakdown cases * adds a test to prove that funnels can receive a string and not an array * protect saved dashboards from multi property changeover * WIP * multi breakdown working with funnel step breakdown * prove funnel step person breakdown works with multi property breakdown * don't need to protect cached dashboards from multi property breakdowns when they can't be set from the UI * capitalise keywords in SQL * convert a single test to journey helper * wip * account for funnel step breakdown sometimes being an array sent as a string * safer handling of funnel step breakdown * convert a test * revert commits that made things worse * simpler handling of funnel step breakdown * no need to change funnel step breakdown type hint * update imports * guard against integer properties * compare funnel step breakdown differently now there are arrays involved * look for strict intersection for funnel step breakdown * update test snapshots * need to set breakdown_values earlier in processing * remove tests that cover speculative functionality * update snapshot * move setup of breakdown values back out of update_filters * update snapshots * remove a sql parameter that was never assigned to * Update ee/clickhouse/models/test/test_property.py Co-authored-by: Harry Waye <harry@posthog.com> * Update ee/clickhouse/queries/funnels/base.py Co-authored-by: Harry Waye <harry@posthog.com> * address review comment to simplify reading json expressions for breakdown * clarify why some uses of get_property_string_expr escape params before passing * add keyword arguments for calls to getting property string expressions in funnels * switch to keyword arguments in test helper method * fix parameterised test * add multi property materialized column tests * introduce the shim to allow new API for breakdown properties * can't remove the naive funnel step breakdown list detection * move funnel step breakdown list handling * better handling of numeric funnel step breakdown values * update snapshots Co-authored-by: Harry Waye <harry@posthog.com>
2021-11-22 12:20:01 +01:00
if "timestamp" not in event:
event["timestamp"] = datetime.now()
events_to_create.append(
_create_event(
team=team,
distinct_id=distinct_id,
event=event["event"],
timestamp=event["timestamp"],
properties=event.get("properties", {}),
)
)
_create_all_events(events_to_create)
return people
def _create_all_events(all_events: List[Dict]):
parsed = ""
for event in all_events:
data: Dict[str, Any] = {"properties": {}, "timestamp": timezone.now().strftime("%Y-%m-%d %H:%M:%S.%f")}
data.update(event)
in_memory_event = InMemoryEvent(**data)
parsed += f"""
('{str(uuid4())}', '{in_memory_event.event}', '{json.dumps(in_memory_event.properties)}', '{in_memory_event.timestamp}', {in_memory_event.team.pk}, '{in_memory_event.distinct_id}', '', '{timezone.now().strftime("%Y-%m-%d %H:%M:%S.%f")}', now(), 0)
"""
sync_execute(
f"""
INSERT INTO events (uuid, event, properties, timestamp, team_id, distinct_id, elements_chain, created_at, _timestamp, _offset) VALUES
{parsed}
"""
)
# We collect all events per test into an array and batch create the events to reduce creation time
@dataclasses.dataclass
class InMemoryEvent:
event: str
distinct_id: str
team: Team
timestamp: str
properties: Dict
def _create_event(**event):
return {**event}
def update_or_create_person(distinct_ids: List[str], team_id: int, **kwargs):
(person, _) = Person.objects.update_or_create(
persondistinctid__distinct_id__in=distinct_ids,
persondistinctid__team_id=team_id,
defaults={**kwargs, "team_id": team_id},
)
for distinct_id in distinct_ids:
PersonDistinctId.objects.update_or_create(
distinct_id=distinct_id,
team_id=person.team_id,
defaults={"person_id": person.id, "team_id": team_id, "distinct_id": distinct_id},
)
return person