Files

321 lines
8.6 KiB
Go

package handlers
import (
"encoding/json"
"testing"
)
func TestNewJSONLDOrganization(t *testing.T) {
registryURL := "atcr.io"
shortName := "ATCR"
fullName := "AT Container Registry"
org := NewJSONLDOrganization(registryURL, shortName, fullName)
// Verify required fields
if org.Context != "https://schema.org" {
t.Errorf("Context = %q, want %q", org.Context, "https://schema.org")
}
if org.Type != "Organization" {
t.Errorf("Type = %q, want %q", org.Type, "Organization")
}
if org.Name != shortName {
t.Errorf("Name = %q, want %q", org.Name, shortName)
}
if org.AlternateName != fullName {
t.Errorf("AlternateName = %q, want %q", org.AlternateName, fullName)
}
if org.URL != "https://atcr.io" {
t.Errorf("URL = %q, want %q", org.URL, "https://atcr.io")
}
if org.Logo != "https://atcr.io/favicon.svg" {
t.Errorf("Logo = %q, want %q", org.Logo, "https://atcr.io/favicon.svg")
}
// Verify it marshals to valid JSON
data, err := json.Marshal(org)
if err != nil {
t.Fatalf("Failed to marshal organization: %v", err)
}
if len(data) == 0 {
t.Error("Marshaled JSON is empty")
}
}
func TestNewJSONLDWebSite(t *testing.T) {
registryURL := "atcr.io"
shortName := "ATCR"
site := NewJSONLDWebSite(registryURL, shortName)
// Verify required fields
if site.Context != "https://schema.org" {
t.Errorf("Context = %q, want %q", site.Context, "https://schema.org")
}
if site.Type != "WebSite" {
t.Errorf("Type = %q, want %q", site.Type, "WebSite")
}
if site.Name != shortName {
t.Errorf("Name = %q, want %q", site.Name, shortName)
}
if site.URL != "https://atcr.io" {
t.Errorf("URL = %q, want %q", site.URL, "https://atcr.io")
}
// Verify search action
if site.PotentialAction == nil {
t.Fatal("PotentialAction is nil")
}
if site.PotentialAction.Type != "SearchAction" {
t.Errorf("PotentialAction.Type = %q, want %q", site.PotentialAction.Type, "SearchAction")
}
if site.PotentialAction.Target == nil {
t.Fatal("PotentialAction.Target is nil")
}
expectedTemplate := "https://atcr.io/search?q={search_term_string}"
if site.PotentialAction.Target.URLTemplate != expectedTemplate {
t.Errorf("URLTemplate = %q, want %q", site.PotentialAction.Target.URLTemplate, expectedTemplate)
}
// Verify it marshals to valid JSON
data, err := json.Marshal(site)
if err != nil {
t.Fatalf("Failed to marshal website: %v", err)
}
if len(data) == 0 {
t.Error("Marshaled JSON is empty")
}
}
func TestNewJSONLDSoftwareSourceCode(t *testing.T) {
tests := []struct {
name string
registryURL string
handle string
repoName string
description string
license string
sourceURL string
}{
{
name: "full details",
registryURL: "atcr.io",
handle: "alice.bsky.social",
repoName: "myapp",
description: "A cool container image",
license: "MIT",
sourceURL: "https://github.com/alice/myapp",
},
{
name: "minimal details",
registryURL: "atcr.io",
handle: "bob.test",
repoName: "simple",
description: "",
license: "",
sourceURL: "",
},
{
name: "with license only",
registryURL: "localhost:5000",
handle: "dev",
repoName: "test-image",
description: "Test image",
license: "Apache-2.0",
sourceURL: "",
},
}
shortName := "ATCR"
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
code := NewJSONLDSoftwareSourceCode(
tt.registryURL,
tt.handle,
tt.repoName,
tt.description,
tt.license,
tt.sourceURL,
shortName,
)
// Verify required fields
if code.Context != "https://schema.org" {
t.Errorf("Context = %q, want %q", code.Context, "https://schema.org")
}
if code.Type != "SoftwareSourceCode" {
t.Errorf("Type = %q, want %q", code.Type, "SoftwareSourceCode")
}
expectedName := tt.handle + "/" + tt.repoName
if code.Name != expectedName {
t.Errorf("Name = %q, want %q", code.Name, expectedName)
}
expectedCodeRepo := "https://" + tt.registryURL + "/r/" + tt.handle + "/" + tt.repoName
if code.CodeRepository != expectedCodeRepo {
t.Errorf("CodeRepository = %q, want %q", code.CodeRepository, expectedCodeRepo)
}
// Verify author
if code.Author == nil {
t.Fatal("Author is nil")
}
if code.Author.Type != "Person" {
t.Errorf("Author.Type = %q, want %q", code.Author.Type, "Person")
}
if code.Author.Name != tt.handle {
t.Errorf("Author.Name = %q, want %q", code.Author.Name, tt.handle)
}
// Verify publisher
if code.Publisher == nil {
t.Fatal("Publisher is nil")
}
if code.Publisher.Name != shortName {
t.Errorf("Publisher.Name = %q, want %q", code.Publisher.Name, shortName)
}
// Verify optional fields
if tt.license != "" && code.License != tt.license {
t.Errorf("License = %q, want %q", code.License, tt.license)
}
if tt.license == "" && code.License != "" {
t.Errorf("License = %q, want empty", code.License)
}
if tt.sourceURL != "" && code.IsBasedOn != tt.sourceURL {
t.Errorf("IsBasedOn = %q, want %q", code.IsBasedOn, tt.sourceURL)
}
if tt.sourceURL == "" && code.IsBasedOn != "" {
t.Errorf("IsBasedOn = %q, want empty", code.IsBasedOn)
}
// Verify it marshals to valid JSON
data, err := json.Marshal(code)
if err != nil {
t.Fatalf("Failed to marshal code: %v", err)
}
if len(data) == 0 {
t.Error("Marshaled JSON is empty")
}
})
}
}
func TestNewJSONLDProfilePage(t *testing.T) {
tests := []struct {
name string
registryURL string
handle string
avatar string
}{
{
name: "with avatar",
registryURL: "atcr.io",
handle: "alice.bsky.social",
avatar: "https://cdn.bsky.app/avatar/alice.jpg",
},
{
name: "without avatar",
registryURL: "atcr.io",
handle: "bob.test",
avatar: "",
},
{
name: "localhost registry",
registryURL: "localhost:5000",
handle: "dev",
avatar: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
page := NewJSONLDProfilePage(tt.registryURL, tt.handle, tt.avatar)
// Verify required fields
if page.Context != "https://schema.org" {
t.Errorf("Context = %q, want %q", page.Context, "https://schema.org")
}
if page.Type != "ProfilePage" {
t.Errorf("Type = %q, want %q", page.Type, "ProfilePage")
}
// Verify main entity
if page.MainEntity == nil {
t.Fatal("MainEntity is nil")
}
if page.MainEntity.Type != "Person" {
t.Errorf("MainEntity.Type = %q, want %q", page.MainEntity.Type, "Person")
}
if page.MainEntity.Name != tt.handle {
t.Errorf("MainEntity.Name = %q, want %q", page.MainEntity.Name, tt.handle)
}
expectedURL := "https://" + tt.registryURL + "/u/" + tt.handle
if page.MainEntity.URL != expectedURL {
t.Errorf("MainEntity.URL = %q, want %q", page.MainEntity.URL, expectedURL)
}
// Verify avatar handling
if tt.avatar != "" && page.MainEntity.Image != tt.avatar {
t.Errorf("MainEntity.Image = %q, want %q", page.MainEntity.Image, tt.avatar)
}
if tt.avatar == "" && page.MainEntity.Image != "" {
t.Errorf("MainEntity.Image = %q, want empty", page.MainEntity.Image)
}
// Verify it marshals to valid JSON
data, err := json.Marshal(page)
if err != nil {
t.Fatalf("Failed to marshal page: %v", err)
}
if len(data) == 0 {
t.Error("Marshaled JSON is empty")
}
})
}
}
func TestJSONLD_ValidJSON(t *testing.T) {
// Test that all constructors produce valid JSON that can be unmarshaled
registryURL := "atcr.io"
shortName := "ATCR"
fullName := "AT Container Registry"
testCases := []struct {
name string
data any
}{
{"Organization", NewJSONLDOrganization(registryURL, shortName, fullName)},
{"WebSite", NewJSONLDWebSite(registryURL, shortName)},
{"SoftwareSourceCode", NewJSONLDSoftwareSourceCode(registryURL, "alice", "myapp", "desc", "MIT", "https://github.com/alice/myapp", shortName)},
{"ProfilePage", NewJSONLDProfilePage(registryURL, "alice", "https://example.com/avatar.jpg")},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Marshal to JSON
data, err := json.MarshalIndent(tc.data, "", " ")
if err != nil {
t.Fatalf("Failed to marshal %s: %v", tc.name, err)
}
// Unmarshal back to verify it's valid JSON
var result map[string]any
if err := json.Unmarshal(data, &result); err != nil {
t.Fatalf("Failed to unmarshal %s: %v\nJSON: %s", tc.name, err, string(data))
}
// Verify @context is present
if _, ok := result["@context"]; !ok {
t.Errorf("%s missing @context field", tc.name)
}
// Verify @type is present
if _, ok := result["@type"]; !ok {
t.Errorf("%s missing @type field", tc.name)
}
})
}
}