Skip to content

Commit 3d1fde8

Browse files
committed
feat(provider): resolve_boolean_details honors default_value
Signed-off-by: Kiki L Hakiem <[email protected]>
1 parent 6f7f253 commit 3d1fde8

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

providers/openfeature-provider-unleash/src/openfeature/contrib/provider/unleash/flag_evaluation.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,13 @@ def resolve_boolean_details(
5454
Returns:
5555
FlagResolutionDetails with the resolved boolean value
5656
"""
57+
5758
context = self._provider._build_unleash_context(evaluation_context)
58-
is_enabled = self._provider.client.is_enabled(flag_key, context=context)
59+
is_enabled = self._provider.client.is_enabled(
60+
flag_key,
61+
context=context,
62+
fallback_function=self._fallback_function(default_value),
63+
)
5964

6065
return FlagResolutionDetails(
6166
value=is_enabled,
@@ -224,3 +229,11 @@ def _parse_json(self, value: Any) -> Any:
224229
except json.JSONDecodeError as e:
225230
raise ParseError(f"Invalid JSON: {e}") from e
226231
return value
232+
233+
def _fallback_function(self, default_value: bool) -> Callable:
234+
"""Default fallback function for Unleash provider."""
235+
236+
def fallback_function(feature_name: str, context: dict) -> bool:
237+
return default_value
238+
239+
return fallback_function

providers/openfeature-provider-unleash/tests/test_flag_evaluation.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""Tests for flag evaluation functionality."""
22

3-
from unittest.mock import Mock, patch
3+
from unittest.mock import ANY, Mock, patch
44

55
import pytest
6+
from UnleashClient.cache import FileCache
67

78
from openfeature.contrib.provider.unleash import UnleashProvider
89
from openfeature.evaluation_context import EvaluationContext
@@ -34,6 +35,29 @@ def test_resolve_boolean_details():
3435
assert flag.reason == Reason.TARGETING_MATCH
3536

3637

38+
def test_resolve_boolean_details_with_true_default():
39+
"""Ensure default_value is used when engine returns None (fallback)."""
40+
# Create a real client via the provider, but prevent network fetches
41+
custom_cache = FileCache("test-app")
42+
custom_cache.bootstrap_from_dict({})
43+
provider = UnleashProvider(
44+
url="http://invalid-host.local", # won't be used since we disable fetch
45+
app_name="test-app",
46+
api_token="test-token",
47+
fetch_toggles=False,
48+
cache=custom_cache,
49+
)
50+
51+
provider.initialize()
52+
53+
try:
54+
result = provider.resolve_boolean_details("test_flag", True)
55+
assert result.value is True # uses the default value via fallback
56+
assert result.reason == Reason.TARGETING_MATCH
57+
finally:
58+
provider.shutdown()
59+
60+
3761
@pytest.mark.parametrize(
3862
"method_name, payload_value, expected_value, default_value",
3963
[
@@ -105,6 +129,7 @@ def test_with_evaluation_context():
105129
mock_client.is_enabled.assert_called_with(
106130
"test_flag",
107131
context={"userId": "user123", "email": "[email protected]", "country": "US"},
132+
fallback_function=ANY,
108133
)
109134

110135
provider.shutdown()

0 commit comments

Comments
 (0)