github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/oapispec/openapi3_test.go (about)

     1  // Copyright © 2021 Kaleido, Inc.
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package oapispec
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"net/http"
    23  	"testing"
    24  
    25  	"github.com/ghodss/yaml"
    26  	"github.com/kaleido-io/firefly/internal/config"
    27  	"github.com/kaleido-io/firefly/internal/i18n"
    28  	"github.com/kaleido-io/firefly/pkg/database"
    29  	"github.com/kaleido-io/firefly/pkg/fftypes"
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  func TestOpenAPI3SwaggerGen(t *testing.T) {
    34  
    35  	config.Reset()
    36  	routes := []*Route{
    37  		{
    38  			Name:   "op1",
    39  			Path:   "namespaces/{ns}/example1/{id}",
    40  			Method: http.MethodPost,
    41  			PathParams: []*PathParam{
    42  				{Name: "ns", ExampleFromConf: config.NamespacesDefault, Description: i18n.MsgTBD},
    43  				{Name: "id", Description: i18n.MsgTBD},
    44  			},
    45  			QueryParams:     nil,
    46  			FilterFactory:   nil,
    47  			Description:     i18n.MsgTBD,
    48  			JSONInputValue:  func() interface{} { return &fftypes.Message{} },
    49  			JSONInputMask:   []string{"id"},
    50  			JSONOutputValue: func() interface{} { return &fftypes.Batch{} },
    51  			JSONOutputCode:  http.StatusOK,
    52  		},
    53  		{
    54  			Name:           "op2",
    55  			Path:           "example2",
    56  			Method:         http.MethodGet,
    57  			PathParams:     nil,
    58  			QueryParams:    nil,
    59  			FilterFactory:  database.MessageQueryFactory,
    60  			Description:    i18n.MsgTBD,
    61  			JSONInputValue: func() interface{} { return nil },
    62  			JSONInputSchema: `{
    63  				"type": "object",
    64  				"properties": {
    65  					"id": "string"
    66  				}
    67  			}`,
    68  			JSONOutputValue: func() interface{} { return []*fftypes.Batch{} },
    69  			JSONOutputCode:  http.StatusOK,
    70  		},
    71  		{
    72  			Name:       "op3",
    73  			Path:       "example2",
    74  			Method:     http.MethodPut,
    75  			PathParams: nil,
    76  			QueryParams: []*QueryParam{
    77  				{Name: "ns", ExampleFromConf: config.NamespacesDefault, Description: i18n.MsgTBD},
    78  				{Name: "id", Description: i18n.MsgTBD},
    79  				{Name: "myfield", Default: "val1", Description: i18n.MsgTBD},
    80  			},
    81  			FilterFactory:     nil,
    82  			Description:       i18n.MsgTBD,
    83  			JSONInputValue:    func() interface{} { return &fftypes.Data{} },
    84  			JSONOutputValue:   func() interface{} { return nil },
    85  			JSONOutputCode:    http.StatusNoContent,
    86  			FormUploadHandler: func(r APIRequest) (output interface{}, err error) { return nil, nil },
    87  		},
    88  		{
    89  			Name:   "op4",
    90  			Path:   "example2/{id}",
    91  			Method: http.MethodDelete,
    92  			PathParams: []*PathParam{
    93  				{Name: "id", Description: i18n.MsgTBD},
    94  			},
    95  			QueryParams:     nil,
    96  			FilterFactory:   nil,
    97  			Description:     i18n.MsgTBD,
    98  			JSONInputValue:  func() interface{} { return nil },
    99  			JSONOutputValue: func() interface{} { return nil },
   100  			JSONOutputCode:  http.StatusNoContent,
   101  		},
   102  	}
   103  
   104  	doc := SwaggerGen(context.Background(), routes)
   105  	err := doc.Validate(context.Background())
   106  	assert.NoError(t, err)
   107  
   108  	b, err := yaml.Marshal(doc)
   109  	assert.NoError(t, err)
   110  	fmt.Print(string(b))
   111  
   112  }
   113  
   114  func TestDuplicateOperationIDCheck(t *testing.T) {
   115  	routes := []*Route{
   116  		{Name: "op1"}, {Name: "op1"},
   117  	}
   118  	assert.PanicsWithValue(t, "Duplicate/invalid name (used as operation ID in swagger): op1", func() {
   119  		_ = SwaggerGen(context.Background(), routes)
   120  	})
   121  }
   122  
   123  func TestBadCustomSchema(t *testing.T) {
   124  
   125  	config.Reset()
   126  	routes := []*Route{
   127  		{
   128  			Name:            "op1",
   129  			Path:            "namespaces/{ns}/example1/{id}",
   130  			Method:          http.MethodPost,
   131  			JSONInputValue:  func() interface{} { return &fftypes.Message{} },
   132  			JSONInputMask:   []string{"id"},
   133  			JSONOutputCode:  http.StatusOK,
   134  			JSONInputSchema: `!json`,
   135  		},
   136  	}
   137  	assert.PanicsWithValue(t, "invalid schema for *fftypes.Message: invalid character '!' looking for beginning of value", func() {
   138  		_ = SwaggerGen(context.Background(), routes)
   139  	})
   140  }