- backend: user_avatar_objects binding (PG+SQLite), GC preserves avatar blobs, avatar service (EXIF-stripping WebP 128/512), public avatar read route - web: avatar upload/crop on profile, round avatar in header/members/comments/author - android: avatar upload/crop, round avatar on profile and albums header - openspec: add-user-avatar proposal/design/specs/tasks
56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestPublicUserOmitsPhone(t *testing.T) {
|
|
u := &User{ID: "u1", Email: "user@test.local", Phone: "+15551234567", Name: "Tester"}
|
|
|
|
pub, err := json.Marshal(u.Public())
|
|
if err != nil {
|
|
t.Fatalf("marshal public: %v", err)
|
|
}
|
|
if strings.Contains(string(pub), "phone") || strings.Contains(string(pub), "+15551234567") {
|
|
t.Fatalf("PublicUser leaks phone: %s", pub)
|
|
}
|
|
|
|
self, err := json.Marshal(u.Self())
|
|
if err != nil {
|
|
t.Fatalf("marshal self: %v", err)
|
|
}
|
|
if !strings.Contains(string(self), "+15551234567") {
|
|
t.Fatalf("SelfUser missing phone: %s", self)
|
|
}
|
|
if !strings.Contains(string(self), `"phone"`) {
|
|
t.Fatalf("SelfUser phone not serialized: %s", self)
|
|
}
|
|
}
|
|
|
|
func TestPublicUserCarriesAvatar(t *testing.T) {
|
|
u := &User{ID: "u1", Name: "Tester", AvatarURL: "/api/avatars/u1/v123"}
|
|
|
|
pub, err := json.Marshal(u.Public())
|
|
if err != nil {
|
|
t.Fatalf("marshal public: %v", err)
|
|
}
|
|
if !strings.Contains(string(pub), `"avatar_url":"/api/avatars/u1/v123"`) {
|
|
t.Fatalf("PublicUser avatar_url missing: %s", pub)
|
|
}
|
|
self, err := json.Marshal(u.Self())
|
|
if err != nil {
|
|
t.Fatalf("marshal self: %v", err)
|
|
}
|
|
if !strings.Contains(string(self), `"avatar_url":"/api/avatars/u1/v123"`) {
|
|
t.Fatalf("SelfUser avatar_url missing: %s", self)
|
|
}
|
|
|
|
// Without an avatar the field is omitted, so clients fall back to a placeholder.
|
|
bare, _ := json.Marshal((&User{ID: "u2", Name: "Bare"}).Public())
|
|
if strings.Contains(string(bare), "avatar_url") {
|
|
t.Fatalf("empty avatar_url should be omitted: %s", bare)
|
|
}
|
|
}
|