Add JSON schema for mock types (#499)
* Add JSON schema for mock types * add unit tests * fix the unit test failure --------- Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
This commit is contained in:
parent
6495a50f51
commit
157253e9c3
|
@ -74,7 +74,7 @@ func TestPrintProto(t *testing.T) {
|
|||
name: "mock server, normal",
|
||||
args: []string{"server", "--mock-config=testdata/invalid-api.yaml", "-p=0", "--http-port=0"},
|
||||
verify: func(t *testing.T, buffer *bytes.Buffer, err error) {
|
||||
assert.NoError(t, err)
|
||||
assert.Error(t, err)
|
||||
},
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Mock Server Schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"objects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"initCount": {"type": "integer"},
|
||||
"sample": {"type": "string"},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"kind": {"type": "string"}
|
||||
},
|
||||
"required": ["name", "kind"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"request": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {"type": "string"},
|
||||
"method": {"type": "string"},
|
||||
"header": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "string"}
|
||||
},
|
||||
"body": {"type": "string"}
|
||||
},
|
||||
"required": ["path"]
|
||||
},
|
||||
"response": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"encoder": {"type": "string"},
|
||||
"body": {"type": "string"},
|
||||
"header": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "string"}
|
||||
},
|
||||
"statusCode": {"type": "integer"},
|
||||
"bodyData": {"type": "string", "contentEncoding": "base64"}
|
||||
}
|
||||
},
|
||||
"param": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"required": ["name", "request", "response"]
|
||||
}
|
||||
},
|
||||
"webhooks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"timer": {"type": "string"},
|
||||
"request": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {"type": "string"},
|
||||
"method": {"type": "string"},
|
||||
"header": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "string"}
|
||||
},
|
||||
"body": {"type": "string"}
|
||||
},
|
||||
"required": ["path"]
|
||||
}
|
||||
},
|
||||
"required": ["name", "timer", "request"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,46 @@
|
|||
/*
|
||||
Copyright 2024 API Testing Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package docs
|
||||
|
||||
import _ "embed"
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
yamlconv "github.com/ghodss/yaml"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
)
|
||||
|
||||
//go:embed api-testing-schema.json
|
||||
var Schema string
|
||||
|
||||
//go:embed api-testing-mock-schema.json
|
||||
var MockSchema string
|
||||
|
||||
func Validate(data []byte, schema string) (err error) {
|
||||
// convert YAML to JSON
|
||||
var jsonData []byte
|
||||
if jsonData, err = yamlconv.YAMLToJSON(data); err == nil {
|
||||
schemaLoader := gojsonschema.NewStringLoader(schema)
|
||||
documentLoader := gojsonschema.NewBytesLoader(jsonData)
|
||||
|
||||
var result *gojsonschema.Result
|
||||
if result, err = gojsonschema.Validate(schemaLoader, documentLoader); err == nil {
|
||||
if !result.Valid() {
|
||||
err = fmt.Errorf("%v", result.Errors())
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ func TestInMemoryServer(t *testing.T) {
|
|||
server := NewInMemoryServer(0)
|
||||
err := server.Start(NewInMemoryReader(`webhooks:
|
||||
- timer: 1s`), "/")
|
||||
assert.NoError(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("invalid webhook payload", func(t *testing.T) {
|
||||
|
@ -189,7 +189,7 @@ func TestInMemoryServer(t *testing.T) {
|
|||
timer: 1ms
|
||||
request:
|
||||
body: "{{.fake"`), "/")
|
||||
assert.NoError(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("invalid webhook api template", func(t *testing.T) {
|
||||
|
|
|
@ -16,6 +16,8 @@ limitations under the License.
|
|||
package mock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/linuxsuren/api-testing/docs"
|
||||
"os"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
@ -41,8 +43,7 @@ func NewLocalFileReader(file string) Reader {
|
|||
|
||||
func (r *localFileReader) Parse() (server *Server, err error) {
|
||||
if r.data, err = os.ReadFile(r.file); err == nil {
|
||||
server = &Server{}
|
||||
err = yaml.Unmarshal(r.data, server)
|
||||
server, err = validateAndParse(r.data)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -67,8 +68,7 @@ func NewInMemoryReader(config string) ReaderAndWriter {
|
|||
}
|
||||
|
||||
func (r *inMemoryReader) Parse() (server *Server, err error) {
|
||||
server = &Server{}
|
||||
err = yaml.Unmarshal(r.data, server)
|
||||
server, err = validateAndParse(r.data)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -79,3 +79,12 @@ func (r *inMemoryReader) GetData() []byte {
|
|||
func (r *inMemoryReader) Write(data []byte) {
|
||||
r.data = data
|
||||
}
|
||||
|
||||
func validateAndParse(data []byte) (server *Server, err error) {
|
||||
server = &Server{}
|
||||
if len(data) > 0 {
|
||||
err = yaml.Unmarshal(data, server)
|
||||
err = errors.Join(err, docs.Validate(data, docs.MockSchema))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -16,47 +16,47 @@ limitations under the License.
|
|||
package mock
|
||||
|
||||
type Object struct {
|
||||
Name string `yaml:"name"`
|
||||
InitCount *int `yaml:"initCount"`
|
||||
Sample string `yaml:"sample"`
|
||||
Fields []Field `yaml:"fields"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
InitCount *int `yaml:"initCount" json:"initCount"`
|
||||
Sample string `yaml:"sample" json:"sample"`
|
||||
Fields []Field `yaml:"fields" json:"fields"`
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
Name string `yaml:"name"`
|
||||
Kind string `yaml:"kind"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Kind string `yaml:"kind" json:"kind"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Name string `yaml:"name"`
|
||||
Request Request `yaml:"request"`
|
||||
Response Response `yaml:"response"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Request Request `yaml:"request" json:"request"`
|
||||
Response Response `yaml:"response" json:"response"`
|
||||
Param map[string]string
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Path string `yaml:"path"`
|
||||
Method string `yaml:"method"`
|
||||
Header map[string]string `yaml:"header"`
|
||||
Body string `yaml:"body"`
|
||||
Path string `yaml:"path" json:"path"`
|
||||
Method string `yaml:"method" json:"method"`
|
||||
Header map[string]string `yaml:"header" json:"header"`
|
||||
Body string `yaml:"body" json:"body"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Encoder string `yaml:"encoder"`
|
||||
Body string `yaml:"body"`
|
||||
Header map[string]string `yaml:"header"`
|
||||
StatusCode int `yaml:"statusCode"`
|
||||
Encoder string `yaml:"encoder" json:"encoder"`
|
||||
Body string `yaml:"body" json:"body"`
|
||||
Header map[string]string `yaml:"header" json:"header"`
|
||||
StatusCode int `yaml:"statusCode" json:"statusCode"`
|
||||
BodyData []byte
|
||||
}
|
||||
|
||||
type Webhook struct {
|
||||
Name string `yaml:"name"`
|
||||
Timer string `yaml:"timer"`
|
||||
Request Request `yaml:"request"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Timer string `yaml:"timer" json:"timer"`
|
||||
Request Request `yaml:"request" json:"request"`
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Objects []Object `yaml:"objects"`
|
||||
Items []Item `yaml:"items"`
|
||||
Webhooks []Webhook `yaml:"webhooks"`
|
||||
Objects []Object `yaml:"objects" json:"objects"`
|
||||
Items []Item `yaml:"items" json:"items"`
|
||||
Webhooks []Webhook `yaml:"webhooks" json:"webhooks"`
|
||||
}
|
||||
|
|
|
@ -16,22 +16,21 @@ limitations under the License.
|
|||
package testing
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
yamlconv "github.com/ghodss/yaml"
|
||||
"github.com/linuxsuren/api-testing/docs"
|
||||
"github.com/linuxsuren/api-testing/pkg/render"
|
||||
"github.com/linuxsuren/api-testing/pkg/util"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
"gopkg.in/yaml.v3"
|
||||
"github.com/linuxsuren/api-testing/docs"
|
||||
"github.com/linuxsuren/api-testing/pkg/render"
|
||||
"github.com/linuxsuren/api-testing/pkg/util"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -41,23 +40,8 @@ const (
|
|||
// Parse parses a file and returns the test suite
|
||||
func Parse(data []byte) (testSuite *TestSuite, err error) {
|
||||
testSuite, err = ParseFromData(data)
|
||||
|
||||
// schema validation
|
||||
if err == nil {
|
||||
// convert YAML to JSON
|
||||
var jsonData []byte
|
||||
if jsonData, err = yamlconv.YAMLToJSON(data); err == nil {
|
||||
schemaLoader := gojsonschema.NewStringLoader(docs.Schema)
|
||||
documentLoader := gojsonschema.NewBytesLoader(jsonData)
|
||||
|
||||
var result *gojsonschema.Result
|
||||
if result, err = gojsonschema.Validate(schemaLoader, documentLoader); err == nil {
|
||||
if !result.Valid() {
|
||||
err = fmt.Errorf("%v", result.Errors())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = errors.Join(err, docs.Validate(data, docs.Schema))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue