From 7e89fa174beec3373faf482a3f458571a81d333f Mon Sep 17 00:00:00 2001 From: Aykhan Shahsuvarov Date: Thu, 4 Sep 2025 23:00:57 +0400 Subject: [PATCH] update types --- pkg/types/body.go | 4 +- pkg/types/body_test.go | 44 +++++++++++++++ pkg/types/cookie.go | 12 ++-- pkg/types/cookie_test.go | 115 +++++++++++++++++++++++++++++++++++++++ pkg/types/header.go | 12 ++-- pkg/types/header_test.go | 105 +++++++++++++++++++++++++++++++++++ pkg/types/param.go | 12 ++-- pkg/types/param_test.go | 87 +++++++++++++++++++++++++++++ pkg/types/proxy.go | 4 +- pkg/types/proxy_test.go | 91 ++++++++++++++++++++++++++++++- 10 files changed, 466 insertions(+), 20 deletions(-) diff --git a/pkg/types/body.go b/pkg/types/body.go index 7e4ae08..fb23aeb 100644 --- a/pkg/types/body.go +++ b/pkg/types/body.go @@ -8,8 +8,8 @@ func (body Body) String() string { type Bodies []Body -func (bodies *Bodies) Append(body Body) { - *bodies = append(*bodies, body) +func (bodies *Bodies) Append(body ...Body) { + *bodies = append(*bodies, body...) } func (bodies *Bodies) Parse(rawValues ...string) { diff --git a/pkg/types/body_test.go b/pkg/types/body_test.go index deb7a06..b4685c3 100644 --- a/pkg/types/body_test.go +++ b/pkg/types/body_test.go @@ -49,6 +49,16 @@ func TestBodies_Append(t *testing.T) { assert.Equal(t, Body("third"), (*bodies)[2]) }) + t.Run("Append multiple bodies in single call", func(t *testing.T) { + bodies := &Bodies{} + bodies.Append(Body("first"), Body("second"), Body("third")) + + assert.Len(t, *bodies, 3) + assert.Equal(t, Body("first"), (*bodies)[0]) + assert.Equal(t, Body("second"), (*bodies)[1]) + assert.Equal(t, Body("third"), (*bodies)[2]) + }) + t.Run("Append to existing bodies", func(t *testing.T) { bodies := &Bodies{Body("existing")} bodies.Append(Body("new")) @@ -58,6 +68,17 @@ func TestBodies_Append(t *testing.T) { assert.Equal(t, Body("new"), (*bodies)[1]) }) + t.Run("Append multiple to existing bodies", func(t *testing.T) { + bodies := &Bodies{Body("existing")} + bodies.Append(Body("new1"), Body("new2"), Body("new3")) + + assert.Len(t, *bodies, 4) + assert.Equal(t, Body("existing"), (*bodies)[0]) + assert.Equal(t, Body("new1"), (*bodies)[1]) + assert.Equal(t, Body("new2"), (*bodies)[2]) + assert.Equal(t, Body("new3"), (*bodies)[3]) + }) + t.Run("Append empty body", func(t *testing.T) { bodies := &Bodies{} bodies.Append(Body("")) @@ -65,6 +86,29 @@ func TestBodies_Append(t *testing.T) { assert.Len(t, *bodies, 1) assert.Empty(t, (*bodies)[0].String()) }) + + t.Run("Append no bodies", func(t *testing.T) { + bodies := &Bodies{Body("existing")} + bodies.Append() + + assert.Len(t, *bodies, 1) + assert.Equal(t, Body("existing"), (*bodies)[0]) + }) + + t.Run("Append mixed bodies", func(t *testing.T) { + bodies := &Bodies{} + bodies.Append(Body("first"), Body("")) + bodies.Append(Body("second")) + bodies.Append(Body("third"), Body("fourth"), Body("fifth")) + + assert.Len(t, *bodies, 6) + assert.Equal(t, Body("first"), (*bodies)[0]) + assert.Equal(t, Body(""), (*bodies)[1]) + assert.Equal(t, Body("second"), (*bodies)[2]) + assert.Equal(t, Body("third"), (*bodies)[3]) + assert.Equal(t, Body("fourth"), (*bodies)[4]) + assert.Equal(t, Body("fifth"), (*bodies)[5]) + }) } func TestBodies_Parse(t *testing.T) { diff --git a/pkg/types/cookie.go b/pkg/types/cookie.go index c2d97a8..fea396c 100644 --- a/pkg/types/cookie.go +++ b/pkg/types/cookie.go @@ -15,11 +15,13 @@ func (cookies Cookies) GetValue(key string) *[]string { return nil } -func (cookies *Cookies) Append(cookie Cookie) { - if item := cookies.GetValue(cookie.Key); item != nil { - *item = append(*item, cookie.Value...) - } else { - *cookies = append(*cookies, cookie) +func (cookies *Cookies) Append(cookie ...Cookie) { + for _, c := range cookie { + if item := cookies.GetValue(c.Key); item != nil { + *item = append(*item, c.Value...) + } else { + *cookies = append(*cookies, c) + } } } diff --git a/pkg/types/cookie_test.go b/pkg/types/cookie_test.go index a457d95..0e82b04 100644 --- a/pkg/types/cookie_test.go +++ b/pkg/types/cookie_test.go @@ -88,6 +88,39 @@ func TestCookies_Append(t *testing.T) { assert.Len(t, *cookies, 3) }) + t.Run("Append multiple cookies in single call", func(t *testing.T) { + cookies := &Cookies{} + cookies.Append( + Cookie{Key: "session", Value: []string{"abc123"}}, + Cookie{Key: "user", Value: []string{"john"}}, + Cookie{Key: "token", Value: []string{"xyz789"}}, + ) + + assert.Len(t, *cookies, 3) + assert.Equal(t, "session", (*cookies)[0].Key) + assert.Equal(t, []string{"abc123"}, (*cookies)[0].Value) + assert.Equal(t, "user", (*cookies)[1].Key) + assert.Equal(t, []string{"john"}, (*cookies)[1].Value) + assert.Equal(t, "token", (*cookies)[2].Key) + assert.Equal(t, []string{"xyz789"}, (*cookies)[2].Value) + }) + + t.Run("Append multiple with existing keys", func(t *testing.T) { + cookies := &Cookies{ + {Key: "prefs", Value: []string{"theme=dark"}}, + } + cookies.Append( + Cookie{Key: "prefs", Value: []string{"lang=en"}}, + Cookie{Key: "prefs", Value: []string{"tz=UTC"}}, + Cookie{Key: "session", Value: []string{"abc123"}}, + ) + + assert.Len(t, *cookies, 2) + assert.Equal(t, []string{"theme=dark", "lang=en", "tz=UTC"}, (*cookies)[0].Value) + assert.Equal(t, "session", (*cookies)[1].Key) + assert.Equal(t, []string{"abc123"}, (*cookies)[1].Value) + }) + t.Run("Append multiple values at once", func(t *testing.T) { cookies := &Cookies{ {Key: "tags", Value: []string{"tag1"}}, @@ -105,6 +138,88 @@ func TestCookies_Append(t *testing.T) { assert.Len(t, *cookies, 1) assert.Equal(t, []string{""}, (*cookies)[0].Value) }) + + t.Run("Append no cookies", func(t *testing.T) { + cookies := &Cookies{ + {Key: "existing", Value: []string{"value"}}, + } + cookies.Append() + + assert.Len(t, *cookies, 1) + assert.Equal(t, "existing", (*cookies)[0].Key) + assert.Equal(t, []string{"value"}, (*cookies)[0].Value) + }) + + t.Run("Append mixed new and existing cookies", func(t *testing.T) { + cookies := &Cookies{ + {Key: "session", Value: []string{"old_session"}}, + {Key: "theme", Value: []string{"dark"}}, + } + cookies.Append( + Cookie{Key: "session", Value: []string{"new_session"}}, + Cookie{Key: "user", Value: []string{"john"}}, + Cookie{Key: "theme", Value: []string{"light"}}, + Cookie{Key: "lang", Value: []string{"en"}}, + ) + + assert.Len(t, *cookies, 4) + + sessionValue := cookies.GetValue("session") + require.NotNil(t, sessionValue) + assert.Equal(t, []string{"old_session", "new_session"}, *sessionValue) + + themeValue := cookies.GetValue("theme") + require.NotNil(t, themeValue) + assert.Equal(t, []string{"dark", "light"}, *themeValue) + + userValue := cookies.GetValue("user") + require.NotNil(t, userValue) + assert.Equal(t, []string{"john"}, *userValue) + + langValue := cookies.GetValue("lang") + require.NotNil(t, langValue) + assert.Equal(t, []string{"en"}, *langValue) + }) + + t.Run("Append cookies with multiple values", func(t *testing.T) { + cookies := &Cookies{} + cookies.Append( + Cookie{Key: "permissions", Value: []string{"read", "write", "delete"}}, + Cookie{Key: "features", Value: []string{"advanced", "beta"}}, + ) + + assert.Len(t, *cookies, 2) + assert.Equal(t, []string{"read", "write", "delete"}, (*cookies)[0].Value) + assert.Equal(t, []string{"advanced", "beta"}, (*cookies)[1].Value) + }) + + t.Run("Append typical session cookies", func(t *testing.T) { + cookies := &Cookies{} + cookies.Append( + Cookie{Key: "JSESSIONID", Value: []string{"A1B2C3D4E5F6"}}, + Cookie{Key: "PHPSESSID", Value: []string{"abcdef123456"}}, + Cookie{Key: "session_token", Value: []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"}}, + Cookie{Key: "__Secure-next-auth.session-token", Value: []string{"secure_token_123"}}, + ) + + assert.Len(t, *cookies, 4) + + jsessionValue := cookies.GetValue("JSESSIONID") + require.NotNil(t, jsessionValue) + assert.Equal(t, []string{"A1B2C3D4E5F6"}, *jsessionValue) + + phpValue := cookies.GetValue("PHPSESSID") + require.NotNil(t, phpValue) + assert.Equal(t, []string{"abcdef123456"}, *phpValue) + + sessionValue := cookies.GetValue("session_token") + require.NotNil(t, sessionValue) + assert.Equal(t, []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"}, *sessionValue) + + secureValue := cookies.GetValue("__Secure-next-auth.session-token") + require.NotNil(t, secureValue) + assert.Equal(t, []string{"secure_token_123"}, *secureValue) + }) } func TestCookies_Parse(t *testing.T) { diff --git a/pkg/types/header.go b/pkg/types/header.go index 147a68d..a5e5e6d 100644 --- a/pkg/types/header.go +++ b/pkg/types/header.go @@ -25,11 +25,13 @@ func (headers Headers) GetValue(key string) *[]string { return nil } -func (headers *Headers) Append(header Header) { - if item := headers.GetValue(header.Key); item != nil { - *item = append(*item, header.Value...) - } else { - *headers = append(*headers, header) +func (headers *Headers) Append(header ...Header) { + for _, h := range header { + if item := headers.GetValue(h.Key); item != nil { + *item = append(*item, h.Value...) + } else { + *headers = append(*headers, h) + } } } diff --git a/pkg/types/header_test.go b/pkg/types/header_test.go index b5a9b23..420148b 100644 --- a/pkg/types/header_test.go +++ b/pkg/types/header_test.go @@ -125,6 +125,39 @@ func TestHeaders_Append(t *testing.T) { assert.Len(t, *headers, 3) }) + t.Run("Append multiple headers in single call", func(t *testing.T) { + headers := &Headers{} + headers.Append( + Header{Key: "Content-Type", Value: []string{"application/json"}}, + Header{Key: "Authorization", Value: []string{"Bearer token"}}, + Header{Key: "Accept", Value: []string{"*/*"}}, + ) + + assert.Len(t, *headers, 3) + assert.Equal(t, "Content-Type", (*headers)[0].Key) + assert.Equal(t, []string{"application/json"}, (*headers)[0].Value) + assert.Equal(t, "Authorization", (*headers)[1].Key) + assert.Equal(t, []string{"Bearer token"}, (*headers)[1].Value) + assert.Equal(t, "Accept", (*headers)[2].Key) + assert.Equal(t, []string{"*/*"}, (*headers)[2].Value) + }) + + t.Run("Append multiple with existing keys", func(t *testing.T) { + headers := &Headers{ + {Key: "Accept", Value: []string{"text/html"}}, + } + headers.Append( + Header{Key: "Accept", Value: []string{"application/json"}}, + Header{Key: "Accept", Value: []string{"application/xml"}}, + Header{Key: "Content-Type", Value: []string{"text/plain"}}, + ) + + assert.Len(t, *headers, 2) + assert.Equal(t, []string{"text/html", "application/json", "application/xml"}, (*headers)[0].Value) + assert.Equal(t, "Content-Type", (*headers)[1].Key) + assert.Equal(t, []string{"text/plain"}, (*headers)[1].Value) + }) + t.Run("Append multiple values at once", func(t *testing.T) { headers := &Headers{ {Key: "Accept-Language", Value: []string{"en"}}, @@ -142,6 +175,78 @@ func TestHeaders_Append(t *testing.T) { assert.Len(t, *headers, 1) assert.Equal(t, []string{""}, (*headers)[0].Value) }) + + t.Run("Append no headers", func(t *testing.T) { + headers := &Headers{ + {Key: "Existing", Value: []string{"value"}}, + } + headers.Append() + + assert.Len(t, *headers, 1) + assert.Equal(t, "Existing", (*headers)[0].Key) + assert.Equal(t, []string{"value"}, (*headers)[0].Value) + }) + + t.Run("Append mixed new and existing headers", func(t *testing.T) { + headers := &Headers{ + {Key: "Cache-Control", Value: []string{"no-cache"}}, + {Key: "Accept", Value: []string{"text/html"}}, + } + headers.Append( + Header{Key: "Cache-Control", Value: []string{"no-store"}}, + Header{Key: "User-Agent", Value: []string{"Mozilla/5.0"}}, + Header{Key: "Accept", Value: []string{"application/json"}}, + Header{Key: "X-Custom", Value: []string{"custom-value"}}, + ) + + assert.Len(t, *headers, 4) + + cacheValue := headers.GetValue("Cache-Control") + require.NotNil(t, cacheValue) + assert.Equal(t, []string{"no-cache", "no-store"}, *cacheValue) + + acceptValue := headers.GetValue("Accept") + require.NotNil(t, acceptValue) + assert.Equal(t, []string{"text/html", "application/json"}, *acceptValue) + + userAgentValue := headers.GetValue("User-Agent") + require.NotNil(t, userAgentValue) + assert.Equal(t, []string{"Mozilla/5.0"}, *userAgentValue) + + customValue := headers.GetValue("X-Custom") + require.NotNil(t, customValue) + assert.Equal(t, []string{"custom-value"}, *customValue) + }) + + t.Run("Append headers with multiple values", func(t *testing.T) { + headers := &Headers{} + headers.Append( + Header{Key: "Accept", Value: []string{"text/html", "application/json", "application/xml"}}, + Header{Key: "Accept-Encoding", Value: []string{"gzip", "deflate"}}, + ) + + assert.Len(t, *headers, 2) + assert.Equal(t, []string{"text/html", "application/json", "application/xml"}, (*headers)[0].Value) + assert.Equal(t, []string{"gzip", "deflate"}, (*headers)[1].Value) + }) + + t.Run("Append common HTTP headers", func(t *testing.T) { + headers := &Headers{} + headers.Append( + Header{Key: "Content-Type", Value: []string{"application/json"}}, + Header{Key: "Authorization", Value: []string{"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"}}, + Header{Key: "User-Agent", Value: []string{"Go-http-client/1.1"}}, + Header{Key: "Accept", Value: []string{"*/*"}}, + Header{Key: "X-Requested-With", Value: []string{"XMLHttpRequest"}}, + ) + + assert.Len(t, *headers, 5) + assert.True(t, headers.Has("Content-Type")) + assert.True(t, headers.Has("Authorization")) + assert.True(t, headers.Has("User-Agent")) + assert.True(t, headers.Has("Accept")) + assert.True(t, headers.Has("X-Requested-With")) + }) } func TestHeaders_Parse(t *testing.T) { diff --git a/pkg/types/param.go b/pkg/types/param.go index 645d484..bc04085 100644 --- a/pkg/types/param.go +++ b/pkg/types/param.go @@ -15,11 +15,13 @@ func (params Params) GetValue(key string) *[]string { return nil } -func (params *Params) Append(param Param) { - if item := params.GetValue(param.Key); item != nil { - *item = append(*item, param.Value...) - } else { - *params = append(*params, param) +func (params *Params) Append(param ...Param) { + for _, p := range param { + if item := params.GetValue(p.Key); item != nil { + *item = append(*item, p.Value...) + } else { + *params = append(*params, p) + } } } diff --git a/pkg/types/param_test.go b/pkg/types/param_test.go index 93b2d89..7b65cd1 100644 --- a/pkg/types/param_test.go +++ b/pkg/types/param_test.go @@ -88,6 +88,39 @@ func TestParams_Append(t *testing.T) { assert.Len(t, *params, 3) }) + t.Run("Append multiple parameters in single call", func(t *testing.T) { + params := &Params{} + params.Append( + Param{Key: "name", Value: []string{"john"}}, + Param{Key: "age", Value: []string{"25"}}, + Param{Key: "city", Value: []string{"NYC"}}, + ) + + assert.Len(t, *params, 3) + assert.Equal(t, "name", (*params)[0].Key) + assert.Equal(t, []string{"john"}, (*params)[0].Value) + assert.Equal(t, "age", (*params)[1].Key) + assert.Equal(t, []string{"25"}, (*params)[1].Value) + assert.Equal(t, "city", (*params)[2].Key) + assert.Equal(t, []string{"NYC"}, (*params)[2].Value) + }) + + t.Run("Append multiple with existing keys", func(t *testing.T) { + params := &Params{ + {Key: "tags", Value: []string{"go"}}, + } + params.Append( + Param{Key: "tags", Value: []string{"test"}}, + Param{Key: "tags", Value: []string{"api"}}, + Param{Key: "version", Value: []string{"1.0"}}, + ) + + assert.Len(t, *params, 2) + assert.Equal(t, []string{"go", "test", "api"}, (*params)[0].Value) + assert.Equal(t, "version", (*params)[1].Key) + assert.Equal(t, []string{"1.0"}, (*params)[1].Value) + }) + t.Run("Append multiple values at once", func(t *testing.T) { params := &Params{ {Key: "colors", Value: []string{"red"}}, @@ -105,6 +138,60 @@ func TestParams_Append(t *testing.T) { assert.Len(t, *params, 1) assert.Equal(t, []string{""}, (*params)[0].Value) }) + + t.Run("Append no parameters", func(t *testing.T) { + params := &Params{ + {Key: "existing", Value: []string{"value"}}, + } + params.Append() + + assert.Len(t, *params, 1) + assert.Equal(t, "existing", (*params)[0].Key) + assert.Equal(t, []string{"value"}, (*params)[0].Value) + }) + + t.Run("Append mixed new and existing keys", func(t *testing.T) { + params := &Params{ + {Key: "filter", Value: []string{"active"}}, + {Key: "sort", Value: []string{"name"}}, + } + params.Append( + Param{Key: "filter", Value: []string{"verified"}}, + Param{Key: "limit", Value: []string{"10"}}, + Param{Key: "sort", Value: []string{"date"}}, + Param{Key: "offset", Value: []string{"0"}}, + ) + + assert.Len(t, *params, 4) + + filterValue := params.GetValue("filter") + require.NotNil(t, filterValue) + assert.Equal(t, []string{"active", "verified"}, *filterValue) + + sortValue := params.GetValue("sort") + require.NotNil(t, sortValue) + assert.Equal(t, []string{"name", "date"}, *sortValue) + + limitValue := params.GetValue("limit") + require.NotNil(t, limitValue) + assert.Equal(t, []string{"10"}, *limitValue) + + offsetValue := params.GetValue("offset") + require.NotNil(t, offsetValue) + assert.Equal(t, []string{"0"}, *offsetValue) + }) + + t.Run("Append parameters with multiple values", func(t *testing.T) { + params := &Params{} + params.Append( + Param{Key: "ids", Value: []string{"1", "2", "3"}}, + Param{Key: "types", Value: []string{"A", "B"}}, + ) + + assert.Len(t, *params, 2) + assert.Equal(t, []string{"1", "2", "3"}, (*params)[0].Value) + assert.Equal(t, []string{"A", "B"}, (*params)[1].Value) + }) } func TestParams_Parse(t *testing.T) { diff --git a/pkg/types/proxy.go b/pkg/types/proxy.go index f5be5ab..365cd13 100644 --- a/pkg/types/proxy.go +++ b/pkg/types/proxy.go @@ -13,8 +13,8 @@ func (proxy Proxy) String() string { type Proxies []Proxy -func (proxies *Proxies) Append(proxy Proxy) { - *proxies = append(*proxies, proxy) +func (proxies *Proxies) Append(proxy ...Proxy) { + *proxies = append(*proxies, proxy...) } func (proxies *Proxies) Parse(rawValue string) error { diff --git a/pkg/types/proxy_test.go b/pkg/types/proxy_test.go index 3bcab02..1f46345 100644 --- a/pkg/types/proxy_test.go +++ b/pkg/types/proxy_test.go @@ -63,7 +63,7 @@ func TestProxies_Append(t *testing.T) { assert.Equal(t, "http://proxy1.example.com:8080", (*proxies)[0].String()) }) - t.Run("Append multiple proxies", func(t *testing.T) { + t.Run("Append multiple proxies sequentially", func(t *testing.T) { proxies := &Proxies{} url1, err := url.Parse("http://proxy1.example.com:8080") @@ -83,6 +83,24 @@ func TestProxies_Append(t *testing.T) { assert.Equal(t, "https://proxy3.example.com:443", (*proxies)[2].String()) }) + t.Run("Append multiple proxies in single call", func(t *testing.T) { + proxies := &Proxies{} + + url1, err := url.Parse("http://proxy1.example.com:8080") + require.NoError(t, err) + url2, err := url.Parse("http://proxy2.example.com:8081") + require.NoError(t, err) + url3, err := url.Parse("https://proxy3.example.com:443") + require.NoError(t, err) + + proxies.Append(Proxy(*url1), Proxy(*url2), Proxy(*url3)) + + assert.Len(t, *proxies, 3) + assert.Equal(t, "http://proxy1.example.com:8080", (*proxies)[0].String()) + assert.Equal(t, "http://proxy2.example.com:8081", (*proxies)[1].String()) + assert.Equal(t, "https://proxy3.example.com:443", (*proxies)[2].String()) + }) + t.Run("Append to existing proxies", func(t *testing.T) { existingURL, err := url.Parse("http://existing.example.com:8080") require.NoError(t, err) @@ -98,6 +116,77 @@ func TestProxies_Append(t *testing.T) { assert.Equal(t, "http://existing.example.com:8080", (*proxies)[0].String()) assert.Equal(t, "http://new.example.com:8081", (*proxies)[1].String()) }) + + t.Run("Append multiple to existing proxies", func(t *testing.T) { + existingURL, err := url.Parse("http://existing.example.com:8080") + require.NoError(t, err) + + proxies := &Proxies{Proxy(*existingURL)} + + url1, err := url.Parse("http://new1.example.com:8081") + require.NoError(t, err) + url2, err := url.Parse("http://new2.example.com:8082") + require.NoError(t, err) + url3, err := url.Parse("https://new3.example.com:443") + require.NoError(t, err) + + proxies.Append(Proxy(*url1), Proxy(*url2), Proxy(*url3)) + + assert.Len(t, *proxies, 4) + assert.Equal(t, "http://existing.example.com:8080", (*proxies)[0].String()) + assert.Equal(t, "http://new1.example.com:8081", (*proxies)[1].String()) + assert.Equal(t, "http://new2.example.com:8082", (*proxies)[2].String()) + assert.Equal(t, "https://new3.example.com:443", (*proxies)[3].String()) + }) + + t.Run("Append no proxies", func(t *testing.T) { + existingURL, err := url.Parse("http://existing.example.com:8080") + require.NoError(t, err) + + proxies := &Proxies{Proxy(*existingURL)} + proxies.Append() + + assert.Len(t, *proxies, 1) + assert.Equal(t, "http://existing.example.com:8080", (*proxies)[0].String()) + }) + + t.Run("Append mixed proxies", func(t *testing.T) { + proxies := &Proxies{} + + url1, err := url.Parse("http://proxy1.example.com:8080") + require.NoError(t, err) + url2, err := url.Parse("socks5://proxy2.example.com:1080") + require.NoError(t, err) + url3, err := url.Parse("https://proxy3.example.com:443") + require.NoError(t, err) + url4, err := url.Parse("http://proxy4.example.com:3128") + require.NoError(t, err) + + proxies.Append(Proxy(*url1), Proxy(*url2)) + proxies.Append(Proxy(*url3)) + proxies.Append(Proxy(*url4)) + + assert.Len(t, *proxies, 4) + assert.Equal(t, "http://proxy1.example.com:8080", (*proxies)[0].String()) + assert.Equal(t, "socks5://proxy2.example.com:1080", (*proxies)[1].String()) + assert.Equal(t, "https://proxy3.example.com:443", (*proxies)[2].String()) + assert.Equal(t, "http://proxy4.example.com:3128", (*proxies)[3].String()) + }) + + t.Run("Append proxies with authentication", func(t *testing.T) { + proxies := &Proxies{} + + url1, err := url.Parse("http://user1:pass1@proxy1.example.com:8080") + require.NoError(t, err) + url2, err := url.Parse("https://user2:pass2@proxy2.example.com:443") + require.NoError(t, err) + + proxies.Append(Proxy(*url1), Proxy(*url2)) + + assert.Len(t, *proxies, 2) + assert.Equal(t, "http://user1:pass1@proxy1.example.com:8080", (*proxies)[0].String()) + assert.Equal(t, "https://user2:pass2@proxy2.example.com:443", (*proxies)[1].String()) + }) } func TestProxies_Parse(t *testing.T) {