blob: b504f0f45ed8cbffe2fed06b01193a92b5ac8fdd [file] [log] [blame]
// 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
`