package storage import ( "context" "encoding/json" "fmt" "os" "strings" "testing" "time" ) func TestDoctorExternalBookingCannotLeakOrReturn(t *testing.T) { dsn := os.Getenv("DANA_AUTONOMY_TEST_DSN") if dsn == "" { t.Skip("requires disposable autonomy database") } ctx := context.Background() s, err := New(ctx, dsn) if err != nil { t.Fatal(err) } defer s.Close() if err = s.Migrate(ctx); err != nil { t.Fatal(err) } slug := fmt.Sprintf("legacy-external-%d", time.Now().UnixNano()) var id int64 if err = s.Pool().QueryRow(ctx, `INSERT INTO doctors(slug,last_name,first_name,booking_provider,medflex_user) VALUES($1,'Тест','Врач','medflex','https://booking.medflex.ru/legacy') RETURNING id`, slug).Scan(&id); err != nil { t.Fatal(err) } d, err := s.DoctorBySlug(ctx, slug) if err != nil { t.Fatal(err) } public, _ := json.Marshal(d) if d.Booking.Provider != "none" || strings.Contains(string(public), "medflex") { t.Fatalf("legacy link leaked: %s", public) } rows, err := s.AdminDoctors(ctx, slug) if err != nil { t.Fatal(err) } if len(rows) != 0 { t.Fatal("slug must not match the name filter") } rows, err = s.AdminDoctors(ctx, "") if err != nil { t.Fatal(err) } found := false for _, row := range rows { if row.ID == id { found = true admin, _ := json.Marshal(row) if row.Booking != "none" || strings.Contains(string(admin), "medflex") { t.Fatalf("legacy option leaked in admin: %s", admin) } } } if !found { t.Fatal("doctor missing from admin") } if err = s.AdminUpdateDoctor(ctx, id, DoctorUpdate{Slug: slug, LastName: "Тест", FirstName: "Врач", Booking: "none", Published: true}); err != nil { t.Fatal(err) } var link string if err = s.Pool().QueryRow(ctx, `SELECT medflex_user FROM doctors WHERE id=$1`, id).Scan(&link); err != nil { t.Fatal(err) } if link != "" { t.Fatal("editing doctor restored an external link") } }