github.com/djarvur/go-swagger@v0.18.0/generator/operation_test.go (about)

     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 generator
    16  
    17  import (
    18  	"bytes"
    19  	"errors"
    20  	"fmt"
    21  	"io/ioutil"
    22  	"log"
    23  	"os"
    24  	"path/filepath"
    25  	"testing"
    26  
    27  	"github.com/go-openapi/analysis"
    28  	"github.com/go-openapi/loads"
    29  	"github.com/go-openapi/spec"
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  func TestUniqueOperationNames(t *testing.T) {
    34  	doc, err := loads.Spec("../fixtures/codegen/todolist.simple.yml")
    35  	if assert.NoError(t, err) {
    36  		sp := doc.Spec()
    37  		sp.Paths.Paths["/tasks"].Post.ID = "saveTask"
    38  		sp.Paths.Paths["/tasks"].Post.AddExtension("origName", "createTask")
    39  		sp.Paths.Paths["/tasks/{id}"].Put.ID = "saveTask"
    40  		sp.Paths.Paths["/tasks/{id}"].Put.AddExtension("origName", "updateTask")
    41  		analyzed := analysis.New(sp)
    42  
    43  		ops := gatherOperations(analyzed, nil)
    44  		assert.Len(t, ops, 6)
    45  		_, exists := ops["saveTask"]
    46  		assert.True(t, exists)
    47  		_, exists = ops["PutTasksID"]
    48  		assert.True(t, exists)
    49  	}
    50  }
    51  
    52  func TestEmptyOperationNames(t *testing.T) {
    53  	doc, err := loads.Spec("../fixtures/codegen/todolist.simple.yml")
    54  	if assert.NoError(t, err) {
    55  		sp := doc.Spec()
    56  		sp.Paths.Paths["/tasks"].Post.ID = ""
    57  		sp.Paths.Paths["/tasks"].Post.AddExtension("origName", "createTask")
    58  		sp.Paths.Paths["/tasks/{id}"].Put.ID = ""
    59  		sp.Paths.Paths["/tasks/{id}"].Put.AddExtension("origName", "updateTask")
    60  		analyzed := analysis.New(sp)
    61  
    62  		ops := gatherOperations(analyzed, nil)
    63  		assert.Len(t, ops, 6)
    64  		_, exists := ops["PostTasks"]
    65  		assert.True(t, exists)
    66  		_, exists = ops["PutTasksID"]
    67  		assert.True(t, exists)
    68  	}
    69  }
    70  
    71  func TestMakeResponseHeader(t *testing.T) {
    72  	b, err := opBuilder("getTasks", "")
    73  	if assert.NoError(t, err) {
    74  		hdr := findResponseHeader(&b.Operation, 200, "X-Rate-Limit")
    75  		gh, er := b.MakeHeader("a", "X-Rate-Limit", *hdr)
    76  		if assert.NoError(t, er) {
    77  			assert.True(t, gh.IsPrimitive)
    78  			assert.Equal(t, "int32", gh.GoType)
    79  			assert.Equal(t, "X-Rate-Limit", gh.Name)
    80  		}
    81  	}
    82  }
    83  
    84  func TestMakeResponseHeaderDefaultValues(t *testing.T) {
    85  	b, err := opBuilder("getTasks", "")
    86  	if assert.NoError(t, err) {
    87  		var testCases = []struct {
    88  			name         string      // input
    89  			typeStr      string      // expected type
    90  			defaultValue interface{} // expected result
    91  		}{
    92  			{"Access-Control-Allow-Origin", "string", "*"},
    93  			{"X-Rate-Limit", "int32", nil},
    94  			{"X-Rate-Limit-Remaining", "int32", float64(42)},
    95  			{"X-Rate-Limit-Reset", "int32", "1449875311"},
    96  			{"X-Rate-Limit-Reset-Human", "string", "3 days"},
    97  			{"X-Rate-Limit-Reset-Human-Number", "string", float64(3)},
    98  		}
    99  
   100  		for _, tc := range testCases {
   101  			// t.Logf("tc: %+v", tc)
   102  			hdr := findResponseHeader(&b.Operation, 200, tc.name)
   103  			assert.NotNil(t, hdr)
   104  			gh, er := b.MakeHeader("a", tc.name, *hdr)
   105  			if assert.NoError(t, er) {
   106  				assert.True(t, gh.IsPrimitive)
   107  				assert.Equal(t, tc.typeStr, gh.GoType)
   108  				assert.Equal(t, tc.name, gh.Name)
   109  				assert.Exactly(t, tc.defaultValue, gh.Default)
   110  			}
   111  		}
   112  	}
   113  }
   114  
   115  func TestMakeResponse(t *testing.T) {
   116  	b, err := opBuilder("getTasks", "")
   117  	if assert.NoError(t, err) {
   118  		resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc}
   119  		resolver.KnownDefs = make(map[string]struct{})
   120  		for k := range b.Doc.Spec().Definitions {
   121  			resolver.KnownDefs[k] = struct{}{}
   122  		}
   123  		gO, err := b.MakeResponse("a", "getTasksSuccess", true, resolver, 200, b.Operation.Responses.StatusCodeResponses[200])
   124  		if assert.NoError(t, err) {
   125  			assert.Len(t, gO.Headers, 6)
   126  			assert.NotNil(t, gO.Schema)
   127  			assert.True(t, gO.Schema.IsArray)
   128  			assert.NotNil(t, gO.Schema.Items)
   129  			assert.False(t, gO.Schema.IsAnonymous)
   130  			assert.Equal(t, "[]*models.Task", gO.Schema.GoType)
   131  		}
   132  	}
   133  }
   134  
   135  func TestMakeResponse_WithAllOfSchema(t *testing.T) {
   136  	b, err := methodPathOpBuilder("get", "/media/search", "../fixtures/codegen/instagram.yml")
   137  	if assert.NoError(t, err) {
   138  		resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc}
   139  		resolver.KnownDefs = make(map[string]struct{})
   140  		for k := range b.Doc.Spec().Definitions {
   141  			resolver.KnownDefs[k] = struct{}{}
   142  		}
   143  		gO, err := b.MakeResponse("a", "get /media/search", true, resolver, 200, b.Operation.Responses.StatusCodeResponses[200])
   144  		if assert.NoError(t, err) {
   145  			if assert.NotNil(t, gO.Schema) {
   146  				assert.Equal(t, "GetMediaSearchBody", gO.Schema.GoType)
   147  			}
   148  			if assert.NotEmpty(t, b.ExtraSchemas) {
   149  				body := b.ExtraSchemas["GetMediaSearchBody"]
   150  				if assert.NotEmpty(t, body.Properties) {
   151  					prop := body.Properties[0]
   152  					assert.Equal(t, "data", prop.Name)
   153  					// is in models only when definition is flattened: otherwise, ExtraSchema is rendered in operations package
   154  					assert.Equal(t, "[]*DataItems0", prop.GoType)
   155  				}
   156  				items := b.ExtraSchemas["DataItems0"]
   157  				if assert.NotEmpty(t, items.AllOf) {
   158  					media := items.AllOf[0]
   159  					// expect #definitions/media to be captured and reused by ExtraSchema
   160  					assert.Equal(t, "models.Media", media.GoType)
   161  				}
   162  			}
   163  		}
   164  	}
   165  }
   166  
   167  func TestMakeOperationParam(t *testing.T) {
   168  	b, err := opBuilder("getTasks", "")
   169  	if assert.NoError(t, err) {
   170  		resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc}
   171  		gO, err := b.MakeParameter("a", resolver, b.Operation.Parameters[0], nil)
   172  		if assert.NoError(t, err) {
   173  			assert.Equal(t, "size", gO.Name)
   174  			assert.True(t, gO.IsPrimitive)
   175  		}
   176  	}
   177  }
   178  
   179  func TestMakeOperationParamItem(t *testing.T) {
   180  	b, err := opBuilder("arrayQueryParams", "../fixtures/codegen/todolist.arrayquery.yml")
   181  	if assert.NoError(t, err) {
   182  		resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc}
   183  		gO, err := b.MakeParameterItem("a", "siString", "ii", "siString", "a.SiString", "query", resolver, b.Operation.Parameters[1].Items, nil)
   184  		if assert.NoError(t, err) {
   185  			assert.Nil(t, gO.Parent)
   186  			assert.True(t, gO.IsPrimitive)
   187  		}
   188  	}
   189  }
   190  
   191  func TestMakeOperation(t *testing.T) {
   192  	b, err := opBuilder("getTasks", "")
   193  	if assert.NoError(t, err) {
   194  		gO, err := b.MakeOperation()
   195  		if assert.NoError(t, err) {
   196  			assert.Equal(t, "getTasks", gO.Name)
   197  			assert.Equal(t, "GET", gO.Method)
   198  			assert.Equal(t, "/tasks", gO.Path)
   199  			assert.Len(t, gO.Params, 2)
   200  			assert.Len(t, gO.Responses, 1)
   201  			assert.NotNil(t, gO.DefaultResponse)
   202  			assert.NotNil(t, gO.SuccessResponse)
   203  		}
   204  	}
   205  }
   206  
   207  func TestRenderOperation_InstagramSearch(t *testing.T) {
   208  	log.SetOutput(ioutil.Discard)
   209  	defer log.SetOutput(os.Stdout)
   210  
   211  	b, err := methodPathOpBuilder("get", "/media/search", "../fixtures/codegen/instagram.yml")
   212  	if assert.NoError(t, err) {
   213  		gO, ero := b.MakeOperation()
   214  		if assert.NoError(t, ero) {
   215  			buf := bytes.NewBuffer(nil)
   216  			opts := opts()
   217  			ert := templates.MustGet("serverOperation").Execute(buf, gO)
   218  			if assert.NoError(t, ert) {
   219  				ff, erf := opts.LanguageOpts.FormatContent("operation.go", buf.Bytes())
   220  				if assert.NoError(t, erf) {
   221  					res := string(ff)
   222  					assertInCode(t, "type GetMediaSearchOKBody struct {", res)
   223  					// codegen does not assumes objects are only in models
   224  					// this is inlined
   225  					assertInCode(t, "Data []*DataItems0 `json:\"data\"`", res)
   226  					assertInCode(t, "type DataItems0 struct {", res)
   227  					// this is a definition: expect this definition to be reused from the models pkg
   228  					assertInCode(t, "models.Media", res)
   229  				} else {
   230  					fmt.Println(buf.String())
   231  					t.FailNow()
   232  				}
   233  			} else {
   234  				t.FailNow()
   235  			}
   236  
   237  			buf = bytes.NewBuffer(nil)
   238  			ert = templates.MustGet("serverResponses").Execute(buf, gO)
   239  			if assert.NoError(t, ert) {
   240  				ff, erf := opts.LanguageOpts.FormatContent("response.go", buf.Bytes())
   241  				if assert.NoError(t, erf) {
   242  					res := string(ff)
   243  					// codegen does not assumes objects are only in models
   244  					assertInCode(t, "type GetMediaSearchOK struct {", res)
   245  					assertInCode(t, "GetMediaSearchOKBody", res)
   246  				} else {
   247  					fmt.Println(buf.String())
   248  					t.FailNow()
   249  				}
   250  			} else {
   251  				t.FailNow()
   252  			}
   253  		}
   254  	}
   255  	b, err = methodPathOpBuilderWithFlatten("get", "/media/search", "../fixtures/codegen/instagram.yml")
   256  	if assert.NoError(t, err) {
   257  		gO, ero := b.MakeOperation()
   258  		if assert.NoError(t, ero) {
   259  			buf := bytes.NewBuffer(nil)
   260  			opts := opts()
   261  			ert := templates.MustGet("serverOperation").Execute(buf, gO)
   262  			if assert.NoError(t, ert) {
   263  				ff, erf := opts.LanguageOpts.FormatContent("operation.go", buf.Bytes())
   264  				if assert.NoError(t, erf) {
   265  					res := string(ff)
   266  					assertNotInCode(t, "DataItems0", res)
   267  					assertNotInCode(t, "models", res)
   268  				} else {
   269  					fmt.Println(buf.String())
   270  					t.FailNow()
   271  				}
   272  			} else {
   273  				t.FailNow()
   274  			}
   275  			buf = bytes.NewBuffer(nil)
   276  			ert = templates.MustGet("serverResponses").Execute(buf, gO)
   277  			if assert.NoError(t, ert) {
   278  				ff, erf := opts.LanguageOpts.FormatContent("operation.go", buf.Bytes())
   279  				if assert.NoError(t, erf) {
   280  					res := string(ff)
   281  					assertInCode(t, "Payload *models.GetMediaSearchOKBody", res)
   282  				} else {
   283  					fmt.Println(buf.String())
   284  				}
   285  			}
   286  		}
   287  	}
   288  }
   289  
   290  func methodPathOpBuilder(method, path, fname string) (codeGenOpBuilder, error) {
   291  	if fname == "" {
   292  		fname = "../fixtures/codegen/todolist.simple.yml"
   293  	}
   294  
   295  	specDoc, err := loads.Spec(fname)
   296  	if err != nil {
   297  		return codeGenOpBuilder{}, err
   298  	}
   299  
   300  	analyzed := analysis.New(specDoc.Spec())
   301  	op, ok := analyzed.OperationFor(method, path)
   302  	if !ok {
   303  		return codeGenOpBuilder{}, errors.New("No operation could be found for " + method + " " + path)
   304  	}
   305  
   306  	return codeGenOpBuilder{
   307  		Name:          method + " " + path,
   308  		Method:        method,
   309  		Path:          path,
   310  		APIPackage:    "restapi",
   311  		ModelsPackage: "models",
   312  		Principal:     "models.User",
   313  		Target:        ".",
   314  		Operation:     *op,
   315  		Doc:           specDoc,
   316  		Analyzed:      analyzed,
   317  		Authed:        false,
   318  		ExtraSchemas:  make(map[string]GenSchema),
   319  		GenOpts:       opts(),
   320  	}, nil
   321  }
   322  
   323  // methodPathOpBuilderWithFlatten prepares an operation build based on method and path, with spec full flattening
   324  func methodPathOpBuilderWithFlatten(method, path, fname string) (codeGenOpBuilder, error) {
   325  	if fname == "" {
   326  		fname = "../fixtures/codegen/todolist.simple.yml"
   327  	}
   328  
   329  	specDoc, err := loads.Spec(fname)
   330  	if err != nil {
   331  		return codeGenOpBuilder{}, err
   332  	}
   333  
   334  	o := opBuildGetOpts(fname, true, false) // flatten: true, minimal: false
   335  
   336  	specDoc, err = validateAndFlattenSpec(o, specDoc)
   337  	if err != nil {
   338  		return codeGenOpBuilder{}, err
   339  	}
   340  
   341  	analyzed := analysis.New(specDoc.Spec())
   342  	op, ok := analyzed.OperationFor(method, path)
   343  	if !ok {
   344  		return codeGenOpBuilder{}, errors.New("No operation could be found for " + method + " " + path)
   345  	}
   346  
   347  	return codeGenOpBuilder{
   348  		Name:          method + " " + path,
   349  		Method:        method,
   350  		Path:          path,
   351  		APIPackage:    "restapi",
   352  		ModelsPackage: "models",
   353  		Principal:     "models.User",
   354  		Target:        ".",
   355  		Operation:     *op,
   356  		Doc:           specDoc,
   357  		Analyzed:      analyzed,
   358  		Authed:        false,
   359  		ExtraSchemas:  make(map[string]GenSchema),
   360  		GenOpts:       opts(),
   361  	}, nil
   362  }
   363  
   364  // opBuilderWithOpts prepares the making of an operation with spec flattening options
   365  func opBuilderWithOpts(name, fname string, o *GenOpts) (codeGenOpBuilder, error) {
   366  	if fname == "" {
   367  		// default fixture
   368  		fname = "../fixtures/codegen/todolist.simple.yml"
   369  	}
   370  
   371  	if !filepath.IsAbs(fname) {
   372  		cwd, _ := os.Getwd()
   373  		fname = filepath.Join(cwd, fname)
   374  	}
   375  
   376  	specDoc, err := loads.Spec(fname)
   377  	if err != nil {
   378  		return codeGenOpBuilder{}, err
   379  	}
   380  	o.Spec = fname
   381  
   382  	log.SetOutput(ioutil.Discard)
   383  	defer log.SetOutput(os.Stdout)
   384  	specDoc, err = validateAndFlattenSpec(o, specDoc)
   385  	if err != nil {
   386  		return codeGenOpBuilder{}, err
   387  	}
   388  	log.SetOutput(os.Stdout)
   389  
   390  	analyzed := analysis.New(specDoc.Spec())
   391  
   392  	method, path, op, ok := analyzed.OperationForName(name)
   393  	if !ok {
   394  		return codeGenOpBuilder{}, errors.New("No operation could be found for " + name)
   395  	}
   396  
   397  	return codeGenOpBuilder{
   398  		Name:          name,
   399  		Method:        method,
   400  		Path:          path,
   401  		BasePath:      specDoc.BasePath(),
   402  		APIPackage:    "restapi",
   403  		ModelsPackage: "models",
   404  		Principal:     "models.User",
   405  		Target:        ".",
   406  		Operation:     *op,
   407  		Doc:           specDoc,
   408  		Analyzed:      analyzed,
   409  		Authed:        false,
   410  		ExtraSchemas:  make(map[string]GenSchema),
   411  		GenOpts:       o, // opts()??
   412  	}, nil
   413  }
   414  
   415  func opBuildGetOpts(specName string, withFlatten bool, withMinimalFlatten bool) (opts *GenOpts) {
   416  	opts = &GenOpts{}
   417  	if erd := opts.EnsureDefaults(); erd != nil {
   418  		panic("Cannot initialize GenOpts")
   419  	}
   420  	opts.ValidateSpec = true
   421  	opts.FlattenOpts.Expand = !withFlatten
   422  	opts.FlattenOpts.Minimal = withMinimalFlatten
   423  	opts.Spec = specName
   424  	return
   425  }
   426  
   427  // opBuilderWithFlatten prepares the making of an operation with spec full flattening prior to rendering
   428  func opBuilderWithFlatten(name, fname string) (codeGenOpBuilder, error) {
   429  	o := opBuildGetOpts(fname, true, false) // flatten: true, minimal: false
   430  	return opBuilderWithOpts(name, fname, o)
   431  }
   432  
   433  // opBuilderWithExpand prepares the making of an operation with spec expansion prior to rendering
   434  func opBuilderWithExpand(name, fname string) (codeGenOpBuilder, error) {
   435  	o := opBuildGetOpts(fname, false, false) // flatten: false => expand
   436  	return opBuilderWithOpts(name, fname, o)
   437  }
   438  
   439  // opBuilder prepares the making of an operation with spec minimal flattening (default for CLI)
   440  func opBuilder(name, fname string) (codeGenOpBuilder, error) {
   441  	o := opBuildGetOpts(fname, true, true) // flatten:true, minimal: true
   442  	// some fixtures do not fully validate - skip this
   443  	o.ValidateSpec = false
   444  	return opBuilderWithOpts(name, fname, o)
   445  	/*
   446  		if fname == "" {
   447  			fname = "../fixtures/codegen/todolist.simple.yml"
   448  		}
   449  
   450  		if !filepath.IsAbs(fname) {
   451  			cwd, _ := os.Getwd()
   452  			fname = filepath.Join(cwd, fname)
   453  		}
   454  
   455  		specDoc, err := loads.Spec(fname)
   456  		if err != nil {
   457  			return codeGenOpBuilder{}, err
   458  		}
   459  		if err != nil {
   460  			return codeGenOpBuilder{}, err
   461  		}
   462  
   463  		analyzed := analysis.New(specDoc.Spec())
   464  
   465  		method, path, op, ok := analyzed.OperationForName(name)
   466  		if !ok {
   467  			return codeGenOpBuilder{}, errors.New("No operation could be found for " + name)
   468  		}
   469  
   470  		return codeGenOpBuilder{
   471  			Name:          name,
   472  			Method:        method,
   473  			Path:          path,
   474  			BasePath:      specDoc.BasePath(),
   475  			APIPackage:    "restapi",
   476  			ModelsPackage: "models",
   477  			Principal:     "models.User",
   478  			Target:        ".",
   479  			Operation:     *op,
   480  			Doc:           specDoc,
   481  			Analyzed:      analyzed,
   482  			Authed:        false,
   483  			ExtraSchemas:  make(map[string]GenSchema),
   484  			GenOpts:       opts(),
   485  		}, nil
   486  	*/
   487  }
   488  
   489  func findResponseHeader(op *spec.Operation, code int, name string) *spec.Header {
   490  	resp := op.Responses.Default
   491  	if code > 0 {
   492  		bb, ok := op.Responses.StatusCodeResponses[code]
   493  		if ok {
   494  			resp = &bb
   495  		}
   496  	}
   497  
   498  	if resp == nil {
   499  		return nil
   500  	}
   501  
   502  	hdr, ok := resp.Headers[name]
   503  	if !ok {
   504  		return nil
   505  	}
   506  
   507  	return &hdr
   508  }
   509  
   510  func TestDateFormat_Spec1(t *testing.T) {
   511  	b, err := opBuilder("putTesting", "../fixtures/bugs/193/spec1.json")
   512  	if assert.NoError(t, err) {
   513  		op, err := b.MakeOperation()
   514  		if assert.NoError(t, err) {
   515  			buf := bytes.NewBuffer(nil)
   516  			opts := opts()
   517  			opts.defaultsEnsured = false
   518  			opts.IsClient = true
   519  			err = opts.EnsureDefaults()
   520  			assert.NoError(t, err)
   521  			err = templates.MustGet("clientParameter").Execute(buf, op)
   522  			if assert.NoError(t, err) {
   523  				ff, err := opts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes())
   524  				if assert.NoError(t, err) {
   525  					res := string(ff)
   526  					assertInCode(t, "frTestingThis.String()", res)
   527  				} else {
   528  					fmt.Println(buf.String())
   529  				}
   530  			}
   531  		}
   532  	}
   533  }
   534  
   535  func TestDateFormat_Spec2(t *testing.T) {
   536  	b, err := opBuilder("putTesting", "../fixtures/bugs/193/spec2.json")
   537  	if assert.NoError(t, err) {
   538  		op, err := b.MakeOperation()
   539  		if assert.NoError(t, err) {
   540  			buf := bytes.NewBuffer(nil)
   541  			opts := opts()
   542  			opts.defaultsEnsured = false
   543  			opts.IsClient = true
   544  			err = opts.EnsureDefaults()
   545  			assert.NoError(t, err)
   546  			err = templates.MustGet("clientParameter").Execute(buf, op)
   547  			if assert.NoError(t, err) {
   548  				ff, err := opts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes())
   549  				if assert.NoError(t, err) {
   550  					res := string(ff)
   551  					assertInCode(t, "valuesTestingThis = append(valuesTestingThis, v.String())", res)
   552  				} else {
   553  					fmt.Println(buf.String())
   554  				}
   555  			}
   556  		}
   557  	}
   558  }
   559  
   560  func TestBuilder_Issue1703(t *testing.T) {
   561  	log.SetOutput(ioutil.Discard)
   562  	defer log.SetOutput(os.Stdout)
   563  	dr, err := os.Getwd()
   564  	assert.NoError(t, err)
   565  
   566  	opts := &GenOpts{
   567  		Spec:              filepath.FromSlash("../fixtures/codegen/existing-model.yml"),
   568  		IncludeModel:      true,
   569  		IncludeValidator:  true,
   570  		IncludeHandler:    true,
   571  		IncludeParameters: true,
   572  		IncludeResponses:  true,
   573  		IncludeMain:       true,
   574  		APIPackage:        "restapi",
   575  		ModelPackage:      "model",
   576  		ServerPackage:     "server",
   577  		ClientPackage:     "client",
   578  		Target:            dr,
   579  	}
   580  	err = opts.EnsureDefaults()
   581  	assert.NoError(t, err)
   582  	appGen, err := newAppGenerator("x-go-type-import-bug", nil, nil, opts)
   583  	if assert.NoError(t, err) {
   584  		op, err := appGen.makeCodegenApp()
   585  		if assert.NoError(t, err) {
   586  			for _, o := range op.Operations {
   587  				buf := bytes.NewBuffer(nil)
   588  				err := templates.MustGet("serverResponses").Execute(buf, o)
   589  				if assert.NoError(t, err) {
   590  					ff, err := appGen.GenOpts.LanguageOpts.FormatContent("response.go", buf.Bytes())
   591  					if assert.NoError(t, err) {
   592  						res := string(ff)
   593  						assertInCode(t, "jwk \"github.com/user/package\"", res)
   594  					} else {
   595  						fmt.Println(buf.String())
   596  					}
   597  				}
   598  			}
   599  		}
   600  	}
   601  }
   602  
   603  func TestBuilder_Issue287(t *testing.T) {
   604  	log.SetOutput(ioutil.Discard)
   605  	defer log.SetOutput(os.Stdout)
   606  	dr, _ := os.Getwd()
   607  
   608  	opts := &GenOpts{
   609  		Spec:              filepath.FromSlash("../fixtures/bugs/287/swagger.yml"),
   610  		IncludeModel:      true,
   611  		IncludeValidator:  true,
   612  		IncludeHandler:    true,
   613  		IncludeParameters: true,
   614  		IncludeResponses:  true,
   615  		IncludeMain:       true,
   616  		APIPackage:        "restapi",
   617  		ModelPackage:      "model",
   618  		ServerPackage:     "server",
   619  		ClientPackage:     "client",
   620  		Target:            dr,
   621  	}
   622  	err := opts.EnsureDefaults()
   623  	assert.NoError(t, err)
   624  	appGen, err := newAppGenerator("plainTexter", nil, nil, opts)
   625  	if assert.NoError(t, err) {
   626  		op, err := appGen.makeCodegenApp()
   627  		if assert.NoError(t, err) {
   628  			buf := bytes.NewBuffer(nil)
   629  			err := templates.MustGet("serverBuilder").Execute(buf, op)
   630  			if assert.NoError(t, err) {
   631  				ff, err := appGen.GenOpts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes())
   632  				if assert.NoError(t, err) {
   633  					res := string(ff)
   634  					assertInCode(t, "case \"text/plain\":", res)
   635  				} else {
   636  					fmt.Println(buf.String())
   637  				}
   638  			}
   639  		}
   640  	}
   641  }
   642  
   643  func TestBuilder_Issue465(t *testing.T) {
   644  	log.SetOutput(ioutil.Discard)
   645  	defer log.SetOutput(os.Stdout)
   646  	dr, _ := os.Getwd()
   647  	opts := &GenOpts{
   648  		Spec:              filepath.FromSlash("../fixtures/bugs/465/swagger.yml"),
   649  		IncludeModel:      true,
   650  		IncludeValidator:  true,
   651  		IncludeHandler:    true,
   652  		IncludeParameters: true,
   653  		IncludeResponses:  true,
   654  		IncludeMain:       true,
   655  		APIPackage:        "restapi",
   656  		ModelPackage:      "model",
   657  		ServerPackage:     "server",
   658  		ClientPackage:     "client",
   659  		Target:            dr,
   660  		IsClient:          true,
   661  	}
   662  	err := opts.EnsureDefaults()
   663  	assert.NoError(t, err)
   664  	appGen, err := newAppGenerator("plainTexter", nil, nil, opts)
   665  
   666  	if assert.NoError(t, err) {
   667  		op, err := appGen.makeCodegenApp()
   668  		if assert.NoError(t, err) {
   669  			buf := bytes.NewBuffer(nil)
   670  			err := templates.MustGet("clientFacade").Execute(buf, op)
   671  			if assert.NoError(t, err) {
   672  				ff, err := appGen.GenOpts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes())
   673  				if assert.NoError(t, err) {
   674  					res := string(ff)
   675  					assertInCode(t, "/v1/fancyAPI", res)
   676  				} else {
   677  					fmt.Println(buf.String())
   678  				}
   679  			}
   680  		}
   681  	}
   682  }
   683  
   684  func TestBuilder_Issue500(t *testing.T) {
   685  	log.SetOutput(ioutil.Discard)
   686  	defer log.SetOutput(os.Stdout)
   687  	dr, _ := os.Getwd()
   688  	opts := &GenOpts{
   689  		Spec:              filepath.FromSlash("../fixtures/bugs/500/swagger.yml"),
   690  		IncludeModel:      true,
   691  		IncludeValidator:  true,
   692  		IncludeHandler:    true,
   693  		IncludeParameters: true,
   694  		IncludeResponses:  true,
   695  		IncludeMain:       true,
   696  		APIPackage:        "restapi",
   697  		ModelPackage:      "model",
   698  		ServerPackage:     "server",
   699  		ClientPackage:     "client",
   700  		Target:            dr,
   701  	}
   702  	err := opts.EnsureDefaults()
   703  	assert.NoError(t, err)
   704  	appGen, err := newAppGenerator("multiTags", nil, nil, opts)
   705  	if assert.NoError(t, err) {
   706  		op, err := appGen.makeCodegenApp()
   707  		if assert.NoError(t, err) {
   708  			buf := bytes.NewBuffer(nil)
   709  			err := templates.MustGet("serverBuilder").Execute(buf, op)
   710  			if assert.NoError(t, err) {
   711  				ff, err := appGen.GenOpts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes())
   712  				if assert.NoError(t, err) {
   713  					res := string(ff)
   714  					assertNotInCode(t, `o.handlers["GET"]["/payment/{invoice_id}/payments/{payment_id}"] = invoices.NewGetPaymentByID(o.context, o.InvoicesGetPaymentByIDHandler)`, res)
   715  					assertInCode(t, `o.handlers["GET"]["/payment/{invoice_id}/payments/{payment_id}"] = NewGetPaymentByID(o.context, o.GetPaymentByIDHandler)`, res)
   716  				} else {
   717  					fmt.Println(buf.String())
   718  				}
   719  			}
   720  		}
   721  	}
   722  }
   723  
   724  func TestGenClient_IllegalBOM(t *testing.T) {
   725  	b, err := methodPathOpBuilder("get", "/v3/attachments/{attachmentId}", "../fixtures/bugs/727/swagger.json")
   726  	if assert.NoError(t, err) {
   727  		op, err := b.MakeOperation()
   728  		if assert.NoError(t, err) {
   729  			buf := bytes.NewBuffer(nil)
   730  			opts := opts()
   731  			opts.defaultsEnsured = false
   732  			opts.IsClient = true
   733  			err = opts.EnsureDefaults()
   734  			assert.NoError(t, err)
   735  			err = templates.MustGet("clientResponse").Execute(buf, op)
   736  			assert.NoError(t, err)
   737  		}
   738  	}
   739  }
   740  
   741  func TestGenClient_CustomFormatPath(t *testing.T) {
   742  	b, err := methodPathOpBuilder("get", "/mosaic/experimental/series/{SeriesId}/mosaics", "../fixtures/bugs/789/swagger.yml")
   743  	if assert.NoError(t, err) {
   744  		op, err := b.MakeOperation()
   745  		if assert.NoError(t, err) {
   746  			buf := bytes.NewBuffer(nil)
   747  			opts := opts()
   748  			opts.defaultsEnsured = false
   749  			opts.IsClient = true
   750  			err = opts.EnsureDefaults()
   751  			assert.NoError(t, err)
   752  			err = templates.MustGet("clientParameter").Execute(buf, op)
   753  			if assert.NoError(t, err) {
   754  				assertInCode(t, `if err := r.SetPathParam("SeriesId", o.SeriesID.String()); err != nil`, buf.String())
   755  			}
   756  		}
   757  	}
   758  }
   759  
   760  func TestGenClient_Issue733(t *testing.T) {
   761  	b, err := opBuilder("get_characters_character_id_mail_mail_id", "../fixtures/bugs/733/swagger.json")
   762  	if assert.NoError(t, err) {
   763  		op, err := b.MakeOperation()
   764  		if assert.NoError(t, err) {
   765  			buf := bytes.NewBuffer(nil)
   766  			opts := opts()
   767  			opts.defaultsEnsured = false
   768  			opts.IsClient = true
   769  			err = opts.EnsureDefaults()
   770  			assert.NoError(t, err)
   771  			err = templates.MustGet("clientResponse").Execute(buf, op)
   772  			if assert.NoError(t, err) {
   773  				assertInCode(t, "Labels []*int64 `json:\"labels\"`", buf.String())
   774  			}
   775  		}
   776  	}
   777  }
   778  
   779  func TestGenServerIssue890_ValidationTrueFlatteningTrue(t *testing.T) {
   780  	log.SetOutput(ioutil.Discard)
   781  	defer log.SetOutput(os.Stdout)
   782  	dr, _ := os.Getwd()
   783  	opts := &GenOpts{
   784  		Spec:              filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"),
   785  		IncludeModel:      true,
   786  		IncludeValidator:  true,
   787  		IncludeHandler:    true,
   788  		IncludeParameters: true,
   789  		IncludeResponses:  true,
   790  		IncludeMain:       true,
   791  		ValidateSpec:      true,
   792  		APIPackage:        "restapi",
   793  		ModelPackage:      "model",
   794  		ServerPackage:     "server",
   795  		ClientPackage:     "client",
   796  		Target:            dr,
   797  		IsClient:          true,
   798  	}
   799  
   800  	//Testing Server Generation
   801  	err := opts.EnsureDefaults()
   802  	// Full flattening
   803  	opts.FlattenOpts.Expand = false
   804  	opts.FlattenOpts.Minimal = false
   805  	assert.NoError(t, err)
   806  	appGen, err := newAppGenerator("JsonRefOperation", nil, nil, opts)
   807  	if assert.NoError(t, err) {
   808  		op, err := appGen.makeCodegenApp()
   809  		if assert.NoError(t, err) {
   810  			buf := bytes.NewBuffer(nil)
   811  			err := templates.MustGet("serverOperation").Execute(buf, op.Operations[0])
   812  			if assert.NoError(t, err) {
   813  				filecontent, err := appGen.GenOpts.LanguageOpts.FormatContent("operation.go", buf.Bytes())
   814  				if assert.NoError(t, err) {
   815  					res := string(filecontent)
   816  					assertInCode(t, "GetHealthCheck", res)
   817  				} else {
   818  					fmt.Println(buf.String())
   819  				}
   820  			}
   821  		}
   822  	}
   823  }
   824  
   825  func TestGenClientIssue890_ValidationTrueFlatteningTrue(t *testing.T) {
   826  	log.SetOutput(ioutil.Discard)
   827  	defer func() {
   828  		log.SetOutput(os.Stdout)
   829  		dr, _ := os.Getwd()
   830  		_ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi"))
   831  	}()
   832  	opts := testGenOpts()
   833  	opts.Spec = "../fixtures/bugs/890/swagger.yaml"
   834  	opts.ValidateSpec = true
   835  	opts.FlattenOpts.Minimal = false
   836  	// Testing this is enough as there is only one operation which is specified as $ref.
   837  	// If this doesn't get resolved then there will be an error definitely.
   838  	assert.NoError(t, GenerateClient("foo", nil, nil, &opts))
   839  }
   840  
   841  func TestGenServerIssue890_ValidationFalseFlattenTrue(t *testing.T) {
   842  	log.SetOutput(ioutil.Discard)
   843  	defer log.SetOutput(os.Stdout)
   844  	dr, _ := os.Getwd()
   845  	opts := &GenOpts{
   846  		Spec:              filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"),
   847  		IncludeModel:      true,
   848  		IncludeValidator:  true,
   849  		IncludeHandler:    true,
   850  		IncludeParameters: true,
   851  		IncludeResponses:  true,
   852  		IncludeMain:       true,
   853  		APIPackage:        "restapi",
   854  		ModelPackage:      "model",
   855  		ServerPackage:     "server",
   856  		ClientPackage:     "client",
   857  		Target:            dr,
   858  		IsClient:          true,
   859  	}
   860  
   861  	//Testing Server Generation
   862  	err := opts.EnsureDefaults()
   863  	// full flattening
   864  	opts.FlattenOpts.Minimal = false
   865  	assert.NoError(t, err)
   866  	appGen, err := newAppGenerator("JsonRefOperation", nil, nil, opts)
   867  	if assert.NoError(t, err) {
   868  		op, err := appGen.makeCodegenApp()
   869  		if assert.NoError(t, err) {
   870  			buf := bytes.NewBuffer(nil)
   871  			err := templates.MustGet("serverOperation").Execute(buf, op.Operations[0])
   872  			if assert.NoError(t, err) {
   873  				filecontent, err := appGen.GenOpts.LanguageOpts.FormatContent("operation.go", buf.Bytes())
   874  				if assert.NoError(t, err) {
   875  					res := string(filecontent)
   876  					assertInCode(t, "GetHealthCheck", res)
   877  				} else {
   878  					fmt.Println(buf.String())
   879  				}
   880  			}
   881  		}
   882  	}
   883  }
   884  
   885  func TestGenClientIssue890_ValidationFalseFlatteningTrue(t *testing.T) {
   886  	log.SetOutput(ioutil.Discard)
   887  	defer func() {
   888  		log.SetOutput(os.Stdout)
   889  		dr, _ := os.Getwd()
   890  		_ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi"))
   891  	}()
   892  	opts := testGenOpts()
   893  	opts.Spec = "../fixtures/bugs/890/swagger.yaml"
   894  	opts.ValidateSpec = false
   895  	// full flattening
   896  	opts.FlattenOpts.Minimal = false
   897  	// Testing this is enough as there is only one operation which is specified as $ref.
   898  	// If this doesn't get resolved then there will be an error definitely.
   899  	assert.NoError(t, GenerateClient("foo", nil, nil, &opts))
   900  }
   901  
   902  func TestGenServerIssue890_ValidationFalseFlattenFalse(t *testing.T) {
   903  	log.SetOutput(ioutil.Discard)
   904  	defer log.SetOutput(os.Stdout)
   905  	dr, _ := os.Getwd()
   906  	opts := &GenOpts{
   907  		Spec:              filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"),
   908  		IncludeModel:      true,
   909  		IncludeValidator:  true,
   910  		IncludeHandler:    true,
   911  		IncludeParameters: true,
   912  		IncludeResponses:  true,
   913  		IncludeMain:       true,
   914  		ValidateSpec:      false,
   915  		APIPackage:        "restapi",
   916  		ModelPackage:      "model",
   917  		ServerPackage:     "server",
   918  		ClientPackage:     "client",
   919  		Target:            dr,
   920  		IsClient:          true,
   921  	}
   922  
   923  	//Testing Server Generation
   924  	err := opts.EnsureDefaults()
   925  	// minimal flattening
   926  	opts.FlattenOpts.Minimal = true
   927  	assert.NoError(t, err)
   928  	_, err = newAppGenerator("JsonRefOperation", nil, nil, opts)
   929  	// if flatten is not set, expand takes over so this would resume normally
   930  	assert.NoError(t, err)
   931  }
   932  
   933  func TestGenClientIssue890_ValidationFalseFlattenFalse(t *testing.T) {
   934  	log.SetOutput(ioutil.Discard)
   935  	defer func() {
   936  		dr, _ := os.Getwd()
   937  		_ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi"))
   938  		log.SetOutput(os.Stdout)
   939  	}()
   940  	opts := testGenOpts()
   941  	opts.Spec = "../fixtures/bugs/890/swagger.yaml"
   942  	opts.ValidateSpec = false
   943  	// minimal flattening
   944  	opts.FlattenOpts.Minimal = true
   945  	// Testing this is enough as there is only one operation which is specified as $ref.
   946  	// If this doesn't get resolved then there will be an error definitely.
   947  	// New: Now if flatten is false, expand takes over so server generation should resume normally
   948  	assert.NoError(t, GenerateClient("foo", nil, nil, &opts))
   949  }
   950  
   951  func TestGenServerIssue890_ValidationTrueFlattenFalse(t *testing.T) {
   952  	log.SetOutput(ioutil.Discard)
   953  	defer log.SetOutput(os.Stdout)
   954  	dr, _ := os.Getwd()
   955  	opts := &GenOpts{
   956  		Spec:              filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"),
   957  		IncludeModel:      true,
   958  		IncludeValidator:  true,
   959  		IncludeHandler:    true,
   960  		IncludeParameters: true,
   961  		IncludeResponses:  true,
   962  		IncludeMain:       true,
   963  		ValidateSpec:      true,
   964  		APIPackage:        "restapi",
   965  		ModelPackage:      "model",
   966  		ServerPackage:     "server",
   967  		ClientPackage:     "client",
   968  		Target:            dr,
   969  		IsClient:          true,
   970  	}
   971  
   972  	//Testing Server Generation
   973  	err := opts.EnsureDefaults()
   974  	// minimal flattening
   975  	opts.FlattenOpts.Minimal = true
   976  	assert.NoError(t, err)
   977  	_, err = newAppGenerator("JsonRefOperation", nil, nil, opts)
   978  	// now if flatten is false, expand takes over so server generation should resume normally
   979  	assert.NoError(t, err)
   980  }
   981  
   982  func TestGenServerWithTemplate(t *testing.T) {
   983  	log.SetOutput(ioutil.Discard)
   984  	defer log.SetOutput(os.Stdout)
   985  	dr, _ := os.Getwd()
   986  
   987  	tests := []struct {
   988  		name      string
   989  		opts      *GenOpts
   990  		wantError bool
   991  	}{
   992  		{
   993  			name: "None_existing_contributor_tempalte",
   994  			opts: &GenOpts{
   995  				Spec:              filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"),
   996  				IncludeModel:      true,
   997  				IncludeValidator:  true,
   998  				IncludeHandler:    true,
   999  				IncludeParameters: true,
  1000  				IncludeResponses:  true,
  1001  				IncludeMain:       true,
  1002  				ValidateSpec:      true,
  1003  				APIPackage:        "restapi",
  1004  				ModelPackage:      "model",
  1005  				ServerPackage:     "server",
  1006  				ClientPackage:     "client",
  1007  				Target:            dr,
  1008  				IsClient:          true,
  1009  				Template:          "InvalidTemplate",
  1010  			},
  1011  			wantError: true,
  1012  		},
  1013  		{
  1014  			name: "Existing_contributor",
  1015  			opts: &GenOpts{
  1016  				Spec:              filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"),
  1017  				IncludeModel:      true,
  1018  				IncludeValidator:  true,
  1019  				IncludeHandler:    true,
  1020  				IncludeParameters: true,
  1021  				IncludeResponses:  true,
  1022  				IncludeMain:       true,
  1023  				ValidateSpec:      true,
  1024  				APIPackage:        "restapi",
  1025  				ModelPackage:      "model",
  1026  				ServerPackage:     "server",
  1027  				ClientPackage:     "client",
  1028  				Target:            dr,
  1029  				IsClient:          true,
  1030  				Template:          "stratoscale",
  1031  			},
  1032  			wantError: false,
  1033  		},
  1034  	}
  1035  
  1036  	for _, tt := range tests {
  1037  		t.Run(tt.name, func(t *testing.T) {
  1038  			//Testing Server Generation
  1039  			err := tt.opts.EnsureDefaults()
  1040  			// minimal flattening
  1041  			tt.opts.FlattenOpts.Minimal = true
  1042  			assert.NoError(t, err)
  1043  			_, err = newAppGenerator("JsonRefOperation", nil, nil, tt.opts)
  1044  			if tt.wantError {
  1045  				assert.Error(t, err)
  1046  			} else {
  1047  				assert.NoError(t, err)
  1048  			}
  1049  		})
  1050  	}
  1051  }
  1052  
  1053  func TestGenClientIssue890_ValidationTrueFlattenFalse(t *testing.T) {
  1054  	log.SetOutput(ioutil.Discard)
  1055  	defer func() {
  1056  		log.SetOutput(os.Stdout)
  1057  		dr, _ := os.Getwd()
  1058  		_ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi"))
  1059  	}()
  1060  	opts := testGenOpts()
  1061  	opts.Spec = filepath.FromSlash("../fixtures/bugs/890/swagger.yaml")
  1062  	opts.ValidateSpec = true
  1063  	// Testing this is enough as there is only one operation which is specified as $ref.
  1064  	// If this doesn't get resolved then there will be an error definitely.
  1065  	// same here: now if flatten doesn't resume, expand takes over
  1066  	assert.NoError(t, GenerateClient("foo", nil, nil, &opts))
  1067  }
  1068  
  1069  // This tests that securityDefinitions generate stable code
  1070  func TestBuilder_Issue1214(t *testing.T) {
  1071  	const any = `(.|\n)+`
  1072  	log.SetOutput(ioutil.Discard)
  1073  	defer log.SetOutput(os.Stdout)
  1074  	dr, _ := os.Getwd()
  1075  	opts := &GenOpts{
  1076  		Spec:              filepath.FromSlash("../fixtures/bugs/1214/fixture-1214.yaml"),
  1077  		IncludeModel:      true,
  1078  		IncludeValidator:  true,
  1079  		IncludeHandler:    true,
  1080  		IncludeParameters: true,
  1081  		IncludeResponses:  true,
  1082  		IncludeMain:       true,
  1083  		APIPackage:        "restapi",
  1084  		ModelPackage:      "model",
  1085  		ServerPackage:     "server",
  1086  		ClientPackage:     "client",
  1087  		Target:            dr,
  1088  		IsClient:          false,
  1089  	}
  1090  	err := opts.EnsureDefaults()
  1091  	assert.NoError(t, err)
  1092  	appGen, err := newAppGenerator("fixture-1214", nil, nil, opts)
  1093  	if assert.NoError(t, err) {
  1094  		op, err := appGen.makeCodegenApp()
  1095  		if assert.NoError(t, err) {
  1096  			for i := 0; i < 5; i++ {
  1097  				buf := bytes.NewBuffer(nil)
  1098  				ert := templates.MustGet("serverConfigureapi").Execute(buf, op)
  1099  				if assert.NoError(t, ert) {
  1100  					ff, erf := appGen.GenOpts.LanguageOpts.FormatContent("fixture_1214_configure_api.go", buf.Bytes())
  1101  					if assert.NoError(t, erf) {
  1102  						res := string(ff)
  1103  						assertRegexpInCode(t, any+
  1104  							`api\.AAuth = func\(user string, pass string\)`+any+
  1105  							`api\.BAuth = func\(token string\)`+any+
  1106  							`api\.CAuth = func\(token string\)`+any+
  1107  							`api\.DAuth = func\(token string\)`+any+
  1108  							`api\.EAuth = func\(token string, scopes \[\]string\)`+any, res)
  1109  					} else {
  1110  						fmt.Println(buf.String())
  1111  						break
  1112  					}
  1113  				} else {
  1114  					break
  1115  				}
  1116  				buf = bytes.NewBuffer(nil)
  1117  				err = templates.MustGet("serverBuilder").Execute(buf, op)
  1118  				if assert.NoError(t, err) {
  1119  					ff, err := appGen.GenOpts.LanguageOpts.FormatContent("fixture_1214_server.go", buf.Bytes())
  1120  					if assert.NoError(t, err) {
  1121  						res := string(ff)
  1122  						assertRegexpInCode(t, any+
  1123  							`AAuth: func\(user string, pass string\) \(interface{}, error\) {`+any+
  1124  							`BAuth: func\(token string\) \(interface{}, error\) {`+any+
  1125  							`CAuth: func\(token string\) \(interface{}, error\) {`+any+
  1126  							`DAuth: func\(token string\) \(interface{}, error\) {`+any+
  1127  							`EAuth: func\(token string, scopes \[\]string\) \(interface{}, error\) {`+any+
  1128  
  1129  							`AAuth func\(string, string\) \(interface{}, error\)`+any+
  1130  							`BAuth func\(string\) \(interface{}, error\)`+any+
  1131  							`CAuth func\(string\) \(interface{}, error\)`+any+
  1132  							`DAuth func\(string\) \(interface{}, error\)`+any+
  1133  							`EAuth func\(string, \[\]string\) \(interface{}, error\)`+any+
  1134  
  1135  							`if o\.AAuth == nil {`+any+
  1136  							`unregistered = append\(unregistered, "AAuth"\)`+any+
  1137  							`if o\.BAuth == nil {`+any+
  1138  							`unregistered = append\(unregistered, "K1Auth"\)`+any+
  1139  							`if o\.CAuth == nil {`+any+
  1140  							`unregistered = append\(unregistered, "K2Auth"\)`+any+
  1141  							`if o\.DAuth == nil {`+any+
  1142  							`unregistered = append\(unregistered, "K3Auth"\)`+any+
  1143  							`if o\.EAuth == nil {`+any+
  1144  							`unregistered = append\(unregistered, "EAuth"\)`+any+
  1145  
  1146  							`case "A":`+any+
  1147  							`case "B":`+any+
  1148  							`case "C":`+any+
  1149  							`case "D":`+any+
  1150  							`case "E":`+any, res)
  1151  					} else {
  1152  						fmt.Println(buf.String())
  1153  						break
  1154  					}
  1155  				} else {
  1156  					break
  1157  				}
  1158  			}
  1159  		}
  1160  	}
  1161  }
  1162  
  1163  func TestGenSecurityRequirements(t *testing.T) {
  1164  	for i := 0; i < 5; i++ {
  1165  		operation := "asecOp"
  1166  		b, err := opBuilder(operation, "../fixtures/bugs/1214/fixture-1214.yaml")
  1167  		if !assert.NoError(t, err) {
  1168  			t.FailNow()
  1169  			return
  1170  		}
  1171  		b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation)
  1172  		genRequirements := b.makeSecurityRequirements("o")
  1173  		assert.Len(t, genRequirements, 2)
  1174  		assert.Equal(t, []GenSecurityRequirements{
  1175  			{
  1176  				GenSecurityRequirement{
  1177  					Name:   "A",
  1178  					Scopes: []string{},
  1179  				},
  1180  				GenSecurityRequirement{
  1181  					Name:   "B",
  1182  					Scopes: []string{},
  1183  				},
  1184  				GenSecurityRequirement{
  1185  					Name:   "E",
  1186  					Scopes: []string{"s0", "s1", "s2", "s3", "s4"},
  1187  				},
  1188  			},
  1189  			{
  1190  				GenSecurityRequirement{
  1191  					Name:   "C",
  1192  					Scopes: []string{},
  1193  				},
  1194  				GenSecurityRequirement{
  1195  					Name:   "D",
  1196  					Scopes: []string{},
  1197  				},
  1198  				GenSecurityRequirement{
  1199  					Name:   "E",
  1200  					Scopes: []string{"s5", "s6", "s7", "s8", "s9"},
  1201  				},
  1202  			},
  1203  		}, genRequirements)
  1204  
  1205  		operation = "bsecOp"
  1206  		b, err = opBuilder(operation, "../fixtures/bugs/1214/fixture-1214.yaml")
  1207  		if !assert.NoError(t, err) {
  1208  			t.FailNow()
  1209  			return
  1210  		}
  1211  		b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation)
  1212  		genRequirements = b.makeSecurityRequirements("o")
  1213  		assert.Len(t, genRequirements, 2)
  1214  		assert.Equal(t, []GenSecurityRequirements{
  1215  			{
  1216  				GenSecurityRequirement{
  1217  					Name:   "A",
  1218  					Scopes: []string{},
  1219  				},
  1220  				GenSecurityRequirement{
  1221  					Name:   "E",
  1222  					Scopes: []string{"s0", "s1", "s2", "s3", "s4"},
  1223  				},
  1224  			},
  1225  			{
  1226  				GenSecurityRequirement{
  1227  					Name:   "D",
  1228  					Scopes: []string{},
  1229  				},
  1230  				GenSecurityRequirement{
  1231  					Name:   "E",
  1232  					Scopes: []string{"s5", "s6", "s7", "s8", "s9"},
  1233  				},
  1234  			},
  1235  		}, genRequirements)
  1236  	}
  1237  
  1238  	operation := "csecOp"
  1239  	b, err := opBuilder(operation, "../fixtures/bugs/1214/fixture-1214.yaml")
  1240  	if !assert.NoError(t, err) {
  1241  		t.FailNow()
  1242  		return
  1243  	}
  1244  	b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation)
  1245  	genRequirements := b.makeSecurityRequirements("o")
  1246  	assert.NotNil(t, genRequirements)
  1247  	assert.Len(t, genRequirements, 0)
  1248  
  1249  	operation = "nosecOp"
  1250  	b, err = opBuilder(operation, "../fixtures/bugs/1214/fixture-1214-2.yaml")
  1251  	if !assert.NoError(t, err) {
  1252  		t.FailNow()
  1253  		return
  1254  	}
  1255  	b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation)
  1256  	genRequirements = b.makeSecurityRequirements("o")
  1257  	assert.Nil(t, genRequirements)
  1258  }
  1259  
  1260  func TestGenerateServerOperation(t *testing.T) {
  1261  	log.SetOutput(ioutil.Discard)
  1262  	defer log.SetOutput(os.Stdout)
  1263  	fname := "../fixtures/codegen/todolist.simple.yml"
  1264  
  1265  	tgt, _ := ioutil.TempDir(filepath.Dir(fname), "generated")
  1266  	defer func() {
  1267  		_ = os.RemoveAll(tgt)
  1268  	}()
  1269  	o := &GenOpts{
  1270  		IncludeValidator:  true,
  1271  		ValidateSpec:      false,
  1272  		IncludeModel:      true,
  1273  		IncludeHandler:    true,
  1274  		IncludeParameters: true,
  1275  		IncludeResponses:  true,
  1276  		ModelPackage:      "models",
  1277  		Spec:              fname,
  1278  		Target:            tgt,
  1279  	}
  1280  	if err := o.EnsureDefaults(); err != nil {
  1281  		panic(err)
  1282  	}
  1283  
  1284  	err := GenerateServerOperation([]string{"createTask"}, nil)
  1285  	assert.Error(t, err)
  1286  
  1287  	d := o.TemplateDir
  1288  	o.TemplateDir = "./nowhere"
  1289  	err = GenerateServerOperation([]string{"notFound"}, o)
  1290  	assert.Error(t, err)
  1291  	o.TemplateDir = d
  1292  
  1293  	d = o.Spec
  1294  	o.Spec = "nowhere.yaml"
  1295  	err = GenerateServerOperation([]string{"notFound"}, o)
  1296  	assert.Error(t, err)
  1297  	o.Spec = d
  1298  
  1299  	err = GenerateServerOperation([]string{"notFound"}, o)
  1300  	assert.Error(t, err)
  1301  
  1302  	err = GenerateServerOperation([]string{"createTask"}, o)
  1303  	if !assert.NoError(t, err) {
  1304  		t.FailNow()
  1305  		return
  1306  	}
  1307  	// check expected files are generated and that's it
  1308  	_, err = os.Stat(filepath.Join(tgt, "tasks", "create_task.go"))
  1309  	assert.NoError(t, err)
  1310  	_, err = os.Stat(filepath.Join(tgt, "tasks", "create_task_parameters.go"))
  1311  	assert.NoError(t, err)
  1312  	_, err = os.Stat(filepath.Join(tgt, "tasks", "create_task_responses.go"))
  1313  	assert.NoError(t, err)
  1314  
  1315  	origStdout := os.Stdout
  1316  	defer func() {
  1317  		os.Stdout = origStdout
  1318  	}()
  1319  	os.Stdout, _ = os.Create(filepath.Join(tgt, "stdout"))
  1320  	o.DumpData = true
  1321  	// just checks this does not fail
  1322  	err = GenerateServerOperation([]string{"createTask"}, o)
  1323  	assert.NoError(t, err)
  1324  	_, err = os.Stat(filepath.Join(tgt, "stdout"))
  1325  	assert.NoError(t, err)
  1326  }
  1327  
  1328  // This tests that mimetypes generate stable code
  1329  func TestBuilder_Issue1646(t *testing.T) {
  1330  	log.SetOutput(ioutil.Discard)
  1331  	defer log.SetOutput(os.Stdout)
  1332  	dr, _ := os.Getwd()
  1333  	opts := &GenOpts{
  1334  		Spec:              filepath.FromSlash("../fixtures/bugs/1646/fixture-1646.yaml"),
  1335  		IncludeModel:      true,
  1336  		IncludeValidator:  true,
  1337  		IncludeHandler:    true,
  1338  		IncludeParameters: true,
  1339  		IncludeResponses:  true,
  1340  		IncludeMain:       true,
  1341  		APIPackage:        "restapi",
  1342  		ModelPackage:      "model",
  1343  		ServerPackage:     "server",
  1344  		ClientPackage:     "client",
  1345  		Target:            dr,
  1346  		IsClient:          false,
  1347  	}
  1348  	err := opts.EnsureDefaults()
  1349  	assert.NoError(t, err)
  1350  	appGen, err := newAppGenerator("fixture-1646", nil, nil, opts)
  1351  
  1352  	if assert.NoError(t, err) {
  1353  		preCons, preConj := appGen.makeConsumes()
  1354  		preProds, preProdj := appGen.makeProduces()
  1355  		assert.True(t, preConj)
  1356  		assert.True(t, preProdj)
  1357  		for i := 0; i < 5; i++ {
  1358  			cons, conj := appGen.makeConsumes()
  1359  			prods, prodj := appGen.makeProduces()
  1360  			assert.True(t, conj)
  1361  			assert.True(t, prodj)
  1362  			assert.Equal(t, preConj, conj)
  1363  			assert.Equal(t, preProdj, prodj)
  1364  			assert.Equal(t, preCons, cons)
  1365  			assert.Equal(t, preProds, prods)
  1366  		}
  1367  	}
  1368  }