package importer import ( "bytes" "context" "os" "testing" "munin/internal/export" "munin/internal/store" ) // TestRundreisePostgres prüft Export und Import gegen PostgreSQL: Ein Projekt // wird als ZIP exportiert (derselbe Weg wie „als ZIP herunterladen“) und in // einen zweiten, leeren Workspace importiert. Danach müssen dieselben Einträge // mit demselben Inhalt dastehen. // // Läuft nur mit MUNIN_TEST_PG (siehe internal/store/postgres_test.go). Export // und Import lesen und schreiben ausschließlich über den Store, sind also // nicht an SQLite gebunden — dieser Test belegt das. func TestRundreisePostgres(t *testing.T) { url := os.Getenv("MUNIN_TEST_PG") if url == "" { t.Skip("MUNIN_TEST_PG ist nicht gesetzt — PostgreSQL-Test übersprungen") } ctx := context.Background() sp, err := store.NewPostgres(ctx, url) if err != nil { t.Fatal(err) } t.Cleanup(func() { sp.Close() }) // Zwei frische Workspace-Schemas, nach dem Test wieder weg. oeffne := func() *store.Store { id := store.NewID() s, err := sp.OpenWorkspace(id) if err != nil { t.Fatal(err) } t.Cleanup(func() { s.Close() sp.DeleteWorkspace(id) }) return s } quelle, ziel := oeffne(), oeffne() // Quelle: ein Projekt mit Schlagworten, Verweis, Umlauten und einem // kuratierten Eintrag. projekt, err := quelle.CreateProject(ctx, "ws", "plattform", "Plattform", "") if err != nil { t.Fatal(err) } for _, e := range []store.EntryWrite{ {Slug: "deployment", Title: "Deployment-Prozess", Content: "Über die Pipeline, siehe [[vpn]].", Tags: []string{"ops"}, Source: store.SourceHuman, Curated: true}, {Slug: "vpn", Title: "VPN-Zugang", Content: "Zugang über vpn.intern — Änderungen bei der IT.", Tags: []string{"ops", "zugang"}, Source: store.SourceAgent}, } { e.ProjectID = projekt.ID if _, err := quelle.PutEntry(ctx, e); err != nil { t.Fatal(err) } } // Export als ZIP und wieder auspacken — wie Download und Upload. dateien, err := export.ProjektDateien(ctx, quelle, projekt) if err != nil { t.Fatal(err) } var zip bytes.Buffer if err := export.SchreibeZIP(&zip, dateien); err != nil { t.Fatal(err) } gelesen, err := LeseZip(zip.Bytes()) if err != nil { t.Fatal(err) } zielProjekt, err := ziel.CreateProject(ctx, "ws", "plattform", "Plattform", "") if err != nil { t.Fatal(err) } bericht, err := Importiere(ctx, ziel, zielProjekt.ID, gelesen, Optionen{Modus: ModusUeberspringen}) if err != nil { t.Fatal(err) } if bericht.Neu != 2 || bericht.Fehler != 0 { t.Fatalf("Import: %d neu, %d Fehler, erwartet 2 neu und 0 Fehler: %+v", bericht.Neu, bericht.Fehler, bericht.Zeilen) } for _, slug := range []string{"deployment", "vpn"} { vorher, err := quelle.EntryBySlug(ctx, projekt.ID, slug) if err != nil { t.Fatal(err) } nachher, err := ziel.EntryBySlug(ctx, zielProjekt.ID, slug) if err != nil { t.Fatalf("%s fehlt nach dem Import: %v", slug, err) } if nachher.Title != vorher.Title || nachher.Content != vorher.Content || nachher.Curated != vorher.Curated || len(nachher.Tags) != len(vorher.Tags) { t.Errorf("%s unterscheidet sich:\nvorher: %+v\nnachher: %+v", slug, vorher, nachher) } } }