117 lines
4.1 KiB
Go
117 lines
4.1 KiB
Go
package templates
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type memoryCatalog struct {
|
|
items []Template
|
|
err error
|
|
}
|
|
|
|
func (catalog *memoryCatalog) ListTemplates(_ context.Context, owner string) ([]Template, error) {
|
|
if catalog.err != nil {
|
|
return nil, catalog.err
|
|
}
|
|
out := []Template{}
|
|
for _, item := range catalog.items {
|
|
if item.OwnerID == owner {
|
|
out = append(out, item)
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|
|
func (catalog *memoryCatalog) CreateTemplate(_ context.Context, item Template) (Template, error) {
|
|
if catalog.err != nil {
|
|
return Template{}, catalog.err
|
|
}
|
|
catalog.items = append(catalog.items, item)
|
|
return item, nil
|
|
}
|
|
func (catalog *memoryCatalog) UpdateTemplate(_ context.Context, owner, id string, patch Patch, now time.Time) (Template, bool, error) {
|
|
if catalog.err != nil {
|
|
return Template{}, false, catalog.err
|
|
}
|
|
for index := range catalog.items {
|
|
if catalog.items[index].OwnerID != owner || catalog.items[index].ID != id {
|
|
continue
|
|
}
|
|
applyPatch(&catalog.items[index], patch)
|
|
catalog.items[index].UpdatedAt = now
|
|
return catalog.items[index], true, nil
|
|
}
|
|
return Template{}, false, nil
|
|
}
|
|
func (catalog *memoryCatalog) DeleteTemplate(_ context.Context, owner, id string) (Template, bool, error) {
|
|
if catalog.err != nil {
|
|
return Template{}, false, catalog.err
|
|
}
|
|
for index, item := range catalog.items {
|
|
if item.OwnerID != owner || item.ID != id {
|
|
continue
|
|
}
|
|
catalog.items = append(catalog.items[:index], catalog.items[index+1:]...)
|
|
return item, true, nil
|
|
}
|
|
return Template{}, false, nil
|
|
}
|
|
|
|
func TestServiceNormalizesAndScopesTemplates(t *testing.T) {
|
|
now := time.Date(2026, 8, 13, 12, 0, 0, 0, time.UTC)
|
|
catalog := &memoryCatalog{}
|
|
service := NewService(catalog, func() time.Time { return now }, func() string { return "tmpl_fixed" })
|
|
created, err := service.Create(context.Background(), "owner-a", CreateCommand{
|
|
Name: " Campaign ", Description: " ", Prompt: " make it vivid ",
|
|
PreviewImageURL: "/uploads/preview.png", SortOrder: 2,
|
|
Settings: Settings{Engine: "jimeng", Width: 2048, Height: 2048, Scale: 50},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if created.ID != "tmpl_fixed" || created.OwnerID != "owner-a" || created.Name != "Campaign" || created.Prompt != "make it vivid" {
|
|
t.Fatalf("unexpected template: %#v", created)
|
|
}
|
|
if created.Description != "" || created.CreatedAt != now || created.UpdatedAt != now {
|
|
t.Fatalf("unexpected normalized values: %#v", created)
|
|
}
|
|
if _, err := service.Create(context.Background(), "owner-a", CreateCommand{Name: "x", Prompt: "p", PreviewImageURL: "ftp://bad"}); !errors.Is(err, ErrInvalidTemplate) {
|
|
t.Fatalf("expected invalid preview URL, got %v", err)
|
|
}
|
|
items, err := service.List(context.Background(), "owner-b")
|
|
if err != nil || len(items) != 0 {
|
|
t.Fatalf("scope leak: %#v %v", items, err)
|
|
}
|
|
}
|
|
|
|
func TestServiceUpdateDeleteAndNotFound(t *testing.T) {
|
|
now := time.Now().UTC()
|
|
catalog := &memoryCatalog{items: []Template{{ID: "t1", OwnerID: "owner", Name: "old", Prompt: "p", Settings: Settings{}, CreatedAt: now, UpdatedAt: now}}}
|
|
service := NewService(catalog, func() time.Time { return now.Add(time.Hour) }, nil)
|
|
name := " new "
|
|
updated, err := service.Update(context.Background(), "owner", "t1", UpdateCommand{Name: &name})
|
|
if err != nil || updated.Name != "new" {
|
|
t.Fatalf("update: %#v %v", updated, err)
|
|
}
|
|
if _, err := service.Update(context.Background(), "other", "t1", UpdateCommand{Name: &name}); !errors.Is(err, ErrNotFound) {
|
|
t.Fatalf("expected scoped not found, got %v", err)
|
|
}
|
|
deleted, err := service.Delete(context.Background(), "owner", "t1")
|
|
if err != nil || deleted.ID != "t1" {
|
|
t.Fatalf("delete: %#v %v", deleted, err)
|
|
}
|
|
if _, err := service.Delete(context.Background(), "owner", "t1"); !errors.Is(err, ErrNotFound) {
|
|
t.Fatalf("expected not found, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestServicePropagatesInfrastructureFailures(t *testing.T) {
|
|
want := errors.New("database unavailable")
|
|
service := NewService(&memoryCatalog{err: want}, nil, nil)
|
|
if _, err := service.List(context.Background(), "owner"); !errors.Is(err, want) {
|
|
t.Fatalf("expected wrapped cause, got %v", err)
|
|
}
|
|
}
|