Files
excalicloud/internal/storage/settings_test.go
T
claude BotandClaude Opus 5.5 baa412d02e API : titre et logo personnalisés (/api/settings, /api/logo)
Logo PNG recadré au centre et réduit à 64x64 côté serveur, ré-encodé.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013WSSWgbf7gUzTzEqhjqtzN
2026-10-07 15:00:21 +02:00

96 lines
2.4 KiB
Go

package storage
import (
"bytes"
"errors"
"image"
"image/color"
"image/png"
"strings"
"testing"
)
func encodePNG(t *testing.T, img image.Image) []byte {
t.Helper()
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
t.Fatal(err)
}
return buf.Bytes()
}
func TestTitle(t *testing.T) {
s := newStore(t)
if st, err := s.ReadSettings(); err != nil || st != (Settings{}) {
t.Fatalf("défauts : %+v, %v", st, err)
}
st, err := s.WriteTitle(" Schémas vLab ")
if err != nil || st.Title != "Schémas vLab" {
t.Fatalf("titre : %+v, %v", st, err)
}
if st, _ := s.ReadSettings(); st.Title != "Schémas vLab" {
t.Fatalf("titre non persisté : %+v", st)
}
for _, bad := range []string{"a\nb", strings.Repeat("é", MaxTitleLen+1)} {
if _, err := s.WriteTitle(bad); !errors.Is(err, ErrInvalidPath) {
t.Errorf("titre %q accepté", bad)
}
}
// Les fichiers de réglages n'apparaissent pas dans l'explorateur.
if entries, _ := s.List(""); len(entries) != 0 {
t.Fatalf("réglages visibles : %+v", entries)
}
}
func TestLogo(t *testing.T) {
s := newStore(t)
if _, err := s.ReadLogo(); !errors.Is(err, ErrNotFound) {
t.Fatalf("logo absent : %v", err)
}
if _, err := s.WriteLogo([]byte("pas une image")); !errors.Is(err, ErrInvalidImage) {
t.Fatalf("non-PNG accepté : %v", err)
}
// 300x200 : bande rouge à gauche (hors recadrage), vert au centre.
src := image.NewNRGBA(image.Rect(0, 0, 300, 200))
for y := 0; y < 200; y++ {
for x := 0; x < 300; x++ {
c := color.NRGBA{0, 200, 0, 255}
if x < 50 {
c = color.NRGBA{255, 0, 0, 255}
}
src.Set(x, y, c)
}
}
st, err := s.WriteLogo(encodePNG(t, src))
if err != nil || st.Logo == "" {
t.Fatalf("écriture : %+v, %v", st, err)
}
b, err := s.ReadLogo()
if err != nil {
t.Fatal(err)
}
img, err := png.Decode(bytes.NewReader(b))
if err != nil {
t.Fatal(err)
}
if sz := img.Bounds().Size(); sz != image.Pt(LogoSize, LogoSize) {
t.Fatalf("taille %v", sz)
}
if r, g, _, _ := img.At(0, 0).RGBA(); r>>8 != 0 || g>>8 != 200 {
t.Fatalf("recadrage centré attendu, coin = %v", img.At(0, 0))
}
// Agrandissement d'une petite image.
if _, err := s.WriteLogo(encodePNG(t, image.NewNRGBA(image.Rect(0, 0, 10, 10)))); err != nil {
t.Fatalf("petite image : %v", err)
}
if st, err := s.DeleteLogo(); err != nil || st.Logo != "" {
t.Fatalf("suppression : %+v, %v", st, err)
}
if _, err := s.DeleteLogo(); err != nil {
t.Fatalf("double suppression : %v", err)
}
}