151 lines
5 KiB
Go
151 lines
5 KiB
Go
package views
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/a-h/templ"
|
|
"github.com/google/uuid"
|
|
tablomodel "xtablo-backend/internal/tablos"
|
|
)
|
|
|
|
func TestOverviewProjectsFromTablosCarriesColorAndEditURL(t *testing.T) {
|
|
record := tablomodel.Record{
|
|
ID: uuid.MustParse("11111111-1111-1111-1111-111111111111"),
|
|
Name: "Palette",
|
|
Color: "#22C55E",
|
|
Status: tablomodel.StatusTodo,
|
|
CreatedAt: time.Date(2026, time.May, 10, 9, 0, 0, 0, time.UTC),
|
|
}
|
|
|
|
projects := OverviewProjectsFromTablos([]tablomodel.Record{record})
|
|
if len(projects) != 1 {
|
|
t.Fatalf("expected one project, got %d", len(projects))
|
|
}
|
|
|
|
project := projects[0]
|
|
if project.Color != "#22C55E" {
|
|
t.Fatalf("expected color to be preserved, got %q", project.Color)
|
|
}
|
|
if project.EditRequestURL != "/tablos/11111111-1111-1111-1111-111111111111/edit" {
|
|
t.Fatalf("expected edit request url to be set, got %q", project.EditRequestURL)
|
|
}
|
|
if project.CardDateLabel != "10 mai 2026" {
|
|
t.Fatalf("expected French card date label, got %q", project.CardDateLabel)
|
|
}
|
|
if project.IconKind != "leaf" {
|
|
t.Fatalf("expected color presentation icon to be preserved, got %q", project.IconKind)
|
|
}
|
|
}
|
|
|
|
func TestOverviewProjectsSectionRendersColorAndEditAction(t *testing.T) {
|
|
record := tablomodel.Record{
|
|
ID: uuid.MustParse("11111111-1111-1111-1111-111111111111"),
|
|
Name: "Palette",
|
|
Color: "#22C55E",
|
|
Status: tablomodel.StatusTodo,
|
|
CreatedAt: time.Date(2026, time.May, 10, 9, 0, 0, 0, time.UTC),
|
|
}
|
|
|
|
html := renderViewToString(t, OverviewProjectsSection(OverviewProjectsFromTablos([]tablomodel.Record{record})))
|
|
|
|
for _, want := range []string{
|
|
`style="--project-color:#22C55E;"`,
|
|
`aria-label="Modifier le projet"`,
|
|
`hx-get="/tablos/11111111-1111-1111-1111-111111111111/edit"`,
|
|
`<path d="M11 20A7 7 0 0 1 4 13V6a1 1 0 0 1 1-1h7a7 7 0 0 1 7 7v0a8 8 0 0 1-8 8Z"></path>`,
|
|
} {
|
|
if !strings.Contains(html, want) {
|
|
t.Fatalf("expected %q in %q", want, html)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTabloListRowRendersLeafIconKind(t *testing.T) {
|
|
component := TabloListRow(TabloCardView{
|
|
ID: "11111111-1111-1111-1111-111111111111",
|
|
Name: "Palette",
|
|
Color: "#22C55E",
|
|
StatusLabel: "À faire",
|
|
StatusTone: "info",
|
|
Progress: 0,
|
|
ProgressLabel: "0%",
|
|
CreatedAtLabel: "10 mai 2026",
|
|
DeleteRequestURL: "/tablos/11111111-1111-1111-1111-111111111111",
|
|
EditRequestURL: "/tablos/11111111-1111-1111-1111-111111111111/edit",
|
|
IconKind: "leaf",
|
|
Initial: "P",
|
|
})
|
|
|
|
html := renderViewToString(t, component)
|
|
|
|
if !strings.Contains(html, `<path d="M11 20A7 7 0 0 1 4 13V6a1 1 0 0 1 1-1h7a7 7 0 0 1 7 7v0a8 8 0 0 1-8 8Z"></path>`) {
|
|
t.Fatalf("expected leaf icon markup, got %q", html)
|
|
}
|
|
}
|
|
|
|
func TestSidebarProjectItemsUsesFirstFourRealTablos(t *testing.T) {
|
|
tablos := []tablomodel.Record{
|
|
{ID: uuid.MustParse("11111111-1111-1111-1111-111111111111"), Name: "Alpha", Color: "#3B82F6"},
|
|
{ID: uuid.MustParse("22222222-2222-2222-2222-222222222222"), Name: "Beta", Color: "#22C55E"},
|
|
{ID: uuid.MustParse("33333333-3333-3333-3333-333333333333"), Name: "Gamma", Color: "#A855F7"},
|
|
{ID: uuid.MustParse("44444444-4444-4444-4444-444444444444"), Name: "Delta", Color: "#EF4444"},
|
|
{ID: uuid.MustParse("55555555-5555-5555-5555-555555555555"), Name: "Epsilon", Color: "#EAB308"},
|
|
}
|
|
|
|
items := sidebarProjectItems(tablos)
|
|
if len(items) != 4 {
|
|
t.Fatalf("expected 4 sidebar items, got %d", len(items))
|
|
}
|
|
|
|
for i, want := range []struct {
|
|
href string
|
|
label string
|
|
icon string
|
|
}{
|
|
{href: "/tablos/11111111-1111-1111-1111-111111111111", label: "Alpha", icon: "bolt"},
|
|
{href: "/tablos/22222222-2222-2222-2222-222222222222", label: "Beta", icon: "leaf"},
|
|
{href: "/tablos/33333333-3333-3333-3333-333333333333", label: "Gamma", icon: "gem"},
|
|
{href: "/tablos/44444444-4444-4444-4444-444444444444", label: "Delta", icon: "flame"},
|
|
} {
|
|
if items[i].Href != want.href || items[i].Label != want.label || items[i].Icon != want.icon {
|
|
t.Fatalf("item %d = %#v, want href=%q label=%q icon=%q", i, items[i], want.href, want.label, want.icon)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTabloListRowDoesNotRenderSpacerBetweenEditAndDelete(t *testing.T) {
|
|
component := TabloListRow(TabloCardView{
|
|
ID: "11111111-1111-1111-1111-111111111111",
|
|
Name: "Palette",
|
|
Color: "#3B82F6",
|
|
StatusLabel: "À faire",
|
|
StatusTone: "info",
|
|
Progress: 0,
|
|
ProgressLabel: "0%",
|
|
CreatedAtLabel: "10 mai 2026",
|
|
DeleteRequestURL: "/tablos/11111111-1111-1111-1111-111111111111",
|
|
EditRequestURL: "/tablos/11111111-1111-1111-1111-111111111111/edit",
|
|
IconKind: "bolt",
|
|
Initial: "P",
|
|
})
|
|
|
|
html := renderViewToString(t, component)
|
|
|
|
if strings.Contains(html, `ui-space-x`) {
|
|
t.Fatalf("expected no spacer markup in list row actions, got %q", html)
|
|
}
|
|
}
|
|
|
|
func renderViewToString(t *testing.T, component templ.Component) string {
|
|
t.Helper()
|
|
|
|
var buf bytes.Buffer
|
|
if err := component.Render(context.Background(), &buf); err != nil {
|
|
t.Fatalf("render component: %v", err)
|
|
}
|
|
return buf.String()
|
|
}
|