Skip to content

Commit 0c4746f

Browse files
committed
Add some more tests
1 parent 211bfe7 commit 0c4746f

File tree

3 files changed

+178
-80
lines changed

3 files changed

+178
-80
lines changed

posthog/test/test_feature_flag.py

Lines changed: 166 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,175 @@
1-
import pytest
2-
from posthog.types import FeatureFlag
1+
import unittest
2+
from posthog.types import (
3+
FeatureFlag,
4+
FlagMetadata,
5+
FlagReason,
6+
LegacyFlagMetadata,
7+
normalize_decide_response,
8+
to_flags_and_payloads,
9+
)
310

411

5-
def test_from_value_and_payload_boolean_true_value():
6-
# Test with boolean value
7-
flag = FeatureFlag.from_value_and_payload(key="my-flag", value=True, payload='{"some": "data"}')
12+
class TestFeatureFlag(unittest.TestCase):
13+
def test_feature_flag_from_json(self):
14+
# Test with full metadata
15+
resp = {
16+
"key": "test-flag",
17+
"enabled": True,
18+
"variant": "test-variant",
19+
"reason": {"code": "matched_condition", "condition_index": 0, "description": "Matched condition set 1"},
20+
"metadata": {"id": 1, "payload": '{"some": "json"}', "version": 2, "description": "test-description"},
21+
}
822

9-
assert flag.key == "my-flag"
10-
assert flag.enabled is True
11-
assert flag.variant is None
12-
assert flag.metadata.payload == '{"some": "data"}'
23+
flag = FeatureFlag.from_json(resp)
24+
self.assertEqual(flag.key, "test-flag")
25+
self.assertTrue(flag.enabled)
26+
self.assertEqual(flag.variant, "test-variant")
27+
self.assertEqual(flag.get_value(), "test-variant")
28+
self.assertEqual(
29+
flag.reason, FlagReason(code="matched_condition", condition_index=0, description="Matched condition set 1")
30+
)
31+
self.assertEqual(
32+
flag.metadata, FlagMetadata(id=1, payload='{"some": "json"}', version=2, description="test-description")
33+
)
1334

35+
def test_feature_flag_from_json_minimal(self):
36+
# Test with minimal required fields
37+
resp = {"key": "test-flag", "enabled": True}
1438

15-
def test_from_value_and_payload_boolean_false_value():
16-
# Test with False value
17-
flag = FeatureFlag.from_value_and_payload(key="my-flag", value=False, payload=None)
39+
flag = FeatureFlag.from_json(resp)
40+
self.assertEqual(flag.key, "test-flag")
41+
self.assertTrue(flag.enabled)
42+
self.assertIsNone(flag.variant)
43+
self.assertEqual(flag.get_value(), True)
44+
self.assertIsNone(flag.reason)
45+
self.assertEqual(flag.metadata, LegacyFlagMetadata(payload=None))
1846

19-
assert flag.key == "my-flag"
20-
assert flag.enabled is False
21-
assert flag.variant is None
22-
assert flag.metadata.payload is None
47+
def test_feature_flag_from_json_without_metadata(self):
48+
# Test with reason but no metadata
49+
resp = {
50+
"key": "test-flag",
51+
"enabled": True,
52+
"variant": "test-variant",
53+
"reason": {"code": "matched_condition", "condition_index": 0, "description": "Matched condition set 1"},
54+
}
2355

56+
flag = FeatureFlag.from_json(resp)
57+
self.assertEqual(flag.key, "test-flag")
58+
self.assertTrue(flag.enabled)
59+
self.assertEqual(flag.variant, "test-variant")
60+
self.assertEqual(flag.get_value(), "test-variant")
61+
self.assertEqual(
62+
flag.reason, FlagReason(code="matched_condition", condition_index=0, description="Matched condition set 1")
63+
)
64+
self.assertEqual(flag.metadata, LegacyFlagMetadata(payload=None))
2465

25-
def test_from_value_and_payload_string_variant():
26-
flag = FeatureFlag.from_value_and_payload(
27-
key="my-flag", value="test-variant", payload='{"variant": "test-variant"}'
28-
)
66+
def test_flag_reason_from_json(self):
67+
# Test with complete data
68+
resp = {
69+
"code": "user_in_segment",
70+
"condition_index": 1,
71+
"description": "User is in segment 'beta_users'"
72+
}
73+
reason = FlagReason.from_json(resp)
74+
self.assertEqual(reason.code, "user_in_segment")
75+
self.assertEqual(reason.condition_index, 1)
76+
self.assertEqual(reason.description, "User is in segment 'beta_users'")
2977

30-
assert flag.key == "my-flag"
31-
assert flag.enabled is True # String values should make enabled True
32-
assert flag.variant == "test-variant"
33-
assert flag.metadata.payload == '{"variant": "test-variant"}'
78+
# Test with partial data
79+
resp = {
80+
"code": "user_in_segment"
81+
}
82+
reason = FlagReason.from_json(resp)
83+
self.assertEqual(reason.code, "user_in_segment")
84+
self.assertEqual(reason.condition_index, 0) # default value
85+
self.assertEqual(reason.description, "") # default value
86+
87+
# Test with None
88+
self.assertIsNone(FlagReason.from_json(None))
89+
90+
def test_flag_metadata_from_json(self):
91+
# Test with complete data
92+
resp = {
93+
"id": 123,
94+
"payload": {"key": "value"},
95+
"version": 1,
96+
"description": "Test flag"
97+
}
98+
metadata = FlagMetadata.from_json(resp)
99+
self.assertEqual(metadata.id, 123)
100+
self.assertEqual(metadata.payload, {"key": "value"})
101+
self.assertEqual(metadata.version, 1)
102+
self.assertEqual(metadata.description, "Test flag")
103+
104+
# Test with partial data
105+
resp = {
106+
"id": 123
107+
}
108+
metadata = FlagMetadata.from_json(resp)
109+
self.assertEqual(metadata.id, 123)
110+
self.assertIsNone(metadata.payload)
111+
self.assertEqual(metadata.version, 0) # default value
112+
self.assertEqual(metadata.description, "") # default value
113+
114+
# Test with None
115+
self.assertIsNone(FlagMetadata.from_json(None))
116+
117+
def test_feature_flag_from_json_complete(self):
118+
# Test with complete data
119+
resp = {
120+
"key": "test-flag",
121+
"enabled": True,
122+
"variant": "control",
123+
"reason": {
124+
"code": "user_in_segment",
125+
"condition_index": 1,
126+
"description": "User is in segment 'beta_users'"
127+
},
128+
"metadata": {
129+
"id": 123,
130+
"payload": {"key": "value"},
131+
"version": 1,
132+
"description": "Test flag"
133+
}
134+
}
135+
flag = FeatureFlag.from_json(resp)
136+
self.assertEqual(flag.key, "test-flag")
137+
self.assertTrue(flag.enabled)
138+
self.assertEqual(flag.variant, "control")
139+
self.assertIsInstance(flag.reason, FlagReason)
140+
self.assertEqual(flag.reason.code, "user_in_segment")
141+
self.assertIsInstance(flag.metadata, FlagMetadata)
142+
self.assertEqual(flag.metadata.id, 123)
143+
self.assertEqual(flag.metadata.payload, {"key": "value"})
144+
145+
def test_feature_flag_from_json_minimal_data(self):
146+
# Test with minimal data
147+
resp = {
148+
"key": "test-flag",
149+
"enabled": False
150+
}
151+
flag = FeatureFlag.from_json(resp)
152+
self.assertEqual(flag.key, "test-flag")
153+
self.assertFalse(flag.enabled)
154+
self.assertIsNone(flag.variant)
155+
self.assertIsNone(flag.reason)
156+
self.assertIsInstance(flag.metadata, LegacyFlagMetadata)
157+
self.assertIsNone(flag.metadata.payload)
158+
159+
def test_feature_flag_from_json_with_reason(self):
160+
# Test with reason but no metadata
161+
resp = {
162+
"key": "test-flag",
163+
"enabled": True,
164+
"reason": {
165+
"code": "user_in_segment"
166+
}
167+
}
168+
flag = FeatureFlag.from_json(resp)
169+
self.assertEqual(flag.key, "test-flag")
170+
self.assertTrue(flag.enabled)
171+
self.assertIsNone(flag.variant)
172+
self.assertIsInstance(flag.reason, FlagReason)
173+
self.assertEqual(flag.reason.code, "user_in_segment")
174+
self.assertIsInstance(flag.metadata, LegacyFlagMetadata)
175+
self.assertIsNone(flag.metadata.payload)

posthog/test/test_types.py

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -171,56 +171,3 @@ def test_to_flags_and_payloads_with_payload(self):
171171

172172
self.assertEqual(result["featureFlags"]["decide-flag"], "decide-variant")
173173
self.assertEqual(result["featureFlagPayloads"]["decide-flag"], '{"foo": "bar"}')
174-
175-
def test_feature_flag_from_json(self):
176-
# Test with full metadata
177-
resp = {
178-
"key": "test-flag",
179-
"enabled": True,
180-
"variant": "test-variant",
181-
"reason": {"code": "matched_condition", "condition_index": 0, "description": "Matched condition set 1"},
182-
"metadata": {"id": 1, "payload": '{"some": "json"}', "version": 2, "description": "test-description"},
183-
}
184-
185-
flag = FeatureFlag.from_json(resp)
186-
self.assertEqual(flag.key, "test-flag")
187-
self.assertTrue(flag.enabled)
188-
self.assertEqual(flag.variant, "test-variant")
189-
self.assertEqual(flag.get_value(), "test-variant")
190-
self.assertEqual(
191-
flag.reason, FlagReason(code="matched_condition", condition_index=0, description="Matched condition set 1")
192-
)
193-
self.assertEqual(
194-
flag.metadata, FlagMetadata(id=1, payload='{"some": "json"}', version=2, description="test-description")
195-
)
196-
197-
def test_feature_flag_from_json_minimal(self):
198-
# Test with minimal required fields
199-
resp = {"key": "test-flag", "enabled": True}
200-
201-
flag = FeatureFlag.from_json(resp)
202-
self.assertEqual(flag.key, "test-flag")
203-
self.assertTrue(flag.enabled)
204-
self.assertIsNone(flag.variant)
205-
self.assertEqual(flag.get_value(), True)
206-
self.assertIsNone(flag.reason)
207-
self.assertEqual(flag.metadata, LegacyFlagMetadata(payload=None))
208-
209-
def test_feature_flag_from_json_without_metadata(self):
210-
# Test with reason but no metadata
211-
resp = {
212-
"key": "test-flag",
213-
"enabled": True,
214-
"variant": "test-variant",
215-
"reason": {"code": "matched_condition", "condition_index": 0, "description": "Matched condition set 1"},
216-
}
217-
218-
flag = FeatureFlag.from_json(resp)
219-
self.assertEqual(flag.key, "test-flag")
220-
self.assertTrue(flag.enabled)
221-
self.assertEqual(flag.variant, "test-variant")
222-
self.assertEqual(flag.get_value(), "test-variant")
223-
self.assertEqual(
224-
flag.reason, FlagReason(code="matched_condition", condition_index=0, description="Matched condition set 1")
225-
)
226-
self.assertEqual(flag.metadata, LegacyFlagMetadata(payload=None))

posthog/types.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
from dataclasses import dataclass
2-
from typing import List, TypedDict, Any, TypeAlias, cast
3-
4-
FlagValue: TypeAlias = bool | str
2+
from typing import List, TypedDict, Any, Union, cast
3+
import sys
4+
5+
try:
6+
from typing import TypeAlias
7+
except ImportError:
8+
TypeAlias = None
9+
10+
if TypeAlias:
11+
FlagValue: TypeAlias = bool | str
12+
else:
13+
FlagValue = Union[bool, str]
514

615

716
@dataclass(frozen=True)

0 commit comments

Comments
 (0)