1- package dev .openfeature .contrib .providers .flagd .e2e ;
1+ package dev .openfeature .contrib .providers .flagd .e2e . steps ;
22
33import static org .junit .jupiter .api .Assertions .assertEquals ;
44
1010import dev .openfeature .sdk .EvaluationContext ;
1111import dev .openfeature .sdk .FlagEvaluationDetails ;
1212import dev .openfeature .sdk .ImmutableContext ;
13+ import dev .openfeature .sdk .ImmutableStructure ;
1314import dev .openfeature .sdk .Reason ;
1415import dev .openfeature .sdk .Structure ;
1516import dev .openfeature .sdk .Value ;
16- import io .cucumber .java .AfterAll ;
1717import io .cucumber .java .BeforeAll ;
18+ import io .cucumber .java .en .And ;
1819import io .cucumber .java .en .Given ;
1920import io .cucumber .java .en .Then ;
2021import io .cucumber .java .en .When ;
2122
2223/**
23- * Common test suite used by both RPC and in-process flagd.
24+ * Common test suite used by both RPC and in-process flagd providers .
2425 */
2526public class StepDefinitions {
2627
2728 private static final ReentrantReadWriteLock sync = new ReentrantReadWriteLock ();
2829 private static Client client ;
2930
30- private boolean booleanFlagValue ;
31- private String stringFlagValue ;
32- private int intFlagValue ;
33- private double doubleFlagValue ;
34- private Value objectFlagValue ;
31+ private String booleanFlagKey ;
32+ private String stringFlagKey ;
33+ private String intFlagKey ;
34+ private String doubleFlagKey ;
35+ private String objectFlagKey ;
36+
37+ private boolean booleanFlagDefaultValue ;
38+ private String stringFlagDefaultValue ;
39+ private int intFlagDefaultValue ;
40+ private double doubleFlagDefaultValue ;
41+ private Value objectFlagDefaultValue ;
3542
36- private FlagEvaluationDetails <Boolean > booleanFlagDetails ;
37- private FlagEvaluationDetails <String > stringFlagDetails ;
38- private FlagEvaluationDetails <Integer > intFlagDetails ;
39- private FlagEvaluationDetails <Double > doubleFlagDetails ;
4043 private FlagEvaluationDetails <Value > objectFlagDetails ;
4144
4245 private String contextAwareFlagKey ;
@@ -51,24 +54,22 @@ public class StepDefinitions {
5154 private int typeErrorDefaultValue ;
5255 private FlagEvaluationDetails <Integer > typeErrorDetails ;
5356
57+ private EvaluationContext customEvaluatorContext ;
58+
5459 /**
5560 * Injects the client to use for this test.
56- * Tests run one at a time, but just in case, a lock is used to make sure the client is not updated mid-test.
61+ * Tests run one at a time, but just in case, a lock is used to make sure the
62+ * client is not updated mid-test.
5763 *
5864 * @param client client to inject into test.
5965 */
6066 public static void setClient (Client client ) {
6167 StepDefinitions .client = client ;
62- sync .writeLock ().lock ();
63- }
64-
65- @ AfterAll ()
66- public static void cleanUp () {
67- sync .writeLock ().unlock ();
6868 }
6969
7070 @ BeforeAll ()
7171 @ Given ("a provider is registered" )
72+ @ Given ("a flagd provider is set" )
7273 public static void setup () {
7374 // this is handled by the "Setup" files
7475 }
@@ -81,57 +82,67 @@ public static void setup() {
8182 @ When ("a boolean flag with key {string} is evaluated with default value {string}" )
8283 public void a_boolean_flag_with_key_boolean_flag_is_evaluated_with_default_value_false (String flagKey ,
8384 String defaultValue ) {
84- this .booleanFlagValue = client .getBooleanValue (flagKey , Boolean .valueOf (defaultValue ));
85+ this .booleanFlagKey = flagKey ;
86+ this .booleanFlagDefaultValue = Boolean .valueOf (defaultValue );
8587 }
8688
8789 @ Then ("the resolved boolean value should be {string}" )
8890 public void the_resolved_boolean_value_should_be_true (String expected ) {
89- assertEquals (Boolean .valueOf (expected ), this .booleanFlagValue );
91+ boolean value = client .getBooleanValue (this .booleanFlagKey , Boolean .valueOf (this .booleanFlagDefaultValue ));
92+ assertEquals (Boolean .valueOf (expected ), value );
9093 }
9194
9295 // string value
9396 @ When ("a string flag with key {string} is evaluated with default value {string}" )
9497 public void a_string_flag_with_key_is_evaluated_with_default_value (String flagKey , String defaultValue ) {
95- this .stringFlagValue = client .getStringValue (flagKey , defaultValue );
98+ this .stringFlagKey = flagKey ;
99+ this .stringFlagDefaultValue = defaultValue ;
96100 }
97101
98102 @ Then ("the resolved string value should be {string}" )
99103 public void the_resolved_string_value_should_be (String expected ) {
100- assertEquals (expected , this .stringFlagValue );
104+ String value = client .getStringValue (this .stringFlagKey , this .stringFlagDefaultValue );
105+ assertEquals (expected , value );
101106 }
102107
103108 // integer value
104109 @ When ("an integer flag with key {string} is evaluated with default value {int}" )
105110 public void an_integer_flag_with_key_is_evaluated_with_default_value (String flagKey , Integer defaultValue ) {
106- this .intFlagValue = client .getIntegerValue (flagKey , defaultValue );
111+ this .intFlagKey = flagKey ;
112+ this .intFlagDefaultValue = defaultValue ;
107113 }
108114
109115 @ Then ("the resolved integer value should be {int}" )
110116 public void the_resolved_integer_value_should_be (int expected ) {
111- assertEquals (expected , this .intFlagValue );
117+ int value = client .getIntegerValue (this .intFlagKey , this .intFlagDefaultValue );
118+ assertEquals (expected , value );
112119 }
113120
114121 // float/double value
115122 @ When ("a float flag with key {string} is evaluated with default value {double}" )
116123 public void a_float_flag_with_key_is_evaluated_with_default_value (String flagKey , double defaultValue ) {
117- this .doubleFlagValue = client .getDoubleValue (flagKey , defaultValue );
124+ this .doubleFlagKey = flagKey ;
125+ this .doubleFlagDefaultValue = defaultValue ;
118126 }
119127
120128 @ Then ("the resolved float value should be {double}" )
121129 public void the_resolved_float_value_should_be (double expected ) {
122- assertEquals (expected , this .doubleFlagValue );
130+ double value = client .getDoubleValue (this .doubleFlagKey , this .doubleFlagDefaultValue );
131+ assertEquals (expected , value );
123132 }
124133
125134 // object value
126135 @ When ("an object flag with key {string} is evaluated with a null default value" )
127136 public void an_object_flag_with_key_is_evaluated_with_a_null_default_value (String flagKey ) {
128- this .objectFlagValue = client .getObjectValue (flagKey , new Value ());
137+ this .objectFlagKey = flagKey ;
138+ this .objectFlagDefaultValue = new Value (); // empty value is equivalent to null
129139 }
130140
131141 @ Then ("the resolved object value should be contain fields {string}, {string}, and {string}, with values {string}, {string} and {int}, respectively" )
132142 public void the_resolved_object_value_should_be_contain_fields_and_with_values_and_respectively (String boolField ,
133143 String stringField , String numberField , String boolValue , String stringValue , int numberValue ) {
134- Structure structure = this .objectFlagValue .asStructure ();
144+ Value value = client .getObjectValue (this .objectFlagKey , this .objectFlagDefaultValue );
145+ Structure structure = value .asStructure ();
135146
136147 assertEquals (Boolean .valueOf (boolValue ), structure .asMap ().get (boolField ).asBoolean ());
137148 assertEquals (stringValue , structure .asMap ().get (stringField ).asString ());
@@ -146,71 +157,88 @@ public void the_resolved_object_value_should_be_contain_fields_and_with_values_a
146157 @ When ("a boolean flag with key {string} is evaluated with details and default value {string}" )
147158 public void a_boolean_flag_with_key_is_evaluated_with_details_and_default_value (String flagKey ,
148159 String defaultValue ) {
149- this .booleanFlagDetails = client .getBooleanDetails (flagKey , Boolean .valueOf (defaultValue ));
160+ this .booleanFlagKey = flagKey ;
161+ this .booleanFlagDefaultValue = Boolean .valueOf (defaultValue );
150162 }
151163
152164 @ Then ("the resolved boolean details value should be {string}, the variant should be {string}, and the reason should be {string}" )
153165 public void the_resolved_boolean_value_should_be_the_variant_should_be_and_the_reason_should_be (
154166 String expectedValue ,
155167 String expectedVariant , String expectedReason ) {
156- assertEquals (Boolean .valueOf (expectedValue ), booleanFlagDetails .getValue ());
157- assertEquals (expectedVariant , booleanFlagDetails .getVariant ());
158- assertEquals (expectedReason , booleanFlagDetails .getReason ());
168+ FlagEvaluationDetails <Boolean > details = client .getBooleanDetails (this .booleanFlagKey ,
169+ Boolean .valueOf (this .booleanFlagDefaultValue ));
170+
171+ assertEquals (Boolean .valueOf (expectedValue ), details .getValue ());
172+ assertEquals (expectedVariant , details .getVariant ());
173+ assertEquals (expectedReason , details .getReason ());
159174 }
160175
161176 // string details
162177 @ When ("a string flag with key {string} is evaluated with details and default value {string}" )
163178 public void a_string_flag_with_key_is_evaluated_with_details_and_default_value (String flagKey ,
164179 String defaultValue ) {
165- this .stringFlagDetails = client .getStringDetails (flagKey , defaultValue );
180+ this .stringFlagKey = flagKey ;
181+ this .stringFlagDefaultValue = defaultValue ;
166182 }
167183
168184 @ Then ("the resolved string details value should be {string}, the variant should be {string}, and the reason should be {string}" )
169185 public void the_resolved_string_value_should_be_the_variant_should_be_and_the_reason_should_be (String expectedValue ,
170186 String expectedVariant , String expectedReason ) {
171- assertEquals (expectedValue , this .stringFlagDetails .getValue ());
172- assertEquals (expectedVariant , this .stringFlagDetails .getVariant ());
173- assertEquals (expectedReason , this .stringFlagDetails .getReason ());
187+ FlagEvaluationDetails <String > details = client .getStringDetails (this .stringFlagKey ,
188+ this .stringFlagDefaultValue );
189+
190+ assertEquals (expectedValue , details .getValue ());
191+ assertEquals (expectedVariant , details .getVariant ());
192+ assertEquals (expectedReason , details .getReason ());
174193 }
175194
176195 // integer details
177196 @ When ("an integer flag with key {string} is evaluated with details and default value {int}" )
178197 public void an_integer_flag_with_key_is_evaluated_with_details_and_default_value (String flagKey , int defaultValue ) {
179- this .intFlagDetails = client .getIntegerDetails (flagKey , defaultValue );
198+ this .intFlagKey = flagKey ;
199+ this .intFlagDefaultValue = defaultValue ;
180200 }
181201
182202 @ Then ("the resolved integer details value should be {int}, the variant should be {string}, and the reason should be {string}" )
183203 public void the_resolved_integer_value_should_be_the_variant_should_be_and_the_reason_should_be (int expectedValue ,
184204 String expectedVariant , String expectedReason ) {
185- assertEquals (expectedValue , this .intFlagDetails .getValue ());
186- assertEquals (expectedVariant , this .intFlagDetails .getVariant ());
187- assertEquals (expectedReason , this .intFlagDetails .getReason ());
205+ FlagEvaluationDetails <Integer > details = client .getIntegerDetails (this .intFlagKey , this .intFlagDefaultValue );
206+
207+ assertEquals (expectedValue , details .getValue ());
208+ assertEquals (expectedVariant , details .getVariant ());
209+ assertEquals (expectedReason , details .getReason ());
188210 }
189211
190212 // float/double details
191213 @ When ("a float flag with key {string} is evaluated with details and default value {double}" )
192214 public void a_float_flag_with_key_is_evaluated_with_details_and_default_value (String flagKey , double defaultValue ) {
193- this .doubleFlagDetails = client .getDoubleDetails (flagKey , defaultValue );
215+ this .doubleFlagKey = flagKey ;
216+ this .doubleFlagDefaultValue = defaultValue ;
194217 }
195218
196219 @ Then ("the resolved float details value should be {double}, the variant should be {string}, and the reason should be {string}" )
197220 public void the_resolved_float_value_should_be_the_variant_should_be_and_the_reason_should_be (double expectedValue ,
198221 String expectedVariant , String expectedReason ) {
199- assertEquals (expectedValue , this .doubleFlagDetails .getValue ());
200- assertEquals (expectedVariant , this .doubleFlagDetails .getVariant ());
201- assertEquals (expectedReason , this .doubleFlagDetails .getReason ());
222+ FlagEvaluationDetails <Double > details = client .getDoubleDetails (this .doubleFlagKey ,
223+ this .doubleFlagDefaultValue );
224+
225+ assertEquals (expectedValue , details .getValue ());
226+ assertEquals (expectedVariant , details .getVariant ());
227+ assertEquals (expectedReason , details .getReason ());
202228 }
203229
204230 // object details
205231 @ When ("an object flag with key {string} is evaluated with details and a null default value" )
206232 public void an_object_flag_with_key_is_evaluated_with_details_and_a_null_default_value (String flagKey ) {
207- this .objectFlagDetails = client .getObjectDetails (flagKey , new Value ());
233+ this .objectFlagKey = flagKey ;
234+ this .objectFlagDefaultValue = new Value ();
208235 }
209236
210237 @ Then ("the resolved object details value should be contain fields {string}, {string}, and {string}, with values {string}, {string} and {int}, respectively" )
211238 public void the_resolved_object_value_should_be_contain_fields_and_with_values_and_respectively_again (
212239 String boolField ,
213240 String stringField , String numberField , String boolValue , String stringValue , int numberValue ) {
241+ this .objectFlagDetails = client .getObjectDetails (this .objectFlagKey , this .objectFlagDefaultValue );
214242 Structure structure = this .objectFlagDetails .getValue ().asStructure ();
215243
216244 assertEquals (Boolean .valueOf (boolValue ), structure .asMap ().get (boolField ).asBoolean ());
@@ -303,4 +331,30 @@ public void the_reason_should_indicate_an_error_and_the_error_code_should_be_typ
303331 assertEquals (errorCode , typeErrorDetails .getErrorCode ().toString ());
304332 }
305333
334+ /*
335+ * Custom JSON evaluators (only run for flagd-in-process)
336+ */
337+
338+ @ And ("a context containing a nested property with outer key {string} and inner key {string}, with value {string}" )
339+ public void a_context_containing_a_nested_property_with_outer_key_and_inner_key_with_value (String outerKey ,
340+ String innerKey , String value ) throws InstantiationException {
341+ Map <String , Value > innerMap = new HashMap <String , Value >();
342+ innerMap .put (innerKey , new Value (value ));
343+ Map <String , Value > outerMap = new HashMap <String , Value >();
344+ outerMap .put (outerKey , new Value (new ImmutableStructure (innerMap )));
345+ this .customEvaluatorContext = new ImmutableContext (outerMap );
346+ }
347+
348+ @ And ("a context containing a key {string}, with value {string}" )
349+ public void a_context_containing_a_key_with_value (String key , String value ) {
350+ Map <String , Value > attrs = new HashMap <String , Value >();
351+ attrs .put (key , new Value (value ));
352+ this .customEvaluatorContext = new ImmutableContext (attrs );
353+ }
354+
355+ @ Then ("the returned value should be {string}" )
356+ public void the_returned_value_should_be (String expected ) {
357+ String value = client .getStringValue (this .stringFlagKey , this .stringFlagDefaultValue , this .customEvaluatorContext );
358+ assertEquals (expected , value );
359+ }
306360}
0 commit comments