- Introduced new functionality for managing email attachments and drafts in the mail API. - Added handlers for listing, uploading, and downloading message attachments in `internal/api/mail/handlers_attachments.go`. - Implemented draft management endpoints for creating, updating, and deleting drafts in `internal/api/mail/handlers_drafts.go`. - Created new service methods for handling draft and attachment operations in `internal/api/mail/drafts.go` and `internal/api/mail/storage.go`. - Added validation and error handling for draft and attachment operations. - Included unit tests for draft and folder functionalities in `internal/api/mail/drafts_test.go` and `internal/api/mail/folders_test.go`. - Updated API routes to support new draft and attachment features, enhancing overall mail management capabilities.
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package smtp
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseJSONAddresses_structured(t *testing.T) {
|
|
data := []byte(`[{"address":"alice@example.com"},{"address":"bob@example.com"}]`)
|
|
got := parseJSONAddresses(data)
|
|
want := []string{"alice@example.com", "bob@example.com"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("parseJSONAddresses() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestParseJSONAddresses_plainStrings(t *testing.T) {
|
|
data := []byte(`["alice@example.com","bob@example.com"]`)
|
|
got := parseJSONAddresses(data)
|
|
want := []string{"alice@example.com", "bob@example.com"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("parseJSONAddresses() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestParseJSONAddresses_empty(t *testing.T) {
|
|
if got := parseJSONAddresses(nil); got != nil {
|
|
t.Fatalf("parseJSONAddresses(nil) = %v, want nil", got)
|
|
}
|
|
if got := parseJSONAddresses([]byte{}); got != nil {
|
|
t.Fatalf("parseJSONAddresses([]) = %v, want nil", got)
|
|
}
|
|
if got := parseJSONAddresses([]byte(`[]`)); len(got) != 0 {
|
|
t.Fatalf("parseJSONAddresses([]) = %v, want empty slice", got)
|
|
}
|
|
}
|
|
|
|
func TestScheduledPromotionSQLUsesScheduledStatus(t *testing.T) {
|
|
const want = "status = 'scheduled'"
|
|
sql := `
|
|
UPDATE outbox SET status = 'queued', updated_at = NOW()
|
|
WHERE status = 'scheduled' AND scheduled_at IS NOT NULL AND scheduled_at <= NOW()
|
|
`
|
|
if !strings.Contains(sql, want) {
|
|
t.Fatalf("scheduled promotion SQL must filter %q", want)
|
|
}
|
|
if strings.Contains(sql, "status = 'queued' AND scheduled_at") {
|
|
t.Fatal("scheduled promotion must not match queued rows with scheduled_at")
|
|
}
|
|
}
|
|
|
|
func TestParseJSONAddresses_invalid(t *testing.T) {
|
|
got := parseJSONAddresses([]byte(`not-json`))
|
|
if got != nil {
|
|
t.Fatalf("parseJSONAddresses(invalid) = %v, want nil", got)
|
|
}
|
|
}
|
|
|
|
func TestParseJSONAddresses_missingAddressField(t *testing.T) {
|
|
data := []byte(`[{"name":"Alice"}]`)
|
|
got := parseJSONAddresses(data)
|
|
want := []string{""}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("parseJSONAddresses() = %v, want %v", got, want)
|
|
}
|
|
}
|