refactor: go fix ftw
This commit is contained in:
@@ -53,13 +53,13 @@ func TestRunSanitizationFuzzTest(t *testing.T) {
|
|||||||
|
|
||||||
sanitizeFunc := func(input string) string {
|
sanitizeFunc := func(input string) string {
|
||||||
|
|
||||||
result := ""
|
var result strings.Builder
|
||||||
for _, char := range input {
|
for _, char := range input {
|
||||||
if char != ' ' {
|
if char != ' ' {
|
||||||
result += string(char)
|
result.WriteString(string(char))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
result := sanitizeFunc("hello world")
|
result := sanitizeFunc("hello world")
|
||||||
@@ -76,13 +76,13 @@ func TestRunSanitizationFuzzTestWithValidation(t *testing.T) {
|
|||||||
|
|
||||||
sanitizeFunc := func(input string) string {
|
sanitizeFunc := func(input string) string {
|
||||||
|
|
||||||
result := ""
|
var result strings.Builder
|
||||||
for _, char := range input {
|
for _, char := range input {
|
||||||
if char != ' ' {
|
if char != ' ' {
|
||||||
result += string(char)
|
result.WriteString(string(char))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
validateFunc := func(input string) bool {
|
validateFunc := func(input string) bool {
|
||||||
@@ -1673,7 +1673,7 @@ func TestValidateHTTPRequestWithManyHeaders(t *testing.T) {
|
|||||||
helper := NewFuzzTestHelper()
|
helper := NewFuzzTestHelper()
|
||||||
|
|
||||||
req := httptest.NewRequest("GET", "/api/test", nil)
|
req := httptest.NewRequest("GET", "/api/test", nil)
|
||||||
for i := 0; i < 20; i++ {
|
for i := range 20 {
|
||||||
req.Header.Set(fmt.Sprintf("Header-%d", i), fmt.Sprintf("Value-%d", i))
|
req.Header.Set(fmt.Sprintf("Header-%d", i), fmt.Sprintf("Value-%d", i))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,10 +158,3 @@ func FuzzPostRepository(f *testing.F) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func min(a, b int) int {
|
|
||||||
if a < b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1364,7 +1364,7 @@ func TestAuthHandler_ConcurrentAccess(t *testing.T) {
|
|||||||
concurrency := 10
|
concurrency := 10
|
||||||
done := make(chan bool, concurrency)
|
done := make(chan bool, concurrency)
|
||||||
|
|
||||||
for i := 0; i < concurrency; i++ {
|
for range concurrency {
|
||||||
go func() {
|
go func() {
|
||||||
req := createLoginRequest(`{"username":"testuser","password":"Password123!"}`)
|
req := createLoginRequest(`{"username":"testuser","password":"Password123!"}`)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
@@ -1376,7 +1376,7 @@ func TestAuthHandler_ConcurrentAccess(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < concurrency; i++ {
|
for range concurrency {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -115,10 +115,7 @@ func NewPageHandler(templatesDir string, authService AuthServiceInterface, postR
|
|||||||
if start >= len(s) {
|
if start >= len(s) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
end := start + length
|
end := min(start+length, len(s))
|
||||||
if end > len(s) {
|
|
||||||
end = len(s)
|
|
||||||
}
|
|
||||||
return s[start:end]
|
return s[start:end]
|
||||||
},
|
},
|
||||||
"upper": strings.ToUpper,
|
"upper": strings.ToUpper,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (c *SMTPChecker) Name() string {
|
|||||||
|
|
||||||
func (c *SMTPChecker) Check(ctx context.Context) Result {
|
func (c *SMTPChecker) Check(ctx context.Context) Result {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
address := fmt.Sprintf("%s:%d", c.config.Host, c.config.Port)
|
address := net.JoinHostPort(c.config.Host, fmt.Sprintf("%d", c.config.Port))
|
||||||
|
|
||||||
result := Result{
|
result := Result{
|
||||||
Status: StatusHealthy,
|
Status: StatusHealthy,
|
||||||
|
|||||||
@@ -635,7 +635,7 @@ func TestIntegration_CompleteAPIEndpoints(t *testing.T) {
|
|||||||
ctx.Suite.EmailSender.Reset()
|
ctx.Suite.EmailSender.Reset()
|
||||||
paginationUser := createAuthenticatedUser(t, ctx.AuthService, ctx.Suite.UserRepo, uniqueTestUsername(t, "pagination_edge"), uniqueTestEmail(t, "pagination_edge"))
|
paginationUser := createAuthenticatedUser(t, ctx.AuthService, ctx.Suite.UserRepo, uniqueTestUsername(t, "pagination_edge"), uniqueTestEmail(t, "pagination_edge"))
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
testutils.CreatePostWithRepo(t, ctx.Suite.PostRepo, paginationUser.User.ID, fmt.Sprintf("Pagination Post %d", i), fmt.Sprintf("https://example.com/pag%d", i))
|
testutils.CreatePostWithRepo(t, ctx.Suite.PostRepo, paginationUser.User.ID, fmt.Sprintf("Pagination Post %d", i), fmt.Sprintf("https://example.com/pag%d", i))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func TestIntegration_RateLimiting(t *testing.T) {
|
|||||||
rateLimitConfig.AuthLimit = 2
|
rateLimitConfig.AuthLimit = 2
|
||||||
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
||||||
|
|
||||||
for i := 0; i < 2; i++ {
|
for range 2 {
|
||||||
request := httptest.NewRequest("POST", "/api/auth/login", bytes.NewBufferString(`{"username":"test","password":"test"}`))
|
request := httptest.NewRequest("POST", "/api/auth/login", bytes.NewBufferString(`{"username":"test","password":"test"}`))
|
||||||
request.Header.Set("Content-Type", "application/json")
|
request.Header.Set("Content-Type", "application/json")
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -80,7 +80,7 @@ func TestIntegration_RateLimiting(t *testing.T) {
|
|||||||
rateLimitConfig.GeneralLimit = 5
|
rateLimitConfig.GeneralLimit = 5
|
||||||
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for range 5 {
|
||||||
request := httptest.NewRequest("GET", "/api/posts", nil)
|
request := httptest.NewRequest("GET", "/api/posts", nil)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
router.ServeHTTP(recorder, request)
|
router.ServeHTTP(recorder, request)
|
||||||
@@ -99,7 +99,7 @@ func TestIntegration_RateLimiting(t *testing.T) {
|
|||||||
rateLimitConfig.HealthLimit = 3
|
rateLimitConfig.HealthLimit = 3
|
||||||
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
||||||
|
|
||||||
for i := 0; i < 3; i++ {
|
for range 3 {
|
||||||
request := httptest.NewRequest("GET", "/health", nil)
|
request := httptest.NewRequest("GET", "/health", nil)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
router.ServeHTTP(recorder, request)
|
router.ServeHTTP(recorder, request)
|
||||||
@@ -118,7 +118,7 @@ func TestIntegration_RateLimiting(t *testing.T) {
|
|||||||
rateLimitConfig.MetricsLimit = 2
|
rateLimitConfig.MetricsLimit = 2
|
||||||
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
||||||
|
|
||||||
for i := 0; i < 2; i++ {
|
for range 2 {
|
||||||
request := httptest.NewRequest("GET", "/metrics", nil)
|
request := httptest.NewRequest("GET", "/metrics", nil)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
router.ServeHTTP(recorder, request)
|
router.ServeHTTP(recorder, request)
|
||||||
@@ -138,7 +138,7 @@ func TestIntegration_RateLimiting(t *testing.T) {
|
|||||||
rateLimitConfig.GeneralLimit = 10
|
rateLimitConfig.GeneralLimit = 10
|
||||||
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
router, _ := setupRateLimitRouter(t, rateLimitConfig)
|
||||||
|
|
||||||
for i := 0; i < 2; i++ {
|
for range 2 {
|
||||||
request := httptest.NewRequest("POST", "/api/auth/login", bytes.NewBufferString(`{"username":"test","password":"test"}`))
|
request := httptest.NewRequest("POST", "/api/auth/login", bytes.NewBufferString(`{"username":"test","password":"test"}`))
|
||||||
request.Header.Set("Content-Type", "application/json")
|
request.Header.Set("Content-Type", "application/json")
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -165,7 +165,7 @@ func TestIntegration_RateLimiting(t *testing.T) {
|
|||||||
suite.EmailSender.Reset()
|
suite.EmailSender.Reset()
|
||||||
user := createAuthenticatedUser(t, authService, suite.UserRepo, uniqueTestUsername(t, "ratelimit_auth"), uniqueTestEmail(t, "ratelimit_auth"))
|
user := createAuthenticatedUser(t, authService, suite.UserRepo, uniqueTestUsername(t, "ratelimit_auth"), uniqueTestEmail(t, "ratelimit_auth"))
|
||||||
|
|
||||||
for i := 0; i < 3; i++ {
|
for range 3 {
|
||||||
request := httptest.NewRequest("GET", "/api/auth/me", nil)
|
request := httptest.NewRequest("GET", "/api/auth/me", nil)
|
||||||
request.Header.Set("Authorization", "Bearer "+user.Token)
|
request.Header.Set("Authorization", "Bearer "+user.Token)
|
||||||
request = testutils.WithUserContext(request, middleware.UserIDKey, user.User.ID)
|
request = testutils.WithUserContext(request, middleware.UserIDKey, user.User.ID)
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ func TestIntegration_Repositories(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
voters := make([]*database.User, 5)
|
voters := make([]*database.User, 5)
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
voter := &database.User{
|
voter := &database.User{
|
||||||
Username: fmt.Sprintf("voter_%d", i),
|
Username: fmt.Sprintf("voter_%d", i),
|
||||||
Email: fmt.Sprintf("voter%d@example.com", i),
|
Email: fmt.Sprintf("voter%d@example.com", i),
|
||||||
|
|||||||
@@ -283,16 +283,16 @@ func TestInMemoryCacheConcurrent(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("Concurrent writes", func(t *testing.T) {
|
t.Run("Concurrent writes", func(t *testing.T) {
|
||||||
done := make(chan bool, numGoroutines)
|
done := make(chan bool, numGoroutines)
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := range numGoroutines {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
t.Errorf("Goroutine %d panicked: %v", id, r)
|
t.Errorf("Goroutine %d panicked: %v", id, r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for j := 0; j < numOps; j++ {
|
for j := range numOps {
|
||||||
entry := &CacheEntry{
|
entry := &CacheEntry{
|
||||||
Data: []byte(fmt.Sprintf("data-%d-%d", id, j)),
|
Data: fmt.Appendf(nil, "data-%d-%d", id, j),
|
||||||
Headers: make(http.Header),
|
Headers: make(http.Header),
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
TTL: 5 * time.Minute,
|
TTL: 5 * time.Minute,
|
||||||
@@ -306,16 +306,16 @@ func TestInMemoryCacheConcurrent(t *testing.T) {
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for range numGoroutines {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Concurrent reads and writes", func(t *testing.T) {
|
t.Run("Concurrent reads and writes", func(t *testing.T) {
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := range 10 {
|
||||||
entry := &CacheEntry{
|
entry := &CacheEntry{
|
||||||
Data: []byte(fmt.Sprintf("data-%d", i)),
|
Data: fmt.Appendf(nil, "data-%d", i),
|
||||||
Headers: make(http.Header),
|
Headers: make(http.Header),
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
TTL: 5 * time.Minute,
|
TTL: 5 * time.Minute,
|
||||||
@@ -325,16 +325,16 @@ func TestInMemoryCacheConcurrent(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan bool, numGoroutines*2)
|
done := make(chan bool, numGoroutines*2)
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := range numGoroutines {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
t.Errorf("Writer goroutine %d panicked: %v", id, r)
|
t.Errorf("Writer goroutine %d panicked: %v", id, r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for j := 0; j < numOps; j++ {
|
for j := range numOps {
|
||||||
entry := &CacheEntry{
|
entry := &CacheEntry{
|
||||||
Data: []byte(fmt.Sprintf("write-%d-%d", id, j)),
|
Data: fmt.Appendf(nil, "write-%d-%d", id, j),
|
||||||
Headers: make(http.Header),
|
Headers: make(http.Header),
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
TTL: 5 * time.Minute,
|
TTL: 5 * time.Minute,
|
||||||
@@ -346,14 +346,14 @@ func TestInMemoryCacheConcurrent(t *testing.T) {
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := range numGoroutines {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
t.Errorf("Reader goroutine %d panicked: %v", id, r)
|
t.Errorf("Reader goroutine %d panicked: %v", id, r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for j := 0; j < numOps; j++ {
|
for j := range numOps {
|
||||||
key := fmt.Sprintf("key-%d", j%10)
|
key := fmt.Sprintf("key-%d", j%10)
|
||||||
cache.Get(key)
|
cache.Get(key)
|
||||||
}
|
}
|
||||||
@@ -368,9 +368,9 @@ func TestInMemoryCacheConcurrent(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("Concurrent deletes", func(t *testing.T) {
|
t.Run("Concurrent deletes", func(t *testing.T) {
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := range numGoroutines {
|
||||||
entry := &CacheEntry{
|
entry := &CacheEntry{
|
||||||
Data: []byte(fmt.Sprintf("data-%d", i)),
|
Data: fmt.Appendf(nil, "data-%d", i),
|
||||||
Headers: make(http.Header),
|
Headers: make(http.Header),
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
TTL: 5 * time.Minute,
|
TTL: 5 * time.Minute,
|
||||||
@@ -379,7 +379,7 @@ func TestInMemoryCacheConcurrent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
done := make(chan bool, numGoroutines)
|
done := make(chan bool, numGoroutines)
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := range numGoroutines {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
@@ -391,7 +391,7 @@ func TestInMemoryCacheConcurrent(t *testing.T) {
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for range numGoroutines {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ func TestConcurrentAccess(t *testing.T) {
|
|||||||
collector := NewMetricsCollector(monitor)
|
collector := NewMetricsCollector(monitor)
|
||||||
|
|
||||||
done := make(chan bool, 10)
|
done := make(chan bool, 10)
|
||||||
for i := 0; i < 10; i++ {
|
for range 10 {
|
||||||
go func() {
|
go func() {
|
||||||
monitor.LogQuery("SELECT * FROM users", 50*time.Millisecond, nil)
|
monitor.LogQuery("SELECT * FROM users", 50*time.Millisecond, nil)
|
||||||
collector.RecordRequest(100*time.Millisecond, false)
|
collector.RecordRequest(100*time.Millisecond, false)
|
||||||
@@ -326,7 +326,7 @@ func TestConcurrentAccess(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for range 10 {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ func TestThreadSafety(t *testing.T) {
|
|||||||
numGoroutines := 100
|
numGoroutines := 100
|
||||||
done := make(chan bool, numGoroutines)
|
done := make(chan bool, numGoroutines)
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := range numGoroutines {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
|
|
||||||
if id%2 == 0 {
|
if id%2 == 0 {
|
||||||
@@ -398,7 +398,7 @@ func TestThreadSafety(t *testing.T) {
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for range numGoroutines {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ func TestRateLimiterMaxKeys(t *testing.T) {
|
|||||||
limiter := NewRateLimiterWithConfig(1*time.Minute, 10, 5, 1*time.Minute, 2*time.Minute)
|
limiter := NewRateLimiterWithConfig(1*time.Minute, 10, 5, 1*time.Minute, 2*time.Minute)
|
||||||
defer limiter.StopCleanup()
|
defer limiter.StopCleanup()
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
key := fmt.Sprintf("key-%d", i)
|
key := fmt.Sprintf("key-%d", i)
|
||||||
if !limiter.Allow(key) {
|
if !limiter.Allow(key) {
|
||||||
t.Errorf("Key %s should be allowed", key)
|
t.Errorf("Key %s should be allowed", key)
|
||||||
@@ -435,7 +435,7 @@ func TestRateLimiterRegistry(t *testing.T) {
|
|||||||
request := httptest.NewRequest("GET", "/test", nil)
|
request := httptest.NewRequest("GET", "/test", nil)
|
||||||
request.RemoteAddr = "127.0.0.1:12345"
|
request.RemoteAddr = "127.0.0.1:12345"
|
||||||
|
|
||||||
for i := 0; i < 50; i++ {
|
for i := range 50 {
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
server1.ServeHTTP(recorder, request)
|
server1.ServeHTTP(recorder, request)
|
||||||
if recorder.Code != http.StatusOK {
|
if recorder.Code != http.StatusOK {
|
||||||
@@ -443,7 +443,7 @@ func TestRateLimiterRegistry(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 50; i++ {
|
for i := range 50 {
|
||||||
recorder2 := httptest.NewRecorder()
|
recorder2 := httptest.NewRecorder()
|
||||||
server2.ServeHTTP(recorder2, request)
|
server2.ServeHTTP(recorder2, request)
|
||||||
if recorder2.Code != http.StatusOK {
|
if recorder2.Code != http.StatusOK {
|
||||||
@@ -463,7 +463,7 @@ func TestRateLimiterRegistry(t *testing.T) {
|
|||||||
t.Error("101st request to server2 should be rejected (shared limiter reached limit)")
|
t.Error("101st request to server2 should be rejected (shared limiter reached limit)")
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 50; i++ {
|
for i := range 50 {
|
||||||
recorder3 := httptest.NewRecorder()
|
recorder3 := httptest.NewRecorder()
|
||||||
server3.ServeHTTP(recorder3, request)
|
server3.ServeHTTP(recorder3, request)
|
||||||
if recorder3.Code != http.StatusOK {
|
if recorder3.Code != http.StatusOK {
|
||||||
|
|||||||
@@ -458,13 +458,13 @@ func TestIsRapidRequest(t *testing.T) {
|
|||||||
|
|
||||||
ip := "192.168.1.1"
|
ip := "192.168.1.1"
|
||||||
|
|
||||||
for i := 0; i < 50; i++ {
|
for i := range 50 {
|
||||||
if isRapidRequest(ip) {
|
if isRapidRequest(ip) {
|
||||||
t.Errorf("Request %d should not be considered rapid", i+1)
|
t.Errorf("Request %d should not be considered rapid", i+1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 110; i++ {
|
for i := range 110 {
|
||||||
result := isRapidRequest(ip)
|
result := isRapidRequest(ip)
|
||||||
if i < 50 {
|
if i < 50 {
|
||||||
if result {
|
if result {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func TestValidationMiddleware(t *testing.T) {
|
|||||||
body, _ := json.Marshal(user)
|
body, _ := json.Marshal(user)
|
||||||
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
||||||
request.Header.Set("Content-Type", "application/json")
|
request.Header.Set("Content-Type", "application/json")
|
||||||
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeOf(TestUser{}))
|
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeFor[TestUser]())
|
||||||
request = request.WithContext(ctx)
|
request = request.WithContext(ctx)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ func TestValidationMiddleware(t *testing.T) {
|
|||||||
body, _ := json.Marshal(user)
|
body, _ := json.Marshal(user)
|
||||||
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
||||||
request.Header.Set("Content-Type", "application/json")
|
request.Header.Set("Content-Type", "application/json")
|
||||||
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeOf(TestUser{}))
|
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeFor[TestUser]())
|
||||||
request = request.WithContext(ctx)
|
request = request.WithContext(ctx)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ func TestValidationMiddleware(t *testing.T) {
|
|||||||
body, _ := json.Marshal(user)
|
body, _ := json.Marshal(user)
|
||||||
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
||||||
request.Header.Set("Content-Type", "application/json")
|
request.Header.Set("Content-Type", "application/json")
|
||||||
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeOf(TestUser{}))
|
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeFor[TestUser]())
|
||||||
request = request.WithContext(ctx)
|
request = request.WithContext(ctx)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ func TestValidationMiddleware(t *testing.T) {
|
|||||||
body, _ := json.Marshal(user)
|
body, _ := json.Marshal(user)
|
||||||
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
request := httptest.NewRequest("POST", "/users", bytes.NewBuffer(body))
|
||||||
request.Header.Set("Content-Type", "application/json")
|
request.Header.Set("Content-Type", "application/json")
|
||||||
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeOf(TestUser{}))
|
ctx := context.WithValue(request.Context(), DTOTypeKey, reflect.TypeFor[TestUser]())
|
||||||
request = request.WithContext(ctx)
|
request = request.WithContext(ctx)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ func TestPostRepository_GetAll(t *testing.T) {
|
|||||||
|
|
||||||
user := suite.CreateTestUser("testuser2", "test2@example.com", "password123")
|
user := suite.CreateTestUser("testuser2", "test2@example.com", "password123")
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
suite.CreateTestPost(user.ID,
|
suite.CreateTestPost(user.ID,
|
||||||
"Post "+strconv.Itoa(i),
|
"Post "+strconv.Itoa(i),
|
||||||
"https://example.com/"+strconv.Itoa(i),
|
"https://example.com/"+strconv.Itoa(i),
|
||||||
@@ -178,7 +178,7 @@ func TestPostRepository_GetAll(t *testing.T) {
|
|||||||
|
|
||||||
user := suite.CreateTestUser("testuser3", "test3@example.com", "password123")
|
user := suite.CreateTestUser("testuser3", "test3@example.com", "password123")
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
suite.CreateTestPost(user.ID,
|
suite.CreateTestPost(user.ID,
|
||||||
"Post "+strconv.Itoa(i),
|
"Post "+strconv.Itoa(i),
|
||||||
"https://example.com/"+strconv.Itoa(i),
|
"https://example.com/"+strconv.Itoa(i),
|
||||||
@@ -328,7 +328,7 @@ func TestPostRepository_Count(t *testing.T) {
|
|||||||
|
|
||||||
user := suite.CreateTestUser("testuser", "test@example.com", "password123")
|
user := suite.CreateTestUser("testuser", "test@example.com", "password123")
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
suite.CreateTestPost(user.ID,
|
suite.CreateTestPost(user.ID,
|
||||||
"Post "+strconv.Itoa(i),
|
"Post "+strconv.Itoa(i),
|
||||||
"https://example.com/"+strconv.Itoa(i),
|
"https://example.com/"+strconv.Itoa(i),
|
||||||
@@ -506,7 +506,7 @@ func TestPostRepository_Search(t *testing.T) {
|
|||||||
|
|
||||||
user := suite.CreateTestUser("testuser2", "test2@example.com", "password123")
|
user := suite.CreateTestUser("testuser2", "test2@example.com", "password123")
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
suite.CreateTestPost(user.ID,
|
suite.CreateTestPost(user.ID,
|
||||||
"Go Post "+strconv.Itoa(i),
|
"Go Post "+strconv.Itoa(i),
|
||||||
"https://example.com/go"+strconv.Itoa(i),
|
"https://example.com/go"+strconv.Itoa(i),
|
||||||
|
|||||||
@@ -621,7 +621,7 @@ func TestUserRepository_GetPosts(t *testing.T) {
|
|||||||
|
|
||||||
user := suite.CreateTestUser("pagination", "pagination@example.com", "password123")
|
user := suite.CreateTestUser("pagination", "pagination@example.com", "password123")
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
suite.CreateTestPost(user.ID,
|
suite.CreateTestPost(user.ID,
|
||||||
"Post "+strconv.Itoa(i),
|
"Post "+strconv.Itoa(i),
|
||||||
"https://example.com/"+strconv.Itoa(i),
|
"https://example.com/"+strconv.Itoa(i),
|
||||||
@@ -1089,7 +1089,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
done := make(chan bool, 10)
|
done := make(chan bool, 10)
|
||||||
errors := make(chan error, 10)
|
errors := make(chan error, 10)
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := range 10 {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer func() { done <- true }()
|
defer func() { done <- true }()
|
||||||
user := &database.User{
|
user := &database.User{
|
||||||
@@ -1099,7 +1099,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
EmailVerified: true,
|
EmailVerified: true,
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
for retries := 0; retries < 5; retries++ {
|
for retries := range 5 {
|
||||||
err = suite.UserRepo.Create(user)
|
err = suite.UserRepo.Create(user)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
@@ -1116,7 +1116,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for range 10 {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
close(errors)
|
close(errors)
|
||||||
@@ -1142,7 +1142,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
user := suite.CreateTestUser("concurrent_update", "update@example.com", "password123")
|
user := suite.CreateTestUser("concurrent_update", "update@example.com", "password123")
|
||||||
|
|
||||||
done := make(chan bool, 5)
|
done := make(chan bool, 5)
|
||||||
for i := 0; i < 5; i++ {
|
for i := range 5 {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer func() { done <- true }()
|
defer func() { done <- true }()
|
||||||
user.Username = fmt.Sprintf("updated%d", id)
|
user.Username = fmt.Sprintf("updated%d", id)
|
||||||
@@ -1150,7 +1150,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for range 5 {
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1172,7 +1172,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
done := make(chan bool, 2)
|
done := make(chan bool, 2)
|
||||||
go func() {
|
go func() {
|
||||||
var err error
|
var err error
|
||||||
for retries := 0; retries < 5; retries++ {
|
for retries := range 5 {
|
||||||
err = suite.UserRepo.Delete(user1.ID)
|
err = suite.UserRepo.Delete(user1.ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
@@ -1187,7 +1187,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
var err error
|
var err error
|
||||||
for retries := 0; retries < 5; retries++ {
|
for retries := range 5 {
|
||||||
err = suite.UserRepo.Delete(user2.ID)
|
err = suite.UserRepo.Delete(user2.ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
@@ -1210,7 +1210,7 @@ func TestUserRepository_ConcurrentAccess(t *testing.T) {
|
|||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
var err error
|
var err error
|
||||||
for retries := 0; retries < 5; retries++ {
|
for retries := range 5 {
|
||||||
count, err = suite.UserRepo.Count()
|
count, err = suite.UserRepo.Count()
|
||||||
if err == nil && count == 0 {
|
if err == nil && count == 0 {
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func TestEmailService_Performance(t *testing.T) {
|
|||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
iterations := 1000
|
iterations := 1000
|
||||||
for i := 0; i < iterations; i++ {
|
for range iterations {
|
||||||
service.GenerateVerificationEmailBody(user.Username, "https://example.com/confirm?token=test")
|
service.GenerateVerificationEmailBody(user.Username, "https://example.com/confirm?token=test")
|
||||||
}
|
}
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -339,11 +340,9 @@ func (s *URLMetadataService) validateURLForSSRF(u *url.URL) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrSSRFBlocked
|
return ErrSSRFBlocked
|
||||||
}
|
}
|
||||||
for _, ip := range ips {
|
if slices.ContainsFunc(ips, isPrivateOrReservedIP) {
|
||||||
if isPrivateOrReservedIP(ip) {
|
|
||||||
return ErrSSRFBlocked
|
return ErrSSRFBlocked
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,13 +358,7 @@ func isLocalhost(hostname string) bool {
|
|||||||
"0:0:0:0:0:0:0:0",
|
"0:0:0:0:0:0:0:0",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range localhostNames {
|
return slices.Contains(localhostNames, hostname)
|
||||||
if hostname == name {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPrivateOrReservedIP(ip net.IP) bool {
|
func isPrivateOrReservedIP(ip net.IP) bool {
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ func (b *VoteRequestBuilder) Build() VoteRequest {
|
|||||||
|
|
||||||
func (f *TestDataFactory) CreateTestUsers(count int) []*database.User {
|
func (f *TestDataFactory) CreateTestUsers(count int) []*database.User {
|
||||||
users := make([]*database.User, count)
|
users := make([]*database.User, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := range count {
|
||||||
users[i] = f.NewUserBuilder().
|
users[i] = f.NewUserBuilder().
|
||||||
WithID(uint(i + 1)).
|
WithID(uint(i + 1)).
|
||||||
WithUsername(fmt.Sprintf("user%d", i+1)).
|
WithUsername(fmt.Sprintf("user%d", i+1)).
|
||||||
@@ -297,7 +297,7 @@ func (f *TestDataFactory) CreateTestUsers(count int) []*database.User {
|
|||||||
|
|
||||||
func (f *TestDataFactory) CreateTestPosts(count int) []*database.Post {
|
func (f *TestDataFactory) CreateTestPosts(count int) []*database.Post {
|
||||||
posts := make([]*database.Post, count)
|
posts := make([]*database.Post, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := range count {
|
||||||
posts[i] = f.NewPostBuilder().
|
posts[i] = f.NewPostBuilder().
|
||||||
WithID(uint(i+1)).
|
WithID(uint(i+1)).
|
||||||
WithTitle(fmt.Sprintf("Post %d", i+1)).
|
WithTitle(fmt.Sprintf("Post %d", i+1)).
|
||||||
@@ -332,7 +332,7 @@ func (f *TestDataFactory) CreateTestVotes(count int) []*database.Vote {
|
|||||||
|
|
||||||
func (f *TestDataFactory) CreateTestAuthResults(count int) []*AuthResult {
|
func (f *TestDataFactory) CreateTestAuthResults(count int) []*AuthResult {
|
||||||
results := make([]*AuthResult, count)
|
results := make([]*AuthResult, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := range count {
|
||||||
results[i] = f.NewAuthResultBuilder().
|
results[i] = f.NewAuthResultBuilder().
|
||||||
WithUser(f.NewUserBuilder().
|
WithUser(f.NewUserBuilder().
|
||||||
WithID(uint(i + 1)).
|
WithID(uint(i + 1)).
|
||||||
@@ -346,7 +346,7 @@ func (f *TestDataFactory) CreateTestAuthResults(count int) []*AuthResult {
|
|||||||
|
|
||||||
func (f *TestDataFactory) CreateTestVoteRequests(count int) []VoteRequest {
|
func (f *TestDataFactory) CreateTestVoteRequests(count int) []VoteRequest {
|
||||||
requests := make([]VoteRequest, count)
|
requests := make([]VoteRequest, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := range count {
|
||||||
voteType := database.VoteUp
|
voteType := database.VoteUp
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
voteType = database.VoteDown
|
voteType = database.VoteDown
|
||||||
@@ -365,8 +365,9 @@ func (f *TestDataFactory) CreateTestVoteRequests(count int) []VoteRequest {
|
|||||||
return requests
|
return requests
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:fix inline
|
||||||
func uintPtr(u uint) *uint {
|
func uintPtr(u uint) *uint {
|
||||||
return &u
|
return new(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
type E2ETestDataFactory struct {
|
type E2ETestDataFactory struct {
|
||||||
@@ -450,7 +451,7 @@ func (f *E2ETestDataFactory) CreateMultipleUsers(t *testing.T, count int, userna
|
|||||||
var users []*TestUser
|
var users []*TestUser
|
||||||
timestamp := time.Now().UnixNano()
|
timestamp := time.Now().UnixNano()
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for i := range count {
|
||||||
uniqueID := timestamp + int64(i)
|
uniqueID := timestamp + int64(i)
|
||||||
username := fmt.Sprintf("%s%d", usernamePrefix, uniqueID)
|
username := fmt.Sprintf("%s%d", usernamePrefix, uniqueID)
|
||||||
email := fmt.Sprintf("%s%d@example.com", emailPrefix, uniqueID)
|
email := fmt.Sprintf("%s%d@example.com", emailPrefix, uniqueID)
|
||||||
|
|||||||
@@ -123,12 +123,12 @@ func defaultIfEmpty(value, fallback string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func extractTokenFromBody(body string) string {
|
func extractTokenFromBody(body string) string {
|
||||||
index := strings.Index(body, "token=")
|
_, after, ok := strings.Cut(body, "token=")
|
||||||
if index == -1 {
|
if !ok {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenPart := body[index+len("token="):]
|
tokenPart := after
|
||||||
|
|
||||||
if delimIdx := strings.IndexAny(tokenPart, "&\"'\\\r\n <>"); delimIdx != -1 {
|
if delimIdx := strings.IndexAny(tokenPart, "&\"'\\\r\n <>"); delimIdx != -1 {
|
||||||
tokenPart = tokenPart[:delimIdx]
|
tokenPart = tokenPart[:delimIdx]
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ func getErrorField(resp *APIResponse) (string, bool) {
|
|||||||
if resp == nil {
|
if resp == nil {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
if dataMap, ok := resp.Data.(map[string]interface{}); ok {
|
if dataMap, ok := resp.Data.(map[string]any); ok {
|
||||||
if errorVal, ok := dataMap["error"].(string); ok {
|
if errorVal, ok := dataMap["error"].(string); ok {
|
||||||
return errorVal, true
|
return errorVal, true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ func camelCaseToWords(s string) string {
|
|||||||
return result.String()
|
return result.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateStruct(s interface{}) error {
|
func ValidateStruct(s any) error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ func ValidateStruct(s interface{}) error {
|
|||||||
val := reflect.ValueOf(s)
|
val := reflect.ValueOf(s)
|
||||||
typ := reflect.TypeOf(s)
|
typ := reflect.TypeOf(s)
|
||||||
|
|
||||||
if val.Kind() == reflect.Ptr {
|
if val.Kind() == reflect.Pointer {
|
||||||
if val.IsNil() {
|
if val.IsNil() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -252,9 +252,9 @@ func ValidateStruct(s interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tagName, param string
|
var tagName, param string
|
||||||
if idx := strings.Index(tag, "="); idx != -1 {
|
if before, after, ok := strings.Cut(tag, "="); ok {
|
||||||
tagName = tag[:idx]
|
tagName = before
|
||||||
param = tag[idx+1:]
|
param = after
|
||||||
} else {
|
} else {
|
||||||
tagName = tag
|
tagName = tag
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user