Files
at-container-registry/pkg/appview/handlers/meta_test.go
T

238 lines
6.3 KiB
Go

package handlers
import (
"testing"
)
func TestNewPageMeta(t *testing.T) {
title := "Test Page"
description := "A test description"
meta := NewPageMeta(title, description)
if meta.Title != title {
t.Errorf("Title = %q, want %q", meta.Title, title)
}
if meta.Description != description {
t.Errorf("Description = %q, want %q", meta.Description, description)
}
if meta.OGType != "website" {
t.Errorf("OGType = %q, want %q", meta.OGType, "website")
}
if meta.TwitterCard != "summary_large_image" {
t.Errorf("TwitterCard = %q, want %q", meta.TwitterCard, "summary_large_image")
}
// Optional fields should be empty
if meta.Canonical != "" {
t.Errorf("Canonical = %q, want empty", meta.Canonical)
}
if meta.Robots != "" {
t.Errorf("Robots = %q, want empty", meta.Robots)
}
if meta.OGImage != "" {
t.Errorf("OGImage = %q, want empty", meta.OGImage)
}
if meta.JSONLD != nil {
t.Errorf("JSONLD = %v, want nil", meta.JSONLD)
}
}
func TestPageMeta_WithCanonical(t *testing.T) {
meta := NewPageMeta("Title", "Desc")
canonical := "https://atcr.io/page"
result := meta.WithCanonical(canonical)
// Should return same pointer for chaining
if result != meta {
t.Error("WithCanonical should return same pointer")
}
if meta.Canonical != canonical {
t.Errorf("Canonical = %q, want %q", meta.Canonical, canonical)
}
}
func TestPageMeta_WithOGImage(t *testing.T) {
meta := NewPageMeta("Title", "Desc")
image := "https://atcr.io/og-image.png"
result := meta.WithOGImage(image)
if result != meta {
t.Error("WithOGImage should return same pointer")
}
if meta.OGImage != image {
t.Errorf("OGImage = %q, want %q", meta.OGImage, image)
}
}
func TestPageMeta_WithOGType(t *testing.T) {
meta := NewPageMeta("Title", "Desc")
result := meta.WithOGType("profile")
if result != meta {
t.Error("WithOGType should return same pointer")
}
if meta.OGType != "profile" {
t.Errorf("OGType = %q, want %q", meta.OGType, "profile")
}
}
func TestPageMeta_WithRobots(t *testing.T) {
meta := NewPageMeta("Title", "Desc")
result := meta.WithRobots("noindex, nofollow")
if result != meta {
t.Error("WithRobots should return same pointer")
}
if meta.Robots != "noindex, nofollow" {
t.Errorf("Robots = %q, want %q", meta.Robots, "noindex, nofollow")
}
}
func TestPageMeta_WithJSONLD(t *testing.T) {
meta := NewPageMeta("Title", "Desc")
org := NewJSONLDOrganization("atcr.io", "ATCR", "AT Container Registry")
site := NewJSONLDWebSite("atcr.io", "ATCR")
result := meta.WithJSONLD(org, site)
if result != meta {
t.Error("WithJSONLD should return same pointer")
}
if len(meta.JSONLD) != 2 {
t.Errorf("JSONLD len = %d, want 2", len(meta.JSONLD))
}
}
func TestPageMeta_Chaining(t *testing.T) {
// Test that all methods can be chained fluently
meta := NewPageMeta("ATCR - Container Registry", "Decentralized container registry").
WithCanonical("https://atcr.io/").
WithOGImage("https://atcr.io/og.png").
WithOGType("website").
WithRobots("index, follow").
WithJSONLD(NewJSONLDOrganization("atcr.io", "ATCR", "AT Container Registry"))
if meta.Title != "ATCR - Container Registry" {
t.Errorf("Title not set correctly after chaining")
}
if meta.Canonical != "https://atcr.io/" {
t.Errorf("Canonical not set correctly after chaining")
}
if meta.OGImage != "https://atcr.io/og.png" {
t.Errorf("OGImage not set correctly after chaining")
}
if meta.OGType != "website" {
t.Errorf("OGType not set correctly after chaining")
}
if meta.Robots != "index, follow" {
t.Errorf("Robots not set correctly after chaining")
}
if len(meta.JSONLD) != 1 {
t.Errorf("JSONLD not set correctly after chaining")
}
}
func TestPageMeta_EmptyJSONLD(t *testing.T) {
meta := NewPageMeta("Title", "Desc")
// Calling WithJSONLD with no args sets nil slice (variadic behavior)
result := meta.WithJSONLD()
if result != meta {
t.Error("WithJSONLD should return same pointer")
}
// Variadic with no args produces nil slice, which is fine
// len(nil slice) == 0, so templates handle it correctly
if len(meta.JSONLD) != 0 {
t.Errorf("JSONLD len = %d, want 0", len(meta.JSONLD))
}
}
func TestPageMeta_RealWorldExamples(t *testing.T) {
tests := []struct {
name string
builder func() *PageMeta
wantTitle string
wantOGType string
wantJSONLen int
}{
{
name: "home page",
builder: func() *PageMeta {
return NewPageMeta(
"ATCR - Decentralized Container Registry",
"Push and pull Docker images with your AT Protocol identity",
).
WithCanonical("https://atcr.io/").
WithJSONLD(
NewJSONLDOrganization("atcr.io", "ATCR", "AT Container Registry"),
NewJSONLDWebSite("atcr.io", "ATCR"),
)
},
wantTitle: "ATCR - Decentralized Container Registry",
wantOGType: "website",
wantJSONLen: 2,
},
{
name: "user profile",
builder: func() *PageMeta {
return NewPageMeta(
"alice.bsky.social - ATCR",
"Container images by alice.bsky.social",
).
WithOGType("profile").
WithOGImage("https://cdn.bsky.app/avatar.jpg").
WithJSONLD(NewJSONLDProfilePage("atcr.io", "alice.bsky.social", "https://cdn.bsky.app/avatar.jpg"))
},
wantTitle: "alice.bsky.social - ATCR",
wantOGType: "profile",
wantJSONLen: 1,
},
{
name: "repository page",
builder: func() *PageMeta {
return NewPageMeta(
"alice.bsky.social/myapp - ATCR",
"A cool container image",
).
WithCanonical("https://atcr.io/r/alice.bsky.social/myapp").
WithJSONLD(NewJSONLDSoftwareSourceCode("atcr.io", "alice.bsky.social", "myapp", "A cool container image", "MIT", "", "ATCR"))
},
wantTitle: "alice.bsky.social/myapp - ATCR",
wantOGType: "website",
wantJSONLen: 1,
},
{
name: "login page with noindex",
builder: func() *PageMeta {
return NewPageMeta("Login - ATCR", "Sign in with your AT Protocol identity").
WithRobots("noindex")
},
wantTitle: "Login - ATCR",
wantOGType: "website",
wantJSONLen: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
meta := tt.builder()
if meta.Title != tt.wantTitle {
t.Errorf("Title = %q, want %q", meta.Title, tt.wantTitle)
}
if meta.OGType != tt.wantOGType {
t.Errorf("OGType = %q, want %q", meta.OGType, tt.wantOGType)
}
if len(meta.JSONLD) != tt.wantJSONLen {
t.Errorf("JSONLD len = %d, want %d", len(meta.JSONLD), tt.wantJSONLen)
}
})
}
}