ultisuite-backend/internal/migration/microsoft_app_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

142 lines
3.7 KiB
Go

package migration
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestNormalizeAuthModeMicrosoftApp(t *testing.T) {
if got := NormalizeAuthMode("microsoft", "microsoft_app"); got != AuthModeMicrosoftApp {
t.Fatalf("got %q", got)
}
if got := NormalizeAuthMode("google", "microsoft_app"); got != AuthModeOAuth {
t.Fatalf("google ignores ms app: got %q", got)
}
}
func TestUsesUserOAuth(t *testing.T) {
if UsesUserOAuth("google", AuthModeGoogleDWD) {
t.Fatal("google dwd should skip user oauth")
}
if UsesUserOAuth("microsoft", AuthModeMicrosoftApp) {
t.Fatal("microsoft app should skip user oauth")
}
if !UsesUserOAuth("microsoft", "oauth") {
t.Fatal("microsoft oauth needs user oauth")
}
}
func TestGraphUserBase(t *testing.T) {
if got := graphUserBase(""); got != "/v1.0/me" {
t.Fatalf("empty upn: %q", got)
}
if got := graphUserBase("alice@contoso.com"); got != "/v1.0/users/alice@contoso.com" {
t.Fatalf("encoded upn: %q", got)
}
}
func TestNewMicrosoftAppEmpty(t *testing.T) {
app, err := NewMicrosoftApp(MicrosoftAppConfig{})
if err != nil || app != nil {
t.Fatalf("empty config: app=%v err=%v", app, err)
}
}
func TestMicrosoftAppAccessToken(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
t.Fatalf("method %s", r.Method)
}
if err := r.ParseForm(); err != nil {
t.Fatal(err)
}
if r.Form.Get("grant_type") != "client_credentials" {
t.Fatalf("grant_type=%q", r.Form.Get("grant_type"))
}
auth := r.Header.Get("Authorization")
if !strings.HasPrefix(auth, "Basic ") {
t.Fatalf("expected basic auth, got %q", auth)
}
if !strings.Contains(r.Form.Get("scope"), "graph.microsoft.com/.default") {
t.Fatalf("scope=%q", r.Form.Get("scope"))
}
w.Header().Set("Content-Type", "application/json")
_, _ = io.WriteString(w, `{"access_token":"app-token","token_type":"Bearer","expires_in":3600}`)
}))
t.Cleanup(srv.Close)
app, err := NewMicrosoftApp(MicrosoftAppConfig{
ClientID: "client-id",
ClientSecret: "client-secret",
TokenURL: srv.URL,
})
if err != nil {
t.Fatal(err)
}
token, err := app.AccessToken(t.Context(), "tenant-123")
if err != nil {
t.Fatal(err)
}
if token != "app-token" {
t.Fatalf("token=%q", token)
}
}
func TestMicrosoftAppRequiresTenant(t *testing.T) {
app, err := NewMicrosoftApp(MicrosoftAppConfig{
ClientID: "client-id",
ClientSecret: "client-secret",
TokenURL: "http://example.invalid/token",
})
if err != nil {
t.Fatal(err)
}
if _, err := app.AccessToken(t.Context(), ""); err == nil {
t.Fatal("expected tenant required error")
}
}
func TestWorkerAuthPathSelection(t *testing.T) {
cases := []struct {
provider string
authMode string
userOAuth bool
}{
{"google", AuthModeOAuth, true},
{"google", AuthModeGoogleDWD, false},
{"microsoft", AuthModeOAuth, true},
{"microsoft", AuthModeMicrosoftApp, false},
{"microsoft", "google_dwd", true},
}
for _, tc := range cases {
got := UsesUserOAuth(tc.provider, tc.authMode)
if got != tc.userOAuth {
t.Fatalf("%s/%s: got userOAuth=%v want %v", tc.provider, tc.authMode, got, tc.userOAuth)
}
}
}
func TestMicrosoftAppTokenError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
_ = json.NewEncoder(w).Encode(map[string]string{"error": "invalid_client"})
}))
t.Cleanup(srv.Close)
app, err := NewMicrosoftApp(MicrosoftAppConfig{
ClientID: "bad",
ClientSecret: "bad",
TokenURL: srv.URL,
})
if err != nil {
t.Fatal(err)
}
if _, err := app.AccessToken(t.Context(), "tenant"); err == nil {
t.Fatal("expected token error")
}
}