| // Copyright 2015 go-swagger maintainers |
| // |
| // 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 swag |
| |
| import ( |
| "encoding/json" |
| "net/http" |
| "net/http/httptest" |
| "testing" |
| |
| yaml "gopkg.in/yaml.v2" |
| |
| "github.com/stretchr/testify/assert" |
| ) |
| |
| /* currently unused: |
| type failJSONMarshal struct { |
| } |
| |
| func (f failJSONMarshal) MarshalJSON() ([]byte, error) { |
| return nil, errors.New("expected") |
| } |
| */ |
| |
| func TestLoadHTTPBytes(t *testing.T) { |
| _, err := LoadFromFileOrHTTP("httx://12394:abd") |
| assert.Error(t, err) |
| |
| serv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { |
| rw.WriteHeader(http.StatusNotFound) |
| })) |
| defer serv.Close() |
| |
| _, err = LoadFromFileOrHTTP(serv.URL) |
| assert.Error(t, err) |
| |
| ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { |
| rw.WriteHeader(http.StatusOK) |
| _, _ = rw.Write([]byte("the content")) |
| })) |
| defer ts2.Close() |
| |
| d, err := LoadFromFileOrHTTP(ts2.URL) |
| assert.NoError(t, err) |
| assert.Equal(t, []byte("the content"), d) |
| } |
| |
| func TestYAMLToJSON(t *testing.T) { |
| |
| sd := `--- |
| 1: the int key value |
| name: a string value |
| 'y': some value |
| ` |
| var data yaml.MapSlice |
| _ = yaml.Unmarshal([]byte(sd), &data) |
| |
| d, err := YAMLToJSON(data) |
| if assert.NoError(t, err) { |
| assert.Equal(t, `{"1":"the int key value","name":"a string value","y":"some value"}`, string(d)) |
| } |
| |
| data = append(data, yaml.MapItem{Key: true, Value: "the bool value"}) |
| d, err = YAMLToJSON(data) |
| assert.Error(t, err) |
| assert.Nil(t, d) |
| |
| data = data[:len(data)-1] |
| |
| tag := yaml.MapSlice{{Key: "name", Value: "tag name"}} |
| data = append(data, yaml.MapItem{Key: "tag", Value: tag}) |
| |
| d, err = YAMLToJSON(data) |
| assert.NoError(t, err) |
| assert.Equal(t, `{"1":"the int key value","name":"a string value","y":"some value","tag":{"name":"tag name"}}`, string(d)) |
| |
| tag = yaml.MapSlice{{Key: true, Value: "bool tag name"}} |
| data = append(data[:len(data)-1], yaml.MapItem{Key: "tag", Value: tag}) |
| |
| d, err = YAMLToJSON(data) |
| assert.Error(t, err) |
| assert.Nil(t, d) |
| |
| var lst []interface{} |
| lst = append(lst, "hello") |
| |
| d, err = YAMLToJSON(lst) |
| assert.NoError(t, err) |
| assert.Equal(t, []byte(`["hello"]`), []byte(d)) |
| |
| lst = append(lst, data) |
| |
| d, err = YAMLToJSON(lst) |
| assert.Error(t, err) |
| assert.Nil(t, d) |
| |
| // _, err := yamlToJSON(failJSONMarhal{}) |
| // assert.Error(t, err) |
| |
| _, err = BytesToYAMLDoc([]byte("- name: hello\n")) |
| assert.Error(t, err) |
| |
| dd, err := BytesToYAMLDoc([]byte("description: 'object created'\n")) |
| assert.NoError(t, err) |
| |
| d, err = YAMLToJSON(dd) |
| assert.NoError(t, err) |
| assert.Equal(t, json.RawMessage(`{"description":"object created"}`), d) |
| } |
| |
| func TestLoadStrategy(t *testing.T) { |
| |
| loader := func(p string) ([]byte, error) { |
| return []byte(yamlPetStore), nil |
| } |
| remLoader := func(p string) ([]byte, error) { |
| return []byte("not it"), nil |
| } |
| |
| ld := LoadStrategy("blah", loader, remLoader) |
| b, _ := ld("") |
| assert.Equal(t, []byte(yamlPetStore), b) |
| |
| serv := httptest.NewServer(http.HandlerFunc(yamlPestoreServer)) |
| defer serv.Close() |
| |
| s, err := YAMLDoc(serv.URL) |
| assert.NoError(t, err) |
| assert.NotNil(t, s) |
| |
| ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { |
| rw.WriteHeader(http.StatusNotFound) |
| _, _ = rw.Write([]byte("\n")) |
| })) |
| defer ts2.Close() |
| _, err = YAMLDoc(ts2.URL) |
| assert.Error(t, err) |
| } |
| |
| var yamlPestoreServer = func(rw http.ResponseWriter, r *http.Request) { |
| rw.WriteHeader(http.StatusOK) |
| _, _ = rw.Write([]byte(yamlPetStore)) |
| } |
| |
| func TestWithYKey(t *testing.T) { |
| doc, err := BytesToYAMLDoc([]byte(withYKey)) |
| if assert.NoError(t, err) { |
| _, err := YAMLToJSON(doc) |
| if assert.Error(t, err) { |
| doc, err := BytesToYAMLDoc([]byte(withQuotedYKey)) |
| if assert.NoError(t, err) { |
| jsond, err := YAMLToJSON(doc) |
| if assert.NoError(t, err) { |
| var yt struct { |
| Definitions struct { |
| Viewbox struct { |
| Properties struct { |
| Y struct { |
| Type string `json:"type"` |
| } `json:"y"` |
| } `json:"properties"` |
| } `json:"viewbox"` |
| } `json:"definitions"` |
| } |
| if assert.NoError(t, json.Unmarshal(jsond, &yt)) { |
| assert.Equal(t, "integer", yt.Definitions.Viewbox.Properties.Y.Type) |
| } |
| } |
| } |
| } |
| |
| } |
| } |
| |
| const withQuotedYKey = `consumes: |
| - application/json |
| definitions: |
| viewBox: |
| type: object |
| properties: |
| x: |
| type: integer |
| format: int16 |
| # y -> types don't match: expect map key string or int get: bool |
| "y": |
| type: integer |
| format: int16 |
| width: |
| type: integer |
| format: int16 |
| height: |
| type: integer |
| format: int16 |
| info: |
| description: Test RESTful APIs |
| title: Test Server |
| version: 1.0.0 |
| basePath: /api |
| paths: |
| /test: |
| get: |
| operationId: findAll |
| parameters: |
| - name: since |
| in: query |
| type: integer |
| format: int64 |
| - name: limit |
| in: query |
| type: integer |
| format: int32 |
| default: 20 |
| responses: |
| 200: |
| description: Array[Trigger] |
| schema: |
| type: array |
| items: |
| $ref: "#/definitions/viewBox" |
| produces: |
| - application/json |
| schemes: |
| - https |
| swagger: "2.0" |
| ` |
| |
| const withYKey = `consumes: |
| - application/json |
| definitions: |
| viewBox: |
| type: object |
| properties: |
| x: |
| type: integer |
| format: int16 |
| # y -> types don't match: expect map key string or int get: bool |
| y: |
| type: integer |
| format: int16 |
| width: |
| type: integer |
| format: int16 |
| height: |
| type: integer |
| format: int16 |
| info: |
| description: Test RESTful APIs |
| title: Test Server |
| version: 1.0.0 |
| basePath: /api |
| paths: |
| /test: |
| get: |
| operationId: findAll |
| parameters: |
| - name: since |
| in: query |
| type: integer |
| format: int64 |
| - name: limit |
| in: query |
| type: integer |
| format: int32 |
| default: 20 |
| responses: |
| 200: |
| description: Array[Trigger] |
| schema: |
| type: array |
| items: |
| $ref: "#/definitions/viewBox" |
| produces: |
| - application/json |
| schemes: |
| - https |
| swagger: "2.0" |
| ` |
| |
| const yamlPetStore = `swagger: '2.0' |
| info: |
| version: '1.0.0' |
| title: Swagger Petstore |
| description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification |
| termsOfService: http://helloreverb.com/terms/ |
| contact: |
| name: Swagger API team |
| email: foo@example.com |
| url: http://swagger.io |
| license: |
| name: MIT |
| url: http://opensource.org/licenses/MIT |
| host: petstore.swagger.wordnik.com |
| basePath: /api |
| schemes: |
| - http |
| consumes: |
| - application/json |
| produces: |
| - application/json |
| paths: |
| /pets: |
| get: |
| description: Returns all pets from the system that the user has access to |
| operationId: findPets |
| produces: |
| - application/json |
| - application/xml |
| - text/xml |
| - text/html |
| parameters: |
| - name: tags |
| in: query |
| description: tags to filter by |
| required: false |
| type: array |
| items: |
| type: string |
| collectionFormat: csv |
| - name: limit |
| in: query |
| description: maximum number of results to return |
| required: false |
| type: integer |
| format: int32 |
| responses: |
| '200': |
| description: pet response |
| schema: |
| type: array |
| items: |
| $ref: '#/definitions/pet' |
| default: |
| description: unexpected error |
| schema: |
| $ref: '#/definitions/errorModel' |
| post: |
| description: Creates a new pet in the store. Duplicates are allowed |
| operationId: addPet |
| produces: |
| - application/json |
| parameters: |
| - name: pet |
| in: body |
| description: Pet to add to the store |
| required: true |
| schema: |
| $ref: '#/definitions/newPet' |
| responses: |
| '200': |
| description: pet response |
| schema: |
| $ref: '#/definitions/pet' |
| default: |
| description: unexpected error |
| schema: |
| $ref: '#/definitions/errorModel' |
| /pets/{id}: |
| get: |
| description: Returns a user based on a single ID, if the user does not have access to the pet |
| operationId: findPetById |
| produces: |
| - application/json |
| - application/xml |
| - text/xml |
| - text/html |
| parameters: |
| - name: id |
| in: path |
| description: ID of pet to fetch |
| required: true |
| type: integer |
| format: int64 |
| responses: |
| '200': |
| description: pet response |
| schema: |
| $ref: '#/definitions/pet' |
| default: |
| description: unexpected error |
| schema: |
| $ref: '#/definitions/errorModel' |
| delete: |
| description: deletes a single pet based on the ID supplied |
| operationId: deletePet |
| parameters: |
| - name: id |
| in: path |
| description: ID of pet to delete |
| required: true |
| type: integer |
| format: int64 |
| responses: |
| '204': |
| description: pet deleted |
| default: |
| description: unexpected error |
| schema: |
| $ref: '#/definitions/errorModel' |
| definitions: |
| pet: |
| required: |
| - id |
| - name |
| properties: |
| id: |
| type: integer |
| format: int64 |
| name: |
| type: string |
| tag: |
| type: string |
| newPet: |
| allOf: |
| - $ref: '#/definitions/pet' |
| - required: |
| - name |
| properties: |
| id: |
| type: integer |
| format: int64 |
| name: |
| type: string |
| errorModel: |
| required: |
| - code |
| - message |
| properties: |
| code: |
| type: integer |
| format: int32 |
| message: |
| type: string |
| ` |