test(17-06): phase 17 gate with one contract test per layer
- scripts/check-phase17.sh: stages go, plugins, admin, layers, docs and postgres across the framework, four plugin repositories, the host and both layers; go test -json, vitest JSON and TAP detectors, required layer test files, --self-test, --all with NOT RUN postgres and PHASE17_REQUIRE_POSTGRES - TestRegistryDuplicateKey: a duplicate key fails Activate naming both plugin IDs, nothing is published - TestSanitizeByteStable: clean editor HTML comes back byte for byte
This commit is contained in:
50
modules/seaglass/seaglass_test.go
Normal file
50
modules/seaglass/seaglass_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package seaglass_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/seaglass"
|
||||
)
|
||||
|
||||
// TestSanitizeByteStable pins D-10's byte-stability promise: HTML the policy
|
||||
// keeps whole comes back byte for byte, with attributes in their source order,
|
||||
// entities as written, whitespace and quoting untouched, and a zero report.
|
||||
func TestSanitizeByteStable(t *testing.T) {
|
||||
for _, html := range []string{
|
||||
"",
|
||||
"plain text",
|
||||
"<p>One paragraph.</p>",
|
||||
"<p>Mushrooms <strong>can</strong> <em>help</em>.</p>\n\n<p>Second.</p>",
|
||||
`<a title="t" href="https://example.com/a?b=1&c=2" class="x y">attributes in source order</a>`,
|
||||
`<a class="x" href="/kontakt">relative</a> <a href="mailto:a@example.com">mail</a> <a href="tel:+48123456">tel</a>`,
|
||||
`<p>Entities: & <tag> "q" 's' © — —</p>`,
|
||||
`<p>Raw text quotes: It's "fine" & done</p>`,
|
||||
`<p class='single-quoted'>single quotes stay</p>`,
|
||||
`<p CLASS="upper">upper-case attribute name</p>`,
|
||||
"<ul>\n <li>one</li>\n <li>two</li>\n</ul>",
|
||||
"<ol><li>a<ol><li>nested</li></ol></li></ol>",
|
||||
`<h2 dir="rtl">heading</h2><h3>h3</h3><blockquote><p>quote</p></blockquote>`,
|
||||
`<p>line<br>break<br/>self-closed</p>`,
|
||||
`<img src="/media/a.jpg" alt="An image" width="10" height="20">`,
|
||||
`<table><thead><tr><th>h</th></tr></thead><tbody><tr><td>c</td></tr></tbody></table>`,
|
||||
`<p style="text-align: center; color: red">styled</p>`,
|
||||
`<div itemscope itemtype="https://schema.org/Recipe"><span itemprop="name">Tea</span></div>`,
|
||||
`<p><sup><a href="#fn1" role="doc-noteref">1</a></sup></p><div role="doc-endnotes"><p id="fn1">note</p></div>`,
|
||||
`<pre><code>if a < b { return }</code></pre>`,
|
||||
"<p>Zażółć gęślą jaźń — unicode “quotes”</p>",
|
||||
} {
|
||||
got, report := seaglass.SanitizeReport(html)
|
||||
if got != html {
|
||||
t.Errorf("SanitizeReport(%q) = %q, want the input byte for byte", html, got)
|
||||
}
|
||||
if report.Changed || report.ElementCount != 0 || report.AttributeCount != 0 || report.Comments != 0 || len(report.Elements) != 0 || len(report.Attributes) != 0 {
|
||||
t.Errorf("SanitizeReport(%q) report = %+v, want zero", html, report)
|
||||
}
|
||||
if out := seaglass.Sanitize(html); out != html {
|
||||
t.Errorf("Sanitize(%q) = %q", html, out)
|
||||
}
|
||||
if err := seaglass.Check(html); err != nil {
|
||||
t.Errorf("Check(%q) = %v", html, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
46
modules/signpost/signpost_test.go
Normal file
46
modules/signpost/signpost_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package signpost_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
"git.golem15.com/golem15/summercms/modules/signpost"
|
||||
)
|
||||
|
||||
// TestRegistryDuplicateKey pins D-01: two plugins registering the same menu
|
||||
// item type key fail Activate, the error names the key and both plugin IDs in
|
||||
// activation order, and nothing is published on the app.
|
||||
func TestRegistryDuplicateKey(t *testing.T) {
|
||||
app := smokeApp(t, "")
|
||||
err := signpost.Activate(app, []typesPlugin{
|
||||
{id: "acme.blog", types: []pact.MenuItemType{
|
||||
{Key: "acme-page", DefaultPattern: "/:slug", Resolve: echo},
|
||||
{Key: "acme-post", DefaultPattern: "/blog/:slug", Resolve: echo},
|
||||
}},
|
||||
{id: "acme.news", types: []pact.MenuItemType{{Key: "acme-post", DefaultPattern: "/news/:slug", Resolve: echo}}},
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("Activate accepted a duplicate menu item type key")
|
||||
}
|
||||
msg := err.Error()
|
||||
if !strings.HasPrefix(msg, "signpost: ") || !strings.Contains(msg, `"acme-post"`) {
|
||||
t.Fatalf("error = %q, want the signpost prefix and the key", msg)
|
||||
}
|
||||
first, second := strings.Index(msg, "acme.blog"), strings.Index(msg, "acme.news")
|
||||
if first < 0 || second < 0 || first > second {
|
||||
t.Fatalf("error = %q, want both plugin IDs, first registrant first", msg)
|
||||
}
|
||||
if _, ok := app.Lookup[*signpost.Registry](); ok {
|
||||
t.Fatal("a registry was published after a failed Activate")
|
||||
}
|
||||
|
||||
// The same key twice inside one plugin is a duplicate too.
|
||||
err = signpost.Activate(smokeApp(t, ""), []typesPlugin{{id: "acme.blog", types: []pact.MenuItemType{
|
||||
{Key: "acme-post", DefaultPattern: "/a", Resolve: echo},
|
||||
{Key: "acme-post", DefaultPattern: "/b", Resolve: echo},
|
||||
}}})
|
||||
if err == nil || !strings.Contains(err.Error(), "acme-post") {
|
||||
t.Fatalf("duplicate inside one plugin: error = %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user