Returns every character image with when it was last changed, in Unix seconds, so clients can cache the images and download only the ones that changed.
86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
package backend
|
|
|
|
import (
|
|
"io"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newCharacterService(t *testing.T) *CharacterService {
|
|
t.Helper()
|
|
base := t.TempDir()
|
|
writeFile(t, filepath.Join(base, "secret.png"), "outside")
|
|
dir := filepath.Join(base, "characters")
|
|
writeFile(t, filepath.Join(dir, "Adol.png"), "adol")
|
|
writeFile(t, filepath.Join(dir, "Aloy.JPG"), "aloy")
|
|
writeFile(t, filepath.Join(dir, "notes.txt"), "text")
|
|
writeFile(t, filepath.Join(dir, "sub", "Hidden.png"), "hidden")
|
|
|
|
c, err := NewCharacterService(dir)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { c.Close() })
|
|
return c
|
|
}
|
|
|
|
func TestCharacterList(t *testing.T) {
|
|
characters, err := newCharacterService(t).List()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, []string{"Adol.png", "Aloy.JPG"}, characters)
|
|
}
|
|
|
|
func TestCharacterListDetails(t *testing.T) {
|
|
c := newCharacterService(t)
|
|
changed := time.Date(2026, 10, 7, 12, 0, 0, 0, time.UTC)
|
|
require.NoError(t, c.root.Chtimes("Adol.png", changed, changed))
|
|
|
|
characters, err := c.ListDetails()
|
|
require.NoError(t, err)
|
|
require.Len(t, characters, 2)
|
|
assert.Equal(t, CharacterDetails{Name: "Adol.png", Modified: changed.Unix()}, characters[0])
|
|
assert.Equal(t, "Aloy.JPG", characters[1].Name)
|
|
}
|
|
|
|
func TestCharacterListDetailsSeesChangedImage(t *testing.T) {
|
|
c := newCharacterService(t)
|
|
before, err := c.ListDetails()
|
|
require.NoError(t, err)
|
|
|
|
later := time.Unix(before[0].Modified, 0).Add(time.Hour)
|
|
require.NoError(t, c.root.Chtimes("Adol.png", later, later))
|
|
|
|
after, err := c.ListDetails()
|
|
require.NoError(t, err)
|
|
assert.Greater(t, after[0].Modified, before[0].Modified)
|
|
assert.Equal(t, before[1], after[1], "unchanged images keep their time")
|
|
}
|
|
|
|
func TestCharacterOpen(t *testing.T) {
|
|
c := newCharacterService(t)
|
|
|
|
f, err := c.Open("Adol.png")
|
|
require.NoError(t, err)
|
|
content, _ := io.ReadAll(f)
|
|
f.Close()
|
|
assert.Equal(t, "adol", string(content))
|
|
|
|
_, err = c.Open("Missing.png")
|
|
assert.ErrorIs(t, err, ErrNotFound)
|
|
}
|
|
|
|
func TestCharacterOpenRejectsPathTraversal(t *testing.T) {
|
|
c := newCharacterService(t)
|
|
for _, name := range []string{"", "../secret.png", "sub/Hidden.png", "/etc/passwd", "..", "notes.txt"} {
|
|
_, err := c.Open(name)
|
|
assert.ErrorIs(t, err, ErrInvalidName, name)
|
|
}
|
|
}
|
|
|
|
func TestNewCharacterServiceMissingDir(t *testing.T) {
|
|
_, err := NewCharacterService(filepath.Join(t.TempDir(), "missing"))
|
|
assert.Error(t, err)
|
|
}
|