-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
test_clickhouse_funnel.py
289 lines (256 loc) 路 10 KB
/
test_clickhouse_funnel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
import json
from datetime import datetime
from ee.api.test.base import LicensedTestMixin
from ee.clickhouse.views.test.funnel.util import (
EventPattern,
FunnelRequest,
get_funnel_actors_ok,
get_funnel_ok,
)
from posthog.constants import INSIGHT_FUNNELS
from posthog.models.group.util import create_group
from posthog.models.group_type_mapping import GroupTypeMapping
from posthog.test.base import (
APIBaseTest,
ClickhouseTestMixin,
snapshot_clickhouse_queries,
)
from posthog.test.test_journeys import journeys_for
class ClickhouseTestFunnelGroups(ClickhouseTestMixin, LicensedTestMixin, APIBaseTest):
maxDiff = None
CLASS_DATA_LEVEL_SETUP = False
def _create_groups(self):
GroupTypeMapping.objects.create(team=self.team, group_type="organization", group_type_index=0)
GroupTypeMapping.objects.create(team=self.team, group_type="company", group_type_index=1)
create_group(
team_id=self.team.pk,
group_type_index=0,
group_key="org:5",
properties={"industry": "finance"},
)
create_group(
team_id=self.team.pk,
group_type_index=0,
group_key="org:6",
properties={"industry": "technology"},
)
create_group(
team_id=self.team.pk,
group_type_index=1,
group_key="company:1",
properties={},
)
create_group(
team_id=self.team.pk,
group_type_index=1,
group_key="company:2",
properties={},
)
@snapshot_clickhouse_queries
def test_funnel_aggregation_with_groups(self):
self._create_groups()
events_by_person = {
"user_1": [
{
"event": "user signed up",
"timestamp": datetime(2020, 1, 2, 14),
"properties": {"$group_0": "org:5"},
},
{
"event": "user signed up", # same person, different group, so should count as different step 1 in funnel
"timestamp": datetime(2020, 1, 10, 14),
"properties": {"$group_0": "org:6"},
},
],
"user_2": [
{ # different person, same group, so should count as step two in funnel
"event": "paid",
"timestamp": datetime(2020, 1, 3, 14),
"properties": {"$group_0": "org:5"},
}
],
}
journeys_for(events_by_person, self.team)
params = FunnelRequest(
events=json.dumps(
[
EventPattern(id="user signed up", type="events", order=0),
EventPattern(id="paid", type="events", order=1),
]
),
date_from="2020-01-01",
date_to="2020-01-14",
aggregation_group_type_index=0,
insight=INSIGHT_FUNNELS,
)
result = get_funnel_ok(self.client, self.team.pk, params)
assert result["user signed up"]["count"] == 2
assert result["paid"]["count"] == 1
assert result["paid"]["average_conversion_time"] == 86400
actors = get_funnel_actors_ok(self.client, result["user signed up"]["converted_people_url"])
actor_ids = [str(val["id"]) for val in actors]
assert actor_ids == ["org:5", "org:6"]
@snapshot_clickhouse_queries
def test_funnel_group_aggregation_with_groups_entity_filtering(self):
self._create_groups()
events_by_person = {
"user_1": [
{
"event": "user signed up",
"timestamp": datetime(2020, 1, 2, 14),
"properties": {"$group_0": "org:5"},
}
],
"user_2": [
{ # different person, same group, so should count as step two in funnel
"event": "paid",
"timestamp": datetime(2020, 1, 3, 14),
"properties": {"$group_0": "org:5"},
}
],
"user_3": [
{ # different person, different group, so should be discarded from step 1 in funnel
"event": "user signed up",
"timestamp": datetime(2020, 1, 10, 14),
"properties": {"$group_0": "org:6"},
}
],
}
journeys_for(events_by_person, self.team)
params = FunnelRequest(
events=json.dumps(
[
EventPattern(
id="user signed up",
type="events",
order=0,
properties={"$group_0": "org:5"},
),
EventPattern(id="paid", type="events", order=1),
]
),
date_from="2020-01-01",
date_to="2020-01-14",
aggregation_group_type_index=0,
insight=INSIGHT_FUNNELS,
)
result = get_funnel_ok(self.client, self.team.pk, params)
assert result["user signed up"]["count"] == 1
assert result["paid"]["count"] == 1
assert result["paid"]["average_conversion_time"] == 86400
actors = get_funnel_actors_ok(self.client, result["user signed up"]["converted_people_url"])
actor_ids = [str(val["id"]) for val in actors]
assert actor_ids == ["org:5"]
@snapshot_clickhouse_queries
def test_funnel_with_groups_entity_filtering(self):
self._create_groups()
events_by_person = {
"user_1": [
{
"event": "user signed up",
"timestamp": datetime(2020, 1, 2, 14),
"properties": {"$group_0": "org:5"},
},
{
"event": "paid",
"timestamp": datetime(2020, 1, 3, 14),
"properties": {
"$group_0": "org:6"
}, # different group, but doesn't matter since not aggregating by groups
},
{
"event": "user signed up", # event belongs to different group, so shouldn't enter funnel
"timestamp": datetime(2020, 1, 2, 14),
"properties": {"$group_0": "org:6"},
},
{
"event": "paid",
"timestamp": datetime(2020, 1, 3, 14),
"properties": {"$group_0": "org:6"}, # event belongs to different group, so shouldn't enter funnel
},
]
}
created_people = journeys_for(events_by_person, self.team)
params = FunnelRequest(
events=json.dumps(
[
EventPattern(
id="user signed up",
type="events",
order=0,
properties={"$group_0": "org:5"},
),
EventPattern(id="paid", type="events", order=1),
]
),
date_from="2020-01-01",
date_to="2020-01-14",
insight=INSIGHT_FUNNELS,
)
result = get_funnel_ok(self.client, self.team.pk, params)
assert result["user signed up"]["count"] == 1
assert result["paid"]["count"] == 1
assert result["paid"]["average_conversion_time"] == 86400
actors = get_funnel_actors_ok(self.client, result["user signed up"]["converted_people_url"])
actor_ids = [str(val["id"]) for val in actors]
assert actor_ids == sorted([str(created_people["user_1"].uuid)])
@snapshot_clickhouse_queries
def test_funnel_with_groups_global_filtering(self):
self._create_groups()
events_by_person = {
"user_1": [
{
"event": "user signed up",
"timestamp": datetime(2020, 1, 2, 14),
"properties": {"$group_0": "org:5"},
},
{
"event": "paid",
"timestamp": datetime(2020, 1, 3, 14),
"properties": {
"$group_0": "org:6"
}, # second event belongs to different group, so shouldn't complete funnel
},
],
"user_2": [
{
"event": "user signed up", # event belongs to different group, so shouldn't enter funnel
"timestamp": datetime(2020, 1, 2, 14),
"properties": {"$group_0": "org:6"},
},
{
"event": "paid",
"timestamp": datetime(2020, 1, 3, 14),
"properties": {"$group_0": "org:5"}, # same group, but different person, so not in funnel
},
],
}
created_people = journeys_for(events_by_person, self.team)
params = FunnelRequest(
events=json.dumps(
[
EventPattern(id="user signed up", type="events", order=0),
EventPattern(id="paid", type="events", order=1),
]
),
date_from="2020-01-01",
date_to="2020-01-14",
insight=INSIGHT_FUNNELS,
properties=json.dumps(
[
{
"key": "industry",
"value": "finance",
"type": "group",
"group_type_index": 0,
}
]
),
)
result = get_funnel_ok(self.client, self.team.pk, params)
assert result["user signed up"]["count"] == 1
assert result["paid"]["count"] == 0
actors = get_funnel_actors_ok(self.client, result["user signed up"]["converted_people_url"])
actor_ids = [str(val["id"]) for val in actors]
assert actor_ids == sorted([str(created_people["user_1"].uuid)])
# TODO: move all tests