mirror of
https://github.com/davidebianchi/gswagger.git
synced 2026-01-18 12:08:52 -05:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09e3bd484e | ||
|
|
617c44900c | ||
|
|
1cd88c70bb | ||
|
|
d3bbc528ac | ||
|
|
91c15b79b1 | ||
|
|
bd884cb1de | ||
|
|
b776ccf233 | ||
|
|
0d75c2cb5e | ||
|
|
2354daa4a9 | ||
|
|
8d05c61745 | ||
|
|
9a6b0b9b16 | ||
|
|
dd94c5cd25 | ||
|
|
8047e54eac | ||
|
|
e6adc34cee | ||
|
|
2b87521135 | ||
|
|
d095403a23 | ||
|
|
526265eda9 | ||
|
|
88bbf2f41c | ||
|
|
6a1bd1cd19 | ||
|
|
c44efeed6e | ||
|
|
4b06c26421 | ||
|
|
7a48480545 | ||
|
|
bbc469d26d | ||
|
|
be8a1de244 | ||
|
|
39f8f916d1 | ||
|
|
9fac1c3a4f | ||
|
|
d5e740ecac | ||
|
|
5f24f99c89 | ||
|
|
19e6e6e888 | ||
|
|
449ee873f8 | ||
|
|
8d08ab4e88 | ||
|
|
e4154d1870 | ||
|
|
34f6bc882e | ||
|
|
bb30bcbb18 | ||
|
|
e3bf8ad397 | ||
|
|
36c6f8b159 | ||
|
|
4cb82ead72 | ||
|
|
5851dbec22 | ||
|
|
7eabb18dd1 | ||
|
|
b50cc86f43 | ||
|
|
8330d20f23 | ||
|
|
68cc1ddbf1 | ||
|
|
5f67ad2aad | ||
|
|
0676ab69a8 | ||
|
|
838f862067 | ||
|
|
48371417ce | ||
|
|
3e11724cd9 | ||
|
|
85a65a69aa | ||
|
|
0b3a79b0b5 | ||
|
|
83cb8c6301 | ||
|
|
a605011038 | ||
|
|
4f18946fab | ||
|
|
8ea5444777 | ||
|
|
e6e53be7d8 | ||
|
|
a503dd54db | ||
|
|
231f0b5b65 | ||
|
|
6d81ef8469 | ||
|
|
f6c98d97cc | ||
|
|
4587271bc2 | ||
|
|
17f9235abd | ||
|
|
e81a74c306 |
15
.github/workflows/test-builds.yml
vendored
15
.github/workflows/test-builds.yml
vendored
@@ -9,10 +9,10 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
go_version: [1.18, 1.19]
|
||||
go_version: ['1.20', '1.21']
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- go_version: 1.19
|
||||
- go_version: '1.21'
|
||||
os: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
@@ -37,3 +37,14 @@ jobs:
|
||||
uses: shogo82148/actions-goveralls@v1
|
||||
with:
|
||||
path-to-profile: cover.out
|
||||
flag-name: Go-${{ matrix.go_version }}
|
||||
parallel: true
|
||||
|
||||
post-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: tests
|
||||
steps:
|
||||
- name: Close coverage report
|
||||
uses: shogo82148/actions-goveralls@v1
|
||||
with:
|
||||
parallel-finished: true
|
||||
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 0.10.0 - 28-02-2024
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- remove support to golang 1.19
|
||||
|
||||
### Updated
|
||||
|
||||
- change jsonschema lib to use again `invopop/jsonschema` one, since now it support additionalProperties instead of patternProperties
|
||||
|
||||
## 0.9.0 - 17-04-2023
|
||||
|
||||
### Added
|
||||
|
||||
- add new fields to Definition:
|
||||
- Security
|
||||
- Tags
|
||||
- Summary
|
||||
- Description
|
||||
- Deprecated
|
||||
- Extensions
|
||||
|
||||
### Updated
|
||||
|
||||
- update kin-openapi to 0.114.0: this change removes components from exposed oas (if not manually set). In this update of kin-openapi, there is a breaking change with the T struct, which now accepts component as pointer.
|
||||
|
||||
## 0.8.0 - 23-12-2022
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- add `TransformPathToOasPath(path string) string` method to apirouter.Router interface to handle different types of paths parameters. If you use one of the supported routers, you should do nothing;
|
||||
|
||||
## 0.7.0 - 22-12-2022
|
||||
|
||||
This is a big major release. The main achievement is to increase the usability of this library to all the routers.
|
||||
|
||||
22
README.md
22
README.md
@@ -25,6 +25,14 @@ To convert struct to schemas, we use [jsonschema] library.
|
||||
The struct must contains the appropriate struct tags to be inserted in json schema to generate the schema dynamically.
|
||||
It is always possible to add a totally custom swagger schema using [kin-openapi].
|
||||
|
||||
## Install
|
||||
|
||||
To use it, install with
|
||||
|
||||
```sh
|
||||
go get github.com/davidebianchi/gswagger
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
An example usage of this lib with gorilla mux:
|
||||
@@ -106,15 +114,25 @@ This configuration will output the schema shown [here](./support/gorilla/testdat
|
||||
|
||||
## Auto generated path params schema
|
||||
|
||||
The path params, if not set in schema, are auto generated from the path. Currently, it is supported only the path params like `{myPath}`.
|
||||
The path params, if not set in schema, are auto generated from the path.
|
||||
The format of the path parameters depends on the router library you are using, as explained below.
|
||||
|
||||
For example, with this use case, you can see the [example test](./support/gorilla/examples_test.go).
|
||||
### Gorilla Mux
|
||||
|
||||
Gorilla Mux supports the path parameters as `{someParam}`, for example as in `/users/{userId}`.
|
||||
|
||||
Here is the [example test](./support/gorilla/examples_test.go).
|
||||
|
||||
The generated oas schema will contains `userId`, `carId` and `driverId` as path params set to string.
|
||||
If only one params is set, you must specify manually all the path params.
|
||||
|
||||
The generated OAS for this test case is visible [here](./support/gorilla/testdata/examples-users.json).
|
||||
|
||||
### Fiber
|
||||
Fiber supports the path parameters as `:someParam`, for example as in `/users/:userId`.
|
||||
|
||||
Here is the [example test](./support/fiber/integration_test.go)
|
||||
|
||||
## SubRouter
|
||||
|
||||
It is possible to create a new sub router from the swagger.Router.
|
||||
|
||||
@@ -3,4 +3,5 @@ package apirouter
|
||||
type Router[HandlerFunc any, Route any] interface {
|
||||
AddRoute(method string, path string, handler HandlerFunc) Route
|
||||
SwaggerHandler(contentType string, blob []byte) HandlerFunc
|
||||
TransformPathToOasPath(path string) string
|
||||
}
|
||||
|
||||
15
apirouter/transformpath.go
Normal file
15
apirouter/transformpath.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package apirouter
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func TransformPathParamsWithColon(path string) string {
|
||||
pathParams := strings.Split(path, "/")
|
||||
for i, param := range pathParams {
|
||||
if strings.HasPrefix(param, ":") {
|
||||
pathParams[i] = strings.Replace(param, ":", "{", 1) + "}"
|
||||
}
|
||||
}
|
||||
return strings.Join(pathParams, "/")
|
||||
}
|
||||
59
apirouter/transformpath_test.go
Normal file
59
apirouter/transformpath_test.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package apirouter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTransformPathParamsWithColon(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
path string
|
||||
expectedPath string
|
||||
}{
|
||||
{
|
||||
name: "only /",
|
||||
path: "/",
|
||||
expectedPath: "/",
|
||||
},
|
||||
{
|
||||
name: "without params",
|
||||
path: "/foo",
|
||||
expectedPath: "/foo",
|
||||
},
|
||||
{
|
||||
name: "without params ending with /",
|
||||
path: "/foo/",
|
||||
expectedPath: "/foo/",
|
||||
},
|
||||
{
|
||||
name: "with params",
|
||||
path: "/foo/:par1",
|
||||
expectedPath: "/foo/{par1}",
|
||||
},
|
||||
{
|
||||
name: "with params ending with /",
|
||||
path: "/foo/:par1/",
|
||||
expectedPath: "/foo/{par1}/",
|
||||
},
|
||||
{
|
||||
name: "with multiple params",
|
||||
path: "/:par1/:par2/:par3",
|
||||
expectedPath: "/{par1}/{par2}/{par3}",
|
||||
},
|
||||
{
|
||||
name: "with multiple params ending with /",
|
||||
path: "/:par1/:par2/:par3/",
|
||||
expectedPath: "/{par1}/{par2}/{par3}/",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
actual := TransformPathParamsWithColon(test.path)
|
||||
|
||||
require.Equal(t, test.expectedPath, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
48
go.mod
48
go.mod
@@ -1,43 +1,49 @@
|
||||
module github.com/davidebianchi/gswagger
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/getkin/kin-openapi v0.111.0
|
||||
github.com/getkin/kin-openapi v0.123.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-openapi/swag v0.21.1 // indirect
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
||||
github.com/labstack/echo/v4 v4.9.1
|
||||
github.com/go-openapi/swag v0.22.8 // indirect
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/labstack/echo/v4 v4.11.4
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mia-platform/jsonschema v0.1.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
)
|
||||
|
||||
require github.com/gofiber/fiber/v2 v2.40.1
|
||||
require (
|
||||
github.com/gofiber/fiber/v2 v2.52.1
|
||||
github.com/invopop/jsonschema v0.12.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.2 // indirect
|
||||
github.com/google/uuid v1.5.0 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.15.9 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/klauspost/compress v1.17.0 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.41.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220312131142-6068a2e6cfdc // indirect
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
137
go.sum
137
go.sum
@@ -1,114 +1,85 @@
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/getkin/kin-openapi v0.111.0 h1:zspOcFKBCQOY8d9Yockcbit8iVR2hco9qLaoQoj7kmw=
|
||||
github.com/getkin/kin-openapi v0.111.0/go.mod h1:QtwUNt0PAAgIIBEvFWYfB7dfngxtAaqCX1zYHMZDeK8=
|
||||
github.com/getkin/kin-openapi v0.123.0 h1:zIik0mRwFNLyvtXK274Q6ut+dPh6nlxBp0x7mNrPhs8=
|
||||
github.com/getkin/kin-openapi v0.123.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
|
||||
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4=
|
||||
github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA=
|
||||
github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
|
||||
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
|
||||
github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw=
|
||||
github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/gofiber/fiber/v2 v2.52.1 h1:1RoU2NS+b98o1L77sdl5mboGPiW+0Ypsi5oLmcYlgHI=
|
||||
github.com/gofiber/fiber/v2 v2.52.1/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI=
|
||||
github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
|
||||
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
|
||||
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
|
||||
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
|
||||
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
|
||||
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mia-platform/jsonschema v0.1.0 h1:tjQf7TaYROsAqk7SXTL+44TrfKk3bSEvhRGPS51IA5Y=
|
||||
github.com/mia-platform/jsonschema v0.1.0/go.mod h1:r2DJjPA/+6S+WPnXZt1xONMvO2b4hlhfXfUYV0po/Dk=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
|
||||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY=
|
||||
github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY=
|
||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220312131142-6068a2e6cfdc h1:i6Z9eOQAdM7lvsbkT3fwFNtSAAC+A59TYilFj53HW+E=
|
||||
golang.org/x/crypto v0.0.0-20220312131142-6068a2e6cfdc/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo=
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
2
main.go
2
main.go
@@ -112,7 +112,7 @@ func generateNewValidOpenapi(swagger *openapi3.T) (*openapi3.T, error) {
|
||||
swagger.OpenAPI = defaultOpenapiVersion
|
||||
}
|
||||
if swagger.Paths == nil {
|
||||
swagger.Paths = openapi3.Paths{}
|
||||
swagger.Paths = &openapi3.Paths{}
|
||||
}
|
||||
|
||||
if swagger.Info == nil {
|
||||
|
||||
34
main_test.go
34
main_test.go
@@ -26,7 +26,7 @@ func TestNewRouter(t *testing.T) {
|
||||
}
|
||||
openapi := &openapi3.T{
|
||||
Info: info,
|
||||
Paths: openapi3.Paths{},
|
||||
Paths: &openapi3.Paths{},
|
||||
}
|
||||
|
||||
t.Run("not ok - invalid Openapi option", func(t *testing.T) {
|
||||
@@ -179,7 +179,7 @@ func TestGenerateValidSwagger(t *testing.T) {
|
||||
require.Equal(t, &openapi3.T{
|
||||
OpenAPI: defaultOpenapiVersion,
|
||||
Info: info,
|
||||
Paths: openapi3.Paths{},
|
||||
Paths: &openapi3.Paths{},
|
||||
}, swagger)
|
||||
})
|
||||
}
|
||||
@@ -193,7 +193,7 @@ func TestGenerateAndExposeSwagger(t *testing.T) {
|
||||
Title: "title",
|
||||
Version: "version",
|
||||
},
|
||||
Components: openapi3.Components{
|
||||
Components: &openapi3.Components{
|
||||
Schemas: map[string]*openapi3.SchemaRef{
|
||||
"&%": {},
|
||||
},
|
||||
@@ -336,7 +336,7 @@ func TestGenerateAndExposeSwagger(t *testing.T) {
|
||||
w.Write([]byte("ok"))
|
||||
}, Definitions{})
|
||||
|
||||
mSubRouter := mRouter.PathPrefix("/prefix").Subrouter()
|
||||
mSubRouter := mRouter.NewRoute().Subrouter()
|
||||
subrouter, err := router.SubRouter(gorilla.NewRouter(mSubRouter), SubRouterOptions{
|
||||
PathPrefix: "/prefix",
|
||||
})
|
||||
@@ -370,6 +370,30 @@ func TestGenerateAndExposeSwagger(t *testing.T) {
|
||||
actual, err := os.ReadFile("testdata/subrouter.json")
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, string(actual), body)
|
||||
|
||||
t.Run("test request /prefix", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/prefix", nil)
|
||||
mRouter.ServeHTTP(w, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
})
|
||||
|
||||
t.Run("test request /prefix/taz", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/prefix/taz", nil)
|
||||
mRouter.ServeHTTP(w, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
})
|
||||
|
||||
t.Run("test request /foo", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/foo", nil)
|
||||
mRouter.ServeHTTP(w, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("ok - new router with path prefix", func(t *testing.T) {
|
||||
@@ -405,7 +429,7 @@ func TestGenerateAndExposeSwagger(t *testing.T) {
|
||||
body := readBody(t, w.Result().Body)
|
||||
actual, err := os.ReadFile("testdata/router_with_prefix.json")
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, string(actual), body)
|
||||
require.JSONEq(t, string(actual), body, body)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
11
operation.go
11
operation.go
@@ -28,7 +28,7 @@ func (o *Operation) AddRequestBody(requestBody *openapi3.RequestBody) {
|
||||
// but it is always possible to add it manually.
|
||||
func (o *Operation) AddResponse(status int, response *openapi3.Response) {
|
||||
if o.Responses == nil {
|
||||
o.Responses = make(openapi3.Responses)
|
||||
o.Responses = &openapi3.Responses{}
|
||||
}
|
||||
if response.Description == nil {
|
||||
// a description is required by kin openapi, so we set an empty description
|
||||
@@ -37,3 +37,12 @@ func (o *Operation) AddResponse(status int, response *openapi3.Response) {
|
||||
}
|
||||
o.Operation.AddResponse(status, response)
|
||||
}
|
||||
|
||||
func (o *Operation) addSecurityRequirements(securityRequirements SecurityRequirements) {
|
||||
if securityRequirements != nil && o.Security == nil {
|
||||
o.Security = openapi3.NewSecurityRequirements()
|
||||
}
|
||||
for _, securityRequirement := range securityRequirements {
|
||||
o.Security.With(openapi3.SecurityRequirement(securityRequirement))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestNewOperation(t *testing.T) {
|
||||
operation.Responses = openapi3.NewResponses()
|
||||
return operation
|
||||
},
|
||||
expectedJSON: `{"components":{},"info":{"title":"test swagger title","version":"test swagger version"},"openapi":"3.0.0","paths":{"/":{"post":{"requestBody":{"content":{"application/json":{"schema":{"properties":{"bar":{"maximum":15,"minimum":5,"type":"integer"},"foo":{"type":"string"}},"type":"object"}}}},"responses":{"default":{"description":""}}}}}}`,
|
||||
expectedJSON: `{"info":{"title":"test swagger title","version":"test swagger version"},"openapi":"3.0.0","paths":{"/":{"post":{"requestBody":{"content":{"application/json":{"schema":{"properties":{"bar":{"maximum":15,"minimum":5,"type":"integer"},"foo":{"type":"string"}},"type":"object"}}}},"responses":{"default":{"description":""}}}}}}`,
|
||||
},
|
||||
{
|
||||
name: "add response",
|
||||
@@ -36,7 +36,7 @@ func TestNewOperation(t *testing.T) {
|
||||
operation.AddResponse(200, response)
|
||||
return operation
|
||||
},
|
||||
expectedJSON: `{"components":{},"info":{"title":"test swagger title","version":"test swagger version"},"openapi":"3.0.0","paths":{"/":{"post":{"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"bar":{"maximum":15,"minimum":5,"type":"integer"},"foo":{"type":"string"}},"type":"object"}}},"description":""}}}}}}`,
|
||||
expectedJSON: `{"info":{"title":"test swagger title","version":"test swagger version"},"openapi":"3.0.0","paths":{"/":{"post":{"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"bar":{"maximum":15,"minimum":5,"type":"integer"},"foo":{"type":"string"}},"type":"object"}}},"description":""}}}}}}`,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
41
route.go
41
route.go
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/mia-platform/jsonschema"
|
||||
"github.com/invopop/jsonschema"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -38,7 +38,8 @@ func (r Router[HandlerFunc, Route]) AddRawRoute(method string, routePath string,
|
||||
}
|
||||
}
|
||||
pathWithPrefix := path.Join(r.pathPrefix, routePath)
|
||||
r.swaggerSchema.AddOperation(pathWithPrefix, method, op)
|
||||
oasPath := r.router.TransformPathToOasPath(pathWithPrefix)
|
||||
r.swaggerSchema.AddOperation(oasPath, method, op)
|
||||
|
||||
// Handle, when content-type is json, the request/response marshalling? Maybe with a specific option.
|
||||
return r.router.AddRoute(method, pathWithPrefix, handler), nil
|
||||
@@ -70,15 +71,42 @@ type ContentValue struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
type SecurityRequirements []SecurityRequirement
|
||||
type SecurityRequirement map[string][]string
|
||||
|
||||
// Definitions of the route.
|
||||
// To see how to use, refer to https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md
|
||||
type Definitions struct {
|
||||
// Specification extensions https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions
|
||||
Extensions map[string]interface{}
|
||||
// Optional field for documentation
|
||||
Tags []string
|
||||
Summary string
|
||||
Description string
|
||||
Deprecated bool
|
||||
|
||||
// PathParams contains the path parameters. If empty is autocompleted from the path
|
||||
PathParams ParameterValue
|
||||
Querystring ParameterValue
|
||||
Headers ParameterValue
|
||||
Cookies ParameterValue
|
||||
RequestBody *ContentValue
|
||||
Responses map[int]ContentValue
|
||||
|
||||
Security SecurityRequirements
|
||||
}
|
||||
|
||||
func newOperationFromDefinition(schema Definitions) Operation {
|
||||
operation := NewOperation()
|
||||
operation.Responses = &openapi3.Responses{}
|
||||
operation.Tags = schema.Tags
|
||||
operation.Extensions = schema.Extensions
|
||||
operation.addSecurityRequirements(schema.Security)
|
||||
operation.Description = schema.Description
|
||||
operation.Summary = schema.Summary
|
||||
operation.Deprecated = schema.Deprecated
|
||||
|
||||
return operation
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -90,9 +118,7 @@ const (
|
||||
|
||||
// AddRoute add a route with json schema inferred by passed schema.
|
||||
func (r Router[HandlerFunc, Route]) AddRoute(method string, path string, handler HandlerFunc, schema Definitions) (Route, error) {
|
||||
operation := NewOperation()
|
||||
operation.Responses = make(openapi3.Responses)
|
||||
operation.Tags = schema.Tags
|
||||
operation := newOperationFromDefinition(schema)
|
||||
|
||||
err := r.resolveRequestBodySchema(schema.RequestBody, operation)
|
||||
if err != nil {
|
||||
@@ -104,7 +130,8 @@ func (r Router[HandlerFunc, Route]) AddRoute(method string, path string, handler
|
||||
return getZero[Route](), fmt.Errorf("%w: %s", ErrResponses, err)
|
||||
}
|
||||
|
||||
err = r.resolveParameterSchema(pathParamsType, getPathParamsAutofilled(schema, path), operation)
|
||||
oasPath := r.router.TransformPathToOasPath(path)
|
||||
err = r.resolveParameterSchema(pathParamsType, getPathParamsAutoComplete(schema, oasPath), operation)
|
||||
if err != nil {
|
||||
return getZero[Route](), fmt.Errorf("%w: %s", ErrPathParams, err)
|
||||
}
|
||||
@@ -260,7 +287,7 @@ func (r Router[_, _]) addContentToOASSchema(content Content) (openapi3.Content,
|
||||
return oasContent, nil
|
||||
}
|
||||
|
||||
func getPathParamsAutofilled(schema Definitions, path string) ParameterValue {
|
||||
func getPathParamsAutoComplete(schema Definitions, path string) ParameterValue {
|
||||
if schema.PathParams == nil {
|
||||
pathParams := strings.Split(path, "/")
|
||||
for _, param := range pathParams {
|
||||
|
||||
@@ -20,7 +20,6 @@ const formDataType = "multipart/form-data"
|
||||
type TestRouter = Router[gorilla.HandlerFunc, gorilla.Route]
|
||||
|
||||
func TestAddRoutes(t *testing.T) {
|
||||
|
||||
type User struct {
|
||||
Name string `json:"name" jsonschema:"title=The user name,required" jsonschema_extras:"example=Jane"`
|
||||
PhoneNumber int `json:"phone" jsonschema:"title=mobile number of user"`
|
||||
@@ -435,6 +434,66 @@ func TestAddRoutes(t *testing.T) {
|
||||
testPath: "/users",
|
||||
fixturesPath: "testdata/tags.json",
|
||||
},
|
||||
{
|
||||
name: "schema with security",
|
||||
routes: func(t *testing.T, router *TestRouter) {
|
||||
_, err := router.AddRoute(http.MethodGet, "/users", okHandler, Definitions{
|
||||
Security: SecurityRequirements{
|
||||
SecurityRequirement{
|
||||
"api_key": []string{},
|
||||
"auth": []string{
|
||||
"resource.write",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
},
|
||||
testPath: "/users",
|
||||
fixturesPath: "testdata/security.json",
|
||||
},
|
||||
{
|
||||
name: "schema with extension",
|
||||
routes: func(t *testing.T, router *TestRouter) {
|
||||
_, err := router.AddRoute(http.MethodGet, "/users", okHandler, Definitions{
|
||||
Extensions: map[string]interface{}{
|
||||
"x-extension-field": map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
},
|
||||
testPath: "/users",
|
||||
fixturesPath: "testdata/extension.json",
|
||||
},
|
||||
{
|
||||
name: "invalid extension - not starts with x-",
|
||||
routes: func(t *testing.T, router *TestRouter) {
|
||||
_, err := router.AddRoute(http.MethodGet, "/", okHandler, Definitions{
|
||||
Extensions: map[string]interface{}{
|
||||
"extension-field": map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.EqualError(t, err, "extra sibling fields: [extension-field]")
|
||||
},
|
||||
fixturesPath: "testdata/empty.json",
|
||||
},
|
||||
{
|
||||
name: "schema with summary, description, deprecated and operationID",
|
||||
routes: func(t *testing.T, router *TestRouter) {
|
||||
_, err := router.AddRoute(http.MethodGet, "/users", okHandler, Definitions{
|
||||
Summary: "small description",
|
||||
Description: "this is the long route description",
|
||||
Deprecated: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
},
|
||||
testPath: "/users",
|
||||
fixturesPath: "testdata/users-deprecated-with-description.json",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@@ -864,7 +923,7 @@ func TestResolveResponsesSchema(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
operation := NewOperation()
|
||||
operation.Responses = make(openapi3.Responses)
|
||||
operation.Responses = &openapi3.Responses{}
|
||||
|
||||
err := router.resolveResponsesSchema(test.responsesSchema, operation)
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ func (r echoRouter) SwaggerHandler(contentType string, blob []byte) echo.Handler
|
||||
}
|
||||
}
|
||||
|
||||
func (r echoRouter) TransformPathToOasPath(path string) string {
|
||||
return apirouter.TransformPathParamsWithColon(path)
|
||||
}
|
||||
|
||||
func NewRouter(router *echo.Echo) apirouter.Router[echo.HandlerFunc, Route] {
|
||||
return echoRouter{
|
||||
router: router,
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
oasEcho "github.com/davidebianchi/gswagger/support/echo"
|
||||
@@ -22,19 +23,36 @@ const (
|
||||
|
||||
type echoSwaggerRouter = swagger.Router[echo.HandlerFunc, *echo.Route]
|
||||
|
||||
func TestIntegration(t *testing.T) {
|
||||
func TestEchoIntegration(t *testing.T) {
|
||||
t.Run("router works correctly - echo", func(t *testing.T) {
|
||||
echoRouter, _ := setupEchoSwagger(t)
|
||||
echoRouter, oasRouter := setupEchoSwagger(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
err := oasRouter.GenerateAndExposeOpenapi()
|
||||
require.NoError(t, err)
|
||||
|
||||
echoRouter.ServeHTTP(w, r)
|
||||
t.Run("/hello", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
echoRouter.ServeHTTP(w, r)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "OK", body)
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "OK", body)
|
||||
})
|
||||
|
||||
t.Run("/hello/:value", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodPost, "/hello/something", nil)
|
||||
|
||||
echoRouter.ServeHTTP(w, r)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "OK", body)
|
||||
})
|
||||
|
||||
t.Run("and generate swagger", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
@@ -45,14 +63,14 @@ func TestIntegration(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
|
||||
require.JSONEq(t, readFile(t, "../testdata/integration.json"), body)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("works correctly with subrouter - handles path prefix - echo", func(t *testing.T) {
|
||||
eRouter, swaggerRouter := setupEchoSwagger(t)
|
||||
eRouter, oasRouter := setupEchoSwagger(t)
|
||||
|
||||
subRouter, err := swaggerRouter.SubRouter(oasEcho.NewRouter(eRouter), swagger.SubRouterOptions{
|
||||
subRouter, err := oasRouter.SubRouter(oasEcho.NewRouter(eRouter), swagger.SubRouterOptions{
|
||||
PathPrefix: "/prefix",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -60,15 +78,20 @@ func TestIntegration(t *testing.T) {
|
||||
_, err = subRouter.AddRoute(http.MethodGet, "/foo", okHandler, swagger.Definitions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
err = oasRouter.GenerateAndExposeOpenapi()
|
||||
require.NoError(t, err)
|
||||
|
||||
eRouter.ServeHTTP(w, r)
|
||||
t.Run("correctly call /hello", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
eRouter.ServeHTTP(w, r)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "OK", body)
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "OK", body)
|
||||
})
|
||||
|
||||
t.Run("correctly call sub router", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
@@ -91,7 +114,7 @@ func TestIntegration(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
|
||||
require.JSONEq(t, readFile(t, "../testdata/intergation-subrouter.json"), body, body)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -127,7 +150,7 @@ func setupEchoSwagger(t *testing.T) (*echo.Echo, *echoSwaggerRouter) {
|
||||
_, err = router.AddRawRoute(http.MethodGet, "/hello", okHandler, operation)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = router.GenerateAndExposeOpenapi()
|
||||
_, err = router.AddRoute(http.MethodPost, "/hello/:value", okHandler, swagger.Definitions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
return e, router
|
||||
@@ -136,3 +159,12 @@ func setupEchoSwagger(t *testing.T) (*echo.Echo, *echoSwaggerRouter) {
|
||||
func okHandler(c echo.Context) error {
|
||||
return c.String(http.StatusOK, "OK")
|
||||
}
|
||||
|
||||
func readFile(t *testing.T, path string) string {
|
||||
t.Helper()
|
||||
|
||||
fileContent, err := os.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
return string(fileContent)
|
||||
}
|
||||
|
||||
@@ -28,3 +28,7 @@ func (r fiberRouter) SwaggerHandler(contentType string, blob []byte) HandlerFunc
|
||||
return c.Send(blob)
|
||||
}
|
||||
}
|
||||
|
||||
func (r fiberRouter) TransformPathToOasPath(path string) string {
|
||||
return apirouter.TransformPathParamsWithColon(path)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
swagger "github.com/davidebianchi/gswagger"
|
||||
@@ -22,18 +23,34 @@ const (
|
||||
swaggerOpenapiVersion = "test swagger version"
|
||||
)
|
||||
|
||||
func TestWithFiber(t *testing.T) {
|
||||
func TestFiberIntegration(t *testing.T) {
|
||||
t.Run("router works correctly", func(t *testing.T) {
|
||||
router, _ := setupSwagger(t)
|
||||
router, oasRouter := setupSwagger(t)
|
||||
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
resp, err := router.Test(r)
|
||||
err := oasRouter.GenerateAndExposeOpenapi()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
body := readBody(t, resp.Body)
|
||||
require.Equal(t, "OK", body)
|
||||
t.Run("/hello", func(t *testing.T) {
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
resp, err := router.Test(r)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
body := readBody(t, resp.Body)
|
||||
require.Equal(t, "OK", body)
|
||||
})
|
||||
|
||||
t.Run("/hello/:value", func(t *testing.T) {
|
||||
r := httptest.NewRequest(http.MethodPost, "/hello/something", nil)
|
||||
|
||||
resp, err := router.Test(r)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
body := readBody(t, resp.Body)
|
||||
require.Equal(t, "OK", body)
|
||||
})
|
||||
|
||||
t.Run("and generate swagger", func(t *testing.T) {
|
||||
r := httptest.NewRequest(http.MethodGet, swagger.DefaultJSONDocumentationPath, nil)
|
||||
@@ -43,36 +60,26 @@ func TestWithFiber(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
body := readBody(t, resp.Body)
|
||||
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
|
||||
require.JSONEq(t, readFile(t, "../testdata/integration.json"), body, body)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("works correctly with subrouter - handles path prefix - gorilla mux", func(t *testing.T) {
|
||||
fiberRouter, oasRouter := setupSwagger(t)
|
||||
|
||||
fiberRouter.Route("/foo", func(router fiber.Router) {
|
||||
subRouter, err := oasRouter.SubRouter(oasFiber.NewRouter(router), swagger.SubRouterOptions{
|
||||
PathPrefix: "/prefix",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = subRouter.AddRoute(http.MethodGet, "/nested", okHandler, swagger.Definitions{})
|
||||
require.NoError(t, err)
|
||||
subRouter, err := oasRouter.SubRouter(oasFiber.NewRouter(fiberRouter), swagger.SubRouterOptions{
|
||||
PathPrefix: "/prefix",
|
||||
})
|
||||
|
||||
oasRouter.AddRoute(http.MethodGet, "/foo", okHandler, swagger.Definitions{})
|
||||
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
resp, err := fiberRouter.Test(r)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
body := readBody(t, resp.Body)
|
||||
require.Equal(t, "OK", body)
|
||||
_, err = subRouter.AddRoute(http.MethodGet, "/foo", okHandler, swagger.Definitions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("correctly call router", func(t *testing.T) {
|
||||
r := httptest.NewRequest(http.MethodGet, "/foo", nil)
|
||||
err = oasRouter.GenerateAndExposeOpenapi()
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("correctly call /hello", func(t *testing.T) {
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
resp, err := fiberRouter.Test(r)
|
||||
require.NoError(t, err)
|
||||
@@ -83,7 +90,7 @@ func TestWithFiber(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("correctly call sub router", func(t *testing.T) {
|
||||
r := httptest.NewRequest(http.MethodGet, "/foo/prefix/nested", nil)
|
||||
r := httptest.NewRequest(http.MethodGet, "/prefix/foo", nil)
|
||||
|
||||
resp, err := fiberRouter.Test(r)
|
||||
require.NoError(t, err)
|
||||
@@ -101,7 +108,7 @@ func TestWithFiber(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
body := readBody(t, resp.Body)
|
||||
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
|
||||
require.JSONEq(t, readFile(t, "../testdata/intergation-subrouter.json"), body, body)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -128,7 +135,7 @@ func setupSwagger(t *testing.T) (*fiber.App, *SwaggerRouter) {
|
||||
_, err = router.AddRawRoute(http.MethodGet, "/hello", okHandler, operation)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = router.GenerateAndExposeOpenapi()
|
||||
_, err = router.AddRoute(http.MethodPost, "/hello/:value", okHandler, swagger.Definitions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
return fiberRouter, router
|
||||
@@ -147,3 +154,12 @@ func readBody(t *testing.T, requestBody io.ReadCloser) string {
|
||||
|
||||
return string(body)
|
||||
}
|
||||
|
||||
func readFile(t *testing.T, path string) string {
|
||||
t.Helper()
|
||||
|
||||
fileContent, err := os.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
return string(fileContent)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ func (r gorillaRouter) SwaggerHandler(contentType string, blob []byte) HandlerFu
|
||||
}
|
||||
}
|
||||
|
||||
func (r gorillaRouter) TransformPathToOasPath(path string) string {
|
||||
return path
|
||||
}
|
||||
|
||||
func NewRouter(router *mux.Router) apirouter.Router[HandlerFunc, Route] {
|
||||
return gorillaRouter{
|
||||
router: router,
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
swagger "github.com/davidebianchi/gswagger"
|
||||
@@ -23,7 +24,10 @@ type SwaggerRouter = swagger.Router[gorilla.HandlerFunc, gorilla.Route]
|
||||
|
||||
func TestGorillaIntegration(t *testing.T) {
|
||||
t.Run("router works correctly", func(t *testing.T) {
|
||||
muxRouter, _ := setupSwagger(t)
|
||||
muxRouter, oasRouter := setupSwagger(t)
|
||||
|
||||
err := oasRouter.GenerateAndExposeOpenapi()
|
||||
require.NoError(t, err)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
@@ -44,15 +48,15 @@ func TestGorillaIntegration(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
|
||||
require.JSONEq(t, readFile(t, "../testdata/integration.json"), body)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("works correctly with subrouter - handles path prefix - gorilla mux", func(t *testing.T) {
|
||||
muxRouter, swaggerRouter := setupSwagger(t)
|
||||
muxRouter, oasRouter := setupSwagger(t)
|
||||
|
||||
muxSubRouter := muxRouter.NewRoute().Subrouter()
|
||||
subRouter, err := swaggerRouter.SubRouter(gorilla.NewRouter(muxSubRouter), swagger.SubRouterOptions{
|
||||
subRouter, err := oasRouter.SubRouter(gorilla.NewRouter(muxSubRouter), swagger.SubRouterOptions{
|
||||
PathPrefix: "/prefix",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -60,15 +64,20 @@ func TestGorillaIntegration(t *testing.T) {
|
||||
_, err = subRouter.AddRoute(http.MethodGet, "/foo", okHandler, swagger.Definitions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
err = oasRouter.GenerateAndExposeOpenapi()
|
||||
require.NoError(t, err)
|
||||
|
||||
muxRouter.ServeHTTP(w, r)
|
||||
t.Run("correctly call router", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
muxRouter.ServeHTTP(w, r)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "OK", body)
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "OK", body)
|
||||
})
|
||||
|
||||
t.Run("correctly call sub router", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
@@ -91,7 +100,7 @@ func TestGorillaIntegration(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
|
||||
body := readBody(t, w.Result().Body)
|
||||
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
|
||||
require.JSONEq(t, readFile(t, "../testdata/intergation-subrouter.json"), body, body)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -127,7 +136,7 @@ func setupSwagger(t *testing.T) (*mux.Router, *SwaggerRouter) {
|
||||
_, err = router.AddRawRoute(http.MethodGet, "/hello", okHandler, operation)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = router.GenerateAndExposeOpenapi()
|
||||
_, err = router.AddRoute(http.MethodPost, "/hello/{value}", okHandler, swagger.Definitions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
return muxRouter, router
|
||||
@@ -137,3 +146,12 @@ func okHandler(w http.ResponseWriter, req *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`OK`))
|
||||
}
|
||||
|
||||
func readFile(t *testing.T, path string) string {
|
||||
t.Helper()
|
||||
|
||||
fileContent, err := os.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
return string(fileContent)
|
||||
}
|
||||
|
||||
1
support/gorilla/testdata/examples-users.json
vendored
1
support/gorilla/testdata/examples-users.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "my title",
|
||||
"version": "1.0.0"
|
||||
|
||||
37
support/testdata/integration.json
vendored
Normal file
37
support/testdata/integration.json
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
},
|
||||
"openapi": "3.0.0",
|
||||
"paths": {
|
||||
"/hello": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/hello/{value}": {
|
||||
"post": {
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "value",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
support/testdata/intergation-subrouter.json
vendored
Normal file
46
support/testdata/intergation-subrouter.json
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
},
|
||||
"openapi": "3.0.0",
|
||||
"paths": {
|
||||
"/hello": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/hello/{value}": {
|
||||
"post": {
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "value",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/prefix/foo": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
testdata/allof.json
vendored
1
testdata/allof.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/anyof.json
vendored
1
testdata/anyof.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/cookies.json
vendored
1
testdata/cookies.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/empty-route-schema.json
vendored
1
testdata/empty-route-schema.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/empty.json
vendored
1
testdata/empty.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
21
testdata/extension.json
vendored
Normal file
21
testdata/extension.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
},
|
||||
"openapi": "3.0.0",
|
||||
"paths": {
|
||||
"/users": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"x-extension-field": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
testdata/headers.json
vendored
1
testdata/headers.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/multipart-requestbody.json
vendored
1
testdata/multipart-requestbody.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/oneOf.json
vendored
1
testdata/oneOf.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/params-autofill.json
vendored
1
testdata/params-autofill.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/params.json
vendored
1
testdata/params.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/query.json
vendored
1
testdata/query.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/router_with_prefix.json
vendored
1
testdata/router_with_prefix.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/schema-no-content.json
vendored
1
testdata/schema-no-content.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
26
testdata/security.json
vendored
Normal file
26
testdata/security.json
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
},
|
||||
"openapi": "3.0.0",
|
||||
"paths": {
|
||||
"/users": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"api_key": [],
|
||||
"auth": [
|
||||
"resource.write"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
testdata/subrouter.json
vendored
1
testdata/subrouter.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/tags.json
vendored
1
testdata/tags.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
21
testdata/users-deprecated-with-description.json
vendored
Normal file
21
testdata/users-deprecated-with-description.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
},
|
||||
"openapi": "3.0.0",
|
||||
"paths": {
|
||||
"/users": {
|
||||
"get": {
|
||||
"deprecated": true,
|
||||
"description": "this is the long route description",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"summary": "small description"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
testdata/users_employees.json
vendored
1
testdata/users_employees.json
vendored
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "test swagger title",
|
||||
"version": "test swagger version"
|
||||
|
||||
1
testdata/users_employees.yaml
vendored
1
testdata/users_employees.yaml
vendored
@@ -1,4 +1,3 @@
|
||||
components: {}
|
||||
info:
|
||||
title: test swagger title
|
||||
version: test swagger version
|
||||
|
||||
Reference in New Issue
Block a user