2025-02-19 15:29:01 +03:00

210 lines
4.8 KiB
Go

package pwextractor
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var testDomain = "dns.google"
var testResult = []string{
"2001:4860:4860::8844", "2001:4860:4860::8888", "8.8.8.8", "8.8.4.4",
}
func TestGetIPs(t *testing.T) {
tests := []struct {
name string
input string
expectedIPStrings []string
wantErr bool
}{
{
name: "valid IPv4",
input: "192.0.2.1",
expectedIPStrings: []string{"192.0.2.1"},
wantErr: false,
},
{
name: "valid IPv6",
input: "2001:db8::1",
expectedIPStrings: []string{"2001:db8::1"},
wantErr: false,
},
{
name: "URL with IPv4 host",
input: "http://192.0.2.1",
expectedIPStrings: []string{"192.0.2.1"},
wantErr: false,
},
{
name: "URL with IPv6 host",
input: "http://[2001:db8::1]",
expectedIPStrings: []string{"2001:db8::1"},
wantErr: false,
},
{
name: "URL with hostname",
input: fmt.Sprintf("https://%s:8080", testDomain),
expectedIPStrings: testResult,
wantErr: false,
},
{
name: "hostname",
input: testDomain,
expectedIPStrings: testResult,
wantErr: false,
},
{
name: "invalid IP address",
input: "256.0.0.0",
wantErr: true,
},
{
name: "empty input",
input: "",
wantErr: true,
},
{
name: "invalid URL format",
input: "://invalid",
wantErr: true,
},
{
name: "unresolvable hostname",
input: "nonexistent.invalid",
wantErr: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
ips, err := getIPs(tc.input)
if tc.wantErr {
require.Error(t, err)
assert.Nil(t, ips)
} else {
require.NoError(t, err)
require.NotEmpty(t, ips, "result slice should not be empty when error is nil")
if tc.expectedIPStrings != nil {
ipStrings := make([]string, len(ips))
for i, ip := range ips {
ipStrings[i] = ip.String()
}
assert.ElementsMatch(t, tc.expectedIPStrings, ipStrings, "IPs do not match expected")
}
}
})
}
t.Run("cache set", func(t *testing.T) {
dnsCache.DeleteAll()
require.False(t, dnsCache.Has(testDomain))
ips, _ := getIPs(testDomain)
require.True(t, dnsCache.Has(testDomain))
require.ElementsMatch(t, ips, dnsCache.Get(testDomain).Value())
})
}
func Test_parseBaseDomain(t *testing.T) {
tests := []struct {
name string
urlStr string
expectedDomain string
expectedScheme string
expectErr bool
}{
{
name: "valid https with subdomain",
urlStr: "https://kek.example.com/lol",
expectedDomain: "example.com",
expectedScheme: "https",
},
{
name: "valid http with www subdomain",
urlStr: "http://www.example.com/path",
expectedDomain: "example.com",
expectedScheme: "http",
},
{
name: "valid http with no subdomain",
urlStr: "http://example.com",
expectedDomain: "example.com",
expectedScheme: "http",
},
{
name: "url with port in host",
urlStr: "http://example.com:8080/path",
expectedDomain: "example.com",
expectedScheme: "http",
},
{
name: "url with ip address host",
urlStr: "http://192.168.1.1",
expectedDomain: "192.168.1.1",
expectedScheme: "http",
},
{
name: "url with uppercase http scheme",
urlStr: "HTTP://EXAMPLE.COM",
expectedDomain: "example.com",
expectedScheme: "http",
},
{
name: "invalid scheme (ftp)",
urlStr: "ftp://example.com",
expectErr: true,
},
{
name: "no scheme",
urlStr: "example.com",
expectErr: true,
},
{
name: "invalid url format",
urlStr: "http//example.com",
expectErr: true,
},
{
name: "empty url string",
urlStr: "",
expectErr: true,
},
{
name: "url with user info",
urlStr: "http://user:pass@example.com",
expectedDomain: "example.com",
expectedScheme: "http",
},
{
name: "url with multiple subdomains",
urlStr: "https://a.b.c.example.com",
expectedDomain: "example.com",
expectedScheme: "https",
},
{
name: "url with leading/trailing whitespace",
urlStr: " https://example.com ",
expectErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
domain, scheme, err := parseBaseDomain(tt.urlStr)
if tt.expectErr {
require.Error(t, err)
assert.Empty(t, domain)
assert.Empty(t, scheme)
} else {
require.NoError(t, err)
assert.Equal(t, tt.expectedDomain, domain)
assert.Equal(t, tt.expectedScheme, scheme)
}
})
}
}