mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-11-13 18:03:53 +00:00
More fixes for _request
This commit is contained in:
parent
682716dd31
commit
7b8216b71c
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -69,7 +69,7 @@ jobs:
|
|||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Run golangci-lint
|
- name: Run golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v6
|
uses: golangci/golangci-lint-action@v9
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
args: --timeout=5m
|
args: --timeout=5m
|
||||||
|
|||||||
@ -71,9 +71,9 @@ func (p *NestedCUDProcessor) ProcessNestedCUD(
|
|||||||
RelationData: make(map[string]interface{}),
|
RelationData: make(map[string]interface{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if data has a crud_request field that overrides the operation
|
// Check if data has a _request field that overrides the operation
|
||||||
if requestOp := p.extractCRUDRequest(data); requestOp != "" {
|
if requestOp := p.extractCRUDRequest(data); requestOp != "" {
|
||||||
logger.Debug("Found crud_request override: %s", requestOp)
|
logger.Debug("Found _request override: %s", requestOp)
|
||||||
operation = requestOp
|
operation = requestOp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,8 +92,8 @@ func (p *NestedCUDProcessor) ProcessNestedCUD(
|
|||||||
regularData := make(map[string]interface{})
|
regularData := make(map[string]interface{})
|
||||||
|
|
||||||
for key, value := range data {
|
for key, value := range data {
|
||||||
// Skip crud_request field in actual data processing
|
// Skip _request field in actual data processing
|
||||||
if key == "crud_request" {
|
if key == "_request" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,9 +162,9 @@ func (p *NestedCUDProcessor) ProcessNestedCUD(
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractCRUDRequest extracts the crud_request field from data if present
|
// extractCRUDRequest extracts the request field from data if present
|
||||||
func (p *NestedCUDProcessor) extractCRUDRequest(data map[string]interface{}) string {
|
func (p *NestedCUDProcessor) extractCRUDRequest(data map[string]interface{}) string {
|
||||||
if request, ok := data["crud_request"]; ok {
|
if request, ok := data["_request"]; ok {
|
||||||
if requestStr, ok := request.(string); ok {
|
if requestStr, ok := request.(string); ok {
|
||||||
return strings.ToLower(strings.TrimSpace(requestStr))
|
return strings.ToLower(strings.TrimSpace(requestStr))
|
||||||
}
|
}
|
||||||
@ -377,10 +377,10 @@ func (p *NestedCUDProcessor) getTableNameForModel(model interface{}, defaultName
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ShouldUseNestedProcessor determines if we should use nested CUD processing
|
// ShouldUseNestedProcessor determines if we should use nested CUD processing
|
||||||
// It checks if the data contains nested relations or a crud_request field
|
// It checks if the data contains nested relations or a _request field
|
||||||
func ShouldUseNestedProcessor(data map[string]interface{}, model interface{}, relationshipHelper RelationshipInfoProvider) bool {
|
func ShouldUseNestedProcessor(data map[string]interface{}, model interface{}, relationshipHelper RelationshipInfoProvider) bool {
|
||||||
// Check for crud_request field
|
// Check for _request field
|
||||||
if _, hasCRUDRequest := data["crud_request"]; hasCRUDRequest {
|
if _, hasCRUDRequest := data["_request"]; hasCRUDRequest {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,8 +396,8 @@ func ShouldUseNestedProcessor(data map[string]interface{}, model interface{}, re
|
|||||||
|
|
||||||
// Check if data contains any fields that are relations (nested objects or arrays)
|
// Check if data contains any fields that are relations (nested objects or arrays)
|
||||||
for key, value := range data {
|
for key, value := range data {
|
||||||
// Skip crud_request and regular scalar fields
|
// Skip _request and regular scalar fields
|
||||||
if key == "crud_request" {
|
if key == "_request" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -294,7 +294,7 @@ func (h *Handler) handleCreate(ctx context.Context, w common.ResponseWriter, dat
|
|||||||
|
|
||||||
logger.Info("Creating records for %s.%s", schema, entity)
|
logger.Info("Creating records for %s.%s", schema, entity)
|
||||||
|
|
||||||
// Check if data contains nested relations or crud_request field
|
// Check if data contains nested relations or _request field
|
||||||
switch v := data.(type) {
|
switch v := data.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
// Check if we should use nested processing
|
// Check if we should use nested processing
|
||||||
@ -1003,7 +1003,7 @@ func (h *Handler) RegisterModel(schema, name string, model interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// shouldUseNestedProcessor determines if we should use nested CUD processing
|
// shouldUseNestedProcessor determines if we should use nested CUD processing
|
||||||
// It checks if the data contains nested relations or a crud_request field
|
// It checks if the data contains nested relations or a _request field
|
||||||
func (h *Handler) shouldUseNestedProcessor(data map[string]interface{}, model interface{}) bool {
|
func (h *Handler) shouldUseNestedProcessor(data map[string]interface{}, model interface{}) bool {
|
||||||
return common.ShouldUseNestedProcessor(data, model, h)
|
return common.ShouldUseNestedProcessor(data, model, h)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,15 +10,15 @@ type GormTableSchemaInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GormTableCRUDRequest struct {
|
type GormTableCRUDRequest struct {
|
||||||
CRUDRequest *string `json:"crud_request"`
|
Request *string `json:"_request"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GormTableCRUDRequest) SetRequest(request string) {
|
func (r *GormTableCRUDRequest) SetRequest(request string) {
|
||||||
r.CRUDRequest = &request
|
r.Request = &request
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r GormTableCRUDRequest) GetRequest() string {
|
func (r GormTableCRUDRequest) GetRequest() string {
|
||||||
return *r.CRUDRequest
|
return *r.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
// New interfaces that replace the legacy ones above
|
// New interfaces that replace the legacy ones above
|
||||||
|
|||||||
@ -1624,7 +1624,7 @@ func filterExtendedOptions(validator *common.ColumnValidator, options ExtendedRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// shouldUseNestedProcessor determines if we should use nested CUD processing
|
// shouldUseNestedProcessor determines if we should use nested CUD processing
|
||||||
// It checks if the data contains nested relations or a crud_request field
|
// It checks if the data contains nested relations or a _request field
|
||||||
func (h *Handler) shouldUseNestedProcessor(data map[string]interface{}, model interface{}) bool {
|
func (h *Handler) shouldUseNestedProcessor(data map[string]interface{}, model interface{}) bool {
|
||||||
return common.ShouldUseNestedProcessor(data, model, h)
|
return common.ShouldUseNestedProcessor(data, model, h)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ func TestDepartmentEmployees(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := makeRequest(t, "/test/departments", deptPayload)
|
resp := makeRequest(t, "/departments", deptPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// Create employees in department
|
// Create employees in department
|
||||||
@ -52,7 +52,7 @@ func TestDepartmentEmployees(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = makeRequest(t, "/test/employees", empPayload)
|
resp = makeRequest(t, "/employees", empPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// Read department with employees
|
// Read department with employees
|
||||||
@ -68,7 +68,7 @@ func TestDepartmentEmployees(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = makeRequest(t, "/test/departments/dept1", readPayload)
|
resp = makeRequest(t, "/departments/dept1", readPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
var result map[string]interface{}
|
var result map[string]interface{}
|
||||||
@ -92,7 +92,7 @@ func TestEmployeeHierarchy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := makeRequest(t, "/test/employees", mgrPayload)
|
resp := makeRequest(t, "/employees", mgrPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// Update employees to set manager
|
// Update employees to set manager
|
||||||
@ -103,9 +103,9 @@ func TestEmployeeHierarchy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = makeRequest(t, "/test/employees/emp1", updatePayload)
|
resp = makeRequest(t, "/employees/emp1", updatePayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
resp = makeRequest(t, "/test/employees/emp2", updatePayload)
|
resp = makeRequest(t, "/employees/emp2", updatePayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// Read manager with reports
|
// Read manager with reports
|
||||||
@ -121,7 +121,7 @@ func TestEmployeeHierarchy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = makeRequest(t, "/test/employees/mgr1", readPayload)
|
resp = makeRequest(t, "/employees/mgr1", readPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
var result map[string]interface{}
|
var result map[string]interface{}
|
||||||
@ -147,7 +147,7 @@ func TestProjectStructure(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := makeRequest(t, "/test/projects", projectPayload)
|
resp := makeRequest(t, "/projects", projectPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// Create project tasks
|
// Create project tasks
|
||||||
@ -177,7 +177,7 @@ func TestProjectStructure(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = makeRequest(t, "/test/project_tasks", taskPayload)
|
resp = makeRequest(t, "/project_tasks", taskPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// Create task comments
|
// Create task comments
|
||||||
@ -191,7 +191,7 @@ func TestProjectStructure(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = makeRequest(t, "/test/comments", commentPayload)
|
resp = makeRequest(t, "/comments", commentPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// Read project with all relations
|
// Read project with all relations
|
||||||
@ -223,7 +223,7 @@ func TestProjectStructure(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = makeRequest(t, "/test/projects/proj1", readPayload)
|
resp = makeRequest(t, "/projects/proj1", readPayload)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
var result map[string]interface{}
|
var result map[string]interface{}
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/database"
|
||||||
|
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/router"
|
||||||
"github.com/bitechdev/ResolveSpec/pkg/logger"
|
"github.com/bitechdev/ResolveSpec/pkg/logger"
|
||||||
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
|
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
|
||||||
"github.com/bitechdev/ResolveSpec/pkg/resolvespec"
|
"github.com/bitechdev/ResolveSpec/pkg/resolvespec"
|
||||||
@ -117,23 +119,44 @@ func setupTestDB() (*gorm.DB, error) {
|
|||||||
func setupTestRouter(db *gorm.DB) http.Handler {
|
func setupTestRouter(db *gorm.DB) http.Handler {
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
|
|
||||||
// Create a new registry instance
|
// Create database adapter
|
||||||
|
dbAdapter := database.NewGormAdapter(db)
|
||||||
|
|
||||||
|
// Create registry
|
||||||
registry := modelregistry.NewModelRegistry()
|
registry := modelregistry.NewModelRegistry()
|
||||||
|
|
||||||
// Register test models with the registry
|
// Register test models without schema prefix for SQLite compatibility
|
||||||
|
// SQLite doesn't support schema prefixes like "test.employees"
|
||||||
testmodels.RegisterTestModels(registry)
|
testmodels.RegisterTestModels(registry)
|
||||||
|
|
||||||
// Create handler with GORM adapter and the registry
|
// Create handler with pre-populated registry
|
||||||
handler := resolvespec.NewHandlerWithGORM(db)
|
handler := resolvespec.NewHandler(dbAdapter, registry)
|
||||||
|
|
||||||
// Register test models with the handler for the "test" schema
|
// Setup routes without schema prefix for SQLite
|
||||||
models := testmodels.GetTestModels()
|
// Routes: GET/POST /{entity}, GET/POST/PUT/PATCH/DELETE /{entity}/{id}
|
||||||
modelNames := []string{"departments", "employees", "projects", "project_tasks", "documents", "comments"}
|
r.HandleFunc("/{entity}", func(w http.ResponseWriter, req *http.Request) {
|
||||||
for i, model := range models {
|
vars := mux.Vars(req)
|
||||||
handler.RegisterModel("test", modelNames[i], model)
|
vars["schema"] = "" // Empty schema for SQLite
|
||||||
}
|
reqAdapter := router.NewHTTPRequest(req)
|
||||||
|
respAdapter := router.NewHTTPResponseWriter(w)
|
||||||
|
handler.Handle(respAdapter, reqAdapter, vars)
|
||||||
|
}).Methods("POST")
|
||||||
|
|
||||||
resolvespec.SetupMuxRoutes(r, handler)
|
r.HandleFunc("/{entity}/{id}", func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
vars := mux.Vars(req)
|
||||||
|
vars["schema"] = "" // Empty schema for SQLite
|
||||||
|
reqAdapter := router.NewHTTPRequest(req)
|
||||||
|
respAdapter := router.NewHTTPResponseWriter(w)
|
||||||
|
handler.Handle(respAdapter, reqAdapter, vars)
|
||||||
|
}).Methods("POST")
|
||||||
|
|
||||||
|
r.HandleFunc("/{entity}", func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
vars := mux.Vars(req)
|
||||||
|
vars["schema"] = "" // Empty schema for SQLite
|
||||||
|
reqAdapter := router.NewHTTPRequest(req)
|
||||||
|
respAdapter := router.NewHTTPResponseWriter(w)
|
||||||
|
handler.HandleGet(respAdapter, reqAdapter, vars)
|
||||||
|
}).Methods("GET")
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user