127 lines
3.4 KiB
Go
127 lines
3.4 KiB
Go
package meta_test
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"aijianzhan/platform/internal/blueprint"
|
|
"aijianzhan/platform/internal/meta"
|
|
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
func testDSN(t *testing.T) string {
|
|
t.Helper()
|
|
dsn := os.Getenv("PLATFORM_TEST_DSN")
|
|
if dsn == "" {
|
|
dsn = "postgres://platform:platform@127.0.0.1:5432/platform?sslmode=disable"
|
|
}
|
|
return dsn
|
|
}
|
|
|
|
func TestPostgresMetaPersist(t *testing.T) {
|
|
db, err := sql.Open("postgres", testDSN(t))
|
|
if err != nil {
|
|
t.Skip(err)
|
|
}
|
|
if err := db.Ping(); err != nil {
|
|
t.Skip(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
ctx := context.Background()
|
|
if err := meta.EnsureSchema(ctx, db); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
store := meta.NewPostgresStore(db)
|
|
slug := "meta_persist_demo"
|
|
tenantID := int64(99001)
|
|
_, _ = db.ExecContext(ctx, `DELETE FROM platform_meta.tenant_apps WHERE tenant_id=$1 AND slug=$2`, tenantID, slug)
|
|
|
|
n := false
|
|
bp := &blueprint.Blueprint{
|
|
Version: "1.0",
|
|
Meta: blueprint.Meta{Name: "持久化测试", Slug: slug, Locale: "zh-CN"},
|
|
Storage: blueprint.Storage{Mode: "schema_per_app", Engine: "postgres", SchemaName: "app_t99001_meta_persist_demo"},
|
|
Entities: []blueprint.Entity{{
|
|
Name: "item", Table: "item", Label: "Item", PrimaryKey: "id",
|
|
Fields: []blueprint.Field{
|
|
{Name: "id", Type: "bigint", Label: "ID", Nullable: &n},
|
|
{Name: "title", Type: "string", Label: "标题", Nullable: &n, MaxLength: 64},
|
|
},
|
|
}},
|
|
Apis: blueprint.Apis{
|
|
BasePath: "/api/v1/apps/" + slug,
|
|
Resources: []blueprint.APIResource{{
|
|
Entity: "item", Path: "/items",
|
|
Operations: []string{"list", "get", "create"},
|
|
}},
|
|
},
|
|
Pages: []blueprint.Page{{
|
|
ID: "list", Title: "列表", Route: "/items", Type: "list", Entity: "item",
|
|
}},
|
|
Security: blueprint.Security{
|
|
Visibility: "private",
|
|
Roles: []blueprint.Role{{
|
|
Name: "管理员", Permissions: []string{"读取模块", "写入模块", "发布模块", "新增数据", "查询数据"},
|
|
}},
|
|
RowPolicies: []blueprint.RowPolicy{{Entity: "item", Rule: "tenant_isolated"}},
|
|
},
|
|
}
|
|
|
|
rec := &meta.AppRecord{
|
|
AppID: "11111111-1111-1111-1111-111111111111",
|
|
TenantID: tenantID,
|
|
Slug: slug,
|
|
Name: bp.Meta.Name,
|
|
SchemaName: bp.Storage.SchemaName,
|
|
Engine: "postgres",
|
|
Status: meta.StatusPublished,
|
|
Blueprint: bp,
|
|
DDL: []string{"SELECT 1"},
|
|
Endpoints: []string{"GET /api/v1/apps/" + slug + "/items"},
|
|
CreatedAt: time.Now().UTC(),
|
|
UpdatedAt: time.Now().UTC(),
|
|
}
|
|
if err := store.Save(ctx, rec); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
got, err := store.GetBySlug(ctx, tenantID, slug)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got.Status != meta.StatusPublished || got.Blueprint == nil || got.Blueprint.Meta.Name != "持久化测试" {
|
|
t.Fatalf("unexpected record: %+v", got)
|
|
}
|
|
|
|
ref, err := store.ResolveResource(ctx, tenantID, slug, "items")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ref.Entity.Name != "item" {
|
|
t.Fatalf("entity=%s", ref.Entity.Name)
|
|
}
|
|
|
|
// 二次 Save 应保留 app_id
|
|
rec.Name = "持久化测试-更新"
|
|
rec.AppID = "22222222-2222-2222-2222-222222222222"
|
|
if err := store.Save(ctx, rec); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got2, err := store.GetBySlug(ctx, tenantID, slug)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got2.AppID != "11111111-1111-1111-1111-111111111111" {
|
|
t.Fatalf("app_id should be preserved, got %s", got2.AppID)
|
|
}
|
|
if got2.Name != "持久化测试-更新" {
|
|
t.Fatalf("name not updated: %s", got2.Name)
|
|
}
|
|
}
|