Merge pull request #473 from trheyi/main
[add] page builder page api (curd)
This commit is contained in:
commit
94d9511687
8 changed files with 1070 additions and 53 deletions
|
|
@ -78,6 +78,36 @@ var dsl = []byte(`
|
||||||
"process": "sui.Page.Tree",
|
"process": "sui.Page.Tree",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
"in": ["$param.id", "$param.template_id", "$param.route"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
"out": { "status": 200, "type": "application/json" }
|
||||||
|
},{
|
||||||
|
"path": "/:id/page/save/:template_id/*route",
|
||||||
|
"method": "POST",
|
||||||
|
"process": "sui.Page.Save",
|
||||||
|
"in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||||
|
"out": { "status": 200, "type": "application/json" }
|
||||||
|
},{
|
||||||
|
"path": "/:id/page/temp/:template_id/*route",
|
||||||
|
"method": "POST",
|
||||||
|
"process": "sui.Page.SaveTemp",
|
||||||
|
"in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||||
|
"out": { "status": 200, "type": "application/json" }
|
||||||
|
},{
|
||||||
|
"path": "/:id/page/create/:template_id/*route",
|
||||||
|
"method": "POST",
|
||||||
|
"process": "sui.Page.Create",
|
||||||
|
"in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||||
|
"out": { "status": 200, "type": "application/json" }
|
||||||
|
},{
|
||||||
|
"path": "/:id/page/exist/:template_id/*route",
|
||||||
|
"method": "GET",
|
||||||
|
"process": "sui.Page.Exist",
|
||||||
|
"in": ["$param.id", "$param.template_id", "$param.route"],
|
||||||
|
"out": { "status": 200, "type": "application/json" }
|
||||||
|
},{
|
||||||
|
"path": "/:id/page/remove/:template_id/*route",
|
||||||
|
"method": "POST",
|
||||||
|
"process": "sui.Page.Remove",
|
||||||
|
"in": ["$param.id", "$param.template_id", "$param.route"],
|
||||||
|
"out": { "status": 200, "type": "application/json" }
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/yaoapp/gou/process"
|
"github.com/yaoapp/gou/process"
|
||||||
"github.com/yaoapp/kun/exception"
|
"github.com/yaoapp/kun/exception"
|
||||||
"github.com/yaoapp/yao/sui/core"
|
"github.com/yaoapp/yao/sui/core"
|
||||||
|
|
@ -24,9 +26,14 @@ func init() {
|
||||||
"component.get": ComponentGet,
|
"component.get": ComponentGet,
|
||||||
"component.find": ComponentFind,
|
"component.find": ComponentFind,
|
||||||
|
|
||||||
"page.tree": PageTree,
|
"page.tree": PageTree,
|
||||||
"page.get": PageGet,
|
"page.get": PageGet,
|
||||||
"page.asset": PageAsset,
|
"page.save": PageSave,
|
||||||
|
"page.savetemp": PageSaveTemp,
|
||||||
|
"page.create": PageCreate,
|
||||||
|
"page.remove": PageRemove,
|
||||||
|
"page.exist": PageExist,
|
||||||
|
"page.asset": PageAsset,
|
||||||
|
|
||||||
"editor.render": EditorRender,
|
"editor.render": EditorRender,
|
||||||
"editor.source": EditorSource,
|
"editor.source": EditorSource,
|
||||||
|
|
@ -34,7 +41,6 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TemplateGet handle the get Template request
|
// TemplateGet handle the get Template request
|
||||||
// Process sui.<ID>.templates
|
|
||||||
func TemplateGet(process *process.Process) interface{} {
|
func TemplateGet(process *process.Process) interface{} {
|
||||||
process.ValidateArgNums(1)
|
process.ValidateArgNums(1)
|
||||||
|
|
||||||
|
|
@ -223,6 +229,164 @@ func PageGet(process *process.Process) interface{} {
|
||||||
return tree
|
return tree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PageSave handle the find Template request
|
||||||
|
func PageSave(process *process.Process) interface{} {
|
||||||
|
process.ValidateArgNums(4)
|
||||||
|
sui := get(process)
|
||||||
|
templateID := process.ArgsString(1)
|
||||||
|
route := route(process, 2)
|
||||||
|
|
||||||
|
tmpl, err := sui.GetTemplate(templateID)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
var page core.IPage
|
||||||
|
if tmpl.PageExist(route) {
|
||||||
|
page, err = tmpl.Page(route)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
page, err = tmpl.CreatePage(route)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := getSource(process)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
if source == nil {
|
||||||
|
exception.New("the source is required", 400).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.Save(source)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PageSaveTemp handle the find Template request
|
||||||
|
func PageSaveTemp(process *process.Process) interface{} {
|
||||||
|
process.ValidateArgNums(4)
|
||||||
|
sui := get(process)
|
||||||
|
templateID := process.ArgsString(1)
|
||||||
|
route := route(process, 2)
|
||||||
|
|
||||||
|
tmpl, err := sui.GetTemplate(templateID)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
var page core.IPage
|
||||||
|
if tmpl.PageExist(route) {
|
||||||
|
page, err = tmpl.Page(route)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
page, err = tmpl.CreatePage(route)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := getSource(process)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
if source == nil {
|
||||||
|
exception.New("the source is required", 400).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
if source.UID == "" {
|
||||||
|
exception.New("the source.uid is required", 400).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.SaveTemp(source)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PageCreate handle the find Template request
|
||||||
|
func PageCreate(process *process.Process) interface{} {
|
||||||
|
process.ValidateArgNums(3)
|
||||||
|
sui := get(process)
|
||||||
|
templateID := process.ArgsString(1)
|
||||||
|
route := route(process, 2)
|
||||||
|
|
||||||
|
tmpl, err := sui.GetTemplate(templateID)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
page, err := tmpl.CreatePage(route)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(process.Args) <= 3 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := getSource(process)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
if source == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.Save(source)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PageRemove handle the find Template request
|
||||||
|
func PageRemove(process *process.Process) interface{} {
|
||||||
|
process.ValidateArgNums(3)
|
||||||
|
sui := get(process)
|
||||||
|
templateID := process.ArgsString(1)
|
||||||
|
route := route(process, 2)
|
||||||
|
|
||||||
|
tmpl, err := sui.GetTemplate(templateID)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tmpl.RemovePage(route)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PageExist handle the find Template request
|
||||||
|
func PageExist(process *process.Process) interface{} {
|
||||||
|
process.ValidateArgNums(3)
|
||||||
|
sui := get(process)
|
||||||
|
templateID := process.ArgsString(1)
|
||||||
|
route := route(process, 2)
|
||||||
|
|
||||||
|
tmpl, err := sui.GetTemplate(templateID)
|
||||||
|
if err != nil {
|
||||||
|
exception.New(err.Error(), 500).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpl.PageExist(route)
|
||||||
|
}
|
||||||
|
|
||||||
// PageAsset handle the find Template request
|
// PageAsset handle the find Template request
|
||||||
func PageAsset(process *process.Process) interface{} {
|
func PageAsset(process *process.Process) interface{} {
|
||||||
process.ValidateArgNums(3)
|
process.ValidateArgNums(3)
|
||||||
|
|
@ -357,3 +521,59 @@ func route(process *process.Process, i int) string {
|
||||||
}
|
}
|
||||||
return route
|
return route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSource(process *process.Process) (*core.RequestSource, error) {
|
||||||
|
|
||||||
|
if process.NumOfArgs() < 4 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := process.Args[3].(type) {
|
||||||
|
case *core.RequestSource:
|
||||||
|
return v, nil
|
||||||
|
|
||||||
|
case *gin.Context:
|
||||||
|
source := core.RequestSource{UID: v.GetHeader("Yao-Builder-Uid")}
|
||||||
|
err := v.Bind(&source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &source, nil
|
||||||
|
|
||||||
|
case string:
|
||||||
|
if process.NumOfArgs() > 4 {
|
||||||
|
uid := process.ArgsString(3)
|
||||||
|
payload, err := jsoniter.Marshal(process.Args[4])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
source := core.RequestSource{UID: uid}
|
||||||
|
err = jsoniter.Unmarshal(payload, &source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &source, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
source := core.RequestSource{}
|
||||||
|
err := jsoniter.UnmarshalFromString(process.ArgsString(3), &source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &source, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
payload, err := jsoniter.Marshal(process.Args[3])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
source := core.RequestSource{}
|
||||||
|
err = jsoniter.Unmarshal(payload, &source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &source, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/yaoapp/gou/process"
|
"github.com/yaoapp/gou/process"
|
||||||
"github.com/yaoapp/yao/config"
|
"github.com/yaoapp/yao/config"
|
||||||
|
|
@ -238,6 +242,233 @@ func TestPageGet(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPageExist(t *testing.T) {
|
||||||
|
|
||||||
|
load(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err := process.Of("sui.page.exist", "demo", "tech-blue", "/index/[invite]")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.IsType(t, true, res)
|
||||||
|
assert.Equal(t, true, res.(bool))
|
||||||
|
|
||||||
|
p, err = process.Of("sui.page.exist", "demo", "tech-blue", "/index/[invite]/[invite]")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.IsType(t, false, res)
|
||||||
|
assert.Equal(t, false, res.(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageCreate(t *testing.T) {
|
||||||
|
|
||||||
|
load(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err := process.Of("sui.page.create", "demo", "tech-blue", "/unit-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageCreateSaveThenRemove(t *testing.T) {
|
||||||
|
|
||||||
|
load(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err := process.Of("sui.page.create", "demo", "tech-blue", "/unit-test", `{"uid":"unit-test", "needToSave":{"page":true}, "page":{"source":"<div>1</div>", "language":"html"}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err = process.Of("sui.page.remove", "demo", "tech-blue", "/unit-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageSaveThenRemove(t *testing.T) {
|
||||||
|
|
||||||
|
load(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err := process.Of("sui.page.create", "demo", "tech-blue", "/unit-test", `{"uid":"unit-test", "needToSave":{"page":true}, "page":{"source":"<div>1</div>", "language":"html"}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err = process.Of("sui.page.SaveTemp", "demo", "tech-blue", "/unit-test", `{"uid":"unit-test", "needToSave":{"page":true}, "page":{"source":"<div>1</div>", "language":"html"}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err = process.Of("sui.page.Save", "demo", "tech-blue", "/unit-test", `{"uid":"unit-test", "needToSave":{"page":true}, "page":{"source":"<div>1</div>", "language":"html"}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
|
// test demo
|
||||||
|
p, err = process.Of("sui.page.remove", "demo", "tech-blue", "/unit-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = p.Exec()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSource(t *testing.T) {
|
||||||
|
|
||||||
|
// *core.RequestSource
|
||||||
|
var payload interface{} = &core.RequestSource{UID: "unit-test"}
|
||||||
|
args := []interface{}{"demo", "tech-blue", "/index/[invite]", payload}
|
||||||
|
p, err := process.Of("sui.page.Save", args...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := getSource(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, "unit-test", src.UID)
|
||||||
|
|
||||||
|
// String
|
||||||
|
args[3] = `{"uid":"unit-test-string"}`
|
||||||
|
p, err = process.Of("sui.page.Save", args...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
src, err = getSource(p)
|
||||||
|
assert.Equal(t, "unit-test-string", src.UID)
|
||||||
|
|
||||||
|
// String & Payload
|
||||||
|
args[3] = "unit-test-string2"
|
||||||
|
newArgs := append(args, map[string]interface{}{
|
||||||
|
"page": map[string]interface{}{
|
||||||
|
"source": "<div>1</div>",
|
||||||
|
"language": "html",
|
||||||
|
}})
|
||||||
|
|
||||||
|
p, err = process.Of("sui.page.Save", newArgs...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
src, err = getSource(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, "unit-test-string2", src.UID)
|
||||||
|
|
||||||
|
// Default
|
||||||
|
args[3] = map[string]interface{}{
|
||||||
|
"uid": "unit-test-map",
|
||||||
|
"page": map[string]interface{}{
|
||||||
|
"source": "<div>1</div>",
|
||||||
|
"language": "html",
|
||||||
|
}}
|
||||||
|
p, err = process.Of("sui.page.Save", args...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
src, err = getSource(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, "unit-test-map", src.UID)
|
||||||
|
|
||||||
|
// Gin Context
|
||||||
|
requestBody := []byte(`{"page": {"source":"gin-context Test", "language":"html"} }`)
|
||||||
|
router := gin.Default()
|
||||||
|
router.POST("/unit-test", func(ctx *gin.Context) {
|
||||||
|
args[3] = ctx
|
||||||
|
p, err = process.Of("sui.page.Save", args...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err = getSource(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if src.Page == nil {
|
||||||
|
t.Fatalf("Page is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, "unit-test-gin-context", src.UID)
|
||||||
|
assert.Equal(t, "html", src.Page.Language)
|
||||||
|
assert.Equal(t, "gin-context Test", src.Page.Source)
|
||||||
|
})
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", "/unit-test", bytes.NewBuffer(requestBody))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Couldn't create request: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Header.Set("Yao-Builder-Uid", "unit-test-gin-context")
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
router.ServeHTTP(httptest.NewRecorder(), req)
|
||||||
|
}
|
||||||
|
|
||||||
func TestPageAssetJS(t *testing.T) {
|
func TestPageAssetJS(t *testing.T) {
|
||||||
|
|
||||||
load(t)
|
load(t)
|
||||||
|
|
@ -351,9 +582,9 @@ func TestEditorPageSource(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
assert.IsType(t, core.ResponseSource{}, res)
|
assert.IsType(t, core.SourceData{}, res)
|
||||||
assert.NotEmpty(t, res.(core.ResponseSource).Source)
|
assert.NotEmpty(t, res.(core.SourceData).Source)
|
||||||
assert.NotEmpty(t, res.(core.ResponseSource).Language)
|
assert.NotEmpty(t, res.(core.SourceData).Language)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,39 +71,39 @@ func (page *Page) EditorRender(request *Request) (*ResponseEditor, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditorPageSource get the editor page source code
|
// EditorPageSource get the editor page source code
|
||||||
func (page *Page) EditorPageSource() ResponseSource {
|
func (page *Page) EditorPageSource() SourceData {
|
||||||
return ResponseSource{
|
return SourceData{
|
||||||
Source: page.Codes.HTML.Code,
|
Source: page.Codes.HTML.Code,
|
||||||
Language: "html",
|
Language: "html",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditorScriptSource get the editor script source code
|
// EditorScriptSource get the editor script source code
|
||||||
func (page *Page) EditorScriptSource() ResponseSource {
|
func (page *Page) EditorScriptSource() SourceData {
|
||||||
if page.Codes.TS.Code != "" {
|
if page.Codes.TS.Code != "" {
|
||||||
return ResponseSource{
|
return SourceData{
|
||||||
Source: page.Codes.TS.Code,
|
Source: page.Codes.TS.Code,
|
||||||
Language: "typescript",
|
Language: "typescript",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResponseSource{
|
return SourceData{
|
||||||
Source: page.Codes.JS.Code,
|
Source: page.Codes.JS.Code,
|
||||||
Language: "javascript",
|
Language: "javascript",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditorStyleSource get the editor style source code
|
// EditorStyleSource get the editor style source code
|
||||||
func (page *Page) EditorStyleSource() ResponseSource {
|
func (page *Page) EditorStyleSource() SourceData {
|
||||||
return ResponseSource{
|
return SourceData{
|
||||||
Source: page.Codes.CSS.Code,
|
Source: page.Codes.CSS.Code,
|
||||||
Language: "css",
|
Language: "css",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditorDataSource get the editor data source code
|
// EditorDataSource get the editor data source code
|
||||||
func (page *Page) EditorDataSource() ResponseSource {
|
func (page *Page) EditorDataSource() SourceData {
|
||||||
return ResponseSource{
|
return SourceData{
|
||||||
Source: page.Codes.DATA.Code,
|
Source: page.Codes.DATA.Code,
|
||||||
Language: "json",
|
Language: "json",
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ type ITemplate interface {
|
||||||
Pages() ([]IPage, error)
|
Pages() ([]IPage, error)
|
||||||
PageTree(route string) ([]*PageTreeNode, error)
|
PageTree(route string) ([]*PageTreeNode, error)
|
||||||
Page(route string) (IPage, error)
|
Page(route string) (IPage, error)
|
||||||
|
PageExist(route string) bool
|
||||||
|
CreatePage(route string) (IPage, error)
|
||||||
|
RemovePage(route string) error
|
||||||
GetPageFromAsset(asset string) (IPage, error)
|
GetPageFromAsset(asset string) (IPage, error)
|
||||||
|
|
||||||
Blocks() ([]IBlock, error)
|
Blocks() ([]IBlock, error)
|
||||||
|
|
@ -35,25 +38,18 @@ type IPage interface {
|
||||||
Load() error
|
Load() error
|
||||||
|
|
||||||
Get() *Page
|
Get() *Page
|
||||||
|
Save(request *RequestSource) error
|
||||||
|
SaveTemp(request *RequestSource) error
|
||||||
|
Remove() error
|
||||||
|
|
||||||
EditorRender(request *Request) (*ResponseEditor, error)
|
EditorRender(request *Request) (*ResponseEditor, error)
|
||||||
EditorPageSource() ResponseSource
|
EditorPageSource() SourceData
|
||||||
EditorScriptSource() ResponseSource
|
EditorScriptSource() SourceData
|
||||||
EditorStyleSource() ResponseSource
|
EditorStyleSource() SourceData
|
||||||
EditorDataSource() ResponseSource
|
EditorDataSource() SourceData
|
||||||
|
|
||||||
AssetScript() (*Asset, error)
|
AssetScript() (*Asset, error)
|
||||||
AssetStyle() (*Asset, error)
|
AssetStyle() (*Asset, error)
|
||||||
|
|
||||||
// Render()
|
|
||||||
|
|
||||||
// Html()
|
|
||||||
// Script()
|
|
||||||
// Style()
|
|
||||||
// Data()
|
|
||||||
|
|
||||||
// Compile()
|
|
||||||
// Locale()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IBlock is the interface for the block
|
// IBlock is the interface for the block
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,25 @@ type Request struct {
|
||||||
Locale string `json:"locale,omitempty"`
|
Locale string `json:"locale,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RequestSource is the struct for the request
|
||||||
|
type RequestSource struct {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
User string `json:"user,omitempty"`
|
||||||
|
Page *SourceData `json:"page,omitempty"`
|
||||||
|
Style *SourceData `json:"style,omitempty"`
|
||||||
|
Script *SourceData `json:"script,omitempty"`
|
||||||
|
Data *SourceData `json:"data,omitempty"`
|
||||||
|
Board *BoardSourceData `json:"board,omitempty"`
|
||||||
|
NeedToSave struct {
|
||||||
|
Page bool `json:"page,omitempty"`
|
||||||
|
Style bool `json:"style,omitempty"`
|
||||||
|
Script bool `json:"script,omitempty"`
|
||||||
|
Data bool `json:"data,omitempty"`
|
||||||
|
Board bool `json:"board,omitempty"`
|
||||||
|
Validate bool `json:"validate,omitempty"`
|
||||||
|
} `json:"needToSave,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// ResponseEditor is the struct for the response
|
// ResponseEditor is the struct for the response
|
||||||
type ResponseEditor struct {
|
type ResponseEditor struct {
|
||||||
HTML string `json:"html,omitempty"`
|
HTML string `json:"html,omitempty"`
|
||||||
|
|
@ -95,10 +114,16 @@ type ResponseEditor struct {
|
||||||
Warnings []string `json:"warnings,omitempty"`
|
Warnings []string `json:"warnings,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResponseSource is the struct for the response
|
// SourceData is the struct for the response
|
||||||
type ResponseSource struct {
|
type SourceData struct {
|
||||||
Source string `json:"source,omitempty"`
|
Source string `json:"source,omitempty"`
|
||||||
Language string `json:"lang,omitempty"`
|
Language string `json:"language,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoardSourceData is the struct for the response
|
||||||
|
type BoardSourceData struct {
|
||||||
|
HTML string `json:"html,omitempty"`
|
||||||
|
Style string `json:"style,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SourceCodes is the struct for the page codes
|
// SourceCodes is the struct for the page codes
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ func (tmpl *Template) Pages() ([]core.IPage, error) {
|
||||||
tmpl.local.fs.Walk(tmpl.Root, func(root, file string, isdir bool) error {
|
tmpl.local.fs.Walk(tmpl.Root, func(root, file string, isdir bool) error {
|
||||||
name := filepath.Base(file)
|
name := filepath.Base(file)
|
||||||
if isdir {
|
if isdir {
|
||||||
if strings.HasPrefix(name, "__") {
|
if strings.HasPrefix(name, "__") || name == ".tmp" {
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -56,7 +56,7 @@ func (tmpl *Template) PageTree(route string) ([]*core.PageTreeNode, error) {
|
||||||
relPath := file
|
relPath := file
|
||||||
|
|
||||||
if isdir {
|
if isdir {
|
||||||
if strings.HasPrefix(name, "__") {
|
if strings.HasPrefix(name, "__") || name == ".tmp" {
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,6 +156,101 @@ func (tmpl *Template) Page(route string) (core.IPage, error) {
|
||||||
return nil, fmt.Errorf("Page %s not found", route)
|
return nil, fmt.Errorf("Page %s not found", route)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PageExist check if the page exist
|
||||||
|
func (tmpl *Template) PageExist(route string) bool {
|
||||||
|
path := tmpl.getPagePath(route)
|
||||||
|
exts := []string{".sui", ".html", ".htm", ".page"}
|
||||||
|
for _, ext := range exts {
|
||||||
|
file := fmt.Sprintf("%s%s", path, ext)
|
||||||
|
if exist, _ := tmpl.local.fs.Exists(file); exist {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePage remove the page
|
||||||
|
func (tmpl *Template) RemovePage(route string) error {
|
||||||
|
if !tmpl.PageExist(route) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
path := filepath.Join(tmpl.Root, route)
|
||||||
|
name := filepath.Base(path) + ".*"
|
||||||
|
err := tmpl.local.fs.Walk(path, func(root, file string, isdir bool) error {
|
||||||
|
if isdir {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return tmpl.local.fs.Remove(file)
|
||||||
|
}, name)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dirs, err := tmpl.local.fs.ReadDir(path, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(dirs) == 0 {
|
||||||
|
return tmpl.local.fs.Remove(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePage create a new page
|
||||||
|
func (tmpl *Template) CreatePage(route string) (core.IPage, error) {
|
||||||
|
if tmpl.PageExist(route) {
|
||||||
|
return nil, fmt.Errorf("Page %s already exist", route)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the page directory
|
||||||
|
name := tmpl.getPageBase(route)
|
||||||
|
return &Page{
|
||||||
|
tmpl: tmpl,
|
||||||
|
Page: &core.Page{
|
||||||
|
Route: route,
|
||||||
|
Path: filepath.Join(tmpl.Root, route),
|
||||||
|
Name: name,
|
||||||
|
Codes: core.SourceCodes{
|
||||||
|
HTML: core.Source{File: fmt.Sprintf("%s.html", name)},
|
||||||
|
CSS: core.Source{File: fmt.Sprintf("%s.css", name)},
|
||||||
|
JS: core.Source{File: fmt.Sprintf("%s.js", name)},
|
||||||
|
TS: core.Source{File: fmt.Sprintf("%s.ts", name)},
|
||||||
|
LESS: core.Source{File: fmt.Sprintf("%s.less", name)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove remove the page
|
||||||
|
func (page *Page) Remove() error {
|
||||||
|
return page.tmpl.RemovePage(page.Route)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPageFromAsset get the page from the asset
|
||||||
|
func (tmpl *Template) GetPageFromAsset(file string) (core.IPage, error) {
|
||||||
|
route := filepath.Dir(file)
|
||||||
|
name := tmpl.getPageBase(route)
|
||||||
|
return &Page{
|
||||||
|
tmpl: tmpl,
|
||||||
|
Page: &core.Page{
|
||||||
|
Route: route,
|
||||||
|
Path: filepath.Join(tmpl.Root, route),
|
||||||
|
Name: name,
|
||||||
|
Codes: core.SourceCodes{
|
||||||
|
CSS: core.Source{File: fmt.Sprintf("%s.css", name)},
|
||||||
|
JS: core.Source{File: fmt.Sprintf("%s.js", name)},
|
||||||
|
TS: core.Source{File: fmt.Sprintf("%s.ts", name)},
|
||||||
|
LESS: core.Source{File: fmt.Sprintf("%s.less", name)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tmpl *Template) getPageFrom(file string) (core.IPage, error) {
|
func (tmpl *Template) getPageFrom(file string) (core.IPage, error) {
|
||||||
route := tmpl.getPageRoute(file)
|
route := tmpl.getPageRoute(file)
|
||||||
return tmpl.getPage(route, file)
|
return tmpl.getPage(route, file)
|
||||||
|
|
@ -255,24 +350,140 @@ func (page *Page) Load() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPageFromAsset get the page from the asset
|
// SaveTemp save page to the temp file
|
||||||
func (tmpl *Template) GetPageFromAsset(file string) (core.IPage, error) {
|
func (page *Page) SaveTemp(request *core.RequestSource) error {
|
||||||
route := filepath.Dir(file)
|
tempPath := filepath.Join(page.Path, ".tmp", request.UID)
|
||||||
name := tmpl.getPageBase(route)
|
return page.save(tempPath, request)
|
||||||
return &Page{
|
|
||||||
tmpl: tmpl,
|
}
|
||||||
Page: &core.Page{
|
|
||||||
Route: route,
|
// Save save page to the storage, if the page not exist, create it
|
||||||
Path: filepath.Join(tmpl.Root, route),
|
func (page *Page) Save(request *core.RequestSource) error {
|
||||||
Name: name,
|
path := page.Path
|
||||||
Codes: core.SourceCodes{
|
err := page.save(path, request)
|
||||||
CSS: core.Source{File: fmt.Sprintf("%s.css", name)},
|
if err != nil {
|
||||||
JS: core.Source{File: fmt.Sprintf("%s.js", name)},
|
return err
|
||||||
TS: core.Source{File: fmt.Sprintf("%s.ts", name)},
|
}
|
||||||
LESS: core.Source{File: fmt.Sprintf("%s.less", name)},
|
|
||||||
},
|
// Remove the temp file
|
||||||
},
|
tempPath := filepath.Join(page.Path, ".tmp", request.UID)
|
||||||
}, nil
|
if exist, _ := page.tmpl.local.fs.Exists(tempPath); exist {
|
||||||
|
err = page.tmpl.local.fs.RemoveAll(tempPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dirs, err := page.tmpl.local.fs.ReadDir(filepath.Join(page.Path, ".tmp"), false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(dirs) == 0 {
|
||||||
|
return page.tmpl.local.fs.Remove(filepath.Join(page.Path, ".tmp"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// save page to the temp file
|
||||||
|
func (page *Page) save(path string, request *core.RequestSource) error {
|
||||||
|
if request.NeedToSave.Board {
|
||||||
|
err := page.saveBoard(path, request.Board)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.NeedToSave.Page {
|
||||||
|
err := page.savePage(path, request.Page)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.NeedToSave.Style {
|
||||||
|
err := page.saveStyle(path, request.Style)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.NeedToSave.Script {
|
||||||
|
err := page.saveScript(path, request.Script)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.NeedToSave.Data {
|
||||||
|
err := page.saveData(path, request.Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// saveBoard save the board to the storage
|
||||||
|
func (page *Page) saveBoard(path string, board *core.BoardSourceData) error {
|
||||||
|
|
||||||
|
htmlFile := filepath.Join(path, page.Codes.HTML.File)
|
||||||
|
_, err := page.tmpl.local.fs.WriteFile(htmlFile, []byte(board.HTML), 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cssFile := filepath.Join(path, page.Codes.CSS.File)
|
||||||
|
_, err = page.tmpl.local.fs.WriteFile(cssFile, []byte(board.Style), 0644)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) savePage(path string, src *core.SourceData) error {
|
||||||
|
if src.Language != "html" {
|
||||||
|
return fmt.Errorf("Page %s language not support", page.Route)
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlFile := filepath.Join(path, page.Codes.HTML.File)
|
||||||
|
_, err := page.tmpl.local.fs.WriteFile(htmlFile, []byte(src.Source), 0644)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) saveStyle(path string, src *core.SourceData) error {
|
||||||
|
if src.Language != "css" {
|
||||||
|
return fmt.Errorf("Page %s language not support", page.Route)
|
||||||
|
}
|
||||||
|
|
||||||
|
cssFile := filepath.Join(path, page.Codes.CSS.File)
|
||||||
|
_, err := page.tmpl.local.fs.WriteFile(cssFile, []byte(src.Source), 0644)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) saveScript(path string, src *core.SourceData) error {
|
||||||
|
|
||||||
|
switch src.Language {
|
||||||
|
case "typescript":
|
||||||
|
tsFile := filepath.Join(path, page.Codes.TS.File)
|
||||||
|
_, err := page.tmpl.local.fs.WriteFile(tsFile, []byte(src.Source), 0644)
|
||||||
|
return err
|
||||||
|
case "javascript":
|
||||||
|
jsFile := filepath.Join(path, page.Codes.JS.File)
|
||||||
|
_, err := page.tmpl.local.fs.WriteFile(jsFile, []byte(src.Source), 0644)
|
||||||
|
return err
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Page %s language not support", page.Route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) saveData(path string, src *core.SourceData) error {
|
||||||
|
if src.Language != "json" {
|
||||||
|
return fmt.Errorf("Page %s language not support", page.Route)
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFile := filepath.Join(path, page.Codes.DATA.File)
|
||||||
|
_, err := page.tmpl.local.fs.WriteFile(dataFile, []byte(src.Source), 0644)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssetScript get the script
|
// AssetScript get the script
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/yaoapp/yao/sui/core"
|
"github.com/yaoapp/yao/sui/core"
|
||||||
)
|
)
|
||||||
|
|
@ -187,6 +188,309 @@ func TestPageRenderEditor(t *testing.T) {
|
||||||
assert.Equal(t, "@pages/index/index.css", res.Styles[4])
|
assert.Equal(t, "@pages/index/index.css", res.Styles[4])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPageSaveTempBoard(t *testing.T) {
|
||||||
|
|
||||||
|
tests := prepare(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
tmpl, err := tests.Demo.GetTemplate("tech-blue")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetTemplate error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = `{
|
||||||
|
"page": null,
|
||||||
|
"style": null,
|
||||||
|
"script": null,
|
||||||
|
"data": null,
|
||||||
|
"board": {
|
||||||
|
"html": "<div class=\"bg-purple-700 p-4 text-base\"><span class=\"text-white mr-2\">Home</span><a href=\"/index/{{user.id}}\" class=\"text-white\">Invite</a></div>\n<div id=\"i2j7\" cui:type=\"Card\">\n <h1>Card Instance</h1>\n <p>Card xx</p>\n <div> Table </div>\n</div>",
|
||||||
|
"style": "#i2j7 {\n color: #2c3e50;\n width: 100%;\n height: 300px;\n background: #d1c2d3;\n padding: .5em;\n}"
|
||||||
|
},
|
||||||
|
"needToSave": {
|
||||||
|
"page": false,
|
||||||
|
"style": false,
|
||||||
|
"script": false,
|
||||||
|
"data": false,
|
||||||
|
"board": true,
|
||||||
|
"validate": true
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
req := &core.RequestSource{UID: "19e09e7e-9e19-44c1-bbab-2a55c51c9df3"}
|
||||||
|
jsoniter.Unmarshal([]byte(payload), &req)
|
||||||
|
|
||||||
|
page, err := tmpl.Page("/index")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Page error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.SaveTemp(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageSaveTempPage(t *testing.T) {
|
||||||
|
tests := prepare(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
tmpl, err := tests.Demo.GetTemplate("tech-blue")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetTemplate error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = `{
|
||||||
|
"page": {
|
||||||
|
"source": "<div class=\"bg-purple-700 p-4 text-base\">\n <span class=\"text-white mr-2\">Home</span>\n <a href=\"/index/{{user.id}}\" class=\"text-white\">Invite</a>\n</div>\n\n<div cui:type=\"Card\">\n <h1>Card Instance</h1>\n <p>Card XYZ</p>\n</div>\n",
|
||||||
|
"language": "html"
|
||||||
|
},
|
||||||
|
"style": null,
|
||||||
|
"script": null,
|
||||||
|
"data": null,
|
||||||
|
"board": {
|
||||||
|
"html": "<body service=\"Index\" data-gjs-type=\"wrapper\" data-gjs-stylable=\"["background","background-color","background-image","background-repeat","background-attachment","background-position","background-size"]\"><div class=\"bg-purple-700 p-4 text-base\"><span class=\"text-white mr-2\" data-gjs-tagName=\"span\" data-gjs-type=\"text\">Home</span><a href=\"/index/{{user.id}}\" class=\"text-white\" data-gjs-type=\"link\">Invite</a></div><div id=\"izaw\" data-gjs-type=\"Card\" data-gjs-style=\"\"><h1 data-gjs-tagName=\"h1\" data-gjs-type=\"text\">Card Instance</h1><p data-gjs-tagName=\"p\" data-gjs-type=\"text\">Card xx</p></div></body>",
|
||||||
|
"style": "#izaw{color:#2c3e50;width:100%;height:300px;background:#d1c2d3;padding:.5em;}"
|
||||||
|
},
|
||||||
|
"needToSave": {
|
||||||
|
"page": true,
|
||||||
|
"style": false,
|
||||||
|
"script": false,
|
||||||
|
"data": false,
|
||||||
|
"board": false,
|
||||||
|
"validate": true
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
req := &core.RequestSource{UID: "19e09e7e-9e19-44c1-bbab-2a55c51c9df3"}
|
||||||
|
jsoniter.Unmarshal([]byte(payload), &req)
|
||||||
|
|
||||||
|
page, err := tmpl.Page("/index")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Page error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.SaveTemp(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageSaveTempStyle(t *testing.T) {
|
||||||
|
tests := prepare(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
tmpl, err := tests.Demo.GetTemplate("tech-blue")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetTemplate error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = `{
|
||||||
|
"page": null,
|
||||||
|
"style": {
|
||||||
|
"source": "* { box-sizing: border-box; }\nbody { margin: 0; }\n#ihjf { color:#ffffff;width:100%;height:100px;background:#1c0d1a;padding:.5em;display:flex; }\n\n",
|
||||||
|
"language": "css"
|
||||||
|
},
|
||||||
|
"script": null,
|
||||||
|
"data": null,
|
||||||
|
"board": {
|
||||||
|
"html": "<body service=\"Index\" data-gjs-type=\"wrapper\" data-gjs-stylable=\"["background","background-color","background-image","background-repeat","background-attachment","background-position","background-size"]\"><div class=\"bg-purple-700 p-4 text-base\"><span class=\"text-white mr-2\" data-gjs-tagName=\"span\" data-gjs-type=\"text\">Home</span><a href=\"/index/{{user.id}}\" class=\"text-white\" data-gjs-type=\"link\">Invite</a></div><div id=\"inhy\" data-gjs-type=\"Card\" data-gjs-style=\"\"><h1 data-gjs-tagName=\"h1\" data-gjs-type=\"text\">Card Instance</h1><p data-gjs-tagName=\"p\" data-gjs-type=\"text\">Card xx</p></div></body>",
|
||||||
|
"style": "#inhy{color:#2c3e50;width:100%;height:300px;background:#d1c2d3;padding:.5em;}"
|
||||||
|
},
|
||||||
|
"needToSave": {
|
||||||
|
"page": false,
|
||||||
|
"style": true,
|
||||||
|
"script": false,
|
||||||
|
"data": false,
|
||||||
|
"board": false,
|
||||||
|
"validate": true
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
req := &core.RequestSource{UID: "19e09e7e-9e19-44c1-bbab-2a55c51c9df3"}
|
||||||
|
jsoniter.Unmarshal([]byte(payload), &req)
|
||||||
|
|
||||||
|
page, err := tmpl.Page("/index")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Page error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.SaveTemp(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageSaveTempScriptJS(t *testing.T) {
|
||||||
|
tests := prepare(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
tmpl, err := tests.Demo.GetTemplate("tech-blue")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetTemplate error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = `{
|
||||||
|
"page": null,
|
||||||
|
"style": null,
|
||||||
|
"script": {
|
||||||
|
"source": "function Hello() {\n console.log(\"Hello World!\");\n}\n\nfunction Index() {\n return {\n title: \"Customers\",\n hello: \"world\",\n rows: [\n { name: \"John\", age: 30, city: \"New York\" },\n { name: \"Mary\", age: 20, city: \"Paris\" },\n { name: \"Peter\", age: 40, city: \"London\" },\n ],\n };\n}\n",
|
||||||
|
"language": "javascript"
|
||||||
|
},
|
||||||
|
"data": null,
|
||||||
|
"board": {
|
||||||
|
"html": "<body service=\"Index\" data-gjs-type=\"wrapper\" data-gjs-stylable=\"["background","background-color","background-image","background-repeat","background-attachment","background-position","background-size"]\"><div class=\"bg-purple-700 p-4 text-base\"><span class=\"text-white mr-2\" data-gjs-tagName=\"span\" data-gjs-type=\"text\">Home</span><a href=\"/index/{{user.id}}\" class=\"text-white\" data-gjs-type=\"link\">Invite</a></div><div id=\"icqh\" data-gjs-type=\"Card\" data-gjs-style=\"\"><h1 data-gjs-tagName=\"h1\" data-gjs-type=\"text\">Card Instance</h1><p data-gjs-tagName=\"p\" data-gjs-type=\"text\">Card xx</p></div></body>",
|
||||||
|
"style": "#icqh{color:#2c3e50;width:100%;height:300px;background:#d1c2d3;padding:.5em;}"
|
||||||
|
},
|
||||||
|
"needToSave": {
|
||||||
|
"page": false,
|
||||||
|
"style": false,
|
||||||
|
"script": true,
|
||||||
|
"data": false,
|
||||||
|
"board": false,
|
||||||
|
"validate": true
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
req := &core.RequestSource{UID: "19e09e7e-9e19-44c1-bbab-2a55c51c9df3"}
|
||||||
|
jsoniter.Unmarshal([]byte(payload), &req)
|
||||||
|
|
||||||
|
page, err := tmpl.Page("/index")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Page error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.SaveTemp(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageSaveTempScriptTS(t *testing.T) {
|
||||||
|
tests := prepare(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
tmpl, err := tests.Demo.GetTemplate("tech-blue")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetTemplate error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = `{
|
||||||
|
"page": null,
|
||||||
|
"style": null,
|
||||||
|
"script": {
|
||||||
|
"source": "import \"@assets/dark/dark.css\";\nimport \"@assets/light/light.css\";\n\nimport { Hello } from \"@assets/main.js\";\n\nconst onPageLoad = (event: Event) => {\n console.log(\"Page Loaded 103\");\n};\n\nconst onPageReady = (event: Event) => {\n Hello(\"world\");\n Foo(\"Bar\");\n console.log(\"Page Ready\");\n return;\n};\n\nconst onData = (\n params: { [key: string]: string[] },\n query: { [key: string]: string[] }\n) => {\n console.log(\"Page Send Data Request\");\n};\n\nconst onDataSuccess = (data: { [key: string]: any }) => {\n console.log(\"Page Data Ready\");\n};\n\nconst onDataError = (data: { code: number; message: string }) => {\n console.log(\"Page Data Ready\");\n};\n\nconst onResize = (event: Event) => {\n console.log(\"Page Resize\");\n};\n\nconst onPageScroll = (event: Event) => {\n console.log(\"Page Scroll\");\n};\n\nfunction Foo(bar: string) {\n console.log(` + "`Foo ${bar}`" + `);\n}\n",
|
||||||
|
"language": "typescript"
|
||||||
|
},
|
||||||
|
"data": null,
|
||||||
|
"board": {
|
||||||
|
"html": "<body service=\"Index\" data-gjs-type=\"wrapper\" data-gjs-stylable=\"["background","background-color","background-image","background-repeat","background-attachment","background-position","background-size"]\"><div class=\"bg-purple-700 p-4 text-base\"><span class=\"text-white mr-2\" data-gjs-tagName=\"span\" data-gjs-type=\"text\">Home</span><a href=\"/index/{{user.id}}\" class=\"text-white\" data-gjs-type=\"link\">Invite</a></div><div id=\"icqh\" data-gjs-type=\"Card\" data-gjs-style=\"\"><h1 data-gjs-tagName=\"h1\" data-gjs-type=\"text\">Card Instance</h1><p data-gjs-tagName=\"p\" data-gjs-type=\"text\">Card xx</p></div></body>",
|
||||||
|
"style": "#icqh{color:#2c3e50;width:100%;height:300px;background:#d1c2d3;padding:.5em;}"
|
||||||
|
},
|
||||||
|
"needToSave": {
|
||||||
|
"page": false,
|
||||||
|
"style": false,
|
||||||
|
"script": true,
|
||||||
|
"data": false,
|
||||||
|
"board": false,
|
||||||
|
"validate": true
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
req := &core.RequestSource{UID: "19e09e7e-9e19-44c1-bbab-2a55c51c9df3"}
|
||||||
|
jsoniter.Unmarshal([]byte(payload), &req)
|
||||||
|
|
||||||
|
page, err := tmpl.Page("/index")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Page error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.SaveTemp(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageSaveTempData(t *testing.T) {
|
||||||
|
tests := prepare(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
tmpl, err := tests.Demo.GetTemplate("tech-blue")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetTemplate error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = `{
|
||||||
|
"page": null,
|
||||||
|
"style": null,
|
||||||
|
"script": null,
|
||||||
|
"data": {
|
||||||
|
"source": "{\n \"title\": \"Home Page\",\n \"data\": { \"service\": \"Index\" },\n \"foo\": \"bar\",\n \"preview\": { \"params\": { \"id\": \"1\" } }\n}\n",
|
||||||
|
"language": "json"
|
||||||
|
},
|
||||||
|
"board": {
|
||||||
|
"html": "<body service=\"Index\" data-gjs-type=\"wrapper\" data-gjs-stylable=\"["background","background-color","background-image","background-repeat","background-attachment","background-position","background-size"]\"><div class=\"bg-purple-700 p-4 text-base\"><span class=\"text-white mr-2\" data-gjs-tagName=\"span\" data-gjs-type=\"text\">Home</span><a href=\"/index/{{user.id}}\" class=\"text-white\" data-gjs-type=\"link\">Invite</a></div><div id=\"ipxs\" data-gjs-type=\"Card\" data-gjs-style=\"\"><h1 data-gjs-tagName=\"h1\" data-gjs-type=\"text\">Card Instance</h1><p data-gjs-tagName=\"p\" data-gjs-type=\"text\">Card xx</p></div></body>",
|
||||||
|
"style": "#ipxs{color:#2c3e50;width:100%;height:300px;background:#d1c2d3;padding:.5em;}"
|
||||||
|
},
|
||||||
|
"needToSave": {
|
||||||
|
"page": false,
|
||||||
|
"style": false,
|
||||||
|
"script": false,
|
||||||
|
"data": true,
|
||||||
|
"board": false,
|
||||||
|
"validate": true
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
req := &core.RequestSource{UID: "19e09e7e-9e19-44c1-bbab-2a55c51c9df3"}
|
||||||
|
jsoniter.Unmarshal([]byte(payload), &req)
|
||||||
|
|
||||||
|
page, err := tmpl.Page("/index")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Page error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.SaveTemp(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPageSave(t *testing.T) {
|
||||||
|
tests := prepare(t)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
tmpl, err := tests.Demo.GetTemplate("tech-blue")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetTemplate error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = `{
|
||||||
|
"page": null,
|
||||||
|
"style": null,
|
||||||
|
"script": null,
|
||||||
|
"data": null,
|
||||||
|
"board": {
|
||||||
|
"html": "<div id=\"io71\">404 {{ $query.message || $post.message }}<br>Add IT</div>",
|
||||||
|
"style": ""
|
||||||
|
},
|
||||||
|
"needToSave": {
|
||||||
|
"page": false,
|
||||||
|
"style": false,
|
||||||
|
"script": false,
|
||||||
|
"data": false,
|
||||||
|
"board": true,
|
||||||
|
"validate": true
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
req := &core.RequestSource{UID: "19e09e7e-9e19-44c1-bbab-2a55c51c9df3"}
|
||||||
|
jsoniter.Unmarshal([]byte(payload), &req)
|
||||||
|
|
||||||
|
page, err := tmpl.CreatePage("/unit-test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Page error: %v", err)
|
||||||
|
}
|
||||||
|
defer page.Remove()
|
||||||
|
|
||||||
|
err = page.SaveTemp(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("SaveTemp error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = page.Save(req)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestPageGetPageFromAsset(t *testing.T) {
|
func TestPageGetPageFromAsset(t *testing.T) {
|
||||||
|
|
||||||
tests := prepare(t)
|
tests := prepare(t)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue