|
7 | 7 | from aws_lambda_powertools.utilities.feature_flags.appconfig import AppConfigStore
|
8 | 8 | from aws_lambda_powertools.utilities.feature_flags.exceptions import StoreClientError
|
9 | 9 | from aws_lambda_powertools.utilities.feature_flags.feature_flags import FeatureFlags
|
10 |
| -from aws_lambda_powertools.utilities.feature_flags.schema import RuleAction |
| 10 | +from aws_lambda_powertools.utilities.feature_flags.schema import ( |
| 11 | + CONDITION_ACTION, |
| 12 | + CONDITION_KEY, |
| 13 | + CONDITION_VALUE, |
| 14 | + CONDITIONS_KEY, |
| 15 | + FEATURE_DEFAULT_VAL_KEY, |
| 16 | + FEATURE_DEFAULT_VAL_TYPE_KEY, |
| 17 | + RULE_MATCH_VALUE, |
| 18 | + RULES_KEY, |
| 19 | + RuleAction, |
| 20 | +) |
11 | 21 | from aws_lambda_powertools.utilities.parameters import GetParameterError
|
12 | 22 |
|
13 | 23 |
|
@@ -1151,3 +1161,130 @@ def test_flags_greater_than_or_equal_match_2(mocker, config):
|
1151 | 1161 | default=False,
|
1152 | 1162 | )
|
1153 | 1163 | assert toggle == expected_value
|
| 1164 | + |
| 1165 | + |
| 1166 | +def test_non_boolean_feature_match(mocker, config): |
| 1167 | + expected_value = ["value1"] |
| 1168 | + # GIVEN |
| 1169 | + mocked_app_config_schema = { |
| 1170 | + "my_feature": { |
| 1171 | + FEATURE_DEFAULT_VAL_KEY: [], |
| 1172 | + FEATURE_DEFAULT_VAL_TYPE_KEY: False, |
| 1173 | + RULES_KEY: { |
| 1174 | + "tenant id equals 345345435": { |
| 1175 | + RULE_MATCH_VALUE: expected_value, |
| 1176 | + CONDITIONS_KEY: [ |
| 1177 | + { |
| 1178 | + CONDITION_ACTION: RuleAction.EQUALS.value, |
| 1179 | + CONDITION_KEY: "tenant_id", |
| 1180 | + CONDITION_VALUE: "345345435", |
| 1181 | + } |
| 1182 | + ], |
| 1183 | + } |
| 1184 | + }, |
| 1185 | + } |
| 1186 | + } |
| 1187 | + |
| 1188 | + # WHEN |
| 1189 | + features = init_feature_flags(mocker, mocked_app_config_schema, config) |
| 1190 | + feature_value = features.evaluate(name="my_feature", context={"tenant_id": "345345435"}, default=[]) |
| 1191 | + # THEN |
| 1192 | + assert feature_value == expected_value |
| 1193 | + |
| 1194 | + |
| 1195 | +def test_non_boolean_feature_with_no_rules(mocker, config): |
| 1196 | + expected_value = ["value1"] |
| 1197 | + # GIVEN |
| 1198 | + mocked_app_config_schema = { |
| 1199 | + "my_feature": {FEATURE_DEFAULT_VAL_KEY: expected_value, FEATURE_DEFAULT_VAL_TYPE_KEY: False} |
| 1200 | + } |
| 1201 | + # WHEN |
| 1202 | + features = init_feature_flags(mocker, mocked_app_config_schema, config) |
| 1203 | + feature_value = features.evaluate(name="my_feature", context={"tenant_id": "345345435"}, default=[]) |
| 1204 | + # THEN |
| 1205 | + assert feature_value == expected_value |
| 1206 | + |
| 1207 | + |
| 1208 | +def test_non_boolean_feature_with_no_rule_match(mocker, config): |
| 1209 | + expected_value = [] |
| 1210 | + mocked_app_config_schema = { |
| 1211 | + "my_feature": { |
| 1212 | + FEATURE_DEFAULT_VAL_KEY: expected_value, |
| 1213 | + FEATURE_DEFAULT_VAL_TYPE_KEY: False, |
| 1214 | + RULES_KEY: { |
| 1215 | + "tenant id equals 345345435": { |
| 1216 | + RULE_MATCH_VALUE: ["value1"], |
| 1217 | + CONDITIONS_KEY: [ |
| 1218 | + { |
| 1219 | + CONDITION_ACTION: RuleAction.EQUALS.value, |
| 1220 | + CONDITION_KEY: "tenant_id", |
| 1221 | + CONDITION_VALUE: "345345435", |
| 1222 | + } |
| 1223 | + ], |
| 1224 | + } |
| 1225 | + }, |
| 1226 | + } |
| 1227 | + } |
| 1228 | + |
| 1229 | + features = init_feature_flags(mocker, mocked_app_config_schema, config) |
| 1230 | + feature_value = features.evaluate(name="my_feature", context={}, default=[]) |
| 1231 | + assert feature_value == expected_value |
| 1232 | + |
| 1233 | + |
| 1234 | +def test_get_all_enabled_features_boolean_and_non_boolean(mocker, config): |
| 1235 | + expected_value = ["my_feature", "my_feature2", "my_non_boolean_feature"] |
| 1236 | + mocked_app_config_schema = { |
| 1237 | + "my_feature": { |
| 1238 | + FEATURE_DEFAULT_VAL_KEY: False, |
| 1239 | + RULES_KEY: { |
| 1240 | + "tenant id is contained in [6, 2]": { |
| 1241 | + RULE_MATCH_VALUE: True, |
| 1242 | + CONDITIONS_KEY: [ |
| 1243 | + { |
| 1244 | + CONDITION_ACTION: RuleAction.IN.value, |
| 1245 | + CONDITION_KEY: "tenant_id", |
| 1246 | + CONDITION_VALUE: ["6", "2"], |
| 1247 | + } |
| 1248 | + ], |
| 1249 | + } |
| 1250 | + }, |
| 1251 | + }, |
| 1252 | + "my_feature2": { |
| 1253 | + FEATURE_DEFAULT_VAL_KEY: True, |
| 1254 | + }, |
| 1255 | + "my_feature3": { |
| 1256 | + FEATURE_DEFAULT_VAL_KEY: False, |
| 1257 | + }, |
| 1258 | + "my_non_boolean_feature": { |
| 1259 | + FEATURE_DEFAULT_VAL_KEY: {}, |
| 1260 | + FEATURE_DEFAULT_VAL_TYPE_KEY: False, |
| 1261 | + RULES_KEY: { |
| 1262 | + "username equals 'a'": { |
| 1263 | + RULE_MATCH_VALUE: {"group": "admin"}, |
| 1264 | + CONDITIONS_KEY: [ |
| 1265 | + { |
| 1266 | + CONDITION_ACTION: RuleAction.EQUALS.value, |
| 1267 | + CONDITION_KEY: "username", |
| 1268 | + CONDITION_VALUE: "a", |
| 1269 | + } |
| 1270 | + ], |
| 1271 | + }, |
| 1272 | + }, |
| 1273 | + }, |
| 1274 | + } |
| 1275 | + |
| 1276 | + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) |
| 1277 | + enabled_list: List[str] = feature_flags.get_enabled_features(context={"tenant_id": "6", "username": "a"}) |
| 1278 | + assert enabled_list == expected_value |
| 1279 | + |
| 1280 | + |
| 1281 | +def test_get_all_enabled_features_non_boolean_truthy_defaults(mocker, config): |
| 1282 | + expected_value = ["my_truthy_feature"] |
| 1283 | + mocked_app_config_schema = { |
| 1284 | + "my_truthy_feature": {FEATURE_DEFAULT_VAL_KEY: {"a": "b"}, FEATURE_DEFAULT_VAL_TYPE_KEY: False}, |
| 1285 | + "my_falsy_feature": {FEATURE_DEFAULT_VAL_KEY: {}, FEATURE_DEFAULT_VAL_TYPE_KEY: False}, |
| 1286 | + } |
| 1287 | + |
| 1288 | + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) |
| 1289 | + enabled_list: List[str] = feature_flags.get_enabled_features(context={"tenant_id": "6", "username": "a"}) |
| 1290 | + assert enabled_list == expected_value |
0 commit comments