diff --git a/pkg/handlers/decide.go b/pkg/handlers/decide.go index da2c0722..9607f6e5 100644 --- a/pkg/handlers/decide.go +++ b/pkg/handlers/decide.go @@ -20,16 +20,20 @@ package handlers import ( "errors" "net/http" + "strings" "github.com/go-chi/render" "github.com/optimizely/agent/pkg/middleware" "github.com/optimizely/go-sdk/v2/pkg/client" + "github.com/optimizely/go-sdk/v2/pkg/config" "github.com/optimizely/go-sdk/v2/pkg/decide" "github.com/optimizely/go-sdk/v2/pkg/decision" "github.com/optimizely/go-sdk/v2/pkg/odp/segment" ) +const DefaultRolloutPrefix = "default-" + // DecideBody defines the request body for decide API type DecideBody struct { UserID string `json:"userId"` @@ -50,7 +54,8 @@ type ForcedDecision struct { // DecideOut defines the response type DecideOut struct { client.OptimizelyDecision - Variables map[string]interface{} `json:"variables,omitempty"` + Variables map[string]interface{} `json:"variables,omitempty"` + IsEveryoneElseVariation bool `json:"isEveryoneElseVariation"` } // Decide makes feature decisions for the selected query parameters @@ -97,6 +102,12 @@ func Decide(w http.ResponseWriter, r *http.Request) { keys = r.Form["keys"] } + featureMap := make(map[string]config.OptimizelyFeature) + cfg := optlyClient.GetOptimizelyConfig() + if cfg != nil { + featureMap = cfg.FeaturesMap + } + var decides map[string]client.OptimizelyDecision switch len(keys) { case 0: @@ -107,7 +118,7 @@ func Decide(w http.ResponseWriter, r *http.Request) { key := keys[0] logger.Debug().Str("featureKey", key).Msg("fetching feature decision") d := optimizelyUserContext.Decide(key, decideOptions) - decideOut := DecideOut{d, d.Variables.ToMap()} + decideOut := DecideOut{d, d.Variables.ToMap(), isEveryoneElseVariation(featureMap[d.FlagKey].DeliveryRules, d.RuleKey)} render.JSON(w, r, decideOut) return default: @@ -117,7 +128,7 @@ func Decide(w http.ResponseWriter, r *http.Request) { decideOuts := []DecideOut{} for _, d := range decides { - decideOut := DecideOut{d, d.Variables.ToMap()} + decideOut := DecideOut{d, d.Variables.ToMap(), isEveryoneElseVariation(featureMap[d.FlagKey].DeliveryRules, d.RuleKey)} decideOuts = append(decideOuts, decideOut) logger.Debug().Msgf("Feature %q is enabled for user %s? %t", d.FlagKey, d.UserContext.UserID, d.Enabled) } @@ -137,3 +148,12 @@ func getUserContextWithOptions(r *http.Request) (DecideBody, error) { return body, nil } + +func isEveryoneElseVariation(rules []config.OptimizelyExperiment, ruleKey string) bool { + for _, r := range rules { + if r.Key == ruleKey { + return r.Key == r.ID && strings.HasPrefix(r.Key, DefaultRolloutPrefix) + } + } + return false +} diff --git a/pkg/handlers/decide_test.go b/pkg/handlers/decide_test.go index b0fd194a..7e47e791 100644 --- a/pkg/handlers/decide_test.go +++ b/pkg/handlers/decide_test.go @@ -124,17 +124,21 @@ func (suite *DecideTestSuite) TestDecideWithFeatureTest() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err := json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "1", - Enabled: true, - VariationKey: "2", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "1", + Enabled: true, + VariationKey: "2", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -152,17 +156,21 @@ func (suite *DecideTestSuite) TestTrackWithFeatureRollout() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err := json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "1", - Enabled: true, - VariationKey: "3", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "1", + Enabled: true, + VariationKey: "3", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -206,17 +214,21 @@ func (suite *DecideTestSuite) TestInvalidForcedDecisions() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err = json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "1", - Enabled: true, - VariationKey: "2", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "1", + Enabled: true, + VariationKey: "2", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -265,17 +277,21 @@ func (suite *DecideTestSuite) TestForcedDecisionWithFeatureTest() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err = json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "1", - Enabled: true, - VariationKey: "4", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "1", + Enabled: true, + VariationKey: "4", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -323,17 +339,21 @@ func (suite *DecideTestSuite) TestForcedDecisionFeatureRollout() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err = json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "1", - Enabled: true, - VariationKey: "4", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "1", + Enabled: true, + VariationKey: "4", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -369,17 +389,21 @@ func (suite *DecideTestSuite) TestForcedDecisionWithInvalidVariationKey() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err = json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "1", - Enabled: true, - VariationKey: "3", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "1", + Enabled: true, + VariationKey: "3", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -416,17 +440,21 @@ func (suite *DecideTestSuite) TestForcedDecisionWithEmptyRuleKey() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err = json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "", - Enabled: true, - VariationKey: "4", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "", + Enabled: true, + VariationKey: "4", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -444,18 +472,23 @@ func (suite *DecideTestSuite) TestTrackWithFeatureTest() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err := json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "one", - RuleKey: "1", - Enabled: true, - VariationKey: "2", - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "one", + RuleKey: "1", + Enabled: true, + VariationKey: "2", + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } + suite.Equal(expected, actual) events := suite.tc.GetProcessedEvents() @@ -473,17 +506,21 @@ func (suite *DecideTestSuite) TestDecideMissingFlag() { suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err := json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, - FlagKey: "feature-missing", - RuleKey: "", - Enabled: false, - VariationKey: "", - Reasons: []string{"No flag was found for key \"feature-missing\"."}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: "testUser", Attributes: map[string]interface{}{}}, + FlagKey: "feature-missing", + RuleKey: "", + Enabled: false, + VariationKey: "", + Reasons: []string{"No flag was found for key \"feature-missing\"."}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(0, len(suite.tc.GetProcessedEvents())) @@ -514,7 +551,8 @@ func (suite *DecideTestSuite) TestDecideMultipleFlags() { VariationKey: "3", Reasons: []string{}, }, - Variables: nil, + Variables: nil, + IsEveryoneElseVariation: false, }, { OptimizelyDecision: client.OptimizelyDecision{ @@ -525,7 +563,8 @@ func (suite *DecideTestSuite) TestDecideMultipleFlags() { VariationKey: "6", Reasons: []string{}, }, - Variables: nil, + Variables: nil, + IsEveryoneElseVariation: false, }, } @@ -573,7 +612,8 @@ func (suite *DecideTestSuite) TestDecideAllFlags() { VariationKey: "3", Reasons: []string{}, }, - Variables: nil, + Variables: nil, + IsEveryoneElseVariation: false, }, { OptimizelyDecision: client.OptimizelyDecision{ @@ -584,7 +624,8 @@ func (suite *DecideTestSuite) TestDecideAllFlags() { VariationKey: "6", Reasons: []string{}, }, - Variables: nil, + Variables: nil, + IsEveryoneElseVariation: false, }, { OptimizelyDecision: client.OptimizelyDecision{ @@ -595,7 +636,8 @@ func (suite *DecideTestSuite) TestDecideAllFlags() { VariationKey: "13", Reasons: []string{}, }, - Variables: map[string]interface{}{"strvar": "abc_notdef"}, + Variables: map[string]interface{}{"strvar": "abc_notdef"}, + IsEveryoneElseVariation: false, }, } @@ -703,17 +745,21 @@ func DecideWithFetchSegments(suite *DecideTestSuite, userID string, fetchSegment suite.Equal(http.StatusOK, rec.Code) // Unmarshal response - var actual client.OptimizelyDecision + var actual DecideOut err = json.Unmarshal(rec.Body.Bytes(), &actual) suite.NoError(err) - expected := client.OptimizelyDecision{ - UserContext: client.OptimizelyUserContext{UserID: userID, Attributes: map[string]interface{}{}}, - FlagKey: featureKey, - RuleKey: experimentKey, - Enabled: true, - VariationKey: variationKey, - Reasons: []string{}, + expected := DecideOut{ + OptimizelyDecision: client.OptimizelyDecision{ + UserContext: client.OptimizelyUserContext{UserID: userID, Attributes: map[string]interface{}{}}, + FlagKey: featureKey, + RuleKey: experimentKey, + Enabled: true, + VariationKey: variationKey, + Reasons: []string{}, + }, + Variables: nil, + IsEveryoneElseVariation: false, } suite.Equal(expected, actual) diff --git a/tests/acceptance/test_acceptance/test_decide.py b/tests/acceptance/test_acceptance/test_decide.py index 6b39e319..e583e2ac 100644 --- a/tests/acceptance/test_acceptance/test_decide.py +++ b/tests/acceptance/test_acceptance/test_decide.py @@ -12,6 +12,7 @@ "enabled": True, "ruleKey": "", "flagKey": "feature_2", + "isEveryoneElseVariation": False, "userContext": { "userId": "matjaz", "attributes": { @@ -26,6 +27,7 @@ "enabled": True, "ruleKey": "feature_2_test", "flagKey": "feature_2", + "isEveryoneElseVariation": False, "userContext": { "userId": "matjaz", "attributes": { @@ -43,6 +45,7 @@ "enabled": true, "ruleKey": "feature_2_test", "flagKey": "feature_2", + "isEveryoneElseVariation": false, "userContext": { "userId": "matjaz", "attributes": { @@ -59,6 +62,7 @@ "enabled": true, "ruleKey": "feature_2_test", "flagKey": "feature_2", + "isEveryoneElseVariation": false, "userContext": { "userId": "matjaz", "attributes": { @@ -75,6 +79,7 @@ "enabled": false, "ruleKey": "", "flagKey": "invalid_flag_key", + "isEveryoneElseVariation": false, "userContext": { "userId": "matjaz", "attributes": { @@ -157,6 +162,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16925940659", "enabled": true, "ruleKey": "default-16943340293", + "isEveryoneElseVariation": true, "flagKey": "feature_4", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": [ @@ -167,6 +173,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "variation_1", "enabled": true, "ruleKey": "ab_test1", + "isEveryoneElseVariation": false, "flagKey": "GkbzTurBWXr8EtNGZj2j6e", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["User \"matjaz\" was previously bucketed into variation \"variation_1\" of experiment \"ab_test1\"."]}, @@ -174,6 +181,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "variation_1", "enabled": true, "ruleKey": "feature_2_test", + "isEveryoneElseVariation": false, "flagKey": "feature_2", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["User \"matjaz\" was previously bucketed into variation \"variation_1\" of experiment \"feature_2_test\"."]}, @@ -181,6 +189,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16927890136", "enabled": true, "ruleKey": "default-16917103311", + "isEveryoneElseVariation": true, "flagKey": "feature_5", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": [ @@ -191,6 +200,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16906801184", "enabled": true, "ruleKey": "16941022436", + "isEveryoneElseVariation": false, "flagKey": "feature_1", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["Audiences for experiment 16941022436 collectively evaluated to true."], @@ -203,6 +213,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16906801184", "enabled": true, "ruleKey": "16941022436", + "isEveryoneElseVariation": false, "flagKey": "feature_1", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["Audiences for experiment 16941022436 collectively evaluated to true."], @@ -211,6 +222,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "variation_1", "enabled": true, "ruleKey": "feature_2_test", + "isEveryoneElseVariation": false, "flagKey": "feature_2", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["User \"matjaz\" was previously bucketed into variation \"variation_1\" of experiment \"feature_2_test\"."]}, @@ -218,6 +230,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16925940659", "enabled": true, "ruleKey": "default-16943340293", + "isEveryoneElseVariation": true, "flagKey": "feature_4", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": [ @@ -228,6 +241,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16927890136", "enabled": true, "ruleKey": "default-16917103311", + "isEveryoneElseVariation": true, "flagKey": "feature_5", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": [ @@ -242,6 +256,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16925940659", "enabled": true, "ruleKey": "16939051724", + "isEveryoneElseVariation": false, "flagKey": "feature_4", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["Audiences for experiment 16939051724 collectively evaluated to true."]}, @@ -249,6 +264,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "variation_1", "enabled": true, "ruleKey": "ab_test1", + "isEveryoneElseVariation": false, "flagKey": "GkbzTurBWXr8EtNGZj2j6e", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["Audiences for experiment ab_test1 collectively evaluated to true."]}, @@ -256,6 +272,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "variation_1", "enabled": true, "ruleKey": "feature_2_test", + "isEveryoneElseVariation": false, "flagKey": "feature_2", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["Audiences for experiment feature_2_test collectively evaluated to true."]}, @@ -263,6 +280,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16927890136", "enabled": true, "ruleKey": "16932940705", + "isEveryoneElseVariation": false, "flagKey": "feature_5", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["Audiences for experiment 16932940705 collectively evaluated to true."]}, @@ -270,6 +288,7 @@ def test_decide__feature_no_ups(session_obj, flag_key, expected_response, expect "variationKey": "16906801184", "enabled": true, "ruleKey": "16941022436", + "isEveryoneElseVariation": false, "flagKey": "feature_1", "userContext": {"userId": "matjaz", "attributes": {"attr_1": "hola"}}, "reasons": ["Audiences for experiment 16941022436 collectively evaluated to true."], diff --git a/tests/acceptance/test_acceptance/test_odp_decide.py b/tests/acceptance/test_acceptance/test_odp_decide.py index 96a49f35..511245d1 100644 --- a/tests/acceptance/test_acceptance/test_odp_decide.py +++ b/tests/acceptance/test_acceptance/test_odp_decide.py @@ -12,6 +12,7 @@ "enabled": False, "ruleKey": "default-rollout-52207-23726430538", "flagKey": "flag1", + "isEveryoneElseVariation": True, "userContext": { "userId": "matjaz-user-1", "attributes": {} @@ -28,6 +29,7 @@ "enabled": False, "ruleKey": "default-rollout-52207-23726430538", "flagKey": "flag1", + "isEveryoneElseVariation": True, "userContext": { "userId": "test_user", "attributes": {} @@ -44,6 +46,7 @@ "enabled": True, "ruleKey": "ab_experiment", "flagKey": "flag1", + "isEveryoneElseVariation": False, "userContext": { "userId": "matjaz-user-1", "attributes": {} @@ -56,6 +59,7 @@ "enabled": False, "ruleKey": "default-rollout-52231-23726430538", "flagKey": "flag2", + "isEveryoneElseVariation": True, "userContext": { "userId": "matjaz-user-1", "attributes": {} diff --git a/tests/acceptance/test_acceptance/test_odp_redis.py b/tests/acceptance/test_acceptance/test_odp_redis.py index 7e4b5fdc..ea0fa24e 100644 --- a/tests/acceptance/test_acceptance/test_odp_redis.py +++ b/tests/acceptance/test_acceptance/test_odp_redis.py @@ -14,6 +14,7 @@ "enabled": True, "ruleKey": "ab_experiment", "flagKey": "flag1", + "isEveryoneElseVariation": False, "userContext": { "userId": "matjaz-user-1", "attributes": {} @@ -26,6 +27,7 @@ "enabled": True, "ruleKey": "ab_experiment", "flagKey": "flag1", + "isEveryoneElseVariation": False, "userContext": { "userId": "matjaz-user-2", "attributes": {} @@ -38,6 +40,7 @@ "enabled": True, "ruleKey": "ab_experiment", "flagKey": "flag1", + "isEveryoneElseVariation": False, "userContext": { "userId": "matjaz-user-4", "attributes": {} diff --git a/tests/acceptance/test_acceptance/test_ups.py b/tests/acceptance/test_acceptance/test_ups.py index 58388f8a..935a3bc4 100644 --- a/tests/acceptance/test_acceptance/test_ups.py +++ b/tests/acceptance/test_acceptance/test_ups.py @@ -25,6 +25,7 @@ def test_ups__feature(session_obj): { "variationKey": "variation_1", "enabled": true, + "isEveryoneElseVariation": false, "ruleKey": "feature_2_test", "flagKey": "feature_2", "userContext": { @@ -98,6 +99,7 @@ def test_ups__save(session_obj): "variationKey": "variation_2", "enabled": true, "ruleKey": "feature_2_test", + "isEveryoneElseVariation": false, "flagKey": "feature_2", "userContext": { "userId": "user1", @@ -186,7 +188,8 @@ def test_ups__save_with_invalid_payload(session_obj): "attr_1": "hola" } }, - "reasons": [] + "reasons": [], + "isEveryoneElseVariation": false } """