package main import ( "me-fit/service" "me-fit/utils" "context" "database/sql" "fmt" "net/http" "net/url" "strings" "testing" "time" "github.com/google/uuid" ) func TestHandleSignIn(t *testing.T) { t.Parallel() t.Run("should signIn and return session cookie", func(t *testing.T) { t.Parallel() ctx, done := context.WithCancel(context.Background()) t.Cleanup(done) db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatalf("Could not open Database data.db: %v", err) } t.Cleanup(func() { db.Close() }) err = utils.RunMigrations(db, "") if err != nil { t.Fatalf("Could not run migrations: %v", err) } pass := service.GetHashPassword("password", []byte("salt")) _, err = db.Exec(` INSERT INTO user (user_uuid, email, email_verified, is_admin, password, salt, created_at) VALUES (?, "mail@mail.de", FALSE, FALSE, ?, ?, datetime())`, uuid.New(), pass, []byte("salt")) if err != nil { t.Fatalf("Error inserting user: %v", err) } go run(ctx, db, func(key string) string { if key == "PORT" { return "8080" } else if key == "SMTP_ENABLED" { return "false" } else if key == "PROMETHEUS_ENABLED" { return "false" } else if key == "BASE_URL" { return "https://localhost:8080" } else if key == "ENVIRONMENT" { return "test" } else { return "" } }) err = waitForReady(ctx, 5*time.Second, "http://localhost:8080") if err != nil { t.Fatalf("Failed to start server: %v", err) } formData := url.Values{ "email": {"mail@mail.de"}, "password": {"password"}, } req, err := http.NewRequestWithContext(ctx, "POST", "http://localhost:8080/api/auth/signin", strings.NewReader(formData.Encode())) if err != nil { t.Fatalf("Error creating request: %v", err) } // Set the content type to application/x-www-form-urlencoded req.Header.Set("Content-Type", "application/x-www-form-urlencoded") client := http.Client{} resp, err := client.Do(req) if err != nil { t.Fatalf("Error making request: %v", err) } if resp.StatusCode != http.StatusOK { t.Fatalf("Expected status code 200, got %d", resp.StatusCode) } }) } // waitForReady calls the specified endpoint until it gets a 200 // response or until the context is cancelled or the timeout is // reached. func waitForReady( ctx context.Context, timeout time.Duration, endpoint string, ) error { client := http.Client{} startTime := time.Now() for { req, err := http.NewRequestWithContext( ctx, http.MethodGet, endpoint, nil, ) if err != nil { return fmt.Errorf("failed to create request: %w", err) } resp, err := client.Do(req) if err != nil { fmt.Printf("Error making request: %s\n", err.Error()) continue } if resp.StatusCode == http.StatusOK { fmt.Println("Endpoint is ready!") resp.Body.Close() return nil } resp.Body.Close() select { case <-ctx.Done(): return ctx.Err() default: if time.Since(startTime) >= timeout { return fmt.Errorf("timeout reached while waiting for endpoint") } // wait a little while between checks time.Sleep(250 * time.Millisecond) } } }