|
1249 | 1249 | expect(holdouts).to eq([]) |
1250 | 1250 | end |
1251 | 1251 |
|
1252 | | - it 'should return only the most specific holdout for the flag' do |
1253 | | - holdouts = config_with_holdouts.get_holdouts_for_flag('multi_variate_feature') |
1254 | | - expect(holdouts.length).to eq(1) |
1255 | | - |
1256 | | - # Should only return the explicit holdout (specific_holdout), not the global ones |
| 1252 | + it 'should return all applicable holdouts for the flag' do |
| 1253 | + # get_holdouts_for_flag expects flag ID, not key |
| 1254 | + feature_flag = config_with_holdouts.feature_flag_key_map['multi_variate_feature'] |
| 1255 | + holdouts = config_with_holdouts.get_holdouts_for_flag(feature_flag['id']) |
| 1256 | + # Should return global holdouts (not excluded) + included holdouts |
| 1257 | + # global_holdout (not excluded), holdout_empty_1 (global), specific_holdout (included) |
| 1258 | + expect(holdouts.length).to eq(3) |
| 1259 | + |
| 1260 | + # Should include the explicit holdout (specific_holdout) |
1257 | 1261 | specific_holdout = holdouts.find { |h| h['key'] == 'specific_holdout' } |
1258 | 1262 | expect(specific_holdout).not_to be_nil |
1259 | 1263 | expect(specific_holdout['id']).to eq('holdout_2') |
1260 | 1264 |
|
1261 | | - # Global holdout should NOT be included when explicit holdout exists |
| 1265 | + # Global holdouts should also be included (Swift SDK alignment) |
1262 | 1266 | global_holdout = holdouts.find { |h| h['key'] == 'global_holdout' } |
1263 | | - expect(global_holdout).to be_nil |
| 1267 | + expect(global_holdout).not_to be_nil |
1264 | 1268 | end |
1265 | 1269 |
|
1266 | 1270 | it 'should not return global holdouts that exclude the flag' do |
1267 | | - holdouts = config_with_holdouts.get_holdouts_for_flag('boolean_single_variable_feature') |
| 1271 | + feature_flag = config_with_holdouts.feature_flag_key_map['boolean_single_variable_feature'] |
| 1272 | + holdouts = config_with_holdouts.get_holdouts_for_flag(feature_flag['id']) |
| 1273 | + # Should only return holdout_empty_1 (global, not excluded) |
| 1274 | + # holdout_1 excludes this flag, so it shouldn't be included |
1268 | 1275 | expect(holdouts.length).to eq(1) |
1269 | 1276 |
|
1270 | 1277 | global_holdout = holdouts.find { |h| h['key'] == 'global_holdout' } |
1271 | 1278 | expect(global_holdout).to be_nil |
| 1279 | + |
| 1280 | + empty_holdout = holdouts.find { |h| h['key'] == 'holdout_empty_1' } |
| 1281 | + expect(empty_holdout).not_to be_nil |
1272 | 1282 | end |
1273 | 1283 |
|
1274 | | - it 'should cache results for subsequent calls' do |
1275 | | - holdouts1 = config_with_holdouts.get_holdouts_for_flag('multi_variate_feature') |
1276 | | - holdouts2 = config_with_holdouts.get_holdouts_for_flag('multi_variate_feature') |
| 1284 | + it 'should return consistent results for subsequent calls' do |
| 1285 | + feature_flag = config_with_holdouts.feature_flag_key_map['multi_variate_feature'] |
| 1286 | + holdouts1 = config_with_holdouts.get_holdouts_for_flag(feature_flag['id']) |
| 1287 | + holdouts2 = config_with_holdouts.get_holdouts_for_flag(feature_flag['id']) |
| 1288 | + # Results are cached in @flag_holdouts_map |
1277 | 1289 | expect(holdouts1).to equal(holdouts2) |
1278 | | - expect(holdouts1.length).to eq(1) |
| 1290 | + expect(holdouts1.length).to eq(3) |
1279 | 1291 | end |
1280 | 1292 |
|
1281 | | - it 'should return only one global holdout for flags not specifically targeted' do |
1282 | | - holdouts = config_with_holdouts.get_holdouts_for_flag('string_single_variable_feature') |
| 1293 | + it 'should return all global holdouts for flags not specifically targeted' do |
| 1294 | + feature_flag = config_with_holdouts.feature_flag_key_map['string_single_variable_feature'] |
| 1295 | + holdouts = config_with_holdouts.get_holdouts_for_flag(feature_flag['id']) |
1283 | 1296 |
|
1284 | | - # Should only include one global holdout (not excluded and no specific targeting) |
1285 | | - expect(holdouts.length).to eq(1) |
1286 | | - expect(holdouts.first['key']).to eq('global_holdout') |
| 1297 | + # Should include all global holdouts (not excluded and no specific targeting) |
| 1298 | + # global_holdout + holdout_empty_1 |
| 1299 | + expect(holdouts.length).to eq(2) |
| 1300 | + |
| 1301 | + global_holdout = holdouts.find { |h| h['key'] == 'global_holdout' } |
| 1302 | + expect(global_holdout).not_to be_nil |
| 1303 | + |
| 1304 | + empty_holdout = holdouts.find { |h| h['key'] == 'holdout_empty_1' } |
| 1305 | + expect(empty_holdout).not_to be_nil |
1287 | 1306 | end |
1288 | 1307 | end |
1289 | 1308 |
|
|
1395 | 1414 |
|
1396 | 1415 | it 'should properly categorize holdouts during initialization' do |
1397 | 1416 | expect(config_with_complex_holdouts.holdout_id_map.keys).to contain_exactly('global_holdout', 'specific_holdout') |
1398 | | - expect(config_with_complex_holdouts.global_holdouts.keys).to contain_exactly('global_holdout') |
| 1417 | + |
| 1418 | + # global_holdouts is now an Array (Swift alignment) |
| 1419 | + expect(config_with_complex_holdouts.global_holdouts).to be_an(Array) |
| 1420 | + expect(config_with_complex_holdouts.global_holdouts.length).to eq(1) |
| 1421 | + expect(config_with_complex_holdouts.global_holdouts.first['id']).to eq('global_holdout') |
1399 | 1422 |
|
1400 | 1423 | # Use the correct feature flag IDs |
1401 | 1424 | boolean_feature_id = '155554' |
|
1417 | 1440 |
|
1418 | 1441 | it 'should only process running holdouts during initialization' do |
1419 | 1442 | expect(config_with_complex_holdouts.holdout_id_map['inactive_holdout']).to be_nil |
1420 | | - expect(config_with_complex_holdouts.global_holdouts['inactive_holdout']).to be_nil |
| 1443 | + |
| 1444 | + # global_holdouts is now an Array - check it doesn't contain inactive holdout |
| 1445 | + inactive_in_global = config_with_complex_holdouts.global_holdouts.any? { |h| h['id'] == 'inactive_holdout' } |
| 1446 | + expect(inactive_in_global).to be false |
1421 | 1447 |
|
1422 | 1448 | boolean_feature_id = '155554' |
1423 | 1449 | included_for_boolean = config_with_complex_holdouts.included_holdouts[boolean_feature_id] |
|
1520 | 1546 | end |
1521 | 1547 |
|
1522 | 1548 | it 'should properly cache holdout lookups' do |
1523 | | - holdouts_1 = config_with_holdouts.get_holdouts_for_flag('boolean_feature') |
1524 | | - holdouts_2 = config_with_holdouts.get_holdouts_for_flag('boolean_feature') |
| 1549 | + feature_flag = config_with_holdouts.feature_flag_key_map['boolean_feature'] |
| 1550 | + holdouts_1 = config_with_holdouts.get_holdouts_for_flag(feature_flag['id']) |
| 1551 | + holdouts_2 = config_with_holdouts.get_holdouts_for_flag(feature_flag['id']) |
1525 | 1552 |
|
1526 | 1553 | expect(holdouts_1).to equal(holdouts_2) |
1527 | 1554 | end |
|
1595 | 1622 |
|
1596 | 1623 | it 'should handle mixed holdout configurations' do |
1597 | 1624 | # Verify the config has properly categorized holdouts |
1598 | | - expect(config_with_holdouts.global_holdouts).to be_a(Hash) |
| 1625 | + # global_holdouts is an Array (Swift alignment), others are Hashes |
| 1626 | + expect(config_with_holdouts.global_holdouts).to be_an(Array) |
1599 | 1627 | expect(config_with_holdouts.included_holdouts).to be_a(Hash) |
1600 | 1628 | expect(config_with_holdouts.excluded_holdouts).to be_a(Hash) |
1601 | 1629 | end |
|
1774 | 1802 | config_json = JSON.dump(config_body_with_nil) |
1775 | 1803 | config = Optimizely::DatafileProjectConfig.new(config_json, logger, error_handler) |
1776 | 1804 |
|
1777 | | - # Should treat as global holdout |
1778 | | - expect(config.global_holdouts['holdout_nil']).not_to be_nil |
| 1805 | + # Should treat as global holdout (global_holdouts is an Array) |
| 1806 | + holdout_found = config.global_holdouts.any? { |h| h['id'] == 'holdout_nil' } |
| 1807 | + expect(holdout_found).to be true |
1779 | 1808 | end |
1780 | 1809 |
|
1781 | 1810 | it 'should only include running holdouts in maps' do |
|
0 commit comments