- Created a CI workflow in `.github/workflows/ci.yml` to run Go tests and verify database migrations. - Added unit tests for the mail API in `internal/api/mail/handlers_test.go`, covering message listing, retrieval, sending, and label updating. - Introduced a service interface for the mail handler in `internal/api/mail/service_iface.go`. - Updated mail handler initialization to accept a service API in `internal/api/mail/handlers.go`. - Implemented test authentication middleware for testing purposes in `internal/api/middleware/testauth.go`. - Added various test cases for IMAP and SMTP functionalities, ensuring robust error handling and validation. - Enhanced project documentation with checklist updates for testing and CI integration.
89 lines
2.7 KiB
Go
89 lines
2.7 KiB
Go
package imap
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/mail/credentials"
|
|
)
|
|
|
|
func TestParseCredentials_missing(t *testing.T) {
|
|
w := &SyncWorker{credentials: &credentials.Manager{}}
|
|
|
|
_, _, err := w.parseCredentials(nil)
|
|
if err == nil || err.Error() != "missing credentials" {
|
|
t.Fatalf("parseCredentials(nil) error = %v, want missing credentials", err)
|
|
}
|
|
|
|
_, _, err = w.parseCredentials([]byte{})
|
|
if err == nil || err.Error() != "missing credentials" {
|
|
t.Fatalf("parseCredentials([]) error = %v, want missing credentials", err)
|
|
}
|
|
}
|
|
|
|
func TestParseCredentials_plaintextForbidden(t *testing.T) {
|
|
w := &SyncWorker{credentials: &credentials.Manager{}}
|
|
|
|
_, _, err := w.parseCredentials([]byte(`{"username":"alice","password":"secret"}`))
|
|
if err == nil || err.Error() != "plaintext credentials forbidden" {
|
|
t.Fatalf("parseCredentials(plaintext) error = %v, want plaintext credentials forbidden", err)
|
|
}
|
|
}
|
|
|
|
func TestParseCredentials_missingManager(t *testing.T) {
|
|
key := base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef"))
|
|
manager, err := credentials.NewManager("v1:"+key, "v1")
|
|
if err != nil {
|
|
t.Fatalf("new manager: %v", err)
|
|
}
|
|
blob, err := manager.Encrypt("alice@example.com", "secret")
|
|
if err != nil {
|
|
t.Fatalf("encrypt: %v", err)
|
|
}
|
|
|
|
w := &SyncWorker{credentials: nil}
|
|
_, _, err = w.parseCredentials(blob)
|
|
if err == nil || err.Error() != "credential manager not configured" {
|
|
t.Fatalf("parseCredentials(no manager) error = %v, want credential manager not configured", err)
|
|
}
|
|
}
|
|
|
|
func TestParseCredentials_encryptedSuccess(t *testing.T) {
|
|
key := base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef"))
|
|
manager, err := credentials.NewManager("v1:"+key, "v1")
|
|
if err != nil {
|
|
t.Fatalf("new manager: %v", err)
|
|
}
|
|
blob, err := manager.Encrypt("alice@example.com", "secret")
|
|
if err != nil {
|
|
t.Fatalf("encrypt: %v", err)
|
|
}
|
|
|
|
w := &SyncWorker{credentials: manager}
|
|
username, password, err := w.parseCredentials(blob)
|
|
if err != nil {
|
|
t.Fatalf("parseCredentials(encrypted) error = %v", err)
|
|
}
|
|
if username != "alice@example.com" || password != "secret" {
|
|
t.Fatalf("got %q/%q, want alice@example.com/secret", username, password)
|
|
}
|
|
}
|
|
|
|
func TestParseCredentials_decryptFailure(t *testing.T) {
|
|
key := base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef"))
|
|
manager, err := credentials.NewManager("v1:"+key, "v1")
|
|
if err != nil {
|
|
t.Fatalf("new manager: %v", err)
|
|
}
|
|
|
|
w := &SyncWorker{credentials: manager}
|
|
_, _, err = w.parseCredentials([]byte("UMC1|v1|invalid|payload"))
|
|
if err == nil {
|
|
t.Fatal("expected decrypt error")
|
|
}
|
|
if !strings.Contains(err.Error(), "decode nonce") {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|