diff --git a/go.mod b/go.mod index 76d5d9c..861fd05 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/expr-lang/expr v1.15.6 github.com/flopp/go-findfont v0.1.0 github.com/ghodss/yaml v1.0.0 + github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 github.com/h2non/gock v1.2.0 github.com/invopop/jsonschema v0.7.0 @@ -42,7 +43,6 @@ require ( github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/gorilla/mux v1.8.1 // indirect github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-memdb v1.3.2 // indirect diff --git a/pkg/mock/data/api.yaml b/pkg/mock/data/api.yaml index 1241dd1..011b3a5 100644 --- a/pkg/mock/data/api.yaml +++ b/pkg/mock/data/api.yaml @@ -27,6 +27,7 @@ items: path: /v1/teams/{team}/repos method: GET response: + statusCode: 200 body: | { "status": 0, @@ -40,12 +41,16 @@ items: request: path: /v1/repos/{repo}/prs response: + headers: + - key: server + value: mock body: | { "count": 1, "items": [{ - "title": "fix: there is a bug on page one", + "title": "fix: there is a bug on page {{ randEnum "one" }}", "number": 123, + "message": "{{index (index .Header "Accept-Encoding") 0}}", "author": "someone", "status": "success" }] diff --git a/pkg/mock/in_memory.go b/pkg/mock/in_memory.go index 62395fb..d350914 100644 --- a/pkg/mock/in_memory.go +++ b/pkg/mock/in_memory.go @@ -21,6 +21,7 @@ import ( "github.com/gorilla/mux" "github.com/linuxsuren/api-testing/pkg/render" "github.com/linuxsuren/api-testing/pkg/util" + "github.com/linuxsuren/api-testing/pkg/version" "io" "log" "net" @@ -57,6 +58,11 @@ func (s *inMemoryServer) Start(reader Reader) (err error) { s.initObjectData(obj) } + log.Println("start to run all the APIs from items") + for _, item := range server.Items { + s.startItem(item) + } + s.listener, err = net.Listen("tcp", fmt.Sprintf(":%d", s.port)) go func() { err = http.Serve(s.listener, s.mux) @@ -201,6 +207,25 @@ func (s *inMemoryServer) startObject(obj Object) { return } +func (s *inMemoryServer) startItem(item Item) { + s.mux.HandleFunc(item.Request.Path, func(w http.ResponseWriter, req *http.Request) { + item.Response.Headers = append(item.Response.Headers, Header{ + Key: headerMockServer, + Value: fmt.Sprintf("api-testing: %s", version.GetVersion()), + }) + for _, header := range item.Response.Headers { + w.Header().Set(header.Key, header.Value) + } + body, err := render.Render("start-item", item.Response.Body, req) + if err == nil { + w.Write([]byte(body)) + } else { + w.Write([]byte(err.Error())) + } + w.WriteHeader(util.ZeroThenDefault(item.Response.StatusCode, http.StatusOK)) + }).Methods(util.EmptyThenDefault(item.Request.Method, http.MethodGet)) +} + func (s *inMemoryServer) initObjectData(obj Object) { if obj.Sample == "" { return diff --git a/pkg/mock/in_memory_test.go b/pkg/mock/in_memory_test.go index 6ec527a..2838c02 100644 --- a/pkg/mock/in_memory_test.go +++ b/pkg/mock/in_memory_test.go @@ -20,6 +20,7 @@ import ( "github.com/stretchr/testify/assert" "io" "net/http" + "strings" "testing" ) @@ -116,6 +117,19 @@ func TestInMemoryServer(t *testing.T) { assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode) }) + t.Run("mock item", func(t *testing.T) { + resp, err := http.Get(api + "/v1/repos/test/prs") + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "mock", resp.Header.Get("server")) + assert.NotEmpty(t, resp.Header.Get(headerMockServer)) + + data, err := io.ReadAll(resp.Body) + assert.NoError(t, err) + + assert.True(t, strings.Contains(string(data), `"message": "gzip"`), string(data)) + }) + t.Run("not found config file", func(t *testing.T) { server := NewInMemoryServer(0) err := server.Start(NewLocalFileReader("fake")) diff --git a/pkg/mock/server.go b/pkg/mock/server.go index b3873a4..7e9f342 100644 --- a/pkg/mock/server.go +++ b/pkg/mock/server.go @@ -20,3 +20,7 @@ type DynamicServer interface { Stop() error GetPort() string } + +const ( + headerMockServer = "MockServer" +) diff --git a/pkg/mock/types.go b/pkg/mock/types.go index 2cc2e33..c417e34 100644 --- a/pkg/mock/types.go +++ b/pkg/mock/types.go @@ -27,6 +27,29 @@ type Field struct { Kind string `yaml:"kind"` } +type Item struct { + Name string `yaml:"name"` + Request Request `yaml:"request"` + Response Response `yaml:"response"` +} + +type Request struct { + Path string `yaml:"path"` + Method string `yaml:"method"` +} + +type Response struct { + Body string `yaml:"body"` + Headers []Header `yaml:"headers"` + StatusCode int `yaml:"statusCode"` +} + +type Header struct { + Key string `yaml:"key"` + Value string `yaml:"value"` +} + type Server struct { Objects []Object `yaml:"objects"` + Items []Item `yaml:"items"` }