package web_test import ( "net/http" "net/url" "strings" "testing" "github.com/netcell-it/deklarix/internal/rules" ) func TestAdminRoutesRejectNonAdminWith404(t *testing.T) { s, _, cookie := newAuthedTestServer(t, fakeExtractor{}) for _, path := range []string{"/admin", "/admin/accounts", "/admin/audit-log"} { resp := getWithCookie(t, s, cookie, path) if resp.Code != http.StatusNotFound { t.Errorf("GET %s status = %d, want 404 for a non-admin user", path, resp.Code) } } } func TestAdminRoutesRedirectToLoginWithoutSession(t *testing.T) { s, _, _ := newAuthedTestServer(t, fakeExtractor{}) resp := getWithCookie(t, s, nil, "/admin") if resp.Code != http.StatusSeeOther { t.Fatalf("status = %d, want 303 redirect to /login", resp.Code) } } func TestAdminDashboardAccessibleForAdmin(t *testing.T) { fs := newFakeStore() s := newServer(t, fakeExtractor{}, fs) adminCookie := seedAccountWithRole(t, fs, "Deklarix Admin", "admin@example.com", "admin") resp := getWithCookie(t, s, adminCookie, "/admin") if resp.Code != http.StatusOK { t.Fatalf("status = %d, want 200, body: %s", resp.Code, resp.Body.String()) } } func TestAdminAccountListShowsAllAccountsAcrossTenants(t *testing.T) { fs := newFakeStore() s := newServer(t, fakeExtractor{}, fs) adminCookie := seedAccountWithRole(t, fs, "Deklarix Admin", "admin@example.com", "admin") seedAccount(t, fs, "Mandant A", "a@example.com") seedAccount(t, fs, "Mandant B", "b@example.com") resp := getWithCookie(t, s, adminCookie, "/admin/accounts") if resp.Code != http.StatusOK { t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String()) } body := resp.Body.String() for _, want := range []string{"Mandant A", "Mandant B", "Deklarix Admin"} { if !strings.Contains(body, want) { t.Errorf("expected %q in the admin account list, got: %s", want, body) } } } func TestAdminAccountDetailShowsUsersAndVerifyToggleOnlyForKanzlei(t *testing.T) { fs := newFakeStore() s := newServer(t, fakeExtractor{}, fs) adminCookie := seedAccountWithRole(t, fs, "Deklarix Admin", "admin@example.com", "admin") creatorCookie := seedAccount(t, fs, "Nur Creator", "creator@example.com") _ = creatorCookie var creatorAccID string for id, acc := range fs.accounts { if acc.Name == "Nur Creator" { creatorAccID = id } } kanzleiCookie := seedAccountWithRole(t, fs, "Kanzlei Musterfrau", "kanzlei@example.com", "kanzlei") _ = kanzleiCookie var kanzleiAccID string for id, acc := range fs.accounts { if acc.Name == "Kanzlei Musterfrau" { kanzleiAccID = id } } creatorResp := getWithCookie(t, s, adminCookie, "/admin/accounts/"+creatorAccID) if creatorResp.Code != http.StatusOK { t.Fatalf("status = %d", creatorResp.Code) } if strings.Contains(creatorResp.Body.String(), "verifizieren") { t.Errorf("expected no verify action for a non-kanzlei account, got: %s", creatorResp.Body.String()) } kanzleiResp := getWithCookie(t, s, adminCookie, "/admin/accounts/"+kanzleiAccID) if kanzleiResp.Code != http.StatusOK { t.Fatalf("status = %d", kanzleiResp.Code) } if !strings.Contains(kanzleiResp.Body.String(), "kanzlei@example.com") { t.Errorf("expected the kanzlei user's email on the account detail page, got: %s", kanzleiResp.Body.String()) } if !strings.Contains(kanzleiResp.Body.String(), "/admin/accounts/"+kanzleiAccID+"/verifizieren") { t.Errorf("expected a verify action for a kanzlei account, got: %s", kanzleiResp.Body.String()) } } func TestAdminVerifyAddsAccountToPublicDirectoryAndAuditLog(t *testing.T) { fs := newFakeStore() s := newServer(t, fakeExtractor{}, fs) adminCookie := seedAccountWithRole(t, fs, "Deklarix Admin", "admin@example.com", "admin") seedAccountWithRole(t, fs, "Kanzlei Musterfrau", "kanzlei@example.com", "kanzlei") var kanzleiAccID string for id, acc := range fs.accounts { if acc.Name == "Kanzlei Musterfrau" { kanzleiAccID = id } } // Vor der Freigabe taucht die Kanzlei nicht im oeffentlichen // Verzeichnis auf. before := getWithCookie(t, s, nil, "/kanzleien") if strings.Contains(before.Body.String(), "Kanzlei Musterfrau") { t.Fatalf("kanzlei should not be public before verification, got: %s", before.Body.String()) } verifyResp := postForm(t, s, adminCookie, "/admin/accounts/"+kanzleiAccID+"/verifizieren", url.Values{"verified": {"true"}}) if verifyResp.Code != http.StatusSeeOther { t.Fatalf("verify status = %d, want 303, body: %s", verifyResp.Code, verifyResp.Body.String()) } after := getWithCookie(t, s, nil, "/kanzleien") if !strings.Contains(after.Body.String(), "Kanzlei Musterfrau") { t.Fatalf("expected the kanzlei to be listed publicly after verification, got: %s", after.Body.String()) } if len(fs.auditLog) != 1 { t.Fatalf("expected exactly one audit entry, got %d", len(fs.auditLog)) } if fs.auditLog[0].Action != "account.verified" || fs.auditLog[0].TargetID != kanzleiAccID { t.Errorf("unexpected audit entry: %+v", fs.auditLog[0]) } auditPageResp := getWithCookie(t, s, adminCookie, "/admin/audit-log") if !strings.Contains(auditPageResp.Body.String(), "account.verified") { t.Errorf("expected the audit entry on the audit log page, got: %s", auditPageResp.Body.String()) } } func TestAdminVerifyRejectsNonAdmin(t *testing.T) { fs := newFakeStore() s := newServer(t, fakeExtractor{}, fs) tenantCookie := seedAccountWithRole(t, fs, "Kanzlei Musterfrau", "kanzlei@example.com", "kanzlei") var kanzleiAccID string for id, acc := range fs.accounts { if acc.Name == "Kanzlei Musterfrau" { kanzleiAccID = id } } resp := postForm(t, s, tenantCookie, "/admin/accounts/"+kanzleiAccID+"/verifizieren", url.Values{"verified": {"true"}}) if resp.Code != http.StatusNotFound { t.Fatalf("status = %d, want 404 for a non-admin actor", resp.Code) } if fs.accounts[kanzleiAccID].Verified { t.Fatal("account should not have been verified by a non-admin request") } } func TestPublicKanzleiDirectoryRequiresNoLogin(t *testing.T) { s, _, _ := newAuthedTestServer(t, fakeExtractor{facts: rules.Facts{Platform: "instagram"}}) req := getWithCookie(t, s, nil, "/kanzleien") if req.Code != http.StatusOK { t.Fatalf("status = %d, want 200 without any session", req.Code) } }