ultisuite-backend/internal/integrationtest/migration/helpers_test.go
R3D347HR4Y 7143a36c19
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Integration tests (push) Waiting to run
CI / DB migrations (push) Waiting to run
feat(mail): integrate Stalwart hosted mail and migration features
- Added configuration options for Stalwart hosted mail in .env.example.
- Updated Docker Compose to include Stalwart service with health checks.
- Introduced new API endpoints for managing mail domains and migration projects.
- Enhanced Authentik blueprints for user enrollment and post-migration security.
- Updated OAuth handling for Google and Microsoft migration processes.
- Improved error handling and response structures in the mail API.
- Added integration tests for email claiming and migration workflows.
2026-06-13 12:47:08 +02:00

118 lines
3.2 KiB
Go

//go:build integration
package migration_test
import (
"context"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/ultisuite/ulti-backend/internal/integrationtest"
"github.com/ultisuite/ulti-backend/internal/mail/credentials"
"github.com/ultisuite/ulti-backend/internal/nextcloud"
"github.com/ultisuite/ulti-backend/internal/users"
)
func mockNextcloudServer(t *testing.T) *httptest.Server {
t.Helper()
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPut, "MKCOL", "MKCALENDAR":
w.WriteHeader(http.StatusCreated)
case http.MethodDelete:
w.WriteHeader(http.StatusNoContent)
case "PROPFIND", "REPORT", http.MethodGet:
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`<?xml version="1.0"?><d:multistatus xmlns:d="DAV:"></d:multistatus>`))
default:
w.WriteHeader(http.StatusNoContent)
}
}))
}
func testCredentialManager(t *testing.T) *credentials.Manager {
t.Helper()
mgr, err := credentials.NewManager(
"v1:MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=",
"v1",
)
if err != nil {
t.Fatalf("credential manager: %v", err)
}
return mgr
}
func mockNextcloudClient(t *testing.T, pool *pgxpool.Pool, email string) (*nextcloud.Client, string) {
t.Helper()
srv := mockNextcloudServer(t)
t.Cleanup(srv.Close)
ncUserID := nextcloud.UserIDFromClaims(email, "")
store := nextcloud.NewDAVCredentialStore(pool, testCredentialManager(t))
if err := store.SaveToken(context.Background(), ncUserID, "mock-app-password"); err != nil {
t.Fatalf("seed dav token: %v", err)
}
client := nextcloud.NewClient(srv.URL, "admin", "admin").WithDAVCredentials(store)
return client, ncUserID
}
func insertMigrationTestUser(t *testing.T, pool *pgxpool.Pool, prefix string) (userID, email string) {
t.Helper()
claims := integrationtest.RegularUser(integrationtest.NewExternalID(prefix))
claims.Email = prefix + "-" + uuid.NewString() + "@migration.test"
id, err := users.EnsureUser(context.Background(), pool, claims)
integrationtest.FailIf(err, t, "ensure user")
return id, claims.Email
}
func googleRewriteClient(t *testing.T, handler http.HandlerFunc) *http.Client {
t.Helper()
srv := httptest.NewServer(handler)
t.Cleanup(srv.Close)
return &http.Client{
Transport: &hostRewriteTransport{
mockBase: srv.URL,
match: func(host string) bool {
return strings.Contains(host, "googleapis.com")
},
},
}
}
func graphRewriteClient(t *testing.T, handler http.HandlerFunc) *http.Client {
t.Helper()
srv := httptest.NewServer(handler)
t.Cleanup(srv.Close)
return &http.Client{
Transport: &hostRewriteTransport{
mockBase: srv.URL,
match: func(host string) bool {
return strings.Contains(host, "graph.microsoft.com")
},
},
}
}
type hostRewriteTransport struct {
mockBase string
match func(host string) bool
}
func (rt *hostRewriteTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if rt.match(req.URL.Host) {
mockURL, err := url.Parse(rt.mockBase)
if err != nil {
return nil, err
}
req.URL.Scheme = mockURL.Scheme
req.URL.Host = mockURL.Host
}
return http.DefaultTransport.RoundTrip(req)
}