Skip to content

Commit

Permalink
fix: add tests and impl
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasheartman committed Dec 18, 2023
1 parent b8e8889 commit 6bdcac9
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 9 deletions.
27 changes: 18 additions & 9 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,29 +416,38 @@ func (uc *Client) getVariantWithoutMetrics(feature string, options ...VariantOpt
strategyResult, f = uc.isEnabled(feature, WithContext(*ctx))
}

if !strategyResult.Enabled {
return defaultVariant
}

if f == nil {
getFallbackWithFeatureEnabled := func(featureEnabled bool) *api.Variant {
if opts.variantFallbackFunc != nil {
return opts.variantFallbackFunc(feature, ctx)
variant := opts.variantFallbackFunc(feature, ctx)
if variant != nil {
variant.FeatureEnabled = featureEnabled
}
return variant
} else if opts.variantFallback != nil {
opts.variantFallback.FeatureEnabled = featureEnabled
return opts.variantFallback
}

if featureEnabled {
return disabledVariantFeatureEnabled
}
return defaultVariant
}

if !f.Enabled {
return defaultVariant
if !strategyResult.Enabled {
return getFallbackWithFeatureEnabled(false)
}

if f == nil || !f.Enabled {
return getFallbackWithFeatureEnabled(false)
}

if strategyResult.Variant != nil {
return strategyResult.Variant
}

if len(f.Variants) == 0 {
return disabledVariantFeatureEnabled
return getFallbackWithFeatureEnabled(true)
}

return api.VariantCollection{
Expand Down
213 changes: 213 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1144,3 +1144,216 @@ func TestClient_VariantFromEnabledFeatureWithNoVariants(t *testing.T) {

assert.True(gock.IsDone(), "there should be no more mocks")
}

func TestGetVariantWithFallbackVariantWhenFeatureDisabled(t *testing.T) {
assert := assert.New(t)
defer gock.OffAll()

gock.New(mockerServer).
Post("/client/register").
MatchHeader("UNLEASH-APPNAME", mockAppName).
MatchHeader("UNLEASH-INSTANCEID", mockInstanceId).
Reply(200)

feature := "feature-disabled"
features := []api.Feature{
{
Name: feature,
Description: "feature-desc",
Enabled: false,
CreatedAt: time.Date(1974, time.May, 19, 1, 2, 3, 4, time.UTC),
Strategy: "default-strategy",
Strategies: []api.Strategy{
{
Id: 1,
Name: "default",
},
},
},
}

gock.New(mockerServer).
Get("/client/features").
Reply(200).
JSON(api.FeatureResponse{
Features: features,
Segments: []api.Segment{},
})

mockListener := &MockedListener{}
mockListener.On("OnReady").Return()
mockListener.On("OnRegistered", mock.AnythingOfType("ClientData"))
mockListener.On("OnCount", feature, false).Return()
mockListener.On("OnError").Return()

client, err := NewClient(
WithUrl(mockerServer),
WithAppName(mockAppName),
WithInstanceId(mockInstanceId),
WithListener(mockListener),
)

assert.NoError(err)
client.WaitForReady()

fallbackVariant := api.Variant{
Name: "fallback-variant",
FeatureEnabled: true,
}

variant := client.GetVariant(feature, WithVariantFallback(&fallbackVariant))

assert.False(variant.Enabled)

assert.False(variant.FeatureEnabled)

assert.Equal(fallbackVariant, *variant)

fallbackFunc := func(feature string, ctx *context.Context) *api.Variant {
return &fallbackVariant
}

variantWithFallbackFunc := client.GetVariant(feature, WithVariantFallbackFunc(fallbackFunc))

assert.Equal(fallbackVariant, *variantWithFallbackFunc)

assert.True(gock.IsDone(), "there should be no more mocks")
}

func TestGetVariantWithFallbackVariantWhenFeatureEnabledButNoVariants(t *testing.T) {
assert := assert.New(t)
defer gock.OffAll()

gock.New(mockerServer).
Post("/client/register").
MatchHeader("UNLEASH-APPNAME", mockAppName).
MatchHeader("UNLEASH-INSTANCEID", mockInstanceId).
Reply(200)

feature := "feature-no-variants"
features := []api.Feature{
{
Name: feature,
Description: "feature-desc",
Enabled: true,
CreatedAt: time.Date(1974, time.May, 19, 1, 2, 3, 4, time.UTC),
Strategy: "default-strategy",
Strategies: []api.Strategy{
{
Id: 1,
Name: "default",
},
},
},
}

gock.New(mockerServer).
Get("/client/features").
Reply(200).
JSON(api.FeatureResponse{
Features: features,
Segments: []api.Segment{},
})

mockListener := &MockedListener{}
mockListener.On("OnReady").Return()
mockListener.On("OnRegistered", mock.AnythingOfType("ClientData"))
mockListener.On("OnCount", feature, true).Return()
mockListener.On("OnError").Return()

client, err := NewClient(
WithUrl(mockerServer),
WithAppName(mockAppName),
WithInstanceId(mockInstanceId),
WithListener(mockListener),
)

assert.NoError(err)
client.WaitForReady()

fallbackVariant := api.Variant{
Name: "fallback-variant",
FeatureEnabled: false,
}

variant := client.GetVariant(feature, WithVariantFallback(&fallbackVariant))

assert.False(variant.Enabled)

assert.True(variant.FeatureEnabled)

assert.Equal(fallbackVariant, *variant)

fallbackFunc := func(feature string, ctx *context.Context) *api.Variant {
return &fallbackVariant
}

variantWithFallbackFunc := client.GetVariant(feature, WithVariantFallbackFunc(fallbackFunc))

assert.Equal(fallbackVariant, *variantWithFallbackFunc)

assert.True(gock.IsDone(), "there should be no more mocks")
}

func TestGetVariantWithFallbackVariantWhenFeatureDoesntExist(t *testing.T) {
assert := assert.New(t)
defer gock.OffAll()

gock.New(mockerServer).
Post("/client/register").
MatchHeader("UNLEASH-APPNAME", mockAppName).
MatchHeader("UNLEASH-INSTANCEID", mockInstanceId).
Reply(200)

feature := "feature-no-variants"
features := []api.Feature{
{},
}

gock.New(mockerServer).
Get("/client/features").
Reply(200).
JSON(api.FeatureResponse{
Features: features,
Segments: []api.Segment{},
})

mockListener := &MockedListener{}
mockListener.On("OnReady").Return()
mockListener.On("OnRegistered", mock.AnythingOfType("ClientData"))
mockListener.On("OnCount", feature, false).Return()
mockListener.On("OnError").Return()

client, err := NewClient(
WithUrl(mockerServer),
WithAppName(mockAppName),
WithInstanceId(mockInstanceId),
WithListener(mockListener),
)

assert.NoError(err)
client.WaitForReady()

fallbackVariant := api.Variant{
Name: "fallback-variant",
FeatureEnabled: true,
}

variant := client.GetVariant(feature, WithVariantFallback(&fallbackVariant))

assert.False(variant.Enabled)

assert.False(variant.FeatureEnabled)

assert.Equal(fallbackVariant, *variant)

fallbackFunc := func(feature string, ctx *context.Context) *api.Variant {
return &fallbackVariant
}

variantWithFallbackFunc := client.GetVariant(feature, WithVariantFallbackFunc(fallbackFunc))

assert.Equal(fallbackVariant, *variantWithFallbackFunc)

assert.True(gock.IsDone(), "there should be no more mocks")
}

0 comments on commit 6bdcac9

Please sign in to comment.