Coverage priorities 1-5: test pure functions, extract interfaces, mock-based handler tests
- Priority 1: Test NewSendEmailTask + NewSendPushTask (5 tests) - Priority 2: Test customHTTPErrorHandler — all 15+ branches (21 tests) - Priority 3: Extract Enqueuer interface + payload builders in worker pkg (5 tests) - Priority 4: Extract ClassifyFile/ComputeRelPath in migrate-encrypt (6 tests) - Priority 5: Define Handler interfaces, refactor to accept them, mock-based tests (14 tests) - Fix .gitignore: /worker instead of worker to stop ignoring internal/worker/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -162,3 +162,179 @@ func TestDelete_NonexistentFile(t *testing.T) {
|
||||
t.Fatalf("Delete should not error for non-existent file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// === isAllowedType ===
|
||||
|
||||
func TestIsAllowedType(t *testing.T) {
|
||||
cfg := &config.StorageConfig{
|
||||
UploadDir: t.TempDir(),
|
||||
BaseURL: "/uploads",
|
||||
MaxFileSize: 10 * 1024 * 1024,
|
||||
AllowedTypes: "image/jpeg,image/png,application/pdf",
|
||||
}
|
||||
svc := NewStorageServiceForTest(cfg)
|
||||
|
||||
if !svc.isAllowedType("image/jpeg") {
|
||||
t.Fatal("image/jpeg should be allowed")
|
||||
}
|
||||
if !svc.isAllowedType("image/png") {
|
||||
t.Fatal("image/png should be allowed")
|
||||
}
|
||||
if !svc.isAllowedType("application/pdf") {
|
||||
t.Fatal("application/pdf should be allowed")
|
||||
}
|
||||
if svc.isAllowedType("text/html") {
|
||||
t.Fatal("text/html should not be allowed")
|
||||
}
|
||||
if svc.isAllowedType("") {
|
||||
t.Fatal("empty MIME should not be allowed")
|
||||
}
|
||||
}
|
||||
|
||||
// === mimeTypesCompatible ===
|
||||
|
||||
func TestMimeTypesCompatible(t *testing.T) {
|
||||
cfg := &config.StorageConfig{
|
||||
UploadDir: t.TempDir(),
|
||||
BaseURL: "/uploads",
|
||||
MaxFileSize: 10 * 1024 * 1024,
|
||||
AllowedTypes: "image/jpeg",
|
||||
}
|
||||
svc := NewStorageServiceForTest(cfg)
|
||||
|
||||
// Same primary type
|
||||
if !svc.mimeTypesCompatible("image/jpeg", "image/png") {
|
||||
t.Fatal("image/* types should be compatible")
|
||||
}
|
||||
|
||||
// Different primary types
|
||||
if svc.mimeTypesCompatible("image/jpeg", "application/pdf") {
|
||||
t.Fatal("image and application should not be compatible")
|
||||
}
|
||||
|
||||
// Same exact types
|
||||
if !svc.mimeTypesCompatible("application/pdf", "application/octet-stream") {
|
||||
t.Fatal("application/* types should be compatible")
|
||||
}
|
||||
}
|
||||
|
||||
// === getExtensionFromMimeType ===
|
||||
|
||||
func TestGetExtensionFromMimeType(t *testing.T) {
|
||||
cfg := &config.StorageConfig{
|
||||
UploadDir: t.TempDir(),
|
||||
BaseURL: "/uploads",
|
||||
MaxFileSize: 10 * 1024 * 1024,
|
||||
AllowedTypes: "image/jpeg",
|
||||
}
|
||||
svc := NewStorageServiceForTest(cfg)
|
||||
|
||||
tests := []struct {
|
||||
mimeType string
|
||||
expected string
|
||||
}{
|
||||
{"image/jpeg", ".jpg"},
|
||||
{"image/png", ".png"},
|
||||
{"image/gif", ".gif"},
|
||||
{"image/webp", ".webp"},
|
||||
{"application/pdf", ".pdf"},
|
||||
{"text/html", ""},
|
||||
{"unknown/type", ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
got := svc.getExtensionFromMimeType(tt.mimeType)
|
||||
if got != tt.expected {
|
||||
t.Fatalf("getExtensionFromMimeType(%q) = %q, want %q", tt.mimeType, got, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === GetUploadDir ===
|
||||
|
||||
func TestGetUploadDir(t *testing.T) {
|
||||
svc, tmpDir := setupTestStorage(t, false)
|
||||
if svc.GetUploadDir() != tmpDir {
|
||||
t.Fatalf("GetUploadDir() = %q, want %q", svc.GetUploadDir(), tmpDir)
|
||||
}
|
||||
}
|
||||
|
||||
// === SetEncryptionService ===
|
||||
|
||||
func TestSetEncryptionService(t *testing.T) {
|
||||
svc, _ := setupTestStorage(t, false)
|
||||
|
||||
// Initially no encryption service
|
||||
if svc.encryptionSvc != nil && svc.encryptionSvc.IsEnabled() {
|
||||
t.Fatal("encryption should not be enabled initially in plain mode")
|
||||
}
|
||||
|
||||
encSvc, err := NewEncryptionService(validTestKey())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
svc.SetEncryptionService(encSvc)
|
||||
|
||||
if svc.encryptionSvc == nil {
|
||||
t.Fatal("encryption service should be set")
|
||||
}
|
||||
}
|
||||
|
||||
// === NewStorageServiceForTest ===
|
||||
|
||||
func TestNewStorageServiceForTest(t *testing.T) {
|
||||
cfg := &config.StorageConfig{
|
||||
UploadDir: "/tmp/test",
|
||||
BaseURL: "/uploads",
|
||||
MaxFileSize: 5 * 1024 * 1024,
|
||||
AllowedTypes: "image/jpeg, image/png, application/pdf",
|
||||
}
|
||||
svc := NewStorageServiceForTest(cfg)
|
||||
|
||||
// Should have 3 allowed types (whitespace trimmed)
|
||||
if !svc.isAllowedType("image/jpeg") {
|
||||
t.Fatal("image/jpeg should be allowed")
|
||||
}
|
||||
if !svc.isAllowedType("image/png") {
|
||||
t.Fatal("image/png should be allowed")
|
||||
}
|
||||
if !svc.isAllowedType("application/pdf") {
|
||||
t.Fatal("application/pdf should be allowed")
|
||||
}
|
||||
}
|
||||
|
||||
// === Delete only plain file ===
|
||||
|
||||
func TestDelete_OnlyPlainFile(t *testing.T) {
|
||||
svc, tmpDir := setupTestStorage(t, false)
|
||||
|
||||
dir := filepath.Join(tmpDir, "images")
|
||||
os.WriteFile(filepath.Join(dir, "only-plain.jpg"), []byte("plain"), 0644)
|
||||
|
||||
err := svc.Delete("/uploads/images/only-plain.jpg")
|
||||
if err != nil {
|
||||
t.Fatalf("Delete failed: %v", err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(dir, "only-plain.jpg")); !os.IsNotExist(err) {
|
||||
t.Fatal("plain file should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
// === Delete only enc file ===
|
||||
|
||||
func TestDelete_OnlyEncFile(t *testing.T) {
|
||||
svc, tmpDir := setupTestStorage(t, false)
|
||||
|
||||
dir := filepath.Join(tmpDir, "documents")
|
||||
os.WriteFile(filepath.Join(dir, "secret.pdf.enc"), []byte("encrypted"), 0644)
|
||||
|
||||
err := svc.Delete("/uploads/documents/secret.pdf")
|
||||
if err != nil {
|
||||
t.Fatalf("Delete failed: %v", err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(dir, "secret.pdf.enc")); !os.IsNotExist(err) {
|
||||
t.Fatal("encrypted file should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user