@@ -105,6 +105,110 @@ def test_basic_capture_with_feature_flags(self, patch_decide):
105
105
106
106
self .assertEqual (patch_decide .call_count , 1 )
107
107
108
+ @mock .patch ("posthog.client.decide" )
109
+ def test_basic_capture_with_locally_evaluated_feature_flags (self , patch_decide ):
110
+ patch_decide .return_value = {"featureFlags" : {"beta-feature" : "random-variant" }}
111
+ client = Client (FAKE_TEST_API_KEY , on_error = self .set_fail , personal_api_key = FAKE_TEST_API_KEY )
112
+
113
+ multivariate_flag = {
114
+ "id" : 1 ,
115
+ "name" : "Beta Feature" ,
116
+ "key" : "beta-feature-local" ,
117
+ "is_simple_flag" : False ,
118
+ "active" : True ,
119
+ "rollout_percentage" : 100 ,
120
+ "filters" : {
121
+ "groups" : [
122
+ {
123
+ "properties" : [
124
+ {"key" : "email" , "type" : "person" , "value" : "test@posthog.com" , "operator" : "exact" }
125
+ ],
126
+ "rollout_percentage" : 100 ,
127
+ },
128
+ {
129
+ "rollout_percentage" : 50 ,
130
+ },
131
+ ],
132
+ "multivariate" : {
133
+ "variants" : [
134
+ {"key" : "first-variant" , "name" : "First Variant" , "rollout_percentage" : 50 },
135
+ {"key" : "second-variant" , "name" : "Second Variant" , "rollout_percentage" : 25 },
136
+ {"key" : "third-variant" , "name" : "Third Variant" , "rollout_percentage" : 25 },
137
+ ]
138
+ },
139
+ "payloads" : {"first-variant" : "some-payload" , "third-variant" : {"a" : "json" }},
140
+ },
141
+ }
142
+ basic_flag = {
143
+ "id" : 1 ,
144
+ "name" : "Beta Feature" ,
145
+ "key" : "person-flag" ,
146
+ "is_simple_flag" : True ,
147
+ "active" : True ,
148
+ "filters" : {
149
+ "groups" : [
150
+ {
151
+ "properties" : [
152
+ {
153
+ "key" : "region" ,
154
+ "operator" : "exact" ,
155
+ "value" : ["USA" ],
156
+ "type" : "person" ,
157
+ }
158
+ ],
159
+ "rollout_percentage" : 100 ,
160
+ }
161
+ ],
162
+ "payloads" : {"true" : 300 },
163
+ },
164
+ }
165
+ false_flag = {
166
+ "id" : 1 ,
167
+ "name" : "Beta Feature" ,
168
+ "key" : "false-flag" ,
169
+ "is_simple_flag" : True ,
170
+ "active" : True ,
171
+ "filters" : {
172
+ "groups" : [
173
+ {
174
+ "properties" : [],
175
+ "rollout_percentage" : 0 ,
176
+ }
177
+ ],
178
+ "payloads" : {"true" : 300 },
179
+ },
180
+ }
181
+ client .feature_flags = [multivariate_flag , basic_flag , false_flag ]
182
+
183
+ success , msg = client .capture ("distinct_id" , "python test event" )
184
+ client .flush ()
185
+ self .assertTrue (success )
186
+ self .assertFalse (self .failed )
187
+
188
+ self .assertEqual (msg ["event" ], "python test event" )
189
+ self .assertTrue (isinstance (msg ["timestamp" ], str ))
190
+ self .assertIsNone (msg .get ("uuid" ))
191
+ self .assertEqual (msg ["distinct_id" ], "distinct_id" )
192
+ self .assertEqual (msg ["properties" ]["$lib" ], "posthog-python" )
193
+ self .assertEqual (msg ["properties" ]["$lib_version" ], VERSION )
194
+ self .assertEqual (msg ["properties" ]["$feature/beta-feature-local" ], "third-variant" )
195
+ self .assertEqual (msg ["properties" ]["$feature/false-flag" ], False )
196
+ self .assertEqual (msg ["properties" ]["$active_feature_flags" ], ["beta-feature-local" ])
197
+ assert "$feature/beta-feature" not in msg ["properties" ]
198
+
199
+ self .assertEqual (patch_decide .call_count , 0 )
200
+
201
+ # test that flags are not evaluated without local evaluation
202
+ client .feature_flags = []
203
+ success , msg = client .capture ("distinct_id" , "python test event" )
204
+ client .flush ()
205
+ self .assertTrue (success )
206
+ self .assertFalse (self .failed )
207
+ assert "$feature/beta-feature" not in msg ["properties" ]
208
+ assert "$feature/beta-feature-local" not in msg ["properties" ]
209
+ assert "$feature/false-flag" not in msg ["properties" ]
210
+ assert "$active_feature_flags" not in msg ["properties" ]
211
+
108
212
@mock .patch ("posthog.client.decide" )
109
213
def test_get_active_feature_flags (self , patch_decide ):
110
214
patch_decide .return_value = {
@@ -620,7 +724,7 @@ def test_disable_geoip_default_on_decide(self, patch_decide):
620
724
timeout = 10 ,
621
725
distinct_id = "some_id" ,
622
726
groups = {},
623
- person_properties = {},
727
+ person_properties = {"$current_distinct_id" : "some_id" },
624
728
group_properties = {},
625
729
disable_geoip = True ,
626
730
)
@@ -632,7 +736,7 @@ def test_disable_geoip_default_on_decide(self, patch_decide):
632
736
timeout = 10 ,
633
737
distinct_id = "feature_enabled_distinct_id" ,
634
738
groups = {},
635
- person_properties = {},
739
+ person_properties = {"$current_distinct_id" : "feature_enabled_distinct_id" },
636
740
group_properties = {},
637
741
disable_geoip = True ,
638
742
)
@@ -644,7 +748,7 @@ def test_disable_geoip_default_on_decide(self, patch_decide):
644
748
timeout = 10 ,
645
749
distinct_id = "all_flags_payloads_id" ,
646
750
groups = {},
647
- person_properties = {},
751
+ person_properties = {"$current_distinct_id" : "all_flags_payloads_id" },
648
752
group_properties = {},
649
753
disable_geoip = False ,
650
754
)
@@ -660,3 +764,70 @@ def raise_effect():
660
764
client .feature_flags = [{"key" : "example" , "is_simple_flag" : False }]
661
765
662
766
self .assertFalse (client .feature_enabled ("example" , "distinct_id" ))
767
+
768
+ @mock .patch ("posthog.client.decide" )
769
+ def test_default_properties_get_added_properly (self , patch_decide ):
770
+ patch_decide .return_value = {
771
+ "featureFlags" : {"beta-feature" : "random-variant" , "alpha-feature" : True , "off-feature" : False }
772
+ }
773
+ client = Client (FAKE_TEST_API_KEY , on_error = self .set_fail , disable_geoip = False )
774
+ client .get_feature_flag (
775
+ "random_key" ,
776
+ "some_id" ,
777
+ groups = {"company" : "id:5" , "instance" : "app.posthog.com" },
778
+ person_properties = {"x1" : "y1" },
779
+ group_properties = {"company" : {"x" : "y" }},
780
+ )
781
+ patch_decide .assert_called_with (
782
+ "random_key" ,
783
+ None ,
784
+ timeout = 10 ,
785
+ distinct_id = "some_id" ,
786
+ groups = {"company" : "id:5" , "instance" : "app.posthog.com" },
787
+ person_properties = {"$current_distinct_id" : "some_id" , "x1" : "y1" },
788
+ group_properties = {
789
+ "company" : {"$group_key" : "id:5" , "x" : "y" },
790
+ "instance" : {"$group_key" : "app.posthog.com" },
791
+ },
792
+ disable_geoip = False ,
793
+ )
794
+
795
+ patch_decide .reset_mock ()
796
+ client .get_feature_flag (
797
+ "random_key" ,
798
+ "some_id" ,
799
+ groups = {"company" : "id:5" , "instance" : "app.posthog.com" },
800
+ person_properties = {"$current_distinct_id" : "override" },
801
+ group_properties = {
802
+ "company" : {
803
+ "$group_key" : "group_override" ,
804
+ }
805
+ },
806
+ )
807
+ patch_decide .assert_called_with (
808
+ "random_key" ,
809
+ None ,
810
+ timeout = 10 ,
811
+ distinct_id = "some_id" ,
812
+ groups = {"company" : "id:5" , "instance" : "app.posthog.com" },
813
+ person_properties = {"$current_distinct_id" : "override" },
814
+ group_properties = {
815
+ "company" : {"$group_key" : "group_override" },
816
+ "instance" : {"$group_key" : "app.posthog.com" },
817
+ },
818
+ disable_geoip = False ,
819
+ )
820
+
821
+ patch_decide .reset_mock ()
822
+ # test nones
823
+ client .get_all_flags_and_payloads ("some_id" , groups = {}, person_properties = None , group_properties = None )
824
+ patch_decide .assert_called_with (
825
+ "random_key" ,
826
+ None ,
827
+ timeout = 10 ,
828
+ distinct_id = "some_id" ,
829
+ groups = {},
830
+ person_properties = {"$current_distinct_id" : "some_id" },
831
+ group_properties = {},
832
+ disable_geoip = False ,
833
+ )
0 commit comments