Verify multimodal content boundaries and every material sort
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestContentValidation(t *testing.T) {
|
||||
cases := []struct {
|
||||
name, kind, body string
|
||||
valid bool
|
||||
}{
|
||||
{"plain text", "text", `{"text":""}`, true},
|
||||
{"empty article draft", "article", `{"article":{"sections":[]}}`, true},
|
||||
{"paragraph descriptions", "article", `{"article":{"sections":[{"id":"s","title":"Section","description":"Summary","paragraphs":[{"id":"p","text":"Body","description":"Notes"}]}]}}`, true},
|
||||
{"duplicate paragraph IDs", "article", `{"article":{"sections":[{"id":"s","paragraphs":[{"id":"p","text":"One"},{"id":"p","text":"Two"}]}]}}`, false},
|
||||
{"markdown field", "article", `{"markdown":"# Heading"}`, false},
|
||||
{"unknown schema", "text", `{"schema_version":2,"text":"Text"}`, false},
|
||||
{"null content", "board", `null`, false},
|
||||
{"nested unknown field", "image", `{"image":{"url":"https://example.com/image.png","secret":"unexpected"}}`, false},
|
||||
{"insecure image", "image", `{"image":{"url":"http://example.com/image.png"}}`, false},
|
||||
{"URL credentials", "image", `{"image":{"url":"https://user:password@example.com/image.png"}}`, false},
|
||||
{"card and text", "card", `{"parts":[{"kind":"text","text":"Caption"}]}`, true},
|
||||
{"empty card", "card", `{"parts":[]}`, false},
|
||||
{"mismatched part", "card", `{"parts":[{"kind":"text","image":{"url":"https://example.com/image.png"}}]}`, false},
|
||||
{"board payload", "board", `{"text":"Wrong type"}`, false},
|
||||
}
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
out, ok := normalizeContent(test.kind, json.RawMessage(test.body))
|
||||
if ok != test.valid {
|
||||
t.Fatalf("valid=%v, want %v", ok, test.valid)
|
||||
}
|
||||
if ok && !json.Valid(out) {
|
||||
t.Fatal("normalized content is invalid JSON")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -168,6 +168,21 @@ func TestOnboardingAndSharing(t *testing.T) {
|
||||
call("DELETE", workspacePath+"/tags/"+tag["id"].(string), tokens[0], nil, 204)
|
||||
call("PATCH", textPath, tokens[0], changed, 412, `"3"`)
|
||||
|
||||
imageContent := response{"image": response{"url": "https://assets.example.com/image.png", "alt": "Photo"}}
|
||||
call("POST", workspacePath+"/materials", tokens[0], response{"kind": "image", "title": "Photo", "content": imageContent}, 201)
|
||||
call("POST", workspacePath+"/materials", tokens[0], response{"kind": "card", "title": "Mixed card", "content": response{"parts": []any{
|
||||
response{"kind": "text", "text": "Caption"},
|
||||
response{"kind": "article", "article": articleContent["article"]},
|
||||
response{"kind": "image", "image": imageContent["image"]},
|
||||
}}}, 201)
|
||||
for _, sort := range []string{"modified", "created", "alphabetical", "opened", "tag"} {
|
||||
call("GET", workspacePath+"/materials?sort="+sort+"&limit=2", tokens[0], nil, 200)
|
||||
}
|
||||
images := call("GET", workspacePath+"/materials?kind=image&q=Photo", tokens[0], nil, 200)
|
||||
if len(images["items"].([]any)) != 1 {
|
||||
t.Fatal("kind/title filter returned incorrect materials")
|
||||
}
|
||||
|
||||
email := "fixture@example.invalid"
|
||||
password := "a-long-fixture-password"
|
||||
call("POST", base+"/auth/register", "", response{"email": email, "password": password}, 202)
|
||||
|
||||
Reference in New Issue
Block a user