Skip to content

Commit a126308

Browse files
committed
Add special case context handling for prefab.current-time
1 parent 1271d0d commit a126308

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

prefab_cloud_python/config_resolver.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22
import functools
3+
import time
34
from collections.abc import Sequence
45

56
from .read_write_lock import ReadWriteLock
@@ -129,7 +130,11 @@ def all_criteria_match(self, conditional_value, props):
129130
return True
130131

131132
def evaluate_criterion(self, criterion, properties):
132-
value_from_properties = properties.get(criterion.property_name)
133+
if criterion.property_name == "prefab.current-time":
134+
value_from_properties = int(time.time() * 1000)
135+
else:
136+
value_from_properties = properties.get(criterion.property_name)
137+
133138
deepest_value = ConfigValueUnwrapper.deepest_value(
134139
criterion.value_to_match, self.config, properties
135140
)

tests/test_criteria_evaluator.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from prefab_cloud_python.config_resolver import CriteriaEvaluator
22
from prefab_cloud_python.context import Context
33
import prefab_pb2 as Prefab
4+
from datetime import datetime, timezone, timedelta
5+
from unittest.mock import patch
46

57
project_env_id = 1
68
test_env_id = 2
@@ -1019,6 +1021,92 @@ def test_stringifying_property_values_and_names(self):
10191021
== desired_value
10201022
)
10211023

1024+
def test_prefab_current_time(self):
1025+
# Set up a fixed time for testing
1026+
test_time = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc)
1027+
test_time_millis = int(test_time.timestamp() * 1000)
1028+
1029+
# Create a config that checks if current time is before a future time
1030+
future_time = test_time + timedelta(hours=1)
1031+
future_time_millis = int(future_time.timestamp() * 1000)
1032+
1033+
config = Prefab.Config(
1034+
key=key,
1035+
rows=[
1036+
default_row,
1037+
Prefab.ConfigRow(
1038+
project_env_id=project_env_id,
1039+
values=[
1040+
Prefab.ConditionalValue(
1041+
criteria=[
1042+
Prefab.Criterion(
1043+
operator=Prefab.Criterion.CriterionOperator.PROP_BEFORE,
1044+
property_name="prefab.current-time",
1045+
value_to_match=Prefab.ConfigValue(int=future_time_millis)
1046+
)
1047+
],
1048+
value=Prefab.ConfigValue(string=desired_value),
1049+
)
1050+
],
1051+
),
1052+
],
1053+
)
1054+
1055+
# Create a config that checks if current time is after a past time
1056+
past_time = test_time - timedelta(hours=1)
1057+
past_time_millis = int(past_time.timestamp() * 1000)
1058+
1059+
config_past = Prefab.Config(
1060+
key=key,
1061+
rows=[
1062+
default_row,
1063+
Prefab.ConfigRow(
1064+
project_env_id=project_env_id,
1065+
values=[
1066+
Prefab.ConditionalValue(
1067+
criteria=[
1068+
Prefab.Criterion(
1069+
operator=Prefab.Criterion.CriterionOperator.PROP_AFTER,
1070+
property_name="prefab.current-time",
1071+
value_to_match=Prefab.ConfigValue(int=past_time_millis)
1072+
)
1073+
],
1074+
value=Prefab.ConfigValue(string=desired_value),
1075+
)
1076+
],
1077+
),
1078+
],
1079+
)
1080+
1081+
with patch('time.time') as mock_time:
1082+
# Set the mock to return our test time
1083+
mock_time.return_value = test_time.timestamp()
1084+
1085+
evaluator = CriteriaEvaluator(
1086+
config, project_env_id, resolver=None, base_client=None
1087+
)
1088+
evaluator_past = CriteriaEvaluator(
1089+
config_past, project_env_id, resolver=None, base_client=None
1090+
)
1091+
1092+
# Test current time is before future time
1093+
evaluation = evaluator.evaluate(context({}))
1094+
assert evaluation.raw_config_value().string == desired_value
1095+
1096+
# Test current time is after past time
1097+
evaluation = evaluator_past.evaluate(context({}))
1098+
assert evaluation.raw_config_value().string == desired_value
1099+
1100+
# Test with a different time that's after the future time
1101+
mock_time.return_value = future_time.timestamp() + 3600 # 1 hour after future_time
1102+
evaluation = evaluator.evaluate(context({}))
1103+
assert evaluation.raw_config_value().string == default_value
1104+
1105+
# Test with a different time that's before the past time
1106+
mock_time.return_value = past_time.timestamp() - 3600 # 1 hour before past_time
1107+
evaluation = evaluator_past.evaluate(context({}))
1108+
assert evaluation.raw_config_value().string == default_value
1109+
10221110
@staticmethod
10231111
def mock_resolver(config):
10241112
return MockResolver(config)

0 commit comments

Comments
 (0)