mirror of
https://github.com/go-vikunja/vikunja.git
synced 2025-12-05 19:16:51 -06:00
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: kolaente <13721712+kolaente@users.noreply.github.com>
182 lines
4.8 KiB
Go
182 lines
4.8 KiB
Go
// Vikunja is a to-do list application to facilitate your life.
|
|
// Copyright 2018-present Vikunja and contributors. All rights reserved.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package initials
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"code.vikunja.io/api/pkg/user"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGetAvatar(t *testing.T) {
|
|
t.Run("generates valid SVG with name", func(t *testing.T) {
|
|
provider := &Provider{}
|
|
|
|
testUser := &user.User{
|
|
ID: 1,
|
|
Name: "John Doe",
|
|
Username: "johndoe",
|
|
}
|
|
|
|
avatar, mimeType, err := provider.GetAvatar(testUser, 128)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, avatar)
|
|
assert.Equal(t, "image/svg+xml", mimeType)
|
|
|
|
// Verify it's valid SVG
|
|
svgString := string(avatar)
|
|
assert.Contains(t, svgString, "<svg")
|
|
assert.Contains(t, svgString, "viewBox=\"0 0 100 100\"")
|
|
assert.Contains(t, svgString, "width=\"128\"")
|
|
assert.Contains(t, svgString, "height=\"128\"")
|
|
// Should contain "J" from "John"
|
|
assert.Contains(t, svgString, ">J<")
|
|
// Should have a background color
|
|
assert.Contains(t, svgString, "fill=\"#")
|
|
})
|
|
|
|
t.Run("generates valid SVG with username when name is empty", func(t *testing.T) {
|
|
provider := &Provider{}
|
|
|
|
testUser := &user.User{
|
|
ID: 2,
|
|
Name: "", // Empty name
|
|
Username: "jane_smith",
|
|
}
|
|
|
|
avatar, mimeType, err := provider.GetAvatar(testUser, 64)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, avatar)
|
|
assert.Equal(t, "image/svg+xml", mimeType)
|
|
|
|
// Verify it's valid SVG
|
|
svgString := string(avatar)
|
|
assert.Contains(t, svgString, "<svg")
|
|
assert.Contains(t, svgString, "width=\"64\"")
|
|
assert.Contains(t, svgString, "height=\"64\"")
|
|
// Should contain "J" from "jane_smith"
|
|
assert.Contains(t, svgString, ">J<")
|
|
})
|
|
|
|
t.Run("uses consistent colors based on user ID", func(t *testing.T) {
|
|
provider := &Provider{}
|
|
|
|
testUser := &user.User{
|
|
ID: 0,
|
|
Name: "Alice",
|
|
Username: "alice",
|
|
}
|
|
|
|
avatar1, _, err := provider.GetAvatar(testUser, 100)
|
|
require.NoError(t, err)
|
|
|
|
avatar2, _, err := provider.GetAvatar(testUser, 200)
|
|
require.NoError(t, err)
|
|
|
|
// Both should use the same colors (user ID 0 -> index 0)
|
|
svg1 := string(avatar1)
|
|
svg2 := string(avatar2)
|
|
|
|
// Should have the first background color (index 0)
|
|
assert.Contains(t, svg1, `fill="#e0f8d9"`)
|
|
assert.Contains(t, svg2, `fill="#e0f8d9"`)
|
|
// Should have the first text color (index 0)
|
|
assert.Contains(t, svg1, `fill="#005f00"`)
|
|
assert.Contains(t, svg2, `fill="#005f00"`)
|
|
})
|
|
|
|
t.Run("escapes special characters", func(t *testing.T) {
|
|
provider := &Provider{}
|
|
|
|
testUser := &user.User{
|
|
ID: 3,
|
|
Name: "<script>",
|
|
Username: "hacker",
|
|
}
|
|
|
|
avatar, mimeType, err := provider.GetAvatar(testUser, 50)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "image/svg+xml", mimeType)
|
|
|
|
svgString := string(avatar)
|
|
// Should escape the < character
|
|
assert.NotContains(t, svgString, "><script><")
|
|
assert.Contains(t, svgString, "<")
|
|
})
|
|
|
|
t.Run("handles different sizes", func(t *testing.T) {
|
|
provider := &Provider{}
|
|
|
|
testUser := &user.User{
|
|
ID: 4,
|
|
Name: "Bob",
|
|
Username: "bob",
|
|
}
|
|
|
|
testCases := []struct {
|
|
size int64
|
|
expectedSize string
|
|
}{
|
|
{32, "32"},
|
|
{64, "64"},
|
|
{128, "128"},
|
|
{256, "256"},
|
|
{512, "512"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
avatar, mimeType, err := provider.GetAvatar(testUser, tc.size)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "image/svg+xml", mimeType)
|
|
|
|
svgString := string(avatar)
|
|
assert.Contains(t, svgString, `width="`+tc.expectedSize+`"`)
|
|
assert.Contains(t, svgString, `height="`+tc.expectedSize+`"`)
|
|
assert.Contains(t, svgString, ">B<")
|
|
}
|
|
})
|
|
|
|
t.Run("returns error for user without name or username", func(t *testing.T) {
|
|
provider := &Provider{}
|
|
|
|
testUser := &user.User{
|
|
ID: 5,
|
|
Name: "",
|
|
Username: "",
|
|
}
|
|
|
|
_, _, err := provider.GetAvatar(testUser, 100)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "no name or username")
|
|
})
|
|
}
|
|
|
|
func TestFlushCache(t *testing.T) {
|
|
provider := &Provider{}
|
|
testUser := &user.User{
|
|
ID: 999,
|
|
Name: "Test",
|
|
Username: "test",
|
|
}
|
|
|
|
// FlushCache should be a no-op and not return an error
|
|
err := provider.FlushCache(testUser)
|
|
assert.NoError(t, err)
|
|
}
|