package store_test import ( "context" "errors" "testing" "github.com/netcell-it/deklarix/internal/store" ) func testBewertungInput(antragID string) store.BewertungInput { return store.BewertungInput{ AntragID: antragID, Datenklasse: "personenbezogen", DatenklasseHerleitung: "ausgelöst durch b1", Einstufung: "minimal", EinstufungHerleitung: "Auffangregel", Verboten: false, Anforderungen: []store.BewertungAnforderung{ {ID: "avv_erforderlich", Beschreibung: "AVV nötig", Herleitung: "aus Datenklasse personenbezogen"}, }, ZulaessigeWerkzeuge: []string{"werkzeug-a"}, AusgeschlosseneWerkzeuge: []store.BewertungAusschluss{ {WerkzeugID: "werkzeug-b", NichtErfuellt: []string{"avv_erforderlich"}}, }, RegelwerkVersion: "dk1.ei1.an1", KatalogVersion: "3-1735300000", } } func TestBewertungCreateAndGetLatest(t *testing.T) { s := openTestStore(t) ctx := context.Background() accID := testAccountID(t, s) userID := testUserID(t, s, accID) antrag, err := s.CreateAntrag(ctx, accID, userID, nil, "Testantrag") if err != nil { t.Fatalf("CreateAntrag: %v", err) } b, err := s.CreateBewertung(ctx, testBewertungInput(antrag.ID)) if err != nil { t.Fatalf("CreateBewertung: %v", err) } if b.Datenklasse != "personenbezogen" || len(b.Anforderungen) != 1 { t.Fatalf("CreateBewertung = %+v, unerwartete Werte", b) } if b.Anforderungen[0].ID != "avv_erforderlich" { t.Fatalf("Anforderungen[0] = %+v, unerwartet", b.Anforderungen[0]) } if len(b.AusgeschlosseneWerkzeuge) != 1 || b.AusgeschlosseneWerkzeuge[0].WerkzeugID != "werkzeug-b" { t.Fatalf("AusgeschlosseneWerkzeuge = %+v, unerwartet", b.AusgeschlosseneWerkzeuge) } got, err := s.GetLatestBewertungForAntrag(ctx, antrag.ID) if err != nil { t.Fatalf("GetLatestBewertungForAntrag: %v", err) } if got.ID != b.ID { t.Fatalf("GetLatestBewertungForAntrag returned a different row than CreateBewertung") } } func TestGetLatestBewertungForAntragNotFound(t *testing.T) { s := openTestStore(t) ctx := context.Background() accID := testAccountID(t, s) userID := testUserID(t, s, accID) antrag, err := s.CreateAntrag(ctx, accID, userID, nil, "Ohne Bewertung") if err != nil { t.Fatalf("CreateAntrag: %v", err) } _, err = s.GetLatestBewertungForAntrag(ctx, antrag.ID) if !errors.Is(err, store.ErrNotFound) { t.Fatalf("err = %v, want store.ErrNotFound", err) } } func TestBewertungReturnsNewestWhenMultiple(t *testing.T) { s := openTestStore(t) ctx := context.Background() accID := testAccountID(t, s) userID := testUserID(t, s, accID) antrag, err := s.CreateAntrag(ctx, accID, userID, nil, "Mehrfach bewertet") if err != nil { t.Fatalf("CreateAntrag: %v", err) } if _, err := s.CreateBewertung(ctx, testBewertungInput(antrag.ID)); err != nil { t.Fatalf("CreateBewertung (1): %v", err) } second := testBewertungInput(antrag.ID) second.Datenklasse = "besondere_kategorie" newest, err := s.CreateBewertung(ctx, second) if err != nil { t.Fatalf("CreateBewertung (2): %v", err) } got, err := s.GetLatestBewertungForAntrag(ctx, antrag.ID) if err != nil { t.Fatalf("GetLatestBewertungForAntrag: %v", err) } if got.ID != newest.ID || got.Datenklasse != "besondere_kategorie" { t.Fatalf("expected the newest bewertung, got %+v", got) } } func TestBewertungIsAppendOnly(t *testing.T) { s := openTestStore(t) ctx := context.Background() accID := testAccountID(t, s) userID := testUserID(t, s, accID) antrag, err := s.CreateAntrag(ctx, accID, userID, nil, "Append-only Test") if err != nil { t.Fatalf("CreateAntrag: %v", err) } b, err := s.CreateBewertung(ctx, testBewertungInput(antrag.ID)) if err != nil { t.Fatalf("CreateBewertung: %v", err) } _, err = s.Pool.Exec(ctx, `UPDATE bewertung SET datenklasse = 'geaendert' WHERE id = $1`, b.ID) if err == nil { t.Fatal("expected UPDATE on bewertung to be rejected by the append-only trigger") } _, err = s.Pool.Exec(ctx, `DELETE FROM bewertung WHERE id = $1`, b.ID) if err == nil { t.Fatal("expected DELETE on bewertung to be rejected by the append-only trigger") } }