diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 007e3a8b..824a59a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: - name: SonarQube Scan (Push) if: ${{ github.event_name == 'push' }} - uses: SonarSource/sonarcloud-github-action@v5.0.0 + uses: SonarSource/sonarqube-scan-action@v5.0.0 env: SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -46,7 +46,7 @@ jobs: - name: SonarQube Scan (Pull Request) if: ${{ github.event_name == 'pull_request' }} - uses: SonarSource/sonarcloud-github-action@v5.0.0 + uses: SonarSource/sonarqube-scan-action@v5.0.0 env: SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/dtos/fallbacktreatment.go b/dtos/fallbacktreatment.go new file mode 100644 index 00000000..e1c30a44 --- /dev/null +++ b/dtos/fallbacktreatment.go @@ -0,0 +1,63 @@ +package dtos + +const ( + labelPrefix = "fallback - " +) + +type FallbackTreatment struct { + Treatment string + Config *string + Label *string +} + +type FallbackTreatmentConfig struct { + GlobalFallbackTreatment *FallbackTreatment + byFlagFallbackTreatment map[string]FallbackTreatment +} + +type FallbackTreatmentCalculator interface { + Resolve(flagName string, label string) FallbackTreatment +} + +type FallbackTreatmentCalculatorImp struct { + fallbackTreatmentConfig *FallbackTreatmentConfig +} + +func NewFallbackTreatmentCalculatorImp(fallbackTreatmentConfig *FallbackTreatmentConfig) FallbackTreatmentCalculatorImp { + return FallbackTreatmentCalculatorImp{ + fallbackTreatmentConfig: fallbackTreatmentConfig, + } +} + +func (f *FallbackTreatmentCalculatorImp) Resolve(flagName string, label *string) FallbackTreatment { + if f.fallbackTreatmentConfig != nil { + if byFlag := f.fallbackTreatmentConfig.byFlagFallbackTreatment; byFlag != nil { + if val, ok := byFlag[flagName]; ok { + return FallbackTreatment{ + Treatment: val.Treatment, + Config: val.Config, + Label: f.resolveLabel(label), + } + } + } + if f.fallbackTreatmentConfig.GlobalFallbackTreatment != nil { + return FallbackTreatment{ + Treatment: f.fallbackTreatmentConfig.GlobalFallbackTreatment.Treatment, + Config: f.fallbackTreatmentConfig.GlobalFallbackTreatment.Config, + Label: f.resolveLabel(label), + } + } + } + return FallbackTreatment{ + Treatment: "control", + Label: label, + } +} + +func (f *FallbackTreatmentCalculatorImp) resolveLabel(label *string) *string { + if label == nil { + return nil + } + result := labelPrefix + *label + return &result +} diff --git a/dtos/fallbacktreatment_test.go b/dtos/fallbacktreatment_test.go new file mode 100644 index 00000000..c741a103 --- /dev/null +++ b/dtos/fallbacktreatment_test.go @@ -0,0 +1,63 @@ +package dtos + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFallbackTreatmentCalculatorResolve(t *testing.T) { + // Initial setup with both global and flag-specific treatments + stringConfig := "flag1_config" + config := &FallbackTreatmentConfig{ + GlobalFallbackTreatment: &FallbackTreatment{ + Treatment: "global_treatment", + }, + byFlagFallbackTreatment: map[string]FallbackTreatment{ + "flag1": { + Treatment: "flag1_treatment", + Config: &stringConfig, + }, + }, + } + calc := NewFallbackTreatmentCalculatorImp(config) + + // Test flag-specific treatment with label + label := "some_label" + result := calc.Resolve("flag1", &label) + assert.Equal(t, "flag1_treatment", result.Treatment) + assert.Equal(t, &stringConfig, result.Config) + assert.Equal(t, "fallback - some_label", *result.Label) + + // Test fallback to global treatment when flag not found + result = calc.Resolve("flag2", &label) + assert.Equal(t, "global_treatment", result.Treatment) + assert.Nil(t, result.Config) + assert.Equal(t, "fallback - some_label", *result.Label) + + // Test nil label handling + result = calc.Resolve("flag1", nil) + assert.Equal(t, "flag1_treatment", result.Treatment) + assert.Equal(t, &stringConfig, result.Config) + assert.Nil(t, result.Label) + + // Test default control when no config + calcNoConfig := NewFallbackTreatmentCalculatorImp(nil) + result = calcNoConfig.Resolve("flag1", &label) + assert.Equal(t, "control", result.Treatment) + assert.Nil(t, result.Config) + assert.Equal(t, "some_label", *result.Label) + + // Test global treatment when no flag-specific treatments exist + configGlobalOnly := &FallbackTreatmentConfig{ + GlobalFallbackTreatment: &FallbackTreatment{ + Treatment: "global_treatment", + Config: nil, + }, + } + calcGlobalOnly := NewFallbackTreatmentCalculatorImp(configGlobalOnly) + result = calcGlobalOnly.Resolve("any_flag", &label) + assert.Equal(t, "global_treatment", result.Treatment) + assert.Nil(t, result.Config) + assert.Equal(t, "fallback - some_label", *result.Label) +}