Feature 15: Recipe Detail and Kitchen Reading Mode (#162)
CI / ci (push) Successful in 6m44s

Co-authored-by: orchestrator-agent <20+orchestrator-agent@code.cubecraftcreations.com>
This commit was merged in pull request #162.
This commit is contained in:
2026-10-09 14:01:14 -04:00
committed by approver_agent
parent 14f7141e44
commit 4b592fdbbb
39 changed files with 4549 additions and 105 deletions
+101
View File
@@ -1,6 +1,7 @@
package dinners_test
import (
"database/sql"
"encoding/json"
"errors"
"strings"
@@ -74,3 +75,103 @@ func TestCreateRegularNeverNamesFromLink(t *testing.T) {
}
check("duplicate error", dup.Error())
}
// TestPageSiteNameWithholdsHosts: a stored site name that could be a host —
// the link's own, in any case and without "www.", an IP address or a dotted
// host name — is withheld; a name the page gave, dotless or with spaces, is
// kept.
func TestPageSiteNameWithholdsHosts(t *testing.T) {
t.Parallel()
const link = "https://www.TokenHost/recipes/stew"
for _, tc := range []struct {
stored string
valid bool
want *string
}{
{"", false, nil},
{"tokenhost", true, nil},
{"TOKENHOST", true, nil},
{"private-token.example.com", true, nil},
{"Food.com", true, nil},
{"203.0.113.7", true, nil},
{"2001:db8::1", true, nil},
{"Delish", true, ptr("Delish")},
{"Bon Appétit", true, ptr("Bon Appétit")},
{"Mr. Food Test Kitchen", true, ptr("Mr. Food Test Kitchen")},
} {
got, err := dinners.PageSiteName(sql.NullString{String: tc.stored, Valid: tc.valid}, link)
if err != nil {
t.Fatalf("PageSiteName(%q): %v", tc.stored, err)
}
if (got == nil) != (tc.want == nil) || (got != nil && *got != *tc.want) {
t.Errorf("PageSiteName(%q) = %v, want %v", tc.stored, deref(got), deref(tc.want))
}
}
if _, err := dinners.PageSiteName(sql.NullString{String: "Delish", Valid: true}, "https://secret-token\x7f.example/%zz"); err == nil || strings.Contains(err.Error(), "secret-token") {
t.Errorf("PageSiteName of an unparseable link: err = %v, want one not quoting the link", err)
}
}
// TestSafeSourceURLOnlyWithoutSecrets: a recipe link is shown only when it
// is https to a host with no user, password, query or fragment, each of
// which can carry a token; any other link, or one that does not parse, is
// withheld whole.
func TestSafeSourceURLOnlyWithoutSecrets(t *testing.T) {
t.Parallel()
for _, link := range []string{
"https://www.example.com/recipes/chicken-curry",
"https://example.com",
"https://example.com:8443/stew/",
"https://[2001:db8::1]/curry",
"https://1.2.3.4/curry",
"https://Kitchen-2.Example.com./curry",
} {
if got := dinners.SafeSourceURL(link); got == nil || *got != link {
t.Errorf("SafeSourceURL(%q) = %v, want the link", link, deref(got))
}
}
for _, link := range []string{
"https://example.com/curry?access_token=query-token",
"https://example.com/curry?",
"https://user:password@example.com/curry",
"https://token@example.com/curry",
"https://@example.com/curry",
"http://example.com/curry",
"https://example.com/curry#token=fragment-token",
"https://example.com/curry#",
"ftp://example.com/curry",
"https:example.com/curry",
"https:///curry",
"https://example.com:99999/curry",
"https://example.com:0/curry",
"//example.com/curry",
"https://secret-token\x7f.example/%zz",
"",
// Hosts url.Parse accepts but the browser's URL parser refuses
// (or reads as another host), which would fail the whole recipe
// screen.
"https://[bad]/curry",
"https://[fe80::1%25en0]/curry",
"https://[1.2.3.4]/curry",
"https://1.2.3.999/curry",
"https://1.2.3.4.5/curry",
"https://999/curry",
"https://example.0x/curry",
"https://xn--a/curry",
"https://ex%61mple.com/curry",
"https://ex%2fample.com/curry",
"https://a..b/curry",
"https://café.example/curry",
} {
if got := dinners.SafeSourceURL(link); got != nil {
t.Errorf("SafeSourceURL(%q) = %q, want nil", link, *got)
}
}
}
func deref(s *string) any {
if s == nil {
return nil
}
return *s
}