All checks were successful
CI/CD / detect-changes (pull_request) Successful in 5s
CI/CD / test-runners (pull_request) Has been skipped
CI/CD / e2e-smoke (pull_request) Has been skipped
CI/CD / test-frontend (pull_request) Successful in 6s
CI/CD / test-go-pg (pull_request) Successful in 2m42s
CI/CD / test-sqlite (pull_request) Successful in 2m58s
CI/CD / build-and-deploy (pull_request) Successful in 1m33s
Manifest declarations for slots (host surfaces declare injection points) and contributes (extensions declare UI contributions). lib.require() relaxed from library-only to any package with exports. Admin slots aggregation endpoint. SDK renderAll() helper. 7 new tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
98 lines
2.2 KiB
Go
98 lines
2.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestValidateComposabilityFields_ValidSlots(t *testing.T) {
|
|
m := map[string]any{
|
|
"slots": map[string]any{
|
|
"toolbar-actions": map[string]any{
|
|
"description": "Toolbar action buttons",
|
|
"context": map[string]any{
|
|
"noteId": "string",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
if err := ValidateComposabilityFields(m); err != "" {
|
|
t.Errorf("expected valid, got: %s", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateComposabilityFields_SlotMissingDescription(t *testing.T) {
|
|
m := map[string]any{
|
|
"slots": map[string]any{
|
|
"toolbar": map[string]any{
|
|
"context": map[string]any{},
|
|
},
|
|
},
|
|
}
|
|
if err := ValidateComposabilityFields(m); err == "" {
|
|
t.Error("expected error for slot missing description")
|
|
}
|
|
}
|
|
|
|
func TestValidateComposabilityFields_SlotsNotObject(t *testing.T) {
|
|
m := map[string]any{
|
|
"slots": "bad",
|
|
}
|
|
if err := ValidateComposabilityFields(m); err == "" {
|
|
t.Error("expected error for non-object slots")
|
|
}
|
|
}
|
|
|
|
func TestValidateComposabilityFields_ValidContributes(t *testing.T) {
|
|
m := map[string]any{
|
|
"contributes": map[string]any{
|
|
"notes:toolbar-actions": map[string]any{
|
|
"label": "Dictate",
|
|
"icon": "🎤",
|
|
},
|
|
},
|
|
}
|
|
if err := ValidateComposabilityFields(m); err != "" {
|
|
t.Errorf("expected valid, got: %s", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateComposabilityFields_ContributesMissingColon(t *testing.T) {
|
|
m := map[string]any{
|
|
"contributes": map[string]any{
|
|
"toolbar-actions": map[string]any{
|
|
"label": "Bad",
|
|
},
|
|
},
|
|
}
|
|
if err := ValidateComposabilityFields(m); err == "" {
|
|
t.Error("expected error for contributes key without colon")
|
|
}
|
|
}
|
|
|
|
func TestValidateComposabilityFields_Empty(t *testing.T) {
|
|
m := map[string]any{
|
|
"id": "test",
|
|
}
|
|
if err := ValidateComposabilityFields(m); err != "" {
|
|
t.Errorf("expected valid for manifest without slots/contributes, got: %s", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateComposabilityFields_BothValid(t *testing.T) {
|
|
m := map[string]any{
|
|
"slots": map[string]any{
|
|
"my-slot": map[string]any{
|
|
"description": "A slot",
|
|
},
|
|
},
|
|
"contributes": map[string]any{
|
|
"other:their-slot": map[string]any{
|
|
"label": "Hello",
|
|
},
|
|
},
|
|
}
|
|
if err := ValidateComposabilityFields(m); err != "" {
|
|
t.Errorf("expected valid, got: %s", err)
|
|
}
|
|
}
|