github.com/AngusLu/go-swagger@v0.28.0/codescan/parameters_test.go (about)

     1  package codescan
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/go-openapi/spec"
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  const (
    12  	gcBadEnum = "bad_enum"
    13  )
    14  
    15  func getParameter(sctx *scanCtx, nm string) *entityDecl {
    16  	for _, v := range sctx.app.Parameters {
    17  		param := v
    18  		if v.Ident.Name == nm {
    19  			return param
    20  		}
    21  	}
    22  	return nil
    23  }
    24  
    25  func TestScanFileParam(t *testing.T) {
    26  	sctx := loadClassificationPkgsCtx(t)
    27  	operations := make(map[string]*spec.Operation)
    28  	for _, rn := range []string{"OrderBodyParams", "MultipleOrderParams", "ComplexerOneParams", "NoParams", "NoParamsAlias", "MyFileParams", "MyFuncFileParams", "EmbeddedFileParams"} {
    29  		td := getParameter(sctx, rn)
    30  
    31  		prs := &parameterBuilder{
    32  			ctx:  sctx,
    33  			decl: td,
    34  		}
    35  		require.NoError(t, prs.Build(operations))
    36  	}
    37  	assert.Len(t, operations, 10)
    38  
    39  	of, ok := operations["myOperation"]
    40  	assert.True(t, ok)
    41  	assert.Len(t, of.Parameters, 1)
    42  	fileParam := of.Parameters[0]
    43  	assert.Equal(t, "MyFormFile desc.", fileParam.Description)
    44  	assert.Equal(t, "formData", fileParam.In)
    45  	assert.Equal(t, "file", fileParam.Type)
    46  	assert.False(t, fileParam.Required)
    47  
    48  	emb, ok := operations["myOtherOperation"]
    49  	assert.True(t, ok)
    50  	assert.Len(t, emb.Parameters, 2)
    51  	fileParam = emb.Parameters[0]
    52  	assert.Equal(t, "MyFormFile desc.", fileParam.Description)
    53  	assert.Equal(t, "formData", fileParam.In)
    54  	assert.Equal(t, "file", fileParam.Type)
    55  	assert.False(t, fileParam.Required)
    56  	extraParam := emb.Parameters[1]
    57  	assert.Equal(t, "ExtraParam desc.", extraParam.Description)
    58  	assert.Equal(t, "formData", extraParam.In)
    59  	assert.Equal(t, "integer", extraParam.Type)
    60  	assert.True(t, extraParam.Required)
    61  
    62  	ffp, ok := operations["myFuncOperation"]
    63  	assert.True(t, ok)
    64  	assert.Len(t, ffp.Parameters, 1)
    65  	fileParam = ffp.Parameters[0]
    66  	assert.Equal(t, "MyFormFile desc.", fileParam.Description)
    67  	assert.Equal(t, "formData", fileParam.In)
    68  	assert.Equal(t, "file", fileParam.Type)
    69  	assert.False(t, fileParam.Required)
    70  }
    71  
    72  func TestParamsParser(t *testing.T) {
    73  	sctx := loadClassificationPkgsCtx(t)
    74  	operations := make(map[string]*spec.Operation)
    75  	for _, rn := range []string{"OrderBodyParams", "MultipleOrderParams", "ComplexerOneParams", "NoParams", "NoParamsAlias", "MyFileParams", "MyFuncFileParams", "EmbeddedFileParams"} {
    76  		td := getParameter(sctx, rn)
    77  
    78  		prs := &parameterBuilder{
    79  			ctx:  sctx,
    80  			decl: td,
    81  		}
    82  		require.NoError(t, prs.Build(operations))
    83  	}
    84  
    85  	assert.Len(t, operations, 10)
    86  	cr, okParam := operations["yetAnotherOperation"]
    87  	assert.True(t, okParam)
    88  	assert.Len(t, cr.Parameters, 8)
    89  	for _, param := range cr.Parameters {
    90  		switch param.Name {
    91  		case "id":
    92  			assert.Equal(t, "integer", param.Type)
    93  			assert.Equal(t, "int64", param.Format)
    94  		case "name":
    95  			assert.Equal(t, "string", param.Type)
    96  			assert.Equal(t, "", param.Format)
    97  		case "age":
    98  			assert.Equal(t, "integer", param.Type)
    99  			assert.Equal(t, "int32", param.Format)
   100  		case "notes":
   101  			assert.Equal(t, "string", param.Type)
   102  			assert.Equal(t, "", param.Format)
   103  		case "extra":
   104  			assert.Equal(t, "string", param.Type)
   105  			assert.Equal(t, "", param.Format)
   106  		case "createdAt":
   107  			assert.Equal(t, "string", param.Type)
   108  			assert.Equal(t, "date-time", param.Format)
   109  		case "informity":
   110  			assert.Equal(t, "string", param.Type)
   111  			assert.Equal(t, "formData", param.In)
   112  		case "NoTagName":
   113  			assert.Equal(t, "string", param.Type)
   114  			assert.Equal(t, "", param.Format)
   115  		default:
   116  			assert.Fail(t, "unknown property: "+param.Name)
   117  		}
   118  	}
   119  
   120  	ob, okParam := operations["updateOrder"]
   121  	assert.True(t, okParam)
   122  	assert.Len(t, ob.Parameters, 1)
   123  	bodyParam := ob.Parameters[0]
   124  	assert.Equal(t, "The order to submit.", bodyParam.Description)
   125  	assert.Equal(t, "body", bodyParam.In)
   126  	assert.Equal(t, "#/definitions/order", bodyParam.Schema.Ref.String())
   127  	assert.True(t, bodyParam.Required)
   128  
   129  	mop, okParam := operations["getOrders"]
   130  	assert.True(t, okParam)
   131  	assert.Len(t, mop.Parameters, 2)
   132  	ordersParam := mop.Parameters[0]
   133  	assert.Equal(t, "The orders", ordersParam.Description)
   134  	assert.True(t, ordersParam.Required)
   135  	assert.Equal(t, "array", ordersParam.Type)
   136  	otherParam := mop.Parameters[1]
   137  	assert.Equal(t, "And another thing", otherParam.Description)
   138  
   139  	op, okParam := operations["someOperation"]
   140  	assert.True(t, okParam)
   141  	assert.Len(t, op.Parameters, 10)
   142  
   143  	for _, param := range op.Parameters {
   144  		switch param.Name {
   145  		case "id":
   146  			assert.Equal(t, "ID of this no model instance.\nids in this application start at 11 and are smaller than 1000", param.Description)
   147  			assert.Equal(t, "path", param.In)
   148  			assert.Equal(t, "integer", param.Type)
   149  			assert.Equal(t, "int64", param.Format)
   150  			assert.True(t, param.Required)
   151  			assert.Equal(t, "ID", param.Extensions["x-go-name"])
   152  			assert.EqualValues(t, 1000, *param.Maximum)
   153  			assert.True(t, param.ExclusiveMaximum)
   154  			assert.EqualValues(t, 10, *param.Minimum)
   155  			assert.True(t, param.ExclusiveMinimum)
   156  			assert.Equal(t, 1, param.Default, "%s default value is incorrect", param.Name)
   157  
   158  		case "score":
   159  			assert.Equal(t, "The Score of this model", param.Description)
   160  			assert.Equal(t, "query", param.In)
   161  			assert.Equal(t, "integer", param.Type)
   162  			assert.Equal(t, "int32", param.Format)
   163  			assert.True(t, param.Required)
   164  			assert.Equal(t, "Score", param.Extensions["x-go-name"])
   165  			assert.EqualValues(t, 45, *param.Maximum)
   166  			assert.False(t, param.ExclusiveMaximum)
   167  			assert.EqualValues(t, 3, *param.Minimum)
   168  			assert.False(t, param.ExclusiveMinimum)
   169  			assert.Equal(t, 2, param.Default, "%s default value is incorrect", param.Name)
   170  			assert.Equal(t, 27, param.Example)
   171  
   172  		case "x-hdr-name":
   173  			assert.Equal(t, "Name of this no model instance", param.Description)
   174  			assert.Equal(t, "header", param.In)
   175  			assert.Equal(t, "string", param.Type)
   176  			assert.True(t, param.Required)
   177  			assert.Equal(t, "Name", param.Extensions["x-go-name"])
   178  			assert.EqualValues(t, 4, *param.MinLength)
   179  			assert.EqualValues(t, 50, *param.MaxLength)
   180  			assert.Equal(t, "[A-Za-z0-9-.]*", param.Pattern)
   181  
   182  		case "created":
   183  			assert.Equal(t, "Created holds the time when this entry was created", param.Description)
   184  			assert.Equal(t, "query", param.In)
   185  			assert.Equal(t, "string", param.Type)
   186  			assert.Equal(t, "date-time", param.Format)
   187  			assert.False(t, param.Required)
   188  			assert.Equal(t, "Created", param.Extensions["x-go-name"])
   189  
   190  		case "category":
   191  			assert.Equal(t, "The Category of this model", param.Description)
   192  			assert.Equal(t, "query", param.In)
   193  			assert.Equal(t, "string", param.Type)
   194  			assert.True(t, param.Required)
   195  			assert.Equal(t, "Category", param.Extensions["x-go-name"])
   196  			assert.EqualValues(t, []interface{}{"foo", "bar", "none"}, param.Enum, "%s enum values are incorrect", param.Name)
   197  			assert.Equal(t, "bar", param.Default, "%s default value is incorrect", param.Name)
   198  		case "type":
   199  			assert.Equal(t, "Type of this model", param.Description)
   200  			assert.Equal(t, "query", param.In)
   201  			assert.Equal(t, "integer", param.Type)
   202  			assert.EqualValues(t, []interface{}{1, 3, 5}, param.Enum, "%s enum values are incorrect", param.Name)
   203  		case gcBadEnum:
   204  			assert.Equal(t, "query", param.In)
   205  			assert.Equal(t, "integer", param.Type)
   206  			assert.EqualValues(t, []interface{}{1, "rsq", "qaz"}, param.Enum, "%s enum values are incorrect", param.Name)
   207  		case "foo_slice":
   208  			assert.Equal(t, "a FooSlice has foos which are strings", param.Description)
   209  			assert.Equal(t, "FooSlice", param.Extensions["x-go-name"])
   210  			assert.Equal(t, "query", param.In)
   211  			assert.Equal(t, "array", param.Type)
   212  			assert.False(t, param.Required)
   213  			assert.True(t, param.UniqueItems)
   214  			assert.Equal(t, "pipe", param.CollectionFormat)
   215  			assert.EqualValues(t, 3, *param.MinItems, "'foo_slice' should have had 3 min items")
   216  			assert.EqualValues(t, 10, *param.MaxItems, "'foo_slice' should have had 10 max items")
   217  			itprop := param.Items
   218  			assert.EqualValues(t, 3, *itprop.MinLength, "'foo_slice.items.minLength' should have been 3")
   219  			assert.EqualValues(t, 10, *itprop.MaxLength, "'foo_slice.items.maxLength' should have been 10")
   220  			assert.EqualValues(t, "\\w+", itprop.Pattern, "'foo_slice.items.pattern' should have \\w+")
   221  			assert.EqualValues(t, "bar", itprop.Default, "'foo_slice.items.default' should have bar default value")
   222  
   223  		case "items":
   224  			assert.Equal(t, "Items", param.Extensions["x-go-name"])
   225  			assert.Equal(t, "body", param.In)
   226  			assert.NotNil(t, param.Schema)
   227  			aprop := param.Schema
   228  			assert.Equal(t, "array", aprop.Type[0])
   229  			assert.NotNil(t, aprop.Items)
   230  			assert.NotNil(t, aprop.Items.Schema)
   231  			itprop := aprop.Items.Schema
   232  			assert.Len(t, itprop.Properties, 4)
   233  			assert.Len(t, itprop.Required, 3)
   234  			assertProperty(t, itprop, "integer", "id", "int32", "ID")
   235  			iprop, ok := itprop.Properties["id"]
   236  			assert.True(t, ok)
   237  			assert.Equal(t, "ID of this no model instance.\nids in this application start at 11 and are smaller than 1000", iprop.Description)
   238  			assert.EqualValues(t, 1000, *iprop.Maximum)
   239  			assert.True(t, iprop.ExclusiveMaximum, "'id' should have had an exclusive maximum")
   240  			assert.NotNil(t, iprop.Minimum)
   241  			assert.EqualValues(t, 10, *iprop.Minimum)
   242  			assert.True(t, iprop.ExclusiveMinimum, "'id' should have had an exclusive minimum")
   243  			assert.Equal(t, 3, iprop.Default, "Items.ID default value is incorrect")
   244  
   245  			assertRef(t, itprop, "pet", "Pet", "#/definitions/pet")
   246  			iprop, ok = itprop.Properties["pet"]
   247  			assert.True(t, ok)
   248  			// if itprop.Ref.String() == "" {
   249  			// 	assert.Equal(t, "The Pet to add to this NoModel items bucket.\nPets can appear more than once in the bucket", iprop.Description)
   250  			// }
   251  
   252  			assertProperty(t, itprop, "integer", "quantity", "int16", "Quantity")
   253  			iprop, ok = itprop.Properties["quantity"]
   254  			assert.True(t, ok)
   255  			assert.Equal(t, "The amount of pets to add to this bucket.", iprop.Description)
   256  			assert.EqualValues(t, 1, *iprop.Minimum)
   257  			assert.EqualValues(t, 10, *iprop.Maximum)
   258  
   259  			assertProperty(t, itprop, "string", "notes", "", "Notes")
   260  			iprop, ok = itprop.Properties["notes"]
   261  			assert.True(t, ok)
   262  			assert.Equal(t, "Notes to add to this item.\nThis can be used to add special instructions.", iprop.Description)
   263  
   264  		case "bar_slice":
   265  			assert.Equal(t, "a BarSlice has bars which are strings", param.Description)
   266  			assert.Equal(t, "BarSlice", param.Extensions["x-go-name"])
   267  			assert.Equal(t, "query", param.In)
   268  			assert.Equal(t, "array", param.Type)
   269  			assert.False(t, param.Required)
   270  			assert.True(t, param.UniqueItems)
   271  			assert.Equal(t, "pipe", param.CollectionFormat)
   272  			assert.NotNil(t, param.Items, "bar_slice should have had an items property")
   273  			assert.EqualValues(t, 3, *param.MinItems, "'bar_slice' should have had 3 min items")
   274  			assert.EqualValues(t, 10, *param.MaxItems, "'bar_slice' should have had 10 max items")
   275  			itprop := param.Items
   276  			if assert.NotNil(t, itprop) {
   277  				assert.EqualValues(t, 4, *itprop.MinItems, "'bar_slice.items.minItems' should have been 4")
   278  				assert.EqualValues(t, 9, *itprop.MaxItems, "'bar_slice.items.maxItems' should have been 9")
   279  				itprop2 := itprop.Items
   280  				if assert.NotNil(t, itprop2) {
   281  					assert.EqualValues(t, 5, *itprop2.MinItems, "'bar_slice.items.items.minItems' should have been 5")
   282  					assert.EqualValues(t, 8, *itprop2.MaxItems, "'bar_slice.items.items.maxItems' should have been 8")
   283  					itprop3 := itprop2.Items
   284  					if assert.NotNil(t, itprop3) {
   285  						assert.EqualValues(t, 3, *itprop3.MinLength, "'bar_slice.items.items.items.minLength' should have been 3")
   286  						assert.EqualValues(t, 10, *itprop3.MaxLength, "'bar_slice.items.items.items.maxLength' should have been 10")
   287  						assert.EqualValues(t, "\\w+", itprop3.Pattern, "'bar_slice.items.items.items.pattern' should have \\w+")
   288  					}
   289  				}
   290  			}
   291  
   292  		default:
   293  			assert.Fail(t, "unknown property: "+param.Name)
   294  		}
   295  	}
   296  
   297  	// assert that the order of the parameters is maintained
   298  	order, ok := operations["anotherOperation"]
   299  	assert.True(t, ok)
   300  	assert.Len(t, order.Parameters, 10)
   301  
   302  	for index, param := range order.Parameters {
   303  		switch param.Name {
   304  		case "id":
   305  			assert.Equal(t, 0, index, "%s index incorrect", param.Name)
   306  		case "score":
   307  			assert.Equal(t, 1, index, "%s index incorrect", param.Name)
   308  		case "x-hdr-name":
   309  			assert.Equal(t, 2, index, "%s index incorrect", param.Name)
   310  		case "created":
   311  			assert.Equal(t, 3, index, "%s index incorrect", param.Name)
   312  		case "category":
   313  			assert.Equal(t, 4, index, "%s index incorrect", param.Name)
   314  		case "type":
   315  			assert.Equal(t, 5, index, "%s index incorrect", param.Name)
   316  		case gcBadEnum:
   317  			assert.Equal(t, 6, index, "%s index incorrect", param.Name)
   318  		case "foo_slice":
   319  			assert.Equal(t, 7, index, "%s index incorrect", param.Name)
   320  		case "bar_slice":
   321  			assert.Equal(t, 8, index, "%s index incorrect", param.Name)
   322  		case "items":
   323  			assert.Equal(t, 9, index, "%s index incorrect", param.Name)
   324  		default:
   325  			assert.Fail(t, "unknown property: "+param.Name)
   326  		}
   327  	}
   328  
   329  	// check that aliases work correctly
   330  	aliasOp, ok := operations["someAliasOperation"]
   331  	assert.True(t, ok)
   332  	assert.Len(t, aliasOp.Parameters, 4)
   333  	for _, param := range aliasOp.Parameters {
   334  		switch param.Name {
   335  		case "intAlias":
   336  			assert.Equal(t, "query", param.In)
   337  			assert.Equal(t, "integer", param.Type)
   338  			assert.Equal(t, "int64", param.Format)
   339  			assert.True(t, param.Required)
   340  			assert.EqualValues(t, 10, *param.Maximum)
   341  			assert.EqualValues(t, 1, *param.Minimum)
   342  		case "stringAlias":
   343  			assert.Equal(t, "query", param.In)
   344  			assert.Equal(t, "string", param.Type)
   345  		case "intAliasPath":
   346  			assert.Equal(t, "path", param.In)
   347  			assert.Equal(t, "integer", param.Type)
   348  			assert.Equal(t, "int64", param.Format)
   349  		case "intAliasForm":
   350  			assert.Equal(t, "formData", param.In)
   351  			assert.Equal(t, "integer", param.Type)
   352  			assert.Equal(t, "int64", param.Format)
   353  		default:
   354  			assert.Fail(t, "unknown property: "+param.Name)
   355  		}
   356  	}
   357  }
   358  
   359  func TestParameterParser_Issue2007(t *testing.T) {
   360  	sctx := loadClassificationPkgsCtx(t)
   361  	operations := make(map[string]*spec.Operation)
   362  	td := getParameter(sctx, "SetConfiguration")
   363  	prs := &parameterBuilder{
   364  		ctx:  sctx,
   365  		decl: td,
   366  	}
   367  	require.NoError(t, prs.Build(operations))
   368  
   369  	op := operations["getConfiguration"]
   370  	require.NotNil(t, op)
   371  	require.Len(t, op.Parameters, 1)
   372  	sch := op.Parameters[0].Schema
   373  	require.NotNil(t, sch)
   374  
   375  	require.True(t, sch.Type.Contains("object"))
   376  	require.NotNil(t, sch.AdditionalProperties)
   377  	require.NotNil(t, sch.AdditionalProperties.Schema)
   378  	require.True(t, sch.AdditionalProperties.Schema.Type.Contains("string"))
   379  }
   380  
   381  func TestParameterParser_Issue2011(t *testing.T) {
   382  	sctx := loadClassificationPkgsCtx(t)
   383  	operations := make(map[string]*spec.Operation)
   384  	td := getParameter(sctx, "NumPlates")
   385  	prs := &parameterBuilder{
   386  		ctx:  sctx,
   387  		decl: td,
   388  	}
   389  	require.NoError(t, prs.Build(operations))
   390  
   391  	op := operations["putNumPlate"]
   392  	require.NotNil(t, op)
   393  	require.Len(t, op.Parameters, 1)
   394  	sch := op.Parameters[0].Schema
   395  	require.NotNil(t, sch)
   396  
   397  	require.True(t, sch.Type.Contains("object"))
   398  }