feat: harden loose-offline sync for user JWT, schema, and console ops
Enable Binding-scoped agent push/pull, empty-table schema ensure, SyncPage inspect/drop-table, default module import, and agent-bound publish docs from the 宇恒联调意见. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -40,14 +40,70 @@ func TestMergeIntoAddsPages(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeIntoRejectsDuplicatePageID(t *testing.T) {
|
||||
func TestMergeIntoUpdatesExistingPageAndResource(t *testing.T) {
|
||||
base := &Blueprint{
|
||||
Apis: Apis{Resources: []APIResource{{
|
||||
Entity: "settlement_points", Path: "/settlement_points",
|
||||
Operations: []string{"list", "get", "create", "update", "delete"},
|
||||
}}},
|
||||
Pages: []Page{{
|
||||
ID: "record_list", Route: "/records", Type: "list", Entity: "settlement_points",
|
||||
Layout: &PageLayout{Actions: []string{"create", "edit", "delete"}},
|
||||
}},
|
||||
}
|
||||
incoming := &Blueprint{
|
||||
Apis: Apis{Resources: []APIResource{{
|
||||
Entity: "settlement_points", Path: "/settlement_points",
|
||||
Operations: []string{"list", "get", "create", "update", "delete", "import", "export"},
|
||||
}}},
|
||||
Pages: []Page{{
|
||||
ID: "record_list", Route: "/records", Type: "list", Entity: "settlement_points",
|
||||
Layout: &PageLayout{Actions: []string{"create", "edit", "delete", "import"}},
|
||||
}},
|
||||
}
|
||||
res, err := MergeInto(base, incoming)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(res.AddedPages) != 0 {
|
||||
t.Fatalf("should not add pages: %+v", res.AddedPages)
|
||||
}
|
||||
if len(res.UpdatedResources) != 1 || res.UpdatedResources[0] != "settlement_points" {
|
||||
t.Fatalf("updated resources: %+v", res.UpdatedResources)
|
||||
}
|
||||
ops := base.Apis.Resources[0].Operations
|
||||
hasImport := false
|
||||
for _, op := range ops {
|
||||
if op == "import" {
|
||||
hasImport = true
|
||||
}
|
||||
}
|
||||
if !hasImport {
|
||||
t.Fatalf("ops missing import: %+v", ops)
|
||||
}
|
||||
acts := base.Pages[0].Layout.Actions
|
||||
hasAct := false
|
||||
for _, a := range acts {
|
||||
if a == "import" {
|
||||
hasAct = true
|
||||
}
|
||||
}
|
||||
if !hasAct {
|
||||
t.Fatalf("actions missing import: %+v", acts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeIntoRejectsRouteConflictDifferentID(t *testing.T) {
|
||||
base := &Blueprint{
|
||||
Pages: []Page{{ID: "a", Route: "/a", Type: "list", Entity: "x"}},
|
||||
}
|
||||
incoming := &Blueprint{
|
||||
Pages: []Page{{ID: "a", Route: "/b", Type: "list", Entity: "x"}},
|
||||
Pages: []Page{{ID: "b", Route: "/a", Type: "list", Entity: "x"}},
|
||||
Apis: Apis{Resources: []APIResource{{
|
||||
Entity: "x", Path: "/x", Operations: []string{"list", "import"},
|
||||
}}},
|
||||
}
|
||||
if _, err := MergeInto(base, incoming); err == nil {
|
||||
t.Fatal("expected duplicate page id error")
|
||||
t.Fatal("expected route conflict error")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user