[add] app & login widget
This commit is contained in:
parent
95f7cc026d
commit
4830c55441
13 changed files with 762 additions and 1 deletions
14
.github/workflows/pr-test.yml
vendored
14
.github/workflows/pr-test.yml
vendored
|
|
@ -38,6 +38,8 @@ env:
|
|||
MONGO_TEST_USER: "root"
|
||||
MONGO_TEST_PASS: "123456"
|
||||
|
||||
DEMO_APP: ${{ github.WORKSPACE }}/../app
|
||||
|
||||
jobs:
|
||||
UnitTest:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -130,12 +132,19 @@ jobs:
|
|||
ref: 5e91d3d9dcabd2986f901b6b31590e49fc3c4dd8
|
||||
path: v8go
|
||||
|
||||
- name: Checkout Demo App
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: yaoapp/demo-app
|
||||
path: app
|
||||
|
||||
- name: Move Kun, Xun, Gou, V8Go
|
||||
run: |
|
||||
mv kun ../
|
||||
mv xun ../
|
||||
mv gou ../
|
||||
mv v8go ../
|
||||
mv app ../
|
||||
ls -l .
|
||||
ls -l ../
|
||||
|
||||
|
|
@ -218,6 +227,11 @@ jobs:
|
|||
run: |
|
||||
make test
|
||||
|
||||
- name: Run widgets test
|
||||
run: |
|
||||
echo "YAO_ROOT=$DEMO_APP" >> $GITHUB_ENV
|
||||
make test-widgets
|
||||
|
||||
- name: Codecov Report
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
|
|
|
|||
14
.github/workflows/unit-test.yml
vendored
14
.github/workflows/unit-test.yml
vendored
|
|
@ -42,6 +42,8 @@ env:
|
|||
MONGO_TEST_USER: "root"
|
||||
MONGO_TEST_PASS: "123456"
|
||||
|
||||
DEMO_APP: ${{ github.WORKSPACE }}/../app
|
||||
|
||||
jobs:
|
||||
unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -87,12 +89,19 @@ jobs:
|
|||
ref: 5e91d3d9dcabd2986f901b6b31590e49fc3c4dd8
|
||||
path: v8go
|
||||
|
||||
- name: Checkout Demo App
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: yaoapp/demo-app
|
||||
path: app
|
||||
|
||||
- name: Move Kun, Xun, Gou, V8Go
|
||||
run: |
|
||||
mv kun ../
|
||||
mv xun ../
|
||||
mv gou ../
|
||||
mv v8go ../
|
||||
mv app ../
|
||||
ls -l .
|
||||
ls -l ../
|
||||
|
||||
|
|
@ -173,6 +182,11 @@ jobs:
|
|||
run: |
|
||||
make test
|
||||
|
||||
- name: Run widgets test
|
||||
run: |
|
||||
echo "YAO_ROOT=$DEMO_APP" >> $GITHUB_ENV
|
||||
make test-widgets
|
||||
|
||||
- name: Codecov Report
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
|
|
|
|||
30
Makefile
30
Makefile
|
|
@ -8,9 +8,11 @@ VERSION := $(shell grep 'const VERSION =' share/const.go |awk '{print $$4}' |sed
|
|||
COMMIT := $(shell git log | head -n 1 | awk '{print substr($$2, 0, 12)}')
|
||||
|
||||
# ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
TESTFOLDER := $(shell $(GO) list ./... | grep -vE 'examples|tests*|config')
|
||||
TESTFOLDER := $(shell $(GO) list ./... | grep -vE 'examples|tests*|config|widgets')
|
||||
TESTTAGS ?= ""
|
||||
|
||||
TESTWIDGETS := $(shell $(GO) list ./widgets/...)
|
||||
|
||||
# Unit Test
|
||||
.PHONY: test
|
||||
test:
|
||||
|
|
@ -37,6 +39,32 @@ test:
|
|||
fi; \
|
||||
done
|
||||
|
||||
# Unit Test
|
||||
.PHONY: test-widgets
|
||||
test-widgets:
|
||||
echo "mode: count" > coverage.out
|
||||
for d in $(TESTWIDGETS); do \
|
||||
$(GO) test -tags $(TESTTAGS) -v -covermode=count -coverprofile=profile.out -coverpkg=$$(echo $$d | sed "s/\/test$$//g") $$d > tmp.out; \
|
||||
cat tmp.out; \
|
||||
if grep -q "^--- FAIL" tmp.out; then \
|
||||
rm tmp.out; \
|
||||
exit 1; \
|
||||
elif grep -q "build failed" tmp.out; then \
|
||||
rm tmp.out; \
|
||||
exit 1; \
|
||||
elif grep -q "setup failed" tmp.out; then \
|
||||
rm tmp.out; \
|
||||
exit 1; \
|
||||
elif grep -q "runtime error" tmp.out; then \
|
||||
rm tmp.out; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
if [ -f profile.out ]; then \
|
||||
cat profile.out | grep -v "mode:" >> coverage.out; \
|
||||
rm profile.out; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
$(GOFMT) -w $(GOFILES)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ func init() {
|
|||
lang.RegisterWidget("kanban", "page")
|
||||
lang.RegisterWidget("screen", "page")
|
||||
lang.RegisterWidget("pages", "page")
|
||||
lang.RegisterWidget("logins", "login")
|
||||
}
|
||||
|
||||
// Load language packs
|
||||
|
|
@ -25,6 +26,8 @@ func Load(cfg config.Config) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Set default
|
||||
lang.Pick("default").AsDefault()
|
||||
name := os.Getenv("YAO_LANG")
|
||||
if name != "" {
|
||||
if _, has := lang.Dicts[name]; !has {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ func Walk(root string, typeName string, cb func(root, filename string)) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// ID parse unique name root: "/tests/apis" file: "/tests/apis/foo/bar.http.json"
|
||||
func ID(root string, file string) string {
|
||||
return SpecName(root, file)
|
||||
}
|
||||
|
||||
// SpecName 解析名称 root: "/tests/apis" file: "/tests/apis/foo/bar.http.json"
|
||||
func SpecName(root string, file string) string {
|
||||
filename := strings.TrimPrefix(file, root+"/") // "foo/bar.http.json"
|
||||
|
|
|
|||
193
widgets/app/app.go
Normal file
193
widgets/app/app.go
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/gou/lang"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/share"
|
||||
"github.com/yaoapp/yao/widgets/login"
|
||||
)
|
||||
|
||||
//
|
||||
// API:
|
||||
// GET /api/__yao/app/setting -> Default process: yao.app.Xgen
|
||||
// GET /api/__yao/app/menu -> Default process: yao.app.Menu
|
||||
//
|
||||
// Process:
|
||||
// yao.app.Setting Return the App DSL
|
||||
// yao.app.Xgen Return the Xgen setting ( merge app & login )
|
||||
// yao.app.Menu Return the menu list
|
||||
//
|
||||
|
||||
// Setting the application setting
|
||||
var Setting *DSL
|
||||
|
||||
// Load the app DSL
|
||||
func Load(cfg config.Config) error {
|
||||
|
||||
file := filepath.Join(cfg.Root, "app.json")
|
||||
file, err := filepath.Abs(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dsl := &DSL{}
|
||||
err = jsoniter.Unmarshal(data, dsl)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Apply a language pack
|
||||
if lang.Default != nil {
|
||||
lang.Default.Apply(dsl)
|
||||
}
|
||||
|
||||
Setting = dsl
|
||||
return nil
|
||||
}
|
||||
|
||||
// exportAPI export login api
|
||||
func exportAPI() error {
|
||||
|
||||
if Setting == nil {
|
||||
return fmt.Errorf("the app does not init")
|
||||
}
|
||||
|
||||
http := gou.HTTP{
|
||||
Name: "Widget App API",
|
||||
Description: "Widget App API",
|
||||
Version: share.VERSION,
|
||||
Guard: "bearer-jwt",
|
||||
Group: "__yao/app",
|
||||
Paths: []gou.Path{},
|
||||
}
|
||||
|
||||
process := "yao.app.Xgen"
|
||||
if Setting.Optional.Setting != "" {
|
||||
process = Setting.Optional.Setting
|
||||
}
|
||||
|
||||
path := gou.Path{
|
||||
Label: "App Setting",
|
||||
Description: "App Setting",
|
||||
Guard: "-",
|
||||
Path: "/setting",
|
||||
Method: "GET",
|
||||
Process: process,
|
||||
In: []string{},
|
||||
Out: gou.Out{Status: 200, Type: "application/json"},
|
||||
}
|
||||
http.Paths = append(http.Paths, path)
|
||||
|
||||
process = "yao.app.Menu"
|
||||
args := []string{}
|
||||
if Setting.Menu.Process != "" {
|
||||
process = Setting.Menu.Process
|
||||
args = Setting.Menu.Args
|
||||
}
|
||||
|
||||
path = gou.Path{
|
||||
Label: "App Menu",
|
||||
Description: "App Menu",
|
||||
Path: "/menu",
|
||||
Method: "GET",
|
||||
Process: process,
|
||||
In: args,
|
||||
Out: gou.Out{Status: 200, Type: "application/json"},
|
||||
}
|
||||
http.Paths = append(http.Paths, path)
|
||||
|
||||
// api source
|
||||
source, err := jsoniter.Marshal(http)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// load apis
|
||||
_, err = gou.LoadAPIReturn(string(source), "widgets.app")
|
||||
return err
|
||||
}
|
||||
|
||||
// Export export login api
|
||||
func Export() error {
|
||||
exportProcess()
|
||||
return exportAPI()
|
||||
}
|
||||
|
||||
func exportProcess() {
|
||||
gou.RegisterProcessHandler("yao.app.setting", processSetting)
|
||||
gou.RegisterProcessHandler("yao.app.xgen", processXgen)
|
||||
gou.AliasProcess("flows.xiang.menu", "yao.app.menu")
|
||||
}
|
||||
|
||||
func processSetting(process *gou.Process) interface{} {
|
||||
if Setting == nil {
|
||||
exception.New("the app does not init", 500).Throw()
|
||||
return nil
|
||||
}
|
||||
return *Setting
|
||||
}
|
||||
|
||||
func processXgen(process *gou.Process) interface{} {
|
||||
|
||||
if Setting == nil {
|
||||
exception.New("the app does not init", 500).Throw()
|
||||
}
|
||||
|
||||
mode := os.Getenv("YAO_ENV")
|
||||
if mode == "" {
|
||||
mode = "production"
|
||||
}
|
||||
|
||||
xgenLogin := map[string]map[string]interface{}{
|
||||
"entry": {"admin": "/x/Welcome"},
|
||||
}
|
||||
|
||||
if admin, has := login.Logins["admin"]; has {
|
||||
xgenLogin["entry"]["admin"] = admin.Layout.Entry
|
||||
xgenLogin["admin"] = map[string]interface{}{
|
||||
"captcha": "/api/__yao/login/admin/captcha",
|
||||
"login": "/api/__yao/login/admin",
|
||||
}
|
||||
}
|
||||
|
||||
if user, has := login.Logins["user"]; has {
|
||||
xgenLogin["entry"]["user"] = user.Layout.Entry
|
||||
xgenLogin["user"] = map[string]interface{}{
|
||||
"captcha": "/api/__yao/login/user/captcha",
|
||||
"login": "/api/__yao/login/user",
|
||||
}
|
||||
}
|
||||
|
||||
xgenSetting := map[string]interface{}{
|
||||
"name": Setting.Name,
|
||||
"description": Setting.Description,
|
||||
"mode": mode,
|
||||
"apiPrefix": "__yao",
|
||||
"token": "localStorage",
|
||||
"optional": Setting.Optional,
|
||||
"login": xgenLogin,
|
||||
}
|
||||
|
||||
return xgenSetting
|
||||
}
|
||||
|
||||
// Lang for applying a language pack
|
||||
func (dsl *DSL) Lang(trans func(widget string, inst string, value *string) bool) {
|
||||
widget := "app"
|
||||
trans(widget, "app", &dsl.Name)
|
||||
trans(widget, "app", &dsl.Short)
|
||||
trans(widget, "app", &dsl.Description)
|
||||
}
|
||||
161
widgets/app/app_test.go
Normal file
161
widgets/app/app_test.go
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/kun/any"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/lang"
|
||||
"github.com/yaoapp/yao/widgets/login"
|
||||
)
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
|
||||
lang.Load(config.Conf)
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "Demo Application", Setting.Name)
|
||||
assert.Equal(t, "Demo", Setting.Short)
|
||||
assert.Equal(t, "Another yao application", Setting.Description)
|
||||
assert.Equal(t, []string{"demo"}, Setting.Menu.Args)
|
||||
assert.Equal(t, "flows.app.menu", Setting.Menu.Process)
|
||||
assert.Equal(t, true, Setting.Optional.HideNotification)
|
||||
assert.Equal(t, false, Setting.Optional.HideSetting)
|
||||
}
|
||||
|
||||
func TestLoadHK(t *testing.T) {
|
||||
|
||||
os.Setenv("YAO_LANG", "zh-hk")
|
||||
lang.Load(config.Conf)
|
||||
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "示例應用", Setting.Name)
|
||||
assert.Equal(t, "演示", Setting.Short)
|
||||
assert.Equal(t, "又一個YAO應用", Setting.Description)
|
||||
assert.Equal(t, []string{"demo"}, Setting.Menu.Args)
|
||||
assert.Equal(t, "flows.app.menu", Setting.Menu.Process)
|
||||
assert.Equal(t, true, Setting.Optional.HideNotification)
|
||||
assert.Equal(t, false, Setting.Optional.HideSetting)
|
||||
}
|
||||
|
||||
func TestLoadCN(t *testing.T) {
|
||||
|
||||
os.Setenv("YAO_LANG", "zh-cn")
|
||||
lang.Load(config.Conf)
|
||||
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "示例应用", Setting.Name)
|
||||
assert.Equal(t, "演示", Setting.Short)
|
||||
assert.Equal(t, "又一个 YAO 应用", Setting.Description)
|
||||
assert.Equal(t, []string{"demo"}, Setting.Menu.Args)
|
||||
assert.Equal(t, "flows.app.menu", Setting.Menu.Process)
|
||||
assert.Equal(t, true, Setting.Optional.HideNotification)
|
||||
assert.Equal(t, false, Setting.Optional.HideSetting)
|
||||
}
|
||||
|
||||
func TestExport(t *testing.T) {
|
||||
|
||||
err := login.Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = Export()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
api, has := gou.APIs["widgets.app"]
|
||||
assert.True(t, has)
|
||||
assert.Equal(t, 2, len(api.HTTP.Paths))
|
||||
|
||||
_, has = gou.ThirdHandlers["yao.app.setting"]
|
||||
assert.True(t, has)
|
||||
|
||||
_, has = gou.ThirdHandlers["yao.app.xgen"]
|
||||
assert.True(t, has)
|
||||
|
||||
_, has = gou.ThirdHandlers["yao.app.menu"]
|
||||
assert.True(t, has)
|
||||
}
|
||||
|
||||
func TestProcessSetting(t *testing.T) {
|
||||
loadApp(t)
|
||||
res, err := gou.NewProcess("yao.app.Setting").Exec()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
setting, ok := res.(DSL)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "Demo Application", setting.Name)
|
||||
assert.Equal(t, "Demo", setting.Short)
|
||||
assert.Equal(t, "Another yao application", setting.Description)
|
||||
assert.Equal(t, []string{"demo"}, setting.Menu.Args)
|
||||
assert.Equal(t, "flows.app.menu", setting.Menu.Process)
|
||||
assert.Equal(t, true, setting.Optional.HideNotification)
|
||||
assert.Equal(t, false, setting.Optional.HideSetting)
|
||||
}
|
||||
|
||||
func TestProcessXgen(t *testing.T) {
|
||||
loadApp(t)
|
||||
res, err := gou.NewProcess("yao.app.Xgen").Exec()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
xgen := any.Of(res).MapStr().Dot()
|
||||
assert.Equal(t, "__yao", xgen.Get("apiPrefix"))
|
||||
assert.Equal(t, "Another yao application", xgen.Get("description"))
|
||||
assert.Equal(t, "/api/__yao/login/admin/captcha", xgen.Get("login.admin.captcha"))
|
||||
assert.Equal(t, "/api/__yao/login/admin", xgen.Get("login.admin.login"))
|
||||
assert.Equal(t, "/x/Table/pet", xgen.Get("login.entry.admin"))
|
||||
assert.Equal(t, "/x/Table/dash", xgen.Get("login.entry.user"))
|
||||
assert.Equal(t, "/api/__yao/login/user/captcha", xgen.Get("login.user.captcha"))
|
||||
assert.Equal(t, "/api/__yao/login/user", xgen.Get("login.user.login"))
|
||||
assert.Equal(t, os.Getenv("YAO_ENV"), xgen.Get("mode"))
|
||||
assert.Equal(t, "Demo Application", xgen.Get("name"))
|
||||
assert.Equal(t, true, xgen.Get("optional.hideNotification"))
|
||||
assert.Equal(t, "localStorage", xgen.Get("token"))
|
||||
}
|
||||
|
||||
func loadApp(t *testing.T) {
|
||||
|
||||
os.Setenv("YAO_LANG", "")
|
||||
lang.Load(config.Conf)
|
||||
|
||||
err := login.Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = Export()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
25
widgets/app/types.go
Normal file
25
widgets/app/types.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package app
|
||||
|
||||
// DSL the app DSL
|
||||
type DSL struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Short string `json:"short,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Theme string `json:"theme,omitempty"`
|
||||
Menu MenuDSL `json:"menu,omitempty"`
|
||||
Optional OptionalDSL `json:"optional,omitempty"`
|
||||
}
|
||||
|
||||
// MenuDSL the menu DSL
|
||||
type MenuDSL struct {
|
||||
Process string `json:"process,omitempty"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
}
|
||||
|
||||
// OptionalDSL the Optional DSL
|
||||
type OptionalDSL struct {
|
||||
HideNotification bool `json:"hideNotification,omitempty"`
|
||||
HideSetting bool `json:"hideSetting,omitempty"`
|
||||
Setting string `json:"setting,omitempty"` // custom setting process
|
||||
}
|
||||
133
widgets/login/login.go
Normal file
133
widgets/login/login.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
package login
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/gou/lang"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/share"
|
||||
)
|
||||
|
||||
//
|
||||
// API:
|
||||
// GET /api/__yao/login/:id/captcha -> Default process: yao.utils.Captcha :query
|
||||
// POST /api/__yao/login/:id -> Default process: yao.user.Login :payload
|
||||
//
|
||||
|
||||
// Logins the loaded login widgets
|
||||
var Logins map[string]*DSL = map[string]*DSL{}
|
||||
|
||||
// Load load task
|
||||
func Load(cfg config.Config) error {
|
||||
var root = filepath.Join(cfg.Root, "logins")
|
||||
return LoadFrom(root, "")
|
||||
}
|
||||
|
||||
// LoadFrom load from dir
|
||||
func LoadFrom(dir string, prefix string) error {
|
||||
|
||||
if share.DirNotExists(dir) {
|
||||
return fmt.Errorf("%s does not exists", dir)
|
||||
}
|
||||
|
||||
messages := []string{}
|
||||
err := share.Walk(dir, ".json", func(root, filename string) {
|
||||
id := prefix + share.ID(root, filename)
|
||||
data := share.ReadFile(filename)
|
||||
dsl := &DSL{ID: id}
|
||||
err := jsoniter.Unmarshal(data, dsl)
|
||||
if err != nil {
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// Apply a language pack
|
||||
if lang.Default != nil {
|
||||
lang.Default.Apply(dsl)
|
||||
}
|
||||
|
||||
Logins[id] = dsl
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Export export login api
|
||||
func Export() error {
|
||||
return exportAPI()
|
||||
}
|
||||
|
||||
// exportAPI export login api
|
||||
func exportAPI() error {
|
||||
|
||||
http := gou.HTTP{
|
||||
Name: "Widget Login API",
|
||||
Description: "Widget Login API",
|
||||
Version: share.VERSION,
|
||||
Guard: "bearer-jwt",
|
||||
Group: "__yao/login",
|
||||
Paths: []gou.Path{},
|
||||
}
|
||||
|
||||
for _, dsl := range Logins {
|
||||
|
||||
// login action
|
||||
process := "yao.user.Login"
|
||||
args := []string{":payload"}
|
||||
if dsl.Action.Process != "" {
|
||||
process = dsl.Action.Process
|
||||
args = dsl.Action.Args
|
||||
}
|
||||
path := gou.Path{
|
||||
Label: fmt.Sprintf("%s login", dsl.ID),
|
||||
Description: fmt.Sprintf("%s login", dsl.ID),
|
||||
Guard: "-",
|
||||
Path: fmt.Sprintf("/%s", dsl.ID),
|
||||
Method: "POST",
|
||||
Process: process,
|
||||
In: args,
|
||||
Out: gou.Out{Status: 200, Type: "application/json"},
|
||||
}
|
||||
http.Paths = append(http.Paths, path)
|
||||
|
||||
// captcha
|
||||
process = "yao.utils.Captcha"
|
||||
args = []string{":query"}
|
||||
if dsl.Layout.Captcha != "" {
|
||||
process = dsl.Layout.Captcha
|
||||
}
|
||||
|
||||
path = gou.Path{
|
||||
Label: fmt.Sprintf("%s captcha", dsl.ID),
|
||||
Description: fmt.Sprintf("%s captcha", dsl.ID),
|
||||
Guard: "-",
|
||||
Path: fmt.Sprintf("/%s/captcha", dsl.ID),
|
||||
Method: "GET",
|
||||
Process: process,
|
||||
In: args,
|
||||
Out: gou.Out{Status: 200, Type: "application/json"},
|
||||
}
|
||||
http.Paths = append(http.Paths, path)
|
||||
|
||||
}
|
||||
|
||||
// api source
|
||||
source, err := jsoniter.Marshal(http)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// load apis
|
||||
_, err = gou.LoadAPIReturn(string(source), "widgets.login")
|
||||
return err
|
||||
}
|
||||
|
||||
// Lang for applying a language pack
|
||||
func (dsl *DSL) Lang(trans func(widget string, inst string, value *string) bool) {
|
||||
widget := "login"
|
||||
trans(widget, dsl.ID, &dsl.Name)
|
||||
trans(widget, dsl.ID, &dsl.Layout.Slogan)
|
||||
trans(widget, dsl.ID, &dsl.Layout.Site)
|
||||
}
|
||||
124
widgets/login/login_test.go
Normal file
124
widgets/login/login_test.go
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
package login
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/lang"
|
||||
)
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
|
||||
lang.Load(config.Conf)
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 2, len(Logins))
|
||||
|
||||
assert.Equal(t, "admin", Logins["admin"].ID)
|
||||
assert.Equal(t, "Admin Login", Logins["admin"].Name)
|
||||
assert.Equal(t, "yao.user.login", Logins["admin"].Action.Process)
|
||||
assert.Equal(t, []string{":payload"}, Logins["admin"].Action.Args)
|
||||
assert.Equal(t, "yao.utils.Captcha", Logins["admin"].Layout.Captcha)
|
||||
assert.Equal(t, "/images/admin-cover.png", Logins["admin"].Layout.Cover)
|
||||
assert.Equal(t, "/x/Table/pet", Logins["admin"].Layout.Entry)
|
||||
assert.Equal(t, "https://yaoapps.com", Logins["admin"].Layout.Site)
|
||||
assert.Equal(t, "Make Your Dream With Yao App Engine", Logins["admin"].Layout.Slogan)
|
||||
|
||||
assert.Equal(t, "user", Logins["user"].ID)
|
||||
assert.Equal(t, "User Login", Logins["user"].Name)
|
||||
assert.Equal(t, "scripts.user.Login", Logins["user"].Action.Process)
|
||||
assert.Equal(t, []string{":payload"}, Logins["user"].Action.Args)
|
||||
assert.Equal(t, "yao.utils.Captcha", Logins["user"].Layout.Captcha)
|
||||
assert.Equal(t, "/images/user-cover.png", Logins["user"].Layout.Cover)
|
||||
assert.Equal(t, "/x/Table/dash", Logins["user"].Layout.Entry)
|
||||
assert.Equal(t, "https://yaoapps.com/docs", Logins["user"].Layout.Site)
|
||||
assert.Equal(t, "Make Your Dream With Yao App Engine", Logins["user"].Layout.Slogan)
|
||||
}
|
||||
|
||||
func TestLoadHK(t *testing.T) {
|
||||
|
||||
os.Setenv("YAO_LANG", "zh-hk")
|
||||
lang.Load(config.Conf)
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 2, len(Logins))
|
||||
|
||||
assert.Equal(t, "admin", Logins["admin"].ID)
|
||||
assert.Equal(t, "管理員登錄", Logins["admin"].Name)
|
||||
assert.Equal(t, "yao.user.login", Logins["admin"].Action.Process)
|
||||
assert.Equal(t, []string{":payload"}, Logins["admin"].Action.Args)
|
||||
assert.Equal(t, "yao.utils.Captcha", Logins["admin"].Layout.Captcha)
|
||||
assert.Equal(t, "/images/admin-cover.png", Logins["admin"].Layout.Cover)
|
||||
assert.Equal(t, "/x/Table/pet", Logins["admin"].Layout.Entry)
|
||||
assert.Equal(t, "https://yaoapps.com", Logins["admin"].Layout.Site)
|
||||
assert.Equal(t, "夢想讓我們與眾不同", Logins["admin"].Layout.Slogan)
|
||||
|
||||
assert.Equal(t, "user", Logins["user"].ID)
|
||||
assert.Equal(t, "用戶登錄", Logins["user"].Name)
|
||||
assert.Equal(t, "scripts.user.Login", Logins["user"].Action.Process)
|
||||
assert.Equal(t, []string{":payload"}, Logins["user"].Action.Args)
|
||||
assert.Equal(t, "yao.utils.Captcha", Logins["user"].Layout.Captcha)
|
||||
assert.Equal(t, "/images/user-cover.png", Logins["user"].Layout.Cover)
|
||||
assert.Equal(t, "/x/Table/dash", Logins["user"].Layout.Entry)
|
||||
assert.Equal(t, "https://yaoapps.com/docs", Logins["user"].Layout.Site)
|
||||
assert.Equal(t, "夢想讓我們與眾不同", Logins["user"].Layout.Slogan)
|
||||
}
|
||||
|
||||
func TestLoadCN(t *testing.T) {
|
||||
|
||||
os.Setenv("YAO_LANG", "zh-cn")
|
||||
lang.Load(config.Conf)
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 2, len(Logins))
|
||||
|
||||
assert.Equal(t, "admin", Logins["admin"].ID)
|
||||
assert.Equal(t, "管理员登录", Logins["admin"].Name)
|
||||
assert.Equal(t, "yao.user.login", Logins["admin"].Action.Process)
|
||||
assert.Equal(t, []string{":payload"}, Logins["admin"].Action.Args)
|
||||
assert.Equal(t, "yao.utils.Captcha", Logins["admin"].Layout.Captcha)
|
||||
assert.Equal(t, "/images/admin-cover.png", Logins["admin"].Layout.Cover)
|
||||
assert.Equal(t, "/x/Table/pet", Logins["admin"].Layout.Entry)
|
||||
assert.Equal(t, "https://yaoapps.com", Logins["admin"].Layout.Site)
|
||||
assert.Equal(t, "梦想让我们与众不同", Logins["admin"].Layout.Slogan)
|
||||
|
||||
assert.Equal(t, "user", Logins["user"].ID)
|
||||
assert.Equal(t, "用户登录", Logins["user"].Name)
|
||||
assert.Equal(t, "scripts.user.Login", Logins["user"].Action.Process)
|
||||
assert.Equal(t, []string{":payload"}, Logins["user"].Action.Args)
|
||||
assert.Equal(t, "yao.utils.Captcha", Logins["user"].Layout.Captcha)
|
||||
assert.Equal(t, "/images/user-cover.png", Logins["user"].Layout.Cover)
|
||||
assert.Equal(t, "/x/Table/dash", Logins["user"].Layout.Entry)
|
||||
assert.Equal(t, "https://yaoapps.com/docs", Logins["user"].Layout.Site)
|
||||
assert.Equal(t, "梦想让我们与众不同", Logins["user"].Layout.Slogan)
|
||||
}
|
||||
|
||||
func TestExport(t *testing.T) {
|
||||
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = Export()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
api, has := gou.APIs["widgets.login"]
|
||||
assert.True(t, has)
|
||||
assert.Equal(t, 4, len(api.HTTP.Paths))
|
||||
}
|
||||
24
widgets/login/types.go
Normal file
24
widgets/login/types.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package login
|
||||
|
||||
// DSL the app DSL
|
||||
type DSL struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Action ActionDSL `json:"action,omitempty"`
|
||||
Layout LayoutDSL `json:"layout,omitempty"`
|
||||
}
|
||||
|
||||
// ActionDSL the login action DSL
|
||||
type ActionDSL struct {
|
||||
Process string `json:"process,omitempty"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
}
|
||||
|
||||
// LayoutDSL the login page layoutDSL
|
||||
type LayoutDSL struct {
|
||||
Entry string `json:"entry,omitempty"`
|
||||
Captcha string `json:"captcha,omitempty"`
|
||||
Cover string `json:"cover,omitempty"`
|
||||
Slogan string `json:"slogan,omitempty"`
|
||||
Site string `json:"site,omitempty"`
|
||||
}
|
||||
24
widgets/widgets.go
Normal file
24
widgets/widgets.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package widgets
|
||||
|
||||
import (
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/widgets/app"
|
||||
"github.com/yaoapp/yao/widgets/login"
|
||||
)
|
||||
|
||||
// Load the widgets
|
||||
func Load(cfg config.Config) error {
|
||||
|
||||
err := login.Load(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// app login
|
||||
err = app.Load(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
13
widgets/widgets_test.go
Normal file
13
widgets/widgets_test.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package widgets
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/yao/config"
|
||||
)
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
err := Load(config.Conf)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue