Skip to content

Commit

Permalink
feat: add support for booleans for alternate key bucketing
Browse files Browse the repository at this point in the history
  • Loading branch information
kaushalkapasi committed Aug 16, 2024
1 parent dd0e778 commit 7f3cbb6
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 3 deletions.
3 changes: 2 additions & 1 deletion bucketing/bucketing.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ func determineUserBucketingValueForTarget(targetBucketingKey, userId string, mer
return strconv.FormatFloat(v, 'f', -1, 64)
case string:
return v
// For Boolean and other types, we will return the defaultBucketingValue of "null"
case bool:
return strconv.FormatBool(v)
default:
return defaultBucketingValue
}
Expand Down
63 changes: 61 additions & 2 deletions bucketing/bucketing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ func TestGenerateBucketedConfig_MissingVariables(t *testing.T) {
require.ErrorIs(t, err, ErrMissingVariable)
}

func TestBucketing_Deterministic_AlternateKeyRandomDistribution(t *testing.T) {
func TestBucketing_Deterministic_StringAlternateKeyRandomDistribution(t *testing.T) {
user := api.User{
UserId: "client-test",
CustomData: map[string]interface{}{
Expand Down Expand Up @@ -774,7 +774,7 @@ func TestBucketing_Deterministic_AlternateKeyRandomDistribution(t *testing.T) {
require.Equal(t, bucketedUserConfig3.FeatureVariationMap["614ef8aa475928459060721d"], bucketedUserConfig4.FeatureVariationMap["614ef8aa475928459060721d"])
}

func TestBucketing_Deterministic_AlternateKeyRollout(t *testing.T) {
func TestBucketing_Deterministic_NumberAlternateKeyRollout(t *testing.T) {
user := api.User{
UserId: "client-test",
CustomData: map[string]interface{}{
Expand Down Expand Up @@ -832,3 +832,62 @@ func TestBucketing_Deterministic_AlternateKeyRollout(t *testing.T) {

require.Equal(t, bucketedUserConfig3.FeatureVariationMap["614ef8aa475928459060721e"], bucketedUserConfig4.FeatureVariationMap["614ef8aa475928459060721e"])
}

func TestBucketing_Deterministic_BooleanAlternateKeyRandomDistribution(t *testing.T) {
user := api.User{
UserId: "client-test",
CustomData: map[string]interface{}{
"favouriteFood": "cake",
"favouriteNull": nil,
"isSubscriber": true,
},
}.GetPopulatedUser(&api.PlatformData{
PlatformVersion: "1.1.2",
})
user2 := api.User{
UserId: "client_test_2",
CustomData: map[string]interface{}{
"favouriteFood": "cake",
"favouriteNull": nil,
"isSubscriber": true,
},
}.GetPopulatedUser(&api.PlatformData{
PlatformVersion: "1.1.2",
})
user3 := api.User{
UserId: "client_test_3",
CustomData: map[string]interface{}{
"favouriteFood": nil,
"favouriteNull": nil,
"isSubscriber": nil,
},
}.GetPopulatedUser(&api.PlatformData{
PlatformVersion: "1.1.2",
})
user4 := api.User{
UserId: "client_test_3",
CustomData: map[string]interface{}{
"favouriteNull": nil,
},
}.GetPopulatedUser(&api.PlatformData{
PlatformVersion: "1.1.2",
})

err := SetConfig(test_v2_config, "test", "", "", "")
require.NoError(t, err)

// Check if users with the same alternate bucketing key get the same variation
bucketedUserConfig, err := GenerateBucketedConfig("test", user, nil)
require.NoError(t, err)
bucketedUserConfig2, err := GenerateBucketedConfig("test", user2, nil)
require.NoError(t, err)
require.Equal(t, bucketedUserConfig.FeatureVariationMap["614ef8aa475928459060721f"], bucketedUserConfig2.FeatureVariationMap["614ef8aa475928459060721f"])

// Check if users with explicitly null or missing alternate bucketing key get the same variation
bucketedUserConfig3, err := GenerateBucketedConfig("test", user3, nil)
require.NoError(t, err)
bucketedUserConfig4, err := GenerateBucketedConfig("test", user4, nil)
require.NoError(t, err)

require.Equal(t, bucketedUserConfig3.FeatureVariationMap["614ef8aa475928459060721f"], bucketedUserConfig4.FeatureVariationMap["614ef8aa475928459060721f"])
}
66 changes: 66 additions & 0 deletions bucketing/testdata/fixture_test_v2_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,67 @@
]
}
]
},
{
"_id": "614ef8aa475928459060721f",
"type": "ops",
"key": "operational_guard",
"configuration": {
"_id": "61536f62502d80fff97ed643",
"targets": [
{
"_id": "61536f468fd67f0091982535",
"_audience": {
"filters": {
"filters": [
{
"type": "all",
"subType": "",
"comparator": "",
"values": []
}
],
"operator": "and"
}
},
"distribution": [
{
"_variation": "615382338424cb11646d9673",
"percentage": 0.5
},
{
"_variation": "615382338424cb11646d9674",
"percentage": 0.5
}
],
"bucketingKey": "isSubscriber"
}
]
},
"variations": [
{
"_id": "615382338424cb11646d9673",
"name": "Has Access",
"key": "has-access",
"variables": [
{
"_var": "61538937b0a70b58ae6af71h",
"value": true
}
]
},
{
"_id": "615382338424cb11646d9674",
"name": "No Access",
"key": "no-access",
"variables": [
{
"_var": "61538937b0a70b58ae6af71h",
"value": false
}
]
}
]
}
],
"variables": [
Expand Down Expand Up @@ -762,6 +823,11 @@
"_id": "61538937b0a70b58ae6af71g",
"type": "Boolean",
"key": "new_feature"
},
{
"_id": "61538937b0a70b58ae6af71h",
"type": "Boolean",
"key": "gated_access"
}
],
"variableHashes": {
Expand Down

0 comments on commit 7f3cbb6

Please sign in to comment.