...

Source file src/github.com/go-openapi/runtime/middleware/untyped/api_test.go

Documentation: github.com/go-openapi/runtime/middleware/untyped

     1  // Copyright 2015 go-swagger maintainers
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package untyped
    16  
    17  import (
    18  	"io"
    19  	"net/http"
    20  	"sort"
    21  	"testing"
    22  
    23  	"github.com/go-openapi/analysis"
    24  	"github.com/go-openapi/errors"
    25  	"github.com/go-openapi/loads"
    26  	"github.com/go-openapi/runtime"
    27  	swaggerspec "github.com/go-openapi/spec"
    28  	"github.com/stretchr/testify/assert"
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func stubAutenticator() runtime.Authenticator {
    33  	return runtime.AuthenticatorFunc(func(_ interface{}) (bool, interface{}, error) { return false, nil, nil })
    34  }
    35  
    36  func stubAuthorizer() runtime.Authorizer {
    37  	return runtime.AuthorizerFunc(func(_ *http.Request, _ interface{}) error { return nil })
    38  }
    39  
    40  type stubConsumer struct {
    41  }
    42  
    43  func (s *stubConsumer) Consume(_ io.Reader, _ interface{}) error {
    44  	return nil
    45  }
    46  
    47  type stubProducer struct {
    48  }
    49  
    50  func (s *stubProducer) Produce(_ io.Writer, _ interface{}) error {
    51  	return nil
    52  }
    53  
    54  type stubOperationHandler struct {
    55  }
    56  
    57  func (s *stubOperationHandler) ParameterModel() interface{} {
    58  	return nil
    59  }
    60  
    61  func (s *stubOperationHandler) Handle(_ interface{}) (interface{}, error) {
    62  	return map[string]interface{}{}, nil
    63  }
    64  
    65  func TestUntypedAPIRegistrations(t *testing.T) {
    66  	api := NewAPI(new(loads.Document)).WithJSONDefaults()
    67  
    68  	api.RegisterConsumer("application/yada", new(stubConsumer))
    69  	api.RegisterProducer("application/yada-2", new(stubProducer))
    70  	api.RegisterOperation("get", "/{someId}", new(stubOperationHandler))
    71  	api.RegisterAuth("basic", stubAutenticator())
    72  	api.RegisterAuthorizer(stubAuthorizer())
    73  
    74  	assert.NotNil(t, api.authorizer)
    75  	assert.NotEmpty(t, api.authenticators)
    76  
    77  	_, ok := api.authenticators["basic"]
    78  	assert.True(t, ok)
    79  	_, ok = api.consumers["application/yada"]
    80  	assert.True(t, ok)
    81  	_, ok = api.producers["application/yada-2"]
    82  	assert.True(t, ok)
    83  	_, ok = api.consumers["application/json"]
    84  	assert.True(t, ok)
    85  	_, ok = api.producers["application/json"]
    86  	assert.True(t, ok)
    87  	_, ok = api.operations["GET"]["/{someId}"]
    88  	assert.True(t, ok)
    89  
    90  	authorizer := api.Authorizer()
    91  	assert.NotNil(t, authorizer)
    92  
    93  	h, ok := api.OperationHandlerFor("get", "/{someId}")
    94  	assert.True(t, ok)
    95  	assert.NotNil(t, h)
    96  
    97  	_, ok = api.OperationHandlerFor("doesntExist", "/{someId}")
    98  	assert.False(t, ok)
    99  }
   100  
   101  func TestUntypedAppValidation(t *testing.T) {
   102  	invalidSpecStr := `{
   103    "consumes": ["application/json"],
   104    "produces": ["application/json"],
   105    "security": [
   106      {"apiKey":[]}
   107    ],
   108    "parameters": {
   109      "format": {
   110        "in": "query",
   111        "name": "format",
   112        "type": "string"
   113      }
   114    },
   115    "paths": {
   116      "/": {
   117        "parameters": [
   118          {
   119            "name": "limit",
   120            "type": "integer",
   121            "format": "int32",
   122            "x-go-name": "Limit"
   123          }
   124        ],
   125        "get": {
   126          "consumes": ["application/x-yaml"],
   127          "produces": ["application/x-yaml"],
   128          "security": [
   129            {"basic":[]}
   130          ],
   131          "parameters": [
   132            {
   133              "name": "skip",
   134              "type": "integer",
   135              "format": "int32"
   136            }
   137          ]
   138        }
   139      }
   140    }
   141  }`
   142  	specStr := `{
   143  	  "consumes": ["application/json"],
   144  	  "produces": ["application/json"],
   145  	  "security": [
   146  	    {"apiKey":[]}
   147  	  ],
   148  	  "securityDefinitions": {
   149  	    "basic": { "type": "basic" },
   150  	    "apiKey": { "type": "apiKey", "in":"header", "name":"X-API-KEY" }
   151  	  },
   152  	  "parameters": {
   153  	  	"format": {
   154  	  		"in": "query",
   155  	  		"name": "format",
   156  	  		"type": "string"
   157  	  	}
   158  	  },
   159  	  "paths": {
   160  	  	"/": {
   161  	  		"parameters": [
   162  	  			{
   163  	  				"name": "limit",
   164  			  		"type": "integer",
   165  			  		"format": "int32",
   166  			  		"x-go-name": "Limit"
   167  			  	}
   168  	  		],
   169  	  		"get": {
   170  	  			"consumes": ["application/x-yaml"],
   171  	  			"produces": ["application/x-yaml"],
   172  	        "security": [
   173  	          {"basic":[]}
   174  	        ],
   175  	  			"parameters": [
   176  	  				{
   177  				  		"name": "skip",
   178  				  		"type": "integer",
   179  				  		"format": "int32"
   180  				  	}
   181  	  			]
   182  	  		}
   183  	  	}
   184  	  }
   185  	}`
   186  	validSpec, err := loads.Analyzed([]byte(specStr), "")
   187  	require.NoError(t, err)
   188  	assert.NotNil(t, validSpec)
   189  
   190  	spec, err := loads.Analyzed([]byte(invalidSpecStr), "")
   191  	require.NoError(t, err)
   192  	assert.NotNil(t, spec)
   193  
   194  	analyzed := analysis.New(spec.Spec())
   195  	analyzedValid := analysis.New(validSpec.Spec())
   196  	cons := analyzed.ConsumesFor(analyzed.AllPaths()["/"].Get)
   197  	assert.Len(t, cons, 1)
   198  	prods := analyzed.RequiredProduces()
   199  	assert.Len(t, prods, 2)
   200  
   201  	api1 := NewAPI(spec)
   202  	err = api1.Validate()
   203  	require.Error(t, err)
   204  	assert.Equal(t, "missing [application/x-yaml] consumes registrations", err.Error())
   205  
   206  	api1.RegisterConsumer("application/x-yaml", new(stubConsumer))
   207  	err = api1.validate()
   208  	require.Error(t, err)
   209  	assert.Equal(t, "missing [application/x-yaml] produces registrations", err.Error())
   210  
   211  	api1.RegisterProducer("application/x-yaml", new(stubProducer))
   212  	err = api1.validate()
   213  	require.Error(t, err)
   214  	assert.Equal(t, "missing [GET /] operation registrations", err.Error())
   215  
   216  	api1.RegisterOperation("get", "/", new(stubOperationHandler))
   217  	err = api1.validate()
   218  	require.Error(t, err)
   219  	assert.Equal(t, "missing [apiKey, basic] auth scheme registrations", err.Error())
   220  
   221  	api1.RegisterAuth("basic", stubAutenticator())
   222  	api1.RegisterAuth("apiKey", stubAutenticator())
   223  	err = api1.validate()
   224  	require.Error(t, err)
   225  	assert.Equal(t, "missing [apiKey, basic] security definitions registrations", err.Error())
   226  
   227  	api3 := NewAPI(validSpec)
   228  	api3.RegisterConsumer("application/x-yaml", new(stubConsumer))
   229  	api3.RegisterProducer("application/x-yaml", new(stubProducer))
   230  	api3.RegisterOperation("get", "/", new(stubOperationHandler))
   231  	api3.RegisterAuth("basic", stubAutenticator())
   232  	api3.RegisterAuth("apiKey", stubAutenticator())
   233  	err = api3.validate()
   234  	require.NoError(t, err)
   235  	api3.RegisterConsumer("application/something", new(stubConsumer))
   236  	err = api3.validate()
   237  	require.Error(t, err)
   238  	assert.Equal(t, "missing from spec file [application/something] consumes", err.Error())
   239  
   240  	api2 := NewAPI(spec)
   241  	api2.RegisterConsumer("application/something", new(stubConsumer))
   242  	err = api2.validate()
   243  	require.Error(t, err)
   244  	assert.Equal(t, "missing [application/x-yaml] consumes registrations\nmissing from spec file [application/something] consumes", err.Error())
   245  	api2.RegisterConsumer("application/x-yaml", new(stubConsumer))
   246  	delete(api2.consumers, "application/something")
   247  	api2.RegisterProducer("application/something", new(stubProducer))
   248  	err = api2.validate()
   249  	require.Error(t, err)
   250  	assert.Equal(t, "missing [application/x-yaml] produces registrations\nmissing from spec file [application/something] produces", err.Error())
   251  	delete(api2.producers, "application/something")
   252  	api2.RegisterProducer("application/x-yaml", new(stubProducer))
   253  
   254  	expected := []string{"application/x-yaml"}
   255  	sort.Strings(expected)
   256  	consumes := analyzed.ConsumesFor(analyzed.AllPaths()["/"].Get)
   257  	sort.Strings(consumes)
   258  	assert.Equal(t, expected, consumes)
   259  	consumers := api1.ConsumersFor(consumes)
   260  	assert.Len(t, consumers, 1)
   261  
   262  	produces := analyzed.ProducesFor(analyzed.AllPaths()["/"].Get)
   263  	sort.Strings(produces)
   264  	assert.Equal(t, expected, produces)
   265  	producers := api1.ProducersFor(produces)
   266  	assert.Len(t, producers, 1)
   267  
   268  	definitions := analyzedValid.SecurityDefinitionsFor(analyzedValid.AllPaths()["/"].Get)
   269  	expectedSchemes := map[string]swaggerspec.SecurityScheme{"basic": *swaggerspec.BasicAuth()}
   270  	assert.Equal(t, expectedSchemes, definitions)
   271  	authenticators := api3.AuthenticatorsFor(definitions)
   272  	assert.Len(t, authenticators, 1)
   273  
   274  	opHandler := runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
   275  		return data, nil
   276  	})
   277  	d, err := opHandler.Handle(1)
   278  	require.NoError(t, err)
   279  	assert.Equal(t, 1, d)
   280  
   281  	authenticator := runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
   282  		if str, ok := params.(string); ok {
   283  			return ok, str, nil
   284  		}
   285  		return true, nil, errors.Unauthenticated("authenticator")
   286  	})
   287  	ok, p, err := authenticator.Authenticate("hello")
   288  	assert.True(t, ok)
   289  	require.NoError(t, err)
   290  	assert.Equal(t, "hello", p)
   291  }
   292  

View as plain text