Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions internal/server/controllers/agent.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package controllers

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/service"
)
Expand All @@ -13,7 +11,7 @@ func ListAgentStrategies(c *gin.Context) {
Page int `form:"page" validate:"required,min=1"`
PageSize int `form:"page_size" validate:"required,min=1,max=256"`
}) {
c.JSON(http.StatusOK, service.ListAgentStrategies(request.TenantID, request.Page, request.PageSize))
JSONResponse(c, service.ListAgentStrategies(request.TenantID, request.Page, request.PageSize))
})
}

Expand All @@ -23,6 +21,6 @@ func GetAgentStrategy(c *gin.Context) {
PluginID string `form:"plugin_id" validate:"required"`
Provider string `form:"provider" validate:"required"`
}) {
c.JSON(http.StatusOK, service.GetAgentStrategy(request.TenantID, request.PluginID, request.Provider))
JSONResponse(c, service.GetAgentStrategy(request.TenantID, request.PluginID, request.Provider))
})
}
23 changes: 23 additions & 0 deletions internal/server/controllers/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,37 @@ package controllers

import (
"errors"
"net/http"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/server/constants"
"github.com/langgenius/dify-plugin-daemon/internal/types/exception"
"github.com/langgenius/dify-plugin-daemon/pkg/entities"
"github.com/langgenius/dify-plugin-daemon/pkg/entities/plugin_entities"
"github.com/langgenius/dify-plugin-daemon/pkg/validators"
)

func statusCodeFromResponse(resp *entities.Response) int {
if resp == nil {
return http.StatusInternalServerError
}

if resp.Code >= 0 {
return http.StatusOK
}

status := -resp.Code
if status < 100 || status > 599 {
return http.StatusInternalServerError
}

return status
}

func JSONResponse(r *gin.Context, resp *entities.Response) {
r.JSON(statusCodeFromResponse(resp), resp)
}

func BindRequest[T any](r *gin.Context, success func(T)) {
var request T

Expand Down
159 changes: 159 additions & 0 deletions internal/server/controllers/base_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package controllers

import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/pkg/entities"
)

func TestStatusCodeFromResponse(t *testing.T) {
t.Parallel()

tests := []struct {
name string
resp *entities.Response
want int
}{
{
name: "nil response",
resp: nil,
want: http.StatusInternalServerError,
},
{
name: "success response",
resp: &entities.Response{Code: 0},
want: http.StatusOK,
},
{
name: "positive code response",
resp: &entities.Response{Code: 123},
want: http.StatusOK,
},
{
name: "bad request response",
resp: &entities.Response{Code: -400},
want: http.StatusBadRequest,
},
{
name: "not found response",
resp: &entities.Response{Code: -404},
want: http.StatusNotFound,
},
{
name: "internal server error response",
resp: &entities.Response{Code: -500},
want: http.StatusInternalServerError,
},
{
name: "invalid low status code",
resp: &entities.Response{Code: -99},
want: http.StatusInternalServerError,
},
{
name: "invalid high status code",
resp: &entities.Response{Code: -600},
want: http.StatusInternalServerError,
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

got := statusCodeFromResponse(tt.resp)
if got != tt.want {
t.Fatalf("statusCodeFromResponse() = %d, want %d", got, tt.want)
}
})
}
}

func TestJSONResponse(t *testing.T) {
t.Parallel()

gin.SetMode(gin.TestMode)

tests := []struct {
name string
resp *entities.Response
wantStatus int
wantBody entities.Response
}{
{
name: "success response",
resp: entities.NewSuccessResponse(map[string]any{"ok": true}),
wantStatus: http.StatusOK,
wantBody: entities.Response{
Code: 0,
Message: "success",
Data: map[string]any{"ok": true},
},
},
{
name: "bad request response",
resp: entities.NewDaemonErrorResponse(-400, "bad request"),
wantStatus: http.StatusBadRequest,
wantBody: entities.Response{
Code: -400,
Message: "bad request",
Data: nil,
},
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)

JSONResponse(ctx, tt.resp)

if recorder.Code != tt.wantStatus {
t.Fatalf("recorder.Code = %d, want %d", recorder.Code, tt.wantStatus)
}

var got entities.Response
if err := json.Unmarshal(recorder.Body.Bytes(), &got); err != nil {
t.Fatalf("failed to unmarshal response body: %v", err)
}

if got.Code != tt.wantBody.Code {
t.Fatalf("response code = %d, want %d", got.Code, tt.wantBody.Code)
}
if got.Message != tt.wantBody.Message {
t.Fatalf("response message = %q, want %q", got.Message, tt.wantBody.Message)
}

if tt.wantBody.Data == nil {
if got.Data != nil {
t.Fatalf("response data = %#v, want nil", got.Data)
}
return
}

gotMap, ok := got.Data.(map[string]any)
if !ok {
t.Fatalf("response data type = %T, want map[string]any", got.Data)
}

wantMap := tt.wantBody.Data.(map[string]any)
if len(gotMap) != len(wantMap) {
t.Fatalf("response data length = %d, want %d", len(gotMap), len(wantMap))
}

for key, wantValue := range wantMap {
if gotMap[key] != wantValue {
t.Fatalf("response data[%q] = %#v, want %#v", key, gotMap[key], wantValue)
}
}
})
}
}
6 changes: 2 additions & 4 deletions internal/server/controllers/datasource.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package controllers

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/service"
)
Expand All @@ -13,7 +11,7 @@ func ListDatasources(c *gin.Context) {
Page int `form:"page" validate:"required,min=1"`
PageSize int `form:"page_size" validate:"required,min=1,max=256"`
}) {
c.JSON(http.StatusOK, service.ListDatasources(request.TenantID, request.Page, request.PageSize))
JSONResponse(c, service.ListDatasources(request.TenantID, request.Page, request.PageSize))
})
}

Expand All @@ -23,6 +21,6 @@ func GetDatasource(c *gin.Context) {
PluginID string `form:"plugin_id" validate:"required"`
Provider string `form:"provider" validate:"required"`
}) {
c.JSON(http.StatusOK, service.GetDatasource(request.TenantID, request.PluginID, request.Provider))
JSONResponse(c, service.GetDatasource(request.TenantID, request.PluginID, request.Provider))
})
}
14 changes: 7 additions & 7 deletions internal/server/controllers/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func SetupEndpoint(ctx *gin.Context) {
pluginUniqueIdentifier := request.PluginUniqueIdentifier
name := request.Name

ctx.JSON(200, service.SetupEndpoint(
JSONResponse(ctx, service.SetupEndpoint(
tenantId, userId, pluginUniqueIdentifier, name, settings,
))
})
Expand All @@ -38,7 +38,7 @@ func ListEndpoints(ctx *gin.Context) {
page := request.Page
pageSize := request.PageSize

ctx.JSON(200, service.ListEndpoints(tenantId, page, pageSize))
JSONResponse(ctx, service.ListEndpoints(tenantId, page, pageSize))
})
}

Expand All @@ -54,7 +54,7 @@ func ListPluginEndpoints(ctx *gin.Context) {
page := request.Page
pageSize := request.PageSize

ctx.JSON(200, service.ListPluginEndpoints(tenantId, pluginId, page, pageSize))
JSONResponse(ctx, service.ListPluginEndpoints(tenantId, pluginId, page, pageSize))
})
}

Expand All @@ -66,7 +66,7 @@ func RemoveEndpoint(ctx *gin.Context) {
endpointId := request.EndpointID
tenantId := request.TenantID

ctx.JSON(200, service.RemoveEndpoint(endpointId, tenantId))
JSONResponse(ctx, service.RemoveEndpoint(endpointId, tenantId))
})
}

Expand All @@ -84,7 +84,7 @@ func UpdateEndpoint(ctx *gin.Context) {
settings := request.Settings
name := request.Name

ctx.JSON(200, service.UpdateEndpoint(endpointId, tenantId, userId, name, settings))
JSONResponse(ctx, service.UpdateEndpoint(endpointId, tenantId, userId, name, settings))
})
}

Expand All @@ -96,7 +96,7 @@ func EnableEndpoint(ctx *gin.Context) {
tenantId := request.TenantID
endpointId := request.EndpointID

ctx.JSON(200, service.EnableEndpoint(endpointId, tenantId))
JSONResponse(ctx, service.EnableEndpoint(endpointId, tenantId))
})
}

Expand All @@ -108,6 +108,6 @@ func DisableEndpoint(ctx *gin.Context) {
tenantId := request.TenantID
endpointId := request.EndpointID

ctx.JSON(200, service.DisableEndpoint(endpointId, tenantId))
JSONResponse(ctx, service.DisableEndpoint(endpointId, tenantId))
})
}
4 changes: 1 addition & 3 deletions internal/server/controllers/model.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package controllers

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/langgenius/dify-plugin-daemon/internal/service"
)
Expand All @@ -13,6 +11,6 @@ func ListModels(c *gin.Context) {
Page int `form:"page" validate:"required,min=1"`
PageSize int `form:"page_size" validate:"required,min=1,max=256"`
}) {
c.JSON(http.StatusOK, service.ListModels(request.TenantID, request.Page, request.PageSize))
JSONResponse(c, service.ListModels(request.TenantID, request.Page, request.PageSize))
})
}
Loading
Loading