Skip to content

Commit

Permalink
Adding tests
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Poignant <[email protected]>
  • Loading branch information
thomaspoignant committed Jan 8, 2025
1 parent ed65269 commit 724609c
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ require (
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1074,8 +1074,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down
226 changes: 226 additions & 0 deletions internal/flag/internal_flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,48 @@ func TestInternalFlag_Value(t *testing.T) {
},
},
},
{
name: "Should return the variation specified in the rule if rule match (jsonLogic)",
flag: flag.InternalFlag{
Variations: &map[string]*interface{}{
"variation_A": testconvert.Interface(true),
"variation_B": testconvert.Interface(false),
},
Rules: &[]flag.Rule{
{
Name: testconvert.String("rule1"),
Query: testconvert.String(`{"==":[{"var":"key"},"user-key"]}`),
VariationResult: testconvert.String("variation_B"),
},
},
DefaultRule: &flag.Rule{
VariationResult: testconvert.String("variation_A"),
},
Metadata: &map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
args: args{
flagName: "my-flag",
user: ffcontext.NewEvaluationContext("user-key"),
flagContext: flag.Context{
DefaultSdkValue: false,
},
},
want: false,
want1: flag.ResolutionDetails{
Variant: "variation_B",
Reason: flag.ReasonTargetingMatch,
RuleIndex: testconvert.Int(0),
RuleName: testconvert.String("rule1"),
Cacheable: true,
Metadata: map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
},
{
name: "Should match the 2nd rule",
flag: flag.InternalFlag{
Expand Down Expand Up @@ -301,6 +343,54 @@ func TestInternalFlag_Value(t *testing.T) {
},
},
},
{
name: "Should match the 2nd rule (jsonLogic)",
flag: flag.InternalFlag{
Variations: &map[string]*interface{}{
"variation_A": testconvert.Interface("value_A"),
"variation_B": testconvert.Interface("value_B"),
"variation_C": testconvert.Interface("value_C"),
},
Rules: &[]flag.Rule{
{
Name: testconvert.String("rule1"),
Query: testconvert.String(`{"==":[{"var":"key"},"not-user-key"]}`),
VariationResult: testconvert.String("variation_C"),
},
{
Name: testconvert.String("rule2"),
Query: testconvert.String(`{"==":[{"var":"key"},"user-key"]}`),
VariationResult: testconvert.String("variation_C"),
},
},
DefaultRule: &flag.Rule{
VariationResult: testconvert.String("variation_A"),
},
Metadata: &map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
args: args{
flagName: "my-flag",
user: ffcontext.NewEvaluationContext("user-key"),
flagContext: flag.Context{
DefaultSdkValue: "value_default",
},
},
want: "value_C",
want1: flag.ResolutionDetails{
Variant: "variation_C",
Reason: flag.ReasonTargetingMatch,
RuleIndex: testconvert.Int(1),
RuleName: testconvert.String("rule2"),
Cacheable: true,
Metadata: map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
},
{
name: "Should match a rule with no name",
flag: flag.InternalFlag{
Expand Down Expand Up @@ -346,6 +436,51 @@ func TestInternalFlag_Value(t *testing.T) {
},
},
},
{
name: "Should match a rule with no name (jsonLogic)",
flag: flag.InternalFlag{
Variations: &map[string]*interface{}{
"variation_A": testconvert.Interface("value_A"),
"variation_B": testconvert.Interface("value_B"),
"variation_C": testconvert.Interface("value_C"),
},
Rules: &[]flag.Rule{
{
Query: testconvert.String(`{"==":[{"var":"key"},"not-user-key"]}`),
VariationResult: testconvert.String("variation_C"),
},
{
Query: testconvert.String(`{"==":[{"var":"key"},"user-key"]}`),
VariationResult: testconvert.String("variation_C"),
},
},
DefaultRule: &flag.Rule{
VariationResult: testconvert.String("variation_A"),
},
Metadata: &map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
args: args{
flagName: "my-flag",
user: ffcontext.NewEvaluationContext("user-key"),
flagContext: flag.Context{
DefaultSdkValue: "value_default",
},
},
want: "value_C",
want1: flag.ResolutionDetails{
Variant: "variation_C",
Reason: flag.ReasonTargetingMatch,
RuleIndex: testconvert.Int(1),
Cacheable: true,
Metadata: map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
},
{
name: "Should match only the first rule that apply (even if more than one can apply)",
flag: flag.InternalFlag{
Expand Down Expand Up @@ -396,6 +531,56 @@ func TestInternalFlag_Value(t *testing.T) {
},
},
},
{
name: "Should match only the first rule that apply (even if more than one can apply) (jsonLogic)",
flag: flag.InternalFlag{
Variations: &map[string]*interface{}{
"variation_A": testconvert.Interface("value_A"),
"variation_B": testconvert.Interface("value_B"),
"variation_C": testconvert.Interface("value_C"),
"variation_D": testconvert.Interface("value_D"),
},
Rules: &[]flag.Rule{
{
Query: testconvert.String(`{"==":[{"var":"key"},"not-user-key"]}`),
VariationResult: testconvert.String("variation_C"),
},
{
Query: testconvert.String(`{"==":[{"var":"company"},"go-feature-flag"]}`),
VariationResult: testconvert.String("variation_D"),
},
{
Query: testconvert.String(`{"==":[{"var":"key"},"user-key"]}`),
VariationResult: testconvert.String("variation_C"),
},
},
DefaultRule: &flag.Rule{
VariationResult: testconvert.String("variation_A"),
},
Metadata: &map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
args: args{
flagName: "my-flag",
user: ffcontext.NewEvaluationContextBuilder("user-key").AddCustom("company", "go-feature-flag").Build(),
flagContext: flag.Context{
DefaultSdkValue: "value_default",
},
},
want: "value_D",
want1: flag.ResolutionDetails{
Variant: "variation_D",
Reason: flag.ReasonTargetingMatch,
RuleIndex: testconvert.Int(1),
Cacheable: true,
Metadata: map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
},
{
name: "Should ignore a rule that is disabled",
flag: flag.InternalFlag{
Expand Down Expand Up @@ -488,6 +673,47 @@ func TestInternalFlag_Value(t *testing.T) {
},
},
},
{
name: "Should return an error if rule is invalid (jsonLogic)",
flag: flag.InternalFlag{
Variations: &map[string]*interface{}{
"variation_A": testconvert.Interface("value_A"),
"variation_B": testconvert.Interface("value_B"),
"variation_C": testconvert.Interface("value_C"),
"variation_D": testconvert.Interface("value_D"),
},
Rules: &[]flag.Rule{
{
Query: testconvert.String(`{"==":[{"var":"key"},"user-key"]}`),
Percentages: &map[string]float64{},
},
},
DefaultRule: &flag.Rule{
VariationResult: testconvert.String("variation_A"),
},
Metadata: &map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
args: args{
flagName: "my-flag",
user: ffcontext.NewEvaluationContextBuilder("user-key").Build(),
flagContext: flag.Context{
DefaultSdkValue: "value_default",
},
},
want: "value_default",
want1: flag.ResolutionDetails{
Variant: flag.VariationSDKDefault,
Reason: flag.ReasonError,
ErrorCode: flag.ErrorFlagConfiguration,
Metadata: map[string]interface{}{
"description": "this is a flag",
"issue-link": "https://issue.link/GOFF-1",
},
},
},
{
name: "Should return an error if no targeting match and we have no default rule",
flag: flag.InternalFlag{
Expand Down
44 changes: 44 additions & 0 deletions internal/flag/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,50 @@ func TestRule_Evaluate(t *testing.T) {
args: args{},
wantErr: assert.Error,
},
{
name: "User does not match the query (JsonLogic)",
rule: flag.Rule{
Name: testconvert.String("rule1"),
VariationResult: testconvert.String("variation_A"),
Query: testconvert.String(`{"==": [{"var": "key"}, "def"]}`),
},
args: args{
isDefault: false,
user: ffcontext.NewEvaluationContext("abc"),
},
wantErr: assert.Error,
},
{
name: "User match the query (JsonLogic)",
rule: flag.Rule{
Name: testconvert.String("rule1"),
VariationResult: testconvert.String("variation_A"),
Query: testconvert.String(`{"==": [{"var": "key"}, "abc"]}`),
},
args: args{
isDefault: false,
user: ffcontext.NewEvaluationContext("abc"),
},
want: "variation_A",
wantErr: assert.NoError,
},
{
name: "Percentage + user match query (JsonLogic)",
rule: flag.Rule{
Name: testconvert.String("rule1"),
Percentages: &map[string]float64{
"variation_D": 70,
"variation_C": 10,
"variation_B": 20,
},
Query: testconvert.String(`{"==": [{"var": "key"}, "96ac59e6-7492-436b-b15a-ba1d797d2423"]}`),
},
args: args{
user: ffcontext.NewEvaluationContext("96ac59e6-7492-436b-b15a-ba1d797d2423"),
},
wantErr: assert.NoError,
want: "variation_B",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 724609c

Please sign in to comment.