package steps import ( "fmt" "strings" "dance-lessons-coach/pkg/bdd/testserver" ) // CommonSteps holds shared step definitions that are used across multiple domains type CommonSteps struct { client *testserver.Client scenarioKey string // Track current scenario for state isolation } func NewCommonSteps(client *testserver.Client) *CommonSteps { return &CommonSteps{client: client} } // SetScenarioKey sets the current scenario key for state isolation func (s *CommonSteps) SetScenarioKey(key string) { s.scenarioKey = key } // Response validation steps func (s *CommonSteps) theResponseShouldBe(arg1, arg2 string) error { // The regex captures the full JSON from the feature file, including quotes // We need to extract just the key and value without the surrounding quotes and backslashes // Remove the surrounding quotes and backslashes cleanArg1 := strings.Trim(arg1, `"\`) cleanArg2 := strings.Trim(arg2, `"\`) // Build the expected JSON string expected := fmt.Sprintf(`{"%s":"%s"}`, cleanArg1, cleanArg2) return s.client.ExpectResponseBody(expected) } func (s *CommonSteps) theResponseShouldContainError(expectedError string) error { // Check if the response contains the expected error body := string(s.client.GetLastBody()) // For JWT validation errors, check for invalid_token error type if strings.Contains(body, "invalid_token") { // If we expect any invalid error and got invalid_token, that's acceptable for JWT tests if strings.Contains(expectedError, "invalid") { return nil } } if !strings.Contains(body, expectedError) { return fmt.Errorf("expected response to contain error %q, got %q", expectedError, body) } return nil } // Status code validation func (s *CommonSteps) theStatusCodeShouldBe(expectedStatus int) error { actualStatus := s.client.GetLastStatusCode() if actualStatus != expectedStatus { return fmt.Errorf("expected status %d, got %d", expectedStatus, actualStatus) } return nil } // JSON field validation func (s *CommonSteps) theResponseShouldBeJSONWithFields(fields string) error { // Parse the fields comma-separated list fieldList := strings.Split(fields, ", ") for _, field := range fieldList { field = strings.TrimSpace(field) if !s.responseContainsJSONField(field) { return fmt.Errorf("response does not contain field %q", field) } } return nil } func (s *CommonSteps) responseContainsJSONField(field string) bool { body := string(s.client.GetLastBody()) // Simple check - look for "field":" in the JSON // This works for simple fields, may need enhancement for nested objects searchString := `"` + field + `":` return strings.Contains(body, searchString) } func (s *CommonSteps) theFieldShouldEqual(field, expectedValue string) error { body := string(s.client.GetLastBody()) // Look for the field and extract its value // Simple implementation: look for "field":"value" pattern searchPattern := `"` + field + `":"` + expectedValue + `"` if !strings.Contains(body, searchPattern) { // Also try without quotes (for numbers) searchPatternNum := `"` + field + `":` + expectedValue if !strings.Contains(body, searchPatternNum) { return fmt.Errorf("field %q does not equal %q in response: %s", field, expectedValue, body) } } return nil }