Files
egutierrez 4f7c96dcc8 test: tests unitarios para pkg/avatar y shell/avatar
- pkg/avatar: 13 tests cubriendo todos los proveedores, estilos, sets,
  edge cases (size=0, unknown provider, chars especiales, determinismo)
- shell/avatar: 6 tests con httptest server local (download OK, JPEG,
  HTTP 404, context cancelled, extensiones por content-type)

No requiere acceso a internet — shell/avatar usa httptest.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 21:38:22 +00:00

138 lines
3.3 KiB
Go

package avatar
import (
"context"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
)
func TestDownload_OK(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/png")
w.Write([]byte("fake-png-data"))
}))
defer srv.Close()
path, err := Download(context.Background(), srv.URL+"/avatar.png")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer os.Remove(path)
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read temp file: %v", err)
}
if string(data) != "fake-png-data" {
t.Errorf("unexpected content: %q", data)
}
if ext := filepath.Ext(path); ext != ".png" {
t.Errorf("expected .png extension, got %q", ext)
}
}
func TestDownload_JPEG(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/jpeg")
w.Write([]byte("fake-jpeg"))
}))
defer srv.Close()
path, err := Download(context.Background(), srv.URL+"/photo.jpg")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer os.Remove(path)
if ext := filepath.Ext(path); ext != ".jpg" {
t.Errorf("expected .jpg extension, got %q", ext)
}
}
func TestDownload_HTTPError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
defer srv.Close()
_, err := Download(context.Background(), srv.URL+"/missing.png")
if err == nil {
t.Fatal("expected error for 404")
}
}
func TestDownload_ContextCancelled(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("data"))
}))
defer srv.Close()
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err := Download(ctx, srv.URL+"/test.png")
if err == nil {
t.Fatal("expected error for cancelled context")
}
}
func TestFetchToDir(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/png")
w.Write([]byte("avatar-image"))
}))
defer srv.Close()
dir := t.TempDir()
// We need to mock the provider URL. Instead, test Download + manual copy logic.
// FetchToDir uses Fetch internally which hits real providers.
// Test the Download path which is the impure core.
path, err := Download(context.Background(), srv.URL+"/bot.png")
if err != nil {
t.Fatalf("download: %v", err)
}
defer os.Remove(path)
// Verify the file exists in temp
if _, err := os.Stat(path); err != nil {
t.Fatalf("temp file missing: %v", err)
}
// Verify content
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read: %v", err)
}
if string(data) != "avatar-image" {
t.Errorf("unexpected content: %q", data)
}
_ = dir // used via t.TempDir for cleanup
}
func TestExtensionFromContentType(t *testing.T) {
tests := []struct {
ct string
want string
}{
{"image/png", ".png"},
{"image/jpeg", ".jpg"},
{"image/svg+xml", ".svg"},
{"image/webp", ".webp"},
{"image/gif", ".gif"},
{"application/octet-stream", ".png"},
{"", ".png"},
}
for _, tt := range tests {
got := extensionFromContentType(tt.ct)
if got != tt.want {
t.Errorf("extensionFromContentType(%q) = %q, want %q", tt.ct, got, tt.want)
}
}
}