package store_test import ( "context" "errors" "testing" "github.com/netcell-it/deklarix/internal/store" ) func TestGenehmigerRolleCRUDAndMitgliedschaft(t *testing.T) { s := openTestStore(t) ctx := context.Background() accID := testAccountID(t, s) g, err := s.CreateGenehmigerRolle(ctx, accID, "Datenschutzbeauftragter", "") if err != nil { t.Fatalf("CreateGenehmigerRolle: %v", err) } if g.AccountID != accID || g.Name != "Datenschutzbeauftragter" { t.Fatalf("GenehmigerRolle = %+v, unerwartete Werte", g) } got, err := s.GetGenehmigerRolle(ctx, g.ID) if err != nil || got.Name != "Datenschutzbeauftragter" { t.Fatalf("GetGenehmigerRolle = %+v, err=%v", got, err) } liste, err := s.ListGenehmigerRollenForAccount(ctx, accID) if err != nil || len(liste) != 1 { t.Fatalf("ListGenehmigerRollenForAccount = %+v, err=%v", liste, err) } user := testUserID(t, s, accID) if err := s.AddNutzerGenehmigerRolle(ctx, user, g.ID); err != nil { t.Fatalf("AddNutzerGenehmigerRolle: %v", err) } // Erneutes Hinzufügen derselben Zuordnung ist ein No-op (ON CONFLICT), // kein Fehler. if err := s.AddNutzerGenehmigerRolle(ctx, user, g.ID); err != nil { t.Fatalf("AddNutzerGenehmigerRolle (erneut): %v", err) } rollenDesNutzers, err := s.ListGenehmigerRollenForUser(ctx, user) if err != nil || len(rollenDesNutzers) != 1 || rollenDesNutzers[0].ID != g.ID { t.Fatalf("ListGenehmigerRollenForUser = %+v, err=%v", rollenDesNutzers, err) } mitglieder, err := s.ListNutzerForGenehmigerRolle(ctx, g.ID) if err != nil || len(mitglieder) != 1 || mitglieder[0].UserID != user { t.Fatalf("ListNutzerForGenehmigerRolle = %+v, err=%v", mitglieder, err) } if err := s.RemoveNutzerGenehmigerRolle(ctx, user, g.ID); err != nil { t.Fatalf("RemoveNutzerGenehmigerRolle: %v", err) } rollenNachEntfernen, err := s.ListGenehmigerRollenForUser(ctx, user) if err != nil || len(rollenNachEntfernen) != 0 { t.Fatalf("ListGenehmigerRollenForUser nach Entfernen = %+v, err=%v", rollenNachEntfernen, err) } if err := s.DeleteGenehmigerRolle(ctx, g.ID); err != nil { t.Fatalf("DeleteGenehmigerRolle: %v", err) } if _, err := s.GetGenehmigerRolle(ctx, g.ID); !errors.Is(err, store.ErrNotFound) { t.Fatalf("err nach Delete = %v, want ErrNotFound", err) } } func TestFreigabeRegelCRUD(t *testing.T) { s := openTestStore(t) ctx := context.Background() accID := testAccountID(t, s) g, err := s.CreateGenehmigerRolle(ctx, accID, "Geschaeftsfuehrung", "") if err != nil { t.Fatalf("CreateGenehmigerRolle: %v", err) } regel, err := s.CreateFreigabeRegel(ctx, accID, "einstufung", "hochrisiko", g.ID) if err != nil { t.Fatalf("CreateFreigabeRegel: %v", err) } if regel.BedingungTyp != "einstufung" || regel.BedingungWert != "hochrisiko" { t.Fatalf("FreigabeRegel = %+v, unerwartete Werte", regel) } liste, err := s.ListFreigabeRegelnForAccount(ctx, accID) if err != nil || len(liste) != 1 { t.Fatalf("ListFreigabeRegelnForAccount = %+v, err=%v", liste, err) } got, err := s.GetFreigabeRegel(ctx, regel.ID) if err != nil || got.ID != regel.ID { t.Fatalf("GetFreigabeRegel = %+v, err=%v", got, err) } if err := s.DeleteFreigabeRegel(ctx, regel.ID); err != nil { t.Fatalf("DeleteFreigabeRegel: %v", err) } if _, err := s.GetFreigabeRegel(ctx, regel.ID); !errors.Is(err, store.ErrNotFound) { t.Fatalf("err nach Delete = %v, want ErrNotFound", err) } } func TestFreigabeschrittLifecycleUndKaskade(t *testing.T) { s := openTestStore(t) ctx := context.Background() accID := testAccountID(t, s) user := testUserID(t, s, accID) antrag, err := s.CreateAntrag(ctx, accID, user, nil, "Test-Antrag für Freigabeschritte") if err != nil { t.Fatalf("CreateAntrag: %v", err) } antragID := antrag.ID dsb, _ := s.CreateGenehmigerRolle(ctx, accID, "Datenschutzbeauftragter", "") gf, _ := s.CreateGenehmigerRolle(ctx, accID, "Geschaeftsfuehrung", "") schrittDSB, err := s.CreateFreigabeschritt(ctx, antragID, dsb.ID) if err != nil { t.Fatalf("CreateFreigabeschritt: %v", err) } if schrittDSB.Status != "ausstehend" { t.Fatalf("Status = %q, want ausstehend", schrittDSB.Status) } schrittGF, err := s.CreateFreigabeschritt(ctx, antragID, gf.ID) if err != nil { t.Fatalf("CreateFreigabeschritt: %v", err) } alle, err := s.ListFreigabeschritteForAntrag(ctx, antragID) if err != nil || len(alle) != 2 { t.Fatalf("ListFreigabeschritteForAntrag = %+v, err=%v", alle, err) } ausstehend, err := s.ListAusstehendeFreigabeschritteForUser(ctx, user) if err != nil { t.Fatalf("ListAusstehendeFreigabeschritteForUser: %v", err) } if len(ausstehend) != 0 { t.Fatalf("erwartet 0 ausstehende Freigaben ohne Genehmiger-Rollen-Zuordnung, got %d", len(ausstehend)) } if err := s.AddNutzerGenehmigerRolle(ctx, user, dsb.ID); err != nil { t.Fatalf("AddNutzerGenehmigerRolle: %v", err) } ausstehend, err = s.ListAusstehendeFreigabeschritteForUser(ctx, user) if err != nil || len(ausstehend) != 1 || ausstehend[0].ID != schrittDSB.ID { t.Fatalf("ListAusstehendeFreigabeschritteForUser = %+v, err=%v", ausstehend, err) } entschieden, err := s.EntscheideFreigabeschritt(ctx, schrittDSB.ID, "abgelehnt", user, "nicht ausreichend") if err != nil { t.Fatalf("EntscheideFreigabeschritt: %v", err) } if entschieden.Status != "abgelehnt" || entschieden.EntschiedenVon == nil || *entschieden.EntschiedenVon != user { t.Fatalf("Freigabeschritt nach Entscheidung = %+v, unerwartete Werte", entschieden) } // Ein bereits entschiedener Schritt kann nicht erneut entschieden werden. if _, err := s.EntscheideFreigabeschritt(ctx, schrittDSB.ID, "genehmigt", user, ""); !errors.Is(err, store.ErrNotFound) { t.Fatalf("erneute Entscheidung err = %v, want ErrNotFound", err) } if err := s.KaskadiereAblehnung(ctx, antragID, schrittDSB.ID); err != nil { t.Fatalf("KaskadiereAblehnung: %v", err) } nachKaskade, err := s.GetFreigabeschritt(ctx, schrittGF.ID) if err != nil { t.Fatalf("GetFreigabeschritt: %v", err) } if nachKaskade.Status != "abgelehnt" { t.Fatalf("Status nach Kaskade = %q, want abgelehnt", nachKaskade.Status) } }