feat: OpsxAPI v1.0 全协议接口工作台
- 六协议调试:HTTP/GraphQL/WebSocket/SSE/Socket.IO/MQTT
- 集合树/多标签/多环境变量/历史记录,localStorage 持久化
- 导入:OpenAPI 2/3/3.1、Postman、Apifox、Apipost、cURL、HAR、
Insomnia、Hoppscotch、Markdown(自动识别,21 个单测覆盖)
- 导出:OpenAPI 3.0 JSON/YAML、Postman v2.1、Markdown 文档、
全量备份;单请求生成 cURL/fetch/Python/Go 代码
- Gin 服务:HTTP 代理、NDJSON 流式代理(SSE 透传)、
WebSocket 隧道(浏览器自定义握手 Header)
- 内置产品官网 /home 与用户文档站 /docs(SSR,随二进制交付)
- lucide 图标体系 + 品牌标识(Logo/favicon),明暗双主题
- 环境变量:彩色徽标切换器、管理弹窗、{{ 自动补全
This commit is contained in:
commit
dec66db5aa
182 files changed
+23377
No files matched your search
@@ -0,0 +1,63 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func newTestRouter(t *testing.T) *gin.Engine {
|
||||
t.Helper()
|
||||
gin.SetMode(gin.TestMode)
|
||||
r := gin.New()
|
||||
New().Register(r)
|
||||
return r
|
||||
}
|
||||
|
||||
func TestSitePageRender(t *testing.T) {
|
||||
r := newTestRouter(t)
|
||||
for _, path := range []string{"/", "/home", "/index.html"} {
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, path, nil))
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("%s: expect 200, got %d", path, w.Code)
|
||||
}
|
||||
body := w.Body.String()
|
||||
for _, want := range []string{
|
||||
"<title>OpsxAPI", // 标题
|
||||
`id="features"`, // 功能区
|
||||
`id="pricing"`, // 定价区
|
||||
"¥99", // 入门价
|
||||
"¥8,000", // 企业档标价
|
||||
"¥30,000", // 买断标价
|
||||
"¥5,000–8,000", // 成交区间
|
||||
"永久买断", // 买断 FAQ
|
||||
"早鸟创始价", // 让利策略
|
||||
"Socket.IO", // 协议覆盖
|
||||
"hello@opsxapi.dev", // 联系方式
|
||||
`href="/docs"`, // 文档互链
|
||||
`href="/site/assets/site.css"`, // 样式资源
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("%s: missing %q", path, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSiteAsset(t *testing.T) {
|
||||
r := newTestRouter(t)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/site/assets/site.css", nil))
|
||||
if w.Code != http.StatusOK || !strings.Contains(w.Header().Get("Content-Type"), "text/css") {
|
||||
t.Fatalf("css: %d %s", w.Code, w.Header().Get("Content-Type"))
|
||||
}
|
||||
w = httptest.NewRecorder()
|
||||
r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/site/assets/../template.html", nil))
|
||||
if w.Code != http.StatusBadRequest && w.Code != http.StatusNotFound {
|
||||
t.Fatalf("path traversal should be rejected, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user