update 'Merge' of the 'Config'

This commit is contained in:
2025-09-04 23:13:05 +04:00
parent 7e89fa174b
commit 1eb969480b
3 changed files with 187 additions and 51 deletions

View File

@@ -75,20 +75,20 @@ func (config *Config) Merge(newConfig *Config) {
if newConfig.SkipVerify != nil {
config.SkipVerify = newConfig.SkipVerify
}
if len(newConfig.Params) != 0 { // TODO: append
config.Params = newConfig.Params
if len(newConfig.Params) != 0 {
config.Params.Append(newConfig.Params...)
}
if len(newConfig.Headers) != 0 { // TODO: append
config.Headers = newConfig.Headers
if len(newConfig.Headers) != 0 {
config.Headers.Append(newConfig.Headers...)
}
if len(newConfig.Cookies) != 0 { // TODO: append
config.Cookies = newConfig.Cookies
if len(newConfig.Cookies) != 0 {
config.Cookies.Append(newConfig.Cookies...)
}
if len(newConfig.Bodies) != 0 { // TODO: append
config.Bodies = newConfig.Bodies
if len(newConfig.Bodies) != 0 {
config.Bodies.Append(newConfig.Bodies...)
}
if len(newConfig.Proxies) != 0 { // TODO: append
config.Proxies = newConfig.Proxies
if len(newConfig.Proxies) != 0 {
config.Proxies.Append(newConfig.Proxies...)
}
}

View File

@@ -66,10 +66,10 @@ func TestMergeConfig(t *testing.T) {
assert.Equal(t, newDuration, *config.Duration)
assert.True(t, *config.Yes)
assert.True(t, *config.SkipVerify)
assert.Equal(t, types.Params{{Key: "new", Value: []string{"value"}}}, config.Params)
assert.Equal(t, types.Headers{{Key: "New-Header", Value: []string{"new"}}}, config.Headers)
assert.Equal(t, types.Cookies{{Key: "newCookie", Value: []string{"newValue"}}}, config.Cookies)
assert.Equal(t, types.Bodies{types.Body("new body")}, config.Bodies)
assert.Equal(t, types.Params{{Key: "old", Value: []string{"value"}}, {Key: "new", Value: []string{"value"}}}, config.Params)
assert.Equal(t, types.Headers{{Key: "Old-Header", Value: []string{"old"}}, {Key: "New-Header", Value: []string{"new"}}}, config.Headers)
assert.Equal(t, types.Cookies{{Key: "oldCookie", Value: []string{"oldValue"}}, {Key: "newCookie", Value: []string{"newValue"}}}, config.Cookies)
assert.Equal(t, types.Bodies{types.Body("old body"), types.Body("new body")}, config.Bodies)
assert.Empty(t, config.Proxies)
})
@@ -352,3 +352,176 @@ func TestSetDefaults(t *testing.T) {
assert.Equal(t, Defaults.UserAgent, config.Headers[0].Value[0])
})
}
func TestMergeConfig_AppendBehavior(t *testing.T) {
t.Run("MergeConfig appends params with same key", func(t *testing.T) {
config := &Config{
Params: types.Params{{Key: "filter", Value: []string{"active"}}},
}
newConfig := &Config{
Params: types.Params{{Key: "filter", Value: []string{"verified"}}},
}
config.Merge(newConfig)
assert.Len(t, config.Params, 1)
paramValue := config.Params.GetValue("filter")
require.NotNil(t, paramValue)
assert.Equal(t, []string{"active", "verified"}, *paramValue)
})
t.Run("MergeConfig appends headers with same key", func(t *testing.T) {
config := &Config{
Headers: types.Headers{{Key: "Accept", Value: []string{"text/html"}}},
}
newConfig := &Config{
Headers: types.Headers{{Key: "Accept", Value: []string{"application/json"}}},
}
config.Merge(newConfig)
assert.Len(t, config.Headers, 1)
headerValue := config.Headers.GetValue("Accept")
require.NotNil(t, headerValue)
assert.Equal(t, []string{"text/html", "application/json"}, *headerValue)
})
t.Run("MergeConfig appends cookies with same key", func(t *testing.T) {
config := &Config{
Cookies: types.Cookies{{Key: "session", Value: []string{"old_token"}}},
}
newConfig := &Config{
Cookies: types.Cookies{{Key: "session", Value: []string{"new_token"}}},
}
config.Merge(newConfig)
assert.Len(t, config.Cookies, 1)
cookieValue := config.Cookies.GetValue("session")
require.NotNil(t, cookieValue)
assert.Equal(t, []string{"old_token", "new_token"}, *cookieValue)
})
t.Run("MergeConfig appends bodies", func(t *testing.T) {
config := &Config{
Bodies: types.Bodies{types.Body("first body")},
}
newConfig := &Config{
Bodies: types.Bodies{types.Body("second body"), types.Body("third body")},
}
config.Merge(newConfig)
assert.Len(t, config.Bodies, 3)
assert.Equal(t, types.Body("first body"), config.Bodies[0])
assert.Equal(t, types.Body("second body"), config.Bodies[1])
assert.Equal(t, types.Body("third body"), config.Bodies[2])
})
t.Run("MergeConfig appends proxies", func(t *testing.T) {
proxy1URL, _ := url.Parse("http://proxy1.example.com:8080")
proxy2URL, _ := url.Parse("http://proxy2.example.com:8080")
proxy3URL, _ := url.Parse("https://proxy3.example.com:443")
config := &Config{
Proxies: types.Proxies{types.Proxy(*proxy1URL)},
}
newConfig := &Config{
Proxies: types.Proxies{types.Proxy(*proxy2URL), types.Proxy(*proxy3URL)},
}
config.Merge(newConfig)
assert.Len(t, config.Proxies, 3)
assert.Equal(t, "http://proxy1.example.com:8080", config.Proxies[0].String())
assert.Equal(t, "http://proxy2.example.com:8080", config.Proxies[1].String())
assert.Equal(t, "https://proxy3.example.com:443", config.Proxies[2].String())
})
t.Run("MergeConfig appends mixed content", func(t *testing.T) {
config := &Config{
Params: types.Params{{Key: "limit", Value: []string{"10"}}},
Headers: types.Headers{{Key: "Authorization", Value: []string{"Bearer token1"}}},
Cookies: types.Cookies{{Key: "theme", Value: []string{"dark"}}},
Bodies: types.Bodies{types.Body("original")},
}
newConfig := &Config{
Params: types.Params{{Key: "offset", Value: []string{"0"}}, {Key: "limit", Value: []string{"20"}}},
Headers: types.Headers{{Key: "Content-Type", Value: []string{"application/json"}}, {Key: "Authorization", Value: []string{"Bearer token2"}}},
Cookies: types.Cookies{{Key: "lang", Value: []string{"en"}}, {Key: "theme", Value: []string{"light"}}},
Bodies: types.Bodies{types.Body("updated")},
}
config.Merge(newConfig)
// Check params
assert.Len(t, config.Params, 2)
limitValue := config.Params.GetValue("limit")
require.NotNil(t, limitValue)
assert.Equal(t, []string{"10", "20"}, *limitValue)
offsetValue := config.Params.GetValue("offset")
require.NotNil(t, offsetValue)
assert.Equal(t, []string{"0"}, *offsetValue)
// Check headers
assert.Len(t, config.Headers, 2)
authValue := config.Headers.GetValue("Authorization")
require.NotNil(t, authValue)
assert.Equal(t, []string{"Bearer token1", "Bearer token2"}, *authValue)
contentTypeValue := config.Headers.GetValue("Content-Type")
require.NotNil(t, contentTypeValue)
assert.Equal(t, []string{"application/json"}, *contentTypeValue)
// Check cookies
assert.Len(t, config.Cookies, 2)
themeValue := config.Cookies.GetValue("theme")
require.NotNil(t, themeValue)
assert.Equal(t, []string{"dark", "light"}, *themeValue)
langValue := config.Cookies.GetValue("lang")
require.NotNil(t, langValue)
assert.Equal(t, []string{"en"}, *langValue)
// Check bodies
assert.Len(t, config.Bodies, 2)
assert.Equal(t, types.Body("original"), config.Bodies[0])
assert.Equal(t, types.Body("updated"), config.Bodies[1])
})
t.Run("MergeConfig with empty slices does not append", func(t *testing.T) {
config := &Config{
Params: types.Params{{Key: "existing", Value: []string{"value"}}},
Headers: types.Headers{{Key: "Existing-Header", Value: []string{"value"}}},
Cookies: types.Cookies{{Key: "existing", Value: []string{"value"}}},
Bodies: types.Bodies{types.Body("existing")},
Proxies: types.Proxies{},
}
originalParams := len(config.Params)
originalHeaders := len(config.Headers)
originalCookies := len(config.Cookies)
originalBodies := len(config.Bodies)
originalProxies := len(config.Proxies)
newConfig := &Config{
Params: types.Params{},
Headers: types.Headers{},
Cookies: types.Cookies{},
Bodies: types.Bodies{},
Proxies: types.Proxies{},
}
config.Merge(newConfig)
assert.Len(t, config.Params, originalParams, "Empty params should not change existing params")
assert.Len(t, config.Headers, originalHeaders, "Empty headers should not change existing headers")
assert.Len(t, config.Cookies, originalCookies, "Empty cookies should not change existing cookies")
assert.Len(t, config.Bodies, originalBodies, "Empty bodies should not change existing bodies")
assert.Len(t, config.Proxies, originalProxies, "Empty proxies should not change existing proxies")
})
}

View File

@@ -5,9 +5,7 @@ import (
"testing"
"time"
"github.com/aykhans/dodo/pkg/config"
"github.com/aykhans/dodo/pkg/types"
"github.com/aykhans/dodo/pkg/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -1129,38 +1127,3 @@ func TestConfigENVParser_PartialConfiguration(t *testing.T) {
assert.Nil(t, config.RequestCount)
})
}
func TestConfigENVParser_MergeScenarios(t *testing.T) {
t.Run("Parse configuration suitable for merging", func(t *testing.T) {
// Set only specific fields that would override defaults
t.Setenv("METHOD", "PUT")
t.Setenv("TIMEOUT", "45s")
t.Setenv("HEADER", "X-Custom: value")
parser := NewConfigENVParser("")
envConfig, err := parser.Parse()
require.NoError(t, err)
require.NotNil(t, envConfig)
// Create a default config
defaultConfig := &config.Config{
Method: utils.ToPtr("GET"),
Timeout: utils.ToPtr(30 * time.Second),
DodosCount: utils.ToPtr(uint(1)),
Headers: types.Headers{{Key: "User-Agent", Value: []string{"DefaultAgent/1.0"}}},
}
// Merge the parsed config into defaults
defaultConfig.Merge(envConfig)
// Verify merged values
assert.Equal(t, "PUT", *defaultConfig.Method, "Method should be overridden")
assert.Equal(t, 45*time.Second, *defaultConfig.Timeout, "Timeout should be overridden")
assert.Equal(t, uint(1), *defaultConfig.DodosCount, "DodosCount should remain from default")
// Headers should contain the new header (merge behavior depends on implementation)
assert.Len(t, defaultConfig.Headers, 1)
assert.Equal(t, "X-Custom", defaultConfig.Headers[0].Key)
})
}