github.com/AngusLu/go-swagger@v0.28.0/codescan/responses_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  func getResponse(sctx *scanCtx, nm string) *entityDecl {
    12  	for _, v := range sctx.app.Responses {
    13  		if v.Ident.Name == nm {
    14  			return v
    15  		}
    16  	}
    17  	return nil
    18  }
    19  
    20  func TestParseResponses(t *testing.T) {
    21  	sctx := loadClassificationPkgsCtx(t)
    22  	responses := make(map[string]spec.Response)
    23  	for _, rn := range []string{"ComplexerOne", "SimpleOnes", "SimpleOnesFunc", "ComplexerPointerOne", "SomeResponse", "ValidationError", "Resp", "FileResponse", "GenericError", "ValidationError"} {
    24  		td := getResponse(sctx, rn)
    25  		prs := &responseBuilder{
    26  			ctx:  sctx,
    27  			decl: td,
    28  		}
    29  		require.NoError(t, prs.Build(responses))
    30  	}
    31  
    32  	require.Len(t, responses, 9)
    33  	cr, ok := responses["complexerOne"]
    34  	assert.True(t, ok)
    35  	assert.Len(t, cr.Headers, 7)
    36  	for k, header := range cr.Headers {
    37  		switch k {
    38  		case "id":
    39  			assert.Equal(t, "integer", header.Type)
    40  			assert.Equal(t, "int64", header.Format)
    41  		case "name":
    42  			assert.Equal(t, "string", header.Type)
    43  			assert.Equal(t, "", header.Format)
    44  		case "age":
    45  			assert.Equal(t, "integer", header.Type)
    46  			assert.Equal(t, "int32", header.Format)
    47  		case "notes":
    48  			assert.Equal(t, "string", header.Type)
    49  			assert.Equal(t, "", header.Format)
    50  		case "extra":
    51  			assert.Equal(t, "string", header.Type)
    52  			assert.Equal(t, "", header.Format)
    53  		case "createdAt":
    54  			assert.Equal(t, "string", header.Type)
    55  			assert.Equal(t, "date-time", header.Format)
    56  		case "NoTagName":
    57  			assert.Equal(t, "string", header.Type)
    58  			assert.Equal(t, "", header.Format)
    59  		default:
    60  			assert.Fail(t, "unknown header: "+k)
    61  		}
    62  	}
    63  
    64  	cpr, ok := responses["complexerPointerOne"]
    65  	assert.True(t, ok)
    66  	assert.Len(t, cpr.Headers, 4)
    67  	for k, header := range cpr.Headers {
    68  		switch k {
    69  		case "id":
    70  			assert.Equal(t, "integer", header.Type)
    71  			assert.Equal(t, "int64", header.Format)
    72  		case "name":
    73  			assert.Equal(t, "string", header.Type)
    74  			assert.Equal(t, "", header.Format)
    75  		case "age":
    76  			assert.Equal(t, "integer", header.Type)
    77  			assert.Equal(t, "int32", header.Format)
    78  		case "extra":
    79  			assert.Equal(t, "integer", header.Type)
    80  			assert.Equal(t, "int64", header.Format)
    81  		default:
    82  			assert.Fail(t, "unknown header: "+k)
    83  		}
    84  	}
    85  
    86  	sos, ok := responses["simpleOnes"]
    87  	assert.True(t, ok)
    88  	assert.Len(t, sos.Headers, 1)
    89  
    90  	sosf, ok := responses["simpleOnesFunc"]
    91  	assert.True(t, ok)
    92  	assert.Len(t, sosf.Headers, 1)
    93  
    94  	res, ok := responses["someResponse"]
    95  	assert.True(t, ok)
    96  	assert.Len(t, res.Headers, 7)
    97  
    98  	for k, header := range res.Headers {
    99  		switch k {
   100  		case "id":
   101  			assert.Equal(t, "ID of this some response instance.\nids in this application start at 11 and are smaller than 1000", header.Description)
   102  			assert.Equal(t, "integer", header.Type)
   103  			assert.Equal(t, "int64", header.Format)
   104  			// assert.Equal(t, "ID", header.Extensions["x-go-name"])
   105  			assert.EqualValues(t, 1000, *header.Maximum)
   106  			assert.True(t, header.ExclusiveMaximum)
   107  			assert.EqualValues(t, 10, *header.Minimum)
   108  			assert.True(t, header.ExclusiveMinimum)
   109  			assert.Equal(t, 11, header.Default, "ID default value is incorrect")
   110  
   111  		case "score":
   112  			assert.Equal(t, "The Score of this model", header.Description)
   113  			assert.Equal(t, "integer", header.Type)
   114  			assert.Equal(t, "int32", header.Format)
   115  			// assert.Equal(t, "Score", header.Extensions["x-go-name"])
   116  			assert.EqualValues(t, 45, *header.Maximum)
   117  			assert.False(t, header.ExclusiveMaximum)
   118  			assert.EqualValues(t, 3, *header.Minimum)
   119  			assert.False(t, header.ExclusiveMinimum)
   120  			assert.Equal(t, 27, header.Example)
   121  
   122  		case "x-hdr-name":
   123  			assert.Equal(t, "Name of this some response instance", header.Description)
   124  			assert.Equal(t, "string", header.Type)
   125  			// assert.Equal(t, "Name", header.Extensions["x-go-name"])
   126  			assert.EqualValues(t, 4, *header.MinLength)
   127  			assert.EqualValues(t, 50, *header.MaxLength)
   128  			assert.Equal(t, "[A-Za-z0-9-.]*", header.Pattern)
   129  
   130  		case "active":
   131  			assert.Equal(t, "Active state of the record", header.Description)
   132  			assert.Equal(t, "boolean", header.Type)
   133  			assert.Equal(t, true, header.Default)
   134  
   135  		case "created":
   136  			assert.Equal(t, "Created holds the time when this entry was created", header.Description)
   137  			assert.Equal(t, "string", header.Type)
   138  			assert.Equal(t, "date-time", header.Format)
   139  			// assert.Equal(t, "Created", header.Extensions["x-go-name"])
   140  
   141  		case "foo_slice":
   142  			assert.Equal(t, "a FooSlice has foos which are strings", header.Description)
   143  			// assert.Equal(t, "FooSlice", header.Extensions["x-go-name"])
   144  			assert.Equal(t, "array", header.Type)
   145  			assert.True(t, header.UniqueItems)
   146  			assert.Equal(t, "pipe", header.CollectionFormat)
   147  			assert.NotNil(t, header.Items, "foo_slice should have had an items property")
   148  			assert.EqualValues(t, 3, *header.MinItems, "'foo_slice' should have had 3 min items")
   149  			assert.EqualValues(t, 10, *header.MaxItems, "'foo_slice' should have had 10 max items")
   150  			itprop := header.Items
   151  			assert.EqualValues(t, 3, *itprop.MinLength, "'foo_slice.items.minLength' should have been 3")
   152  			assert.EqualValues(t, 10, *itprop.MaxLength, "'foo_slice.items.maxLength' should have been 10")
   153  			assert.EqualValues(t, "\\w+", itprop.Pattern, "'foo_slice.items.pattern' should have \\w+")
   154  			assert.Equal(t, "foo", itprop.Example)
   155  
   156  		case "bar_slice":
   157  			assert.Equal(t, "a BarSlice has bars which are strings", header.Description)
   158  			assert.Equal(t, "array", header.Type)
   159  			assert.True(t, header.UniqueItems)
   160  			assert.Equal(t, "pipe", header.CollectionFormat)
   161  			assert.NotNil(t, header.Items, "bar_slice should have had an items property")
   162  			assert.EqualValues(t, 3, *header.MinItems, "'bar_slice' should have had 3 min items")
   163  			assert.EqualValues(t, 10, *header.MaxItems, "'bar_slice' should have had 10 max items")
   164  			itprop := header.Items
   165  			if assert.NotNil(t, itprop) {
   166  				assert.EqualValues(t, 4, *itprop.MinItems, "'bar_slice.items.minItems' should have been 4")
   167  				assert.EqualValues(t, 9, *itprop.MaxItems, "'bar_slice.items.maxItems' should have been 9")
   168  				itprop2 := itprop.Items
   169  				if assert.NotNil(t, itprop2) {
   170  					assert.EqualValues(t, 5, *itprop2.MinItems, "'bar_slice.items.items.minItems' should have been 5")
   171  					assert.EqualValues(t, 8, *itprop2.MaxItems, "'bar_slice.items.items.maxItems' should have been 8")
   172  					itprop3 := itprop2.Items
   173  					if assert.NotNil(t, itprop3) {
   174  						assert.EqualValues(t, 3, *itprop3.MinLength, "'bar_slice.items.items.items.minLength' should have been 3")
   175  						assert.EqualValues(t, 10, *itprop3.MaxLength, "'bar_slice.items.items.items.maxLength' should have been 10")
   176  						assert.EqualValues(t, "\\w+", itprop3.Pattern, "'bar_slice.items.items.items.pattern' should have \\w+")
   177  					}
   178  				}
   179  			}
   180  
   181  		default:
   182  			assert.Fail(t, "unknown property: "+k)
   183  		}
   184  	}
   185  
   186  	assert.NotNil(t, res.Schema)
   187  	aprop := res.Schema
   188  	assert.Equal(t, "array", aprop.Type[0])
   189  	assert.NotNil(t, aprop.Items)
   190  	assert.NotNil(t, aprop.Items.Schema)
   191  	itprop := aprop.Items.Schema
   192  	assert.Len(t, itprop.Properties, 4)
   193  	assert.Len(t, itprop.Required, 3)
   194  	assertProperty(t, itprop, "integer", "id", "int32", "ID")
   195  	iprop, ok := itprop.Properties["id"]
   196  	assert.True(t, ok)
   197  	assert.Equal(t, "ID of this some response instance.\nids in this application start at 11 and are smaller than 1000", iprop.Description)
   198  	assert.EqualValues(t, 1000, *iprop.Maximum)
   199  	assert.True(t, iprop.ExclusiveMaximum, "'id' should have had an exclusive maximum")
   200  	assert.NotNil(t, iprop.Minimum)
   201  	assert.EqualValues(t, 10, *iprop.Minimum)
   202  	assert.True(t, iprop.ExclusiveMinimum, "'id' should have had an exclusive minimum")
   203  
   204  	assertRef(t, itprop, "pet", "Pet", "#/definitions/pet")
   205  	iprop, ok = itprop.Properties["pet"]
   206  	assert.True(t, ok)
   207  	// if itprop.Ref.String() == "" {
   208  	// 	assert.Equal(t, "The Pet to add to this NoModel items bucket.\nPets can appear more than once in the bucket", iprop.Description)
   209  	// }
   210  
   211  	assertProperty(t, itprop, "integer", "quantity", "int16", "Quantity")
   212  	iprop, ok = itprop.Properties["quantity"]
   213  	assert.True(t, ok)
   214  	assert.Equal(t, "The amount of pets to add to this bucket.", iprop.Description)
   215  	assert.EqualValues(t, 1, *iprop.Minimum)
   216  	assert.EqualValues(t, 10, *iprop.Maximum)
   217  
   218  	assertProperty(t, itprop, "string", "notes", "", "Notes")
   219  	iprop, ok = itprop.Properties["notes"]
   220  	assert.True(t, ok)
   221  	assert.Equal(t, "Notes to add to this item.\nThis can be used to add special instructions.", iprop.Description)
   222  
   223  	res, ok = responses["resp"]
   224  	assert.True(t, ok)
   225  	assert.NotNil(t, res.Schema)
   226  	assert.Equal(t, "#/definitions/user", res.Schema.Ref.String())
   227  }
   228  
   229  func TestParseResponses_Issue2007(t *testing.T) {
   230  	sctx := loadClassificationPkgsCtx(t)
   231  	responses := make(map[string]spec.Response)
   232  	td := getResponse(sctx, "GetConfiguration")
   233  	prs := &responseBuilder{
   234  		ctx:  sctx,
   235  		decl: td,
   236  	}
   237  	require.NoError(t, prs.Build(responses))
   238  
   239  	resp := responses["GetConfiguration"]
   240  	require.Len(t, resp.Headers, 0)
   241  	require.NotNil(t, resp.Schema)
   242  
   243  	require.True(t, resp.Schema.Type.Contains("object"))
   244  	require.NotNil(t, resp.Schema.AdditionalProperties)
   245  	require.NotNil(t, resp.Schema.AdditionalProperties.Schema)
   246  	require.True(t, resp.Schema.AdditionalProperties.Schema.Type.Contains("string"))
   247  }
   248  
   249  func TestParseResponses_Issue2011(t *testing.T) {
   250  	sctx := loadClassificationPkgsCtx(t)
   251  	responses := make(map[string]spec.Response)
   252  	td := getResponse(sctx, "NumPlatesResp")
   253  	prs := &responseBuilder{
   254  		ctx:  sctx,
   255  		decl: td,
   256  	}
   257  	require.NoError(t, prs.Build(responses))
   258  
   259  	resp := responses["NumPlatesResp"]
   260  	require.Len(t, resp.Headers, 0)
   261  	require.NotNil(t, resp.Schema)
   262  
   263  	require.True(t, resp.Schema.Type.Contains("object"))
   264  }
   265  
   266  func TestParseResponses_Issue2145(t *testing.T) {
   267  	sctx, err := newScanCtx(&Options{
   268  		Packages: []string{"github.com/AngusLu/go-swagger/fixtures/goparsing/product/..."},
   269  	})
   270  	require.NoError(t, err)
   271  	responses := make(map[string]spec.Response)
   272  	td := getResponse(sctx, "GetProductsResponse")
   273  	prs := &responseBuilder{
   274  		ctx:  sctx,
   275  		decl: td,
   276  	}
   277  	require.NoError(t, prs.Build(responses))
   278  	resp := responses["GetProductsResponse"]
   279  	require.Len(t, resp.Headers, 0)
   280  	require.NotNil(t, resp.Schema)
   281  
   282  	assert.NotEqual(t, 0, len(prs.postDecls)) // should have Product
   283  }