diff --git a/test_e2e/badaas_e2e_test.go b/test_e2e/badaas_e2e_test.go index 12cd1c4c..3da722fc 100644 --- a/test_e2e/badaas_e2e_test.go +++ b/test_e2e/badaas_e2e_test.go @@ -77,13 +77,15 @@ func TestMain(_ *testing.M) { func InitializeScenario(ctx *godog.ScenarioContext) { t := &TestContext{} + jar, err := cookiejar.New(nil) if err != nil { panic(err) } + t.httpClient = &http.Client{ Transport: http.DefaultTransport, - Timeout: time.Duration(5 * time.Second), + Timeout: 5 * time.Second, Jar: jar, } @@ -107,5 +109,5 @@ func InitializeScenario(ctx *godog.ScenarioContext) { ctx.Step(`^I request "(.+)"$`, t.requestGet) ctx.Step(`^status code is "(\d+)"$`, t.assertStatusCode) ctx.Step(`^response field "(.+)" is "(.+)"$`, t.assertResponseFieldIsEquals) - ctx.Step(`^I request "(.+)" with method "(.+)" with json$`, t.requestWithJson) + ctx.Step(`^I request "(.+)" with method "(.+)" with json$`, t.requestWithJSON) } diff --git a/test_e2e/go.mod b/test_e2e/go.mod index 228afd5e..3bab21bb 100644 --- a/test_e2e/go.mod +++ b/test_e2e/go.mod @@ -7,6 +7,7 @@ replace github.com/ditrit/badaas => ../ require ( github.com/Masterminds/semver/v3 v3.1.1 github.com/cucumber/godog v0.12.5 + github.com/cucumber/messages-go/v16 v16.0.1 github.com/ditrit/badaas v0.0.0 github.com/elliotchance/pie/v2 v2.7.0 github.com/spf13/pflag v1.0.5 @@ -17,7 +18,6 @@ require ( require ( github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect - github.com/cucumber/messages-go/v16 v16.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/ditrit/verdeter v0.4.0 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect diff --git a/test_e2e/http_support_test.go b/test_e2e/http_support_test.go index a53ab405..dedd9a2e 100644 --- a/test_e2e/http_support_test.go +++ b/test_e2e/http_support_test.go @@ -9,34 +9,35 @@ import ( "strings" "github.com/cucumber/godog" + "github.com/cucumber/messages-go/v16" "github.com/elliotchance/pie/v2" ) -const BaseUrl = "http://localhost:8000" +const BaseURL = "http://localhost:8000" func (t *TestContext) requestGet(url string) error { return t.request(url, http.MethodGet, nil, nil) } -func (t *TestContext) requestWithJson(url, method string, jsonTable *godog.Table) error { +func (t *TestContext) requestWithJSON(url, method string, jsonTable *godog.Table) error { return t.request(url, method, nil, jsonTable) } func (t *TestContext) request(url, method string, query map[string]string, jsonTable *godog.Table) error { var payload io.Reader + var err error + if jsonTable != nil { - payload, err = buildJSONFromTable(jsonTable) - if err != nil { - return err - } + payload = buildJSONFromTable(jsonTable) } method, err = checkMethod(method) if err != nil { return err } - request, err := http.NewRequest(method, BaseUrl+url, payload) + + request, err := http.NewRequest(method, BaseURL+url, payload) if err != nil { return fmt.Errorf("failed to build request ERROR=%s", err.Error()) } @@ -45,13 +46,17 @@ func (t *TestContext) request(url, method string, query map[string]string, jsonT for k, v := range query { q.Add(k, v) } + request.URL.RawQuery = q.Encode() response, err := t.httpClient.Do(request) if err != nil { return fmt.Errorf("failed to run request ERROR=%s", err.Error()) } + t.storeResponseInContext(response) + response.Body.Close() + return nil } @@ -68,6 +73,7 @@ func (t *TestContext) assertStatusCode(expectedStatusCode int) error { if t.statusCode != expectedStatusCode { return fmt.Errorf("expect status code %d but is %d", expectedStatusCode, t.statusCode) } + return nil } @@ -80,6 +86,7 @@ func (t *TestContext) assertResponseFieldIsEquals(field string, expectedValue st if !present { return fmt.Errorf("expected response field %s to be %s but it is not present", field, expectedValue) } + jsonMap = intValue.(map[string]any) } @@ -104,12 +111,14 @@ func assertValue(value any, expectedValue string) bool { if err != nil { panic(err) } + return expectedValueInt == value case float64: expectedValueFloat, err := strconv.ParseFloat(expectedValue, 64) if err != nil { panic(err) } + return expectedValueFloat == value default: panic("unsupported format") @@ -119,60 +128,85 @@ func assertValue(value any, expectedValue string) bool { // build a map from a godog.Table func buildMapFromTable(table *godog.Table) (map[string]any, error) { data := make(map[string]any, 0) - for indexRow, row := range table.Rows { - if indexRow == 0 { - for indexCell, cell := range row.Cells { - if cell.Value != []string{"key", "value", "type"}[indexCell] { - return nil, fmt.Errorf("should have %q as first line of the table", "| key | value | type |") - } - } - } else { - key := row.Cells[0].Value - valueAsString := row.Cells[1].Value - valueType := row.Cells[2].Value - - switch valueType { - case stringValueType: - data[key] = valueAsString - case booleanValueType: - boolean, err := strconv.ParseBool(valueAsString) - if err != nil { - return nil, fmt.Errorf("can't parse %q as boolean for key %q", valueAsString, key) - } - data[key] = boolean - case integerValueType: - integer, err := strconv.ParseInt(valueAsString, 10, 64) - if err != nil { - return nil, fmt.Errorf("can't parse %q as integer for key %q", valueAsString, key) - } - data[key] = integer - case floatValueType: - floatingNumber, err := strconv.ParseFloat(valueAsString, 64) - if err != nil { - return nil, fmt.Errorf("can't parse %q as float for key %q", valueAsString, key) - } - data[key] = floatingNumber - case jsonValueType: - jsonMap := map[string]string{} - err := json.Unmarshal([]byte(valueAsString), &jsonMap) - if err != nil { - return nil, fmt.Errorf("can't parse %q as json for key %q", valueAsString, key) - } - data[key] = jsonMap - case nullValueType: - data[key] = nil - default: - return nil, fmt.Errorf("type %q does not exists, please use %v", valueType, []string{stringValueType, booleanValueType, integerValueType, floatValueType, nullValueType}) - } + err := verifyHeader(table.Rows[0]) + if err != nil { + return nil, err + } + + for _, row := range table.Rows[1:] { + key := row.Cells[0].Value + valueAsString := row.Cells[1].Value + valueType := row.Cells[2].Value + + value, err := getTableValue(key, valueAsString, valueType) + if err != nil { + return nil, err } + + data[key] = value } return data, nil } +// Verifies that the header row of a table has the correct format +func verifyHeader(row *messages.PickleTableRow) error { + for indexCell, cell := range row.Cells { + if cell.Value != []string{"key", "value", "type"}[indexCell] { + return fmt.Errorf("should have %q as first line of the table", "| key | value | type |") + } + } + + return nil +} + +// Returns the value present in a table casted to the correct type +func getTableValue(key, valueAsString, valueType string) (any, error) { + switch valueType { + case stringValueType: + return valueAsString, nil + case booleanValueType: + boolean, err := strconv.ParseBool(valueAsString) + if err != nil { + return nil, fmt.Errorf("can't parse %q as boolean for key %q", valueAsString, key) + } + + return boolean, nil + case integerValueType: + integer, err := strconv.ParseInt(valueAsString, 10, 64) + if err != nil { + return nil, fmt.Errorf("can't parse %q as integer for key %q", valueAsString, key) + } + + return integer, nil + case floatValueType: + floatingNumber, err := strconv.ParseFloat(valueAsString, 64) + if err != nil { + return nil, fmt.Errorf("can't parse %q as float for key %q", valueAsString, key) + } + + return floatingNumber, nil + case jsonValueType: + jsonMap := map[string]string{} + + err := json.Unmarshal([]byte(valueAsString), &jsonMap) + if err != nil { + return nil, fmt.Errorf("can't parse %q as json for key %q", valueAsString, key) + } + + return jsonMap, nil + default: + return nil, fmt.Errorf( + "type %q does not exists, please use %v", + valueType, + []string{stringValueType, booleanValueType, integerValueType, floatValueType}, + ) + } +} + // build a json payload in the form of a reader from a godog.Table -func buildJSONFromTable(table *godog.Table) (io.Reader, error) { +func buildJSONFromTable(table *godog.Table) io.Reader { data, err := buildMapFromTable(table) if err != nil { panic("should not return an error") @@ -182,7 +216,8 @@ func buildJSONFromTable(table *godog.Table) (io.Reader, error) { if err != nil { panic("should not return an error") } - return strings.NewReader(string(bytes)), nil + + return strings.NewReader(string(bytes)) } const ( @@ -208,6 +243,7 @@ func checkMethod(method string) (string, error) { http.MethodTrace, } sanitizedMethod := strings.TrimSpace(strings.ToUpper(method)) + if !pie.Contains( allowedMethods, sanitizedMethod,