From 3ff328d54ff853d7bf24e5f1ab04adb8fd22a317 Mon Sep 17 00:00:00 2001 From: Alan Boudreault Date: Sun, 4 Jun 2023 20:09:28 -0400 Subject: [PATCH] fix: ensure defaults are properly filled for a set --- kong/utils.go | 3 +- kong/utils_test.go | 162 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/kong/utils.go b/kong/utils.go index eaa633277..73dee3145 100644 --- a/kong/utils.go +++ b/kong/utils.go @@ -264,7 +264,8 @@ func fillConfigRecord(schema gjson.Result, config Configuration) Configuration { // If this array is non-nil and non-empty (in Config), go through all the records in this array and add defaults // If the array has only primitives like string/number/boolean then the value is already set // If the array is empty or nil, then no defaults need to be set for its elements - if ftype.String() == "array" { + // The same logic should be applied if field is of type set of records (in Schema) + if ftype.String() == "array" || ftype.String() == "set" { if value.Get(fname).Get("elements.type").String() == "record" { if config[fname] != nil { // Check sub config is of type array and it is non-empty diff --git a/kong/utils_test.go b/kong/utils_test.go index fc70fb833..a231e6fd6 100644 --- a/kong/utils_test.go +++ b/kong/utils_test.go @@ -218,6 +218,47 @@ const StatsDSchema = `{ ] }` +// TestSchemaSetType ( +const TestSchemaSetType = `{ + "fields": [{ + "config": { + "type": "record", + "fields": [{ + "bootstrap_servers": { + "default": [ + { + "host": "127.0.0.1", + "port": 42 + } + ], + "elements": { + "fields": [{ + "host": { + "required": true, + "type": "string" + } + }, + { + "port": { + "between": [ + 0, + 65535 + ], + "required": true, + "type": "integer", + "default": 42 + } + } + ], + "type": "record" + }, + "type": "set" + } + }] + } + }] +}` + func TestStringArrayToString(t *testing.T) { assert := assert.New(t) @@ -1509,3 +1550,124 @@ func Test_FillPluginsDefaults_RequestTransformer(t *testing.T) { }) } } + +func Test_FillPluginsDefaults_SetType(t *testing.T) { + client, err := NewTestClient(nil, nil) + require.NoError(t, err) + require.NotNil(t, client) + + tests := []struct { + name string + plugin *Plugin + expected *Plugin + }{ + { + name: "does not fill defaults when provided", + plugin: &Plugin{ + Config: Configuration{ + "bootstrap_servers": []interface{}{ + map[string]interface{}{ + "host": "192.168.2.100", + "port": float64(3500), + }, + map[string]any{ + "host": "192.168.2.101", + "port": float64(3500), + }, + }, + }, + }, + expected: &Plugin{ + Config: Configuration{ + "bootstrap_servers": []interface{}{ + Configuration{ + "host": "192.168.2.100", + "port": float64(3500), + }, + Configuration{ + "host": "192.168.2.101", + "port": float64(3500), + }, + }, + }, + }, + }, + { + name: "fills defaults for all missing fields", + plugin: &Plugin{ + Config: Configuration{ + "bootstrap_servers": []interface{}{ + map[string]interface{}{ + "host": "127.0.0.1", + }, + }, + }, + }, + expected: &Plugin{ + Config: Configuration{ + "bootstrap_servers": []interface{}{ + Configuration{ + "host": "127.0.0.1", + "port": float64(42), + }, + }, + }, + }, + }, + { + name: "fills defaults when empty set of records in config", + plugin: &Plugin{ + Config: Configuration{ + "bootstrap_servers": []any{}, + }, + }, + expected: &Plugin{ + Config: Configuration{ + "bootstrap_servers": []any{ + map[string]any{ + "host": "127.0.0.1", + "port": float64(42), + }, + }, + }, + }, + }, + { + name: "fills defaults when nil set of records in config", + plugin: &Plugin{ + Config: Configuration{ + "bootstrap_servers": nil, + }, + }, + expected: &Plugin{ + Config: Configuration{ + "bootstrap_servers": []any{ + map[string]any{ + "host": "127.0.0.1", + "port": float64(42), + }, + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + plugin := tc.plugin + + var fullSchema map[string]interface{} + err := json.Unmarshal([]byte(TestSchemaSetType), &fullSchema) + require.NoError(t, err) + require.NotNil(t, fullSchema) + + assert.NoError(t, FillPluginsDefaults(plugin, fullSchema)) + opts := cmpopts.IgnoreFields(*plugin, + "Protocols", "Enabled", + ) + if diff := cmp.Diff(plugin, tc.expected, opts); diff != "" { + t.Errorf(diff) + } + }) + } +}