add docExpansion feature (#163)

* add docExpansion feature

* add pull request template
This commit is contained in:
Bogdan U 2021-09-25 14:14:03 +03:00 committed by GitHub
parent 6433b1c297
commit b388ffa3dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 44 deletions

8
PULL_REQUEST_TEMPLATE.md Normal file
View File

@ -0,0 +1,8 @@
**Describe the PR**
e.g. add cool parser.
**Relation issue**
e.g. https://github.com/swaggo/gin-swagger/pull/123/files
**Additional context**
Add any other context about the problem here.

View File

@ -147,5 +147,6 @@ func main() {
| Option | Type | Default | Description |
|--------------------------|--------|------------|---------------------------------------------------------------------------|
| URL | string | "doc.json" | URL pointing to API definition |
| DeepLinking | bool | true | Swagger deeplinking configuration |
| DocExpantion | string | "list" | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). |
| DeepLinking | bool | true | If set to true, enables deep linking for tags and operations. See the Deep Linking documentation for more information.|
| DefaultModelsExpandDepth | int | 1 | Default expansion depth for models (set to -1 completely hide the models) |

View File

@ -4,8 +4,8 @@ import (
"html/template"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"golang.org/x/net/webdav"
@ -19,6 +19,7 @@ type Config struct {
//The url pointing to API definition (normally swagger.json or swagger.yaml). Default is `doc.json`.
URL string
DeepLinking bool
DocExpansion string
DefaultModelsExpandDepth int
}
@ -29,6 +30,13 @@ func URL(url string) func(c *Config) {
}
}
// DocExpansion list, full, none.
func DocExpansion(docExpansion string) func(c *Config) {
return func(c *Config) {
c.DocExpansion = docExpansion
}
}
// DeepLinking set the swagger deeplinking configuration
func DeepLinking(deepLinking bool) func(c *Config) {
return func(c *Config) {
@ -49,6 +57,7 @@ func WrapHandler(h *webdav.Handler, confs ...func(c *Config)) gin.HandlerFunc {
defaultConfig := &Config{
URL: "doc.json",
DeepLinking: true,
DocExpansion: "list",
DefaultModelsExpandDepth: 1,
}
@ -60,52 +69,43 @@ func WrapHandler(h *webdav.Handler, confs ...func(c *Config)) gin.HandlerFunc {
}
// CustomWrapHandler wraps `http.Handler` into `gin.HandlerFunc`
func CustomWrapHandler(config *Config, h *webdav.Handler) gin.HandlerFunc {
func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc {
var once sync.Once
// create a template with name
t := template.New("swagger_index.html")
index, _ := t.Parse(swagger_index_templ)
var rexp = regexp.MustCompile(`(.*)(index\.html|doc\.json|favicon-16x16\.png|favicon-32x32\.png|/oauth2-redirect\.html|swagger-ui\.css|swagger-ui\.css\.map|swagger-ui\.js|swagger-ui\.js\.map|swagger-ui-bundle\.js|swagger-ui-bundle\.js\.map|swagger-ui-standalone-preset\.js|swagger-ui-standalone-preset\.js\.map)[\?|.]*`)
var locker sync.RWMutex
return func(c *gin.Context) {
matches := rexp.FindStringSubmatch(c.Request.RequestURI)
type swaggerUIBundle struct {
URL string
DeepLinking bool
DefaultModelsExpandDepth int
}
var matches []string
if matches = rexp.FindStringSubmatch(c.Request.RequestURI); len(matches) != 3 {
if len(matches) != 3 {
c.Status(404)
c.Writer.Write([]byte("404 page not found"))
_, _ = c.Writer.Write([]byte("404 page not found"))
return
}
path := matches[2]
prefix := matches[1]
once.Do(func() {
handler.Prefix = matches[1]
})
locker.Lock()
h.Prefix = prefix
locker.Unlock()
if strings.HasSuffix(path, ".html") {
switch filepath.Ext(path) {
case ".html":
c.Header("Content-Type", "text/html; charset=utf-8")
} else if strings.HasSuffix(path, ".css") {
case ".css":
c.Header("Content-Type", "text/css; charset=utf-8")
} else if strings.HasSuffix(path, ".js") {
case ".js":
c.Header("Content-Type", "application/javascript")
} else if strings.HasSuffix(path, ".json") {
case ".json":
c.Header("Content-Type", "application/json; charset=utf-8")
}
switch path {
case "index.html":
index.Execute(c.Writer, &swaggerUIBundle{
URL: config.URL,
DeepLinking: config.DeepLinking,
DefaultModelsExpandDepth: config.DefaultModelsExpandDepth,
})
_ = index.Execute(c.Writer, config)
case "doc.json":
doc, err := swag.ReadDoc()
if err != nil {
@ -113,11 +113,9 @@ func CustomWrapHandler(config *Config, h *webdav.Handler) gin.HandlerFunc {
return
}
c.Writer.Write([]byte(doc))
_, _ = c.Writer.Write([]byte(doc))
default:
locker.RLock()
h.ServeHTTP(c.Writer, c.Request)
locker.RUnlock()
handler.ServeHTTP(c.Writer, c.Request)
}
}
}
@ -238,6 +236,7 @@ window.onload = function() {
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout",
docExpansion: "{{.DocExpansion}}",
deepLinking: {{.DeepLinking}},
defaultModelsExpandDepth: {{.DefaultModelsExpandDepth}}
})

View File

@ -1,13 +1,14 @@
package ginSwagger
import (
"github.com/gin-contrib/gzip"
"github.com/swaggo/swag"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/gin-contrib/gzip"
"github.com/swaggo/swag"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/swaggo/gin-swagger/swaggerFiles"
@ -74,7 +75,7 @@ func TestDisablingWrapHandler(t *testing.T) {
w4 := performRequest("GET", "/simple/notfound", router)
assert.Equal(t, 404, w4.Code)
os.Setenv(disablingKey, "true")
_ = os.Setenv(disablingKey, "true")
router.GET("/disabling/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey))
@ -102,7 +103,7 @@ func TestDisablingCustomWrapHandler(t *testing.T) {
w1 := performRequest("GET", "/simple/index.html", router)
assert.Equal(t, 200, w1.Code)
os.Setenv(disablingKey, "true")
_ = os.Setenv(disablingKey, "true")
router.GET("/disabling/*any", DisablingCustomWrapHandler(&Config{}, swaggerFiles.Handler, disablingKey))
@ -143,25 +144,63 @@ func performRequest(method, target string, router *gin.Engine) *httptest.Respons
}
func TestURL(t *testing.T) {
expected := "https://github.com/swaggo/http-swagger"
cfg := Config{}
expected := "https://github.com/swaggo/http-swagger"
configFunc := URL(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.URL)
}
func TestDeepLinking(t *testing.T) {
expected := true
cfg := Config{}
configFunc := DeepLinking(expected)
func TestDocExpansion(t *testing.T) {
var cfg Config
expected := "list"
configFunc := DocExpansion(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DeepLinking)
assert.Equal(t, expected, cfg.DocExpansion)
expected = "full"
configFunc = DocExpansion(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DocExpansion)
expected = "none"
configFunc = DocExpansion(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DocExpansion)
}
func TestDeepLinking(t *testing.T) {
var cfg Config
assert.Equal(t, false, cfg.DeepLinking)
configFunc := DeepLinking(true)
configFunc(&cfg)
assert.Equal(t, true, cfg.DeepLinking)
configFunc = DeepLinking(false)
configFunc(&cfg)
assert.Equal(t, false, cfg.DeepLinking)
}
func TestDefaultModelsExpandDepth(t *testing.T) {
var cfg Config
assert.Equal(t, 0, cfg.DefaultModelsExpandDepth)
expected := -1
cfg := Config{}
configFunc := DefaultModelsExpandDepth(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DefaultModelsExpandDepth)
expected = 1
configFunc = DefaultModelsExpandDepth(expected)
configFunc(&cfg)
assert.Equal(t, expected, cfg.DefaultModelsExpandDepth)
}
func TestDeepLinking2(t *testing.T) {
t.Logf("extension: %s", filepath.Ext("/asas/index.html"))
}