package web_test import ( "context" "encoding/json" "net/http" "net/url" "strings" "testing" ) func fullAntragForm() url.Values { return url.Values{ "titel": {"Angebotstexte generieren"}, "beschreibung": {"KI schreibt Angebotstexte"}, "ergebnis": {"Fertiger Text zur Freigabe"}, "haeufigkeit": {"gelegentlich"}, "b1": {"ja"}, "b2": {"nein"}, "b3": {"nein"}, "b4": {"nein"}, "b5": {"nein"}, "b6": {"nein"}, "b7": {"nein"}, "c1": {"nein"}, "c2": {"nein"}, "c2_folge": {"keine"}, "c3": {"nein"}, "c3_art": {"keine"}, "c4": {"nein"}, "c5": {"ja"}, "d_werkzeug_freitext": {"ChatGPT"}, "d_zugang": {"firma"}, "d_geraet": {"firma"}, } } func TestAntragNewFormRendersFragebogen(t *testing.T) { s, _, cookie := newAuthedTestServer(t) resp := getWithCookie(t, s, cookie, "/antraege/neu") if resp.Code != http.StatusOK { t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String()) } body := resp.Body.String() for _, want := range []string{`name="titel"`, `name="b1"`, `name="c2_folge"`, `name="d_zugang"`} { if !strings.Contains(body, want) { t.Errorf("expected %q in the Fragebogen, got: %s", want, body) } } } func TestAntragCreateThenDetailShowsAnswers(t *testing.T) { s, fs, cookie := newAuthedTestServer(t) resp := postForm(t, s, cookie, "/antraege", fullAntragForm()) if resp.Code != http.StatusSeeOther { t.Fatalf("status = %d, want 303, body: %s", resp.Code, resp.Body.String()) } loc := resp.Header().Get("Location") if !strings.HasPrefix(loc, "/antraege/") { t.Fatalf("Location = %q, want a redirect to the new antrag", loc) } var antragID string for id := range fs.antraege { antragID = id } antrag, err := fs.GetAntrag(context.Background(), antragID) if err != nil { t.Fatalf("GetAntrag: %v", err) } if antrag.Status != "eingereicht" { t.Fatalf("Status = %q, want eingereicht", antrag.Status) } var antworten map[string]any if err := json.Unmarshal(antrag.Antworten, &antworten); err != nil { t.Fatalf("Antworten unmarshal: %v", err) } if antworten["b1"] != "ja" { t.Errorf("b1 = %v, want ja", antworten["b1"]) } if antworten["c5"] != true { t.Errorf("c5 = %v, want true", antworten["c5"]) } detailResp := getWithCookie(t, s, cookie, loc) if detailResp.Code != http.StatusOK { t.Fatalf("detail status = %d, body: %s", detailResp.Code, detailResp.Body.String()) } if !strings.Contains(detailResp.Body.String(), "Angebotstexte generieren") { t.Errorf("expected the antrag title on the detail page, got: %s", detailResp.Body.String()) } } func TestAntragCreateRejectsMissingFields(t *testing.T) { s, _, cookie := newAuthedTestServer(t) resp := postForm(t, s, cookie, "/antraege", url.Values{"titel": {"Nur Titel"}}) if resp.Code != http.StatusBadRequest { t.Fatalf("status = %d, want 400 for missing required fields", resp.Code) } } func TestAntragListShowsOnlyOwnAntraege(t *testing.T) { fs := newFakeStore() s := newServer(t, fs) cookieA := seedAccount(t, fs, "Mandant A", "a@example.com") cookieB := seedAccount(t, fs, "Mandant B", "b@example.com") if resp := postForm(t, s, cookieA, "/antraege", fullAntragForm()); resp.Code != http.StatusSeeOther { t.Fatalf("create (A) status = %d, body: %s", resp.Code, resp.Body.String()) } listA := getWithCookie(t, s, cookieA, "/antraege") if !strings.Contains(listA.Body.String(), "Angebotstexte generieren") { t.Errorf("expected Mandant A to see their own antrag, got: %s", listA.Body.String()) } listB := getWithCookie(t, s, cookieB, "/antraege") if strings.Contains(listB.Body.String(), "Angebotstexte generieren") { t.Errorf("expected Mandant B to see no antrag, got: %s", listB.Body.String()) } } func TestAntragDetailRejectsForeignUser(t *testing.T) { fs := newFakeStore() s := newServer(t, fs) cookieA := seedAccount(t, fs, "Mandant A", "a@example.com") cookieB := seedAccount(t, fs, "Mandant B", "b@example.com") createResp := postForm(t, s, cookieA, "/antraege", fullAntragForm()) antragURL := createResp.Header().Get("Location") resp := getWithCookie(t, s, cookieB, antragURL) if resp.Code != http.StatusNotFound { t.Fatalf("status = %d, want 404 for a foreign user's antrag", resp.Code) } } func TestBetreiberRedirectedAwayFromAntragPages(t *testing.T) { fs := newFakeStore() s := newServer(t, fs) betreiberCookie := seedAccountWithRole(t, fs, "Deklarix Betreiber", "betreiber@example.com", "betreiber") for _, path := range []string{"/antraege", "/antraege/neu"} { resp := getWithCookie(t, s, betreiberCookie, path) if resp.Code != http.StatusSeeOther { t.Errorf("GET %s status = %d, want 303 redirect for a betreiber", path, resp.Code) } } }