test: add new handler test files for analytics, auth, kobo, library, progress, and sidecar
This commit is contained in:
@@ -0,0 +1,66 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseLimit_Valid(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected int32
|
||||||
|
}{
|
||||||
|
{"string number", "10", 10},
|
||||||
|
{"zero", "0", 0},
|
||||||
|
{"large number", "1000", 1000},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result, err := parseLimit(tt.input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseLimit_Invalid(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
}{
|
||||||
|
{"non-numeric", "abc"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := parseLimit(tt.input)
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFormatUUID(t *testing.T) {
|
||||||
|
uuidBytes := [16]byte{
|
||||||
|
0xf4, 0x7a, 0xc1, 0x0b,
|
||||||
|
0x58, 0xcc,
|
||||||
|
0x43, 0x72,
|
||||||
|
0xa5, 0x67,
|
||||||
|
0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
|
||||||
|
}
|
||||||
|
pgUUID := pgtype.UUID{Bytes: uuidBytes, Valid: true}
|
||||||
|
|
||||||
|
result := formatUUID(pgUUID)
|
||||||
|
assert.Equal(t, "f47ac10b-58cc-4372-a567-0e02b2c3d479", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFormatUUID_Null(t *testing.T) {
|
||||||
|
pgUUID := pgtype.UUID{Valid: false}
|
||||||
|
|
||||||
|
result := formatUUID(pgUUID)
|
||||||
|
assert.Equal(t, "", result)
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateJWTWithAllClaims_UniqueTokens(t *testing.T) {
|
||||||
|
handler := &AuthHandler{jwtKey: []byte("test-secret-key")}
|
||||||
|
|
||||||
|
token1, err := handler.generateJWTWithAllClaims("user-id-1", "admin", "test@test.com", "testuser")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, token1)
|
||||||
|
|
||||||
|
token2, err := handler.generateJWTWithAllClaims("user-id-1", "admin", "test@test.com", "testuser")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, token2)
|
||||||
|
|
||||||
|
assert.NotEqual(t, token1, token2, "Tokens generated at same time should be different due to jti")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateJWTWithAllClaims_ValidClaims(t *testing.T) {
|
||||||
|
handler := &AuthHandler{jwtKey: []byte("test-secret-key")}
|
||||||
|
|
||||||
|
token, err := handler.generateJWTWithAllClaims("user-id-123", "admin", "admin@test.com", "adminuser")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, token)
|
||||||
|
|
||||||
|
parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte("test-secret-key"), nil
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
claims := parsedToken.Claims.(jwt.MapClaims)
|
||||||
|
assert.Equal(t, "user-id-123", claims["user_id"])
|
||||||
|
assert.Equal(t, "admin", claims["user_role"])
|
||||||
|
assert.Equal(t, "admin@test.com", claims["user_email"])
|
||||||
|
assert.Equal(t, "adminuser", claims["user_username"])
|
||||||
|
assert.Contains(t, claims, "jti")
|
||||||
|
assert.Contains(t, claims, "exp")
|
||||||
|
assert.Contains(t, claims, "iat")
|
||||||
|
|
||||||
|
exp := int64(claims["exp"].(float64))
|
||||||
|
iat := int64(claims["iat"].(float64))
|
||||||
|
assert.Greater(t, exp, iat, "exp should be greater than iat")
|
||||||
|
assert.Greater(t, exp, time.Now().Unix(), "exp should be in the future")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateJWTWithRole(t *testing.T) {
|
||||||
|
handler := &AuthHandler{jwtKey: []byte("test-secret-key")}
|
||||||
|
|
||||||
|
token, err := handler.generateJWTWithRole("user-id-456", "moderator")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, token)
|
||||||
|
|
||||||
|
parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte("test-secret-key"), nil
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
claims := parsedToken.Claims.(jwt.MapClaims)
|
||||||
|
assert.Equal(t, "user-id-456", claims["user_id"])
|
||||||
|
assert.Equal(t, "moderator", claims["user_role"])
|
||||||
|
assert.Equal(t, "", claims["user_email"])
|
||||||
|
assert.Equal(t, "", claims["user_username"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateJWT(t *testing.T) {
|
||||||
|
handler := &AuthHandler{jwtKey: []byte("test-secret-key")}
|
||||||
|
|
||||||
|
token, err := handler.generateJWT("user-id-789")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, token)
|
||||||
|
|
||||||
|
parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte("test-secret-key"), nil
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
claims := parsedToken.Claims.(jwt.MapClaims)
|
||||||
|
assert.Equal(t, "user-id-789", claims["user_id"])
|
||||||
|
assert.Equal(t, "user", claims["user_role"])
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLooksLikeSHA256_Valid(t *testing.T) {
|
||||||
|
validSHA256 := "550e8400e29b41d4a716446655440000550e8400e29b41d4a716446655440000"
|
||||||
|
|
||||||
|
result := looksLikeSHA256(validSHA256)
|
||||||
|
assert.True(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLooksLikeSHA256_Lowercase(t *testing.T) {
|
||||||
|
sha256 := "550e8400e29b41d4a716446655440000550e8400e29b41d4a716446655440000"
|
||||||
|
|
||||||
|
result := looksLikeSHA256(sha256)
|
||||||
|
assert.True(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLooksLikeSHA256_Invalid(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
}{
|
||||||
|
{"too short", "abc123"},
|
||||||
|
{"too long", "550e8400e29b41d4a716446655440000550e8400e29b41d4a71644665544000000"},
|
||||||
|
{"wrong characters", "550e8400e29b41d4a716446655440000550e8400e29b41d4a71644665544000gg"},
|
||||||
|
{"empty", ""},
|
||||||
|
{"with spaces", "550e8400 e29b 41d4 a716 446655440000"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := looksLikeSHA256(tt.input)
|
||||||
|
assert.False(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseUUID_Library(t *testing.T) {
|
||||||
|
validUUID := "f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
||||||
|
|
||||||
|
result, err := parseUUID(validUUID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, result.Valid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseUUID_Invalid(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
}{
|
||||||
|
{"not a uuid", "not-a-uuid"},
|
||||||
|
{"empty", ""},
|
||||||
|
{"wrong format", "f47ac10b-58cc-4372"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := parseUUID(tt.input)
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetDeviceIcon_Kobo(t *testing.T) {
|
||||||
|
result := getDeviceIcon("kobo")
|
||||||
|
assert.Equal(t, "📚", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetDeviceIcon_KOReader(t *testing.T) {
|
||||||
|
result := getDeviceIcon("koreader")
|
||||||
|
assert.Equal(t, "📖", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetDeviceIcon_Kindle(t *testing.T) {
|
||||||
|
result := getDeviceIcon("kindle")
|
||||||
|
assert.Equal(t, "📱", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetDeviceIcon_Unknown(t *testing.T) {
|
||||||
|
result := getDeviceIcon("unknown")
|
||||||
|
assert.Equal(t, "📚", result)
|
||||||
|
|
||||||
|
result = getDeviceIcon("")
|
||||||
|
assert.Equal(t, "📚", result)
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseTokenUUID_ValidUUID(t *testing.T) {
|
||||||
|
validUUID := "550e8400-e29b-41d4-a716-446655440000"
|
||||||
|
|
||||||
|
result, err := parseTokenUUID(validUUID)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, result.Valid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseTokenUUID_InvalidUUID(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
}{
|
||||||
|
{"not a uuid", "not-a-valid-jwt-token"},
|
||||||
|
{"empty string", ""},
|
||||||
|
{"invalid format", "550e8400-e29b-41d4"},
|
||||||
|
{"too short", "abc"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := parseTokenUUID(tt.input)
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSanitizeFilename_NoChange(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
}{
|
||||||
|
{"simple_filename"},
|
||||||
|
{"file_name_123"},
|
||||||
|
{"Document"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := sanitizeFilename(tt.name)
|
||||||
|
assert.Equal(t, tt.name, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSanitizeFilename_ReplacesSpecialChars(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{"slash", "file/name", "file_name"},
|
||||||
|
{"backslash", "file\\name", "file_name"},
|
||||||
|
{"colon", "file:name", "file_name"},
|
||||||
|
{"asterisk", "file*name", "file_name"},
|
||||||
|
{"question_mark", "file?name", "file_name"},
|
||||||
|
{"quotes", "file\"name", "file_name"},
|
||||||
|
{"less_than", "file<name", "file_name"},
|
||||||
|
{"greater_than", "file>name", "file_name"},
|
||||||
|
{"pipe", "file|name", "file_name"},
|
||||||
|
{"multiple_chars", "a/b\\c:d*e", "a_b_c_d_e"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := sanitizeFilename(tt.input)
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSanitizeAll_Basic(t *testing.T) {
|
||||||
|
result := sanitizeAll("hello world", "o", "0")
|
||||||
|
assert.Equal(t, "hell0 w0rld", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSanitizeAll_NoMatch(t *testing.T) {
|
||||||
|
result := sanitizeAll("hello", "x", "y")
|
||||||
|
assert.Equal(t, "hello", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSanitizeAll_EmptyStrings(t *testing.T) {
|
||||||
|
result := sanitizeAll("", "a", "b")
|
||||||
|
assert.Equal(t, "", result)
|
||||||
|
|
||||||
|
result = sanitizeAll("test", "", "x")
|
||||||
|
assert.Equal(t, "test", result)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user