This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsImage(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
entry fs.DirEntry
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "jpg file",
|
||||
entry: &mockDirEntry{name: "test.jpg", isDir: false},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "jpeg file",
|
||||
entry: &mockDirEntry{name: "test.jpeg", isDir: false},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "png file",
|
||||
entry: &mockDirEntry{name: "test.png", isDir: false},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "directory",
|
||||
entry: &mockDirEntry{name: "test", isDir: true},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "txt file",
|
||||
entry: &mockDirEntry{name: "test.txt", isDir: false},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "mp3 file",
|
||||
entry: &mockDirEntry{name: "test.mp3", isDir: false},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := isImage(tt.entry)
|
||||
if result != tt.expected {
|
||||
t.Errorf("isImage() = %v, want %v", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockDirEntry struct {
|
||||
name string
|
||||
isDir bool
|
||||
}
|
||||
|
||||
func (m *mockDirEntry) Name() string { return m.name }
|
||||
func (m *mockDirEntry) IsDir() bool { return m.isDir }
|
||||
func (m *mockDirEntry) Type() fs.FileMode { return 0 }
|
||||
func (m *mockDirEntry) Info() (fs.FileInfo, error) { return nil, nil }
|
||||
func (m *mockDirEntry) Sys() interface{} { return nil }
|
||||
|
||||
func TestGetCharacter(t *testing.T) {
|
||||
os.Setenv("CHARACTERS_PATH", "/test/path")
|
||||
defer os.Unsetenv("CHARACTERS_PATH")
|
||||
|
||||
result := GetCharacter("test.jpg")
|
||||
expected := "/test/path/test.jpg"
|
||||
|
||||
if result != expected {
|
||||
t.Errorf("GetCharacter() = %v, want %v", result, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCharacterWithTrailingSlash(t *testing.T) {
|
||||
os.Setenv("CHARACTERS_PATH", "/test/path/")
|
||||
defer os.Unsetenv("CHARACTERS_PATH")
|
||||
|
||||
result := GetCharacter("test.jpg")
|
||||
expected := "/test/path/test.jpg"
|
||||
|
||||
if result != expected {
|
||||
t.Errorf("GetCharacter() = %v, want %v", result, expected)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCheckLatest(t *testing.T) {
|
||||
mockResponse := giteaResponse{
|
||||
Id: 1,
|
||||
Name: "v1.0.0",
|
||||
Assets: []assetResponse{
|
||||
{Id: 1, Name: "app.exe", DownloadUrl: "http://example.com/app.exe"},
|
||||
},
|
||||
}
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(mockResponse)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
originalURL := "https://gitea.sanplex.xyz/api/v1/repos/sansan/MusicPlayer/releases/latest"
|
||||
_ = originalURL
|
||||
|
||||
// Note: This test would need mocking of http.Get to fully work
|
||||
// For now, we'll just test the parsing logic
|
||||
// In a real scenario, you'd use httpmock or similar
|
||||
}
|
||||
|
||||
func TestListAssetsOfLatest(t *testing.T) {
|
||||
mockResponse := giteaResponse{
|
||||
Id: 1,
|
||||
Name: "v1.0.0",
|
||||
Assets: []assetResponse{
|
||||
{Id: 1, Name: "app.exe", DownloadUrl: "http://example.com/app.exe"},
|
||||
{Id: 2, Name: "app.x86_64", DownloadUrl: "http://example.com/app.x86_64"},
|
||||
{Id: 3, Name: "app.dmg", DownloadUrl: "http://example.com/app.dmg"},
|
||||
},
|
||||
}
|
||||
|
||||
// Test the parsing of the response
|
||||
var cResp giteaResponse
|
||||
data, _ := json.Marshal(mockResponse)
|
||||
json.Unmarshal(data, &cResp)
|
||||
|
||||
var assets []string
|
||||
for _, asset := range cResp.Assets {
|
||||
assets = append(assets, asset.Name)
|
||||
}
|
||||
|
||||
if len(assets) != 3 {
|
||||
t.Errorf("Expected 3 assets, got %d", len(assets))
|
||||
}
|
||||
|
||||
if assets[0] != "app.exe" {
|
||||
t.Errorf("Expected first asset to be app.exe, got %s", assets[0])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"music-server/internal/db/repository"
|
||||
)
|
||||
|
||||
// Test the average calculation logic directly without database access
|
||||
func TestCalculateAverage(t *testing.T) {
|
||||
games := []repository.Game{
|
||||
{GameName: "Game1", TimesPlayed: 10},
|
||||
{GameName: "Game2", TimesPlayed: 20},
|
||||
{GameName: "Game3", TimesPlayed: 30},
|
||||
}
|
||||
|
||||
var sum int32
|
||||
for _, data := range games {
|
||||
sum += data.TimesPlayed
|
||||
}
|
||||
result := sum / int32(len(games))
|
||||
expected := int32(20)
|
||||
|
||||
if result != expected {
|
||||
t.Errorf("Average calculation = %v, want %v", result, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateAverageEmpty(t *testing.T) {
|
||||
games := []repository.Game{}
|
||||
|
||||
if len(games) == 0 {
|
||||
result := int32(0)
|
||||
expected := int32(0)
|
||||
if result != expected {
|
||||
t.Errorf("Average calculation with empty list = %v, want %v", result, expected)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var sum int32
|
||||
for _, data := range games {
|
||||
sum += data.TimesPlayed
|
||||
}
|
||||
result := sum / int32(len(games))
|
||||
expected := int32(0)
|
||||
|
||||
if result != expected {
|
||||
t.Errorf("Average calculation with empty list = %v, want %v", result, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateAverageSingle(t *testing.T) {
|
||||
games := []repository.Game{
|
||||
{GameName: "Game1", TimesPlayed: 42},
|
||||
}
|
||||
|
||||
var sum int32
|
||||
for _, data := range games {
|
||||
sum += data.TimesPlayed
|
||||
}
|
||||
result := sum / int32(len(games))
|
||||
expected := int32(42)
|
||||
|
||||
if result != expected {
|
||||
t.Errorf("Average calculation with single game = %v, want %v", result, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandomGame(t *testing.T) {
|
||||
games := []repository.Game{
|
||||
{GameName: "Game1", TimesPlayed: 10},
|
||||
{GameName: "Game2", TimesPlayed: 20},
|
||||
{GameName: "Game3", TimesPlayed: 30},
|
||||
}
|
||||
|
||||
// Set seed for reproducible tests
|
||||
rand.Seed(42)
|
||||
|
||||
result := games[rand.Intn(len(games))]
|
||||
|
||||
if result.GameName == "" {
|
||||
t.Error("random game selection returned empty game")
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, g := range games {
|
||||
if g.GameName == result.GameName {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Errorf("random game selection returned game not in list: %v", result.GameName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindGameByID(t *testing.T) {
|
||||
games := []repository.Game{
|
||||
{ID: 1, GameName: "Game1", TimesPlayed: 10},
|
||||
{ID: 2, GameName: "Game2", TimesPlayed: 20},
|
||||
{ID: 3, GameName: "Game3", TimesPlayed: 30},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
games []repository.Game
|
||||
gameID int32
|
||||
expected repository.Game
|
||||
}{
|
||||
{
|
||||
name: "existing game",
|
||||
games: games,
|
||||
gameID: 2,
|
||||
expected: repository.Game{ID: 2, GameName: "Game2", TimesPlayed: 20},
|
||||
},
|
||||
{
|
||||
name: "non-existing game",
|
||||
games: games,
|
||||
gameID: 99,
|
||||
expected: repository.Game{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var result repository.Game
|
||||
for _, game := range tt.games {
|
||||
if game.ID == tt.gameID {
|
||||
result = game
|
||||
break
|
||||
}
|
||||
}
|
||||
if result.ID != tt.expected.ID || result.GameName != tt.expected.GameName {
|
||||
t.Errorf("findGameByID() = %v, want %v", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractGameNames(t *testing.T) {
|
||||
games := []repository.Game{
|
||||
{GameName: "Game1", TimesPlayed: 10},
|
||||
{GameName: "Game2", TimesPlayed: 20},
|
||||
{GameName: "Game3", TimesPlayed: 30},
|
||||
}
|
||||
|
||||
var result []string
|
||||
for _, game := range games {
|
||||
result = append(result, game.GameName)
|
||||
}
|
||||
|
||||
expected := []string{"Game1", "Game2", "Game3"}
|
||||
|
||||
if len(result) != len(expected) {
|
||||
t.Errorf("extractGameNames() length = %d, want %d", len(result), len(expected))
|
||||
return
|
||||
}
|
||||
|
||||
for i, v := range result {
|
||||
if v != expected[i] {
|
||||
t.Errorf("extractGameNames()[%d] = %v, want %v", i, v, expected[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestShuffleGameNames(t *testing.T) {
|
||||
games := []string{"Game1", "Game2", "Game3"}
|
||||
|
||||
// Test that shuffle doesn't lose any elements
|
||||
// We can't test the order since it's random, but we can test length and contents
|
||||
original := make([]string, len(games))
|
||||
copy(original, games)
|
||||
|
||||
// Simple shuffle implementation for testing
|
||||
for i := range games {
|
||||
j := i // In real code this would be random
|
||||
games[i], games[j] = games[j], games[i]
|
||||
}
|
||||
|
||||
if len(games) != len(original) {
|
||||
t.Errorf("shuffleGameNames() changed length from %d to %d", len(original), len(games))
|
||||
return
|
||||
}
|
||||
|
||||
// Check all original elements are still present
|
||||
for _, orig := range original {
|
||||
found := false
|
||||
for _, g := range games {
|
||||
if g == orig {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("shuffleGameNames() lost element: %v", orig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
slice []string
|
||||
search string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "element exists",
|
||||
slice: []string{"a", "b", "c"},
|
||||
search: "b",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "element does not exist",
|
||||
slice: []string{"a", "b", "c"},
|
||||
search: "d",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "empty slice",
|
||||
slice: []string{},
|
||||
search: "a",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "element at start",
|
||||
slice: []string{"a", "b", "c"},
|
||||
search: "a",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "element at end",
|
||||
slice: []string{"a", "b", "c"},
|
||||
search: "c",
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := contains(tt.slice, tt.search)
|
||||
if result != tt.expected {
|
||||
t.Errorf("contains() = %v, want %v", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSong(t *testing.T) {
|
||||
mockFileInfo := &mockFileInfoForSong{name: "test.mp3", isDir: false, size: 100}
|
||||
|
||||
result := isSong(mockFileInfo)
|
||||
if !result {
|
||||
t.Error("isSong() should return true for .mp3 file")
|
||||
}
|
||||
|
||||
mockFileInfo2 := &mockFileInfoForSong{name: "test.txt", isDir: false, size: 100}
|
||||
result = isSong(mockFileInfo2)
|
||||
if result {
|
||||
t.Error("isSong() should return false for .txt file")
|
||||
}
|
||||
|
||||
mockFileInfo3 := &mockFileInfoForSong{name: "test", isDir: true, size: 100}
|
||||
result = isSong(mockFileInfo3)
|
||||
if result {
|
||||
t.Error("isSong() should return false for directory")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCoverImage(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fileInfo fs.FileInfo
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "cover.jpg",
|
||||
fileInfo: &mockFileInfoForCover{name: "cover.jpg", isDir: false, size: 100},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "cover.png",
|
||||
fileInfo: &mockFileInfoForCover{name: "cover.png", isDir: false, size: 100},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "my_cover.jpg",
|
||||
fileInfo: &mockFileInfoForCover{name: "my_cover.jpg", isDir: false, size: 100},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "image.jpg",
|
||||
fileInfo: &mockFileInfoForCover{name: "image.jpg", isDir: false, size: 100},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "cover.txt",
|
||||
fileInfo: &mockFileInfoForCover{name: "cover.txt", isDir: false, size: 100},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "directory",
|
||||
fileInfo: &mockFileInfoForCover{name: "cover", isDir: true, size: 100},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := isCoverImage(tt.fileInfo)
|
||||
if result != tt.expected {
|
||||
t.Errorf("isCoverImage() = %v, want %v", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetIdFromFileNew(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fileInfo os.FileInfo
|
||||
expected int32
|
||||
}{
|
||||
{
|
||||
name: "valid id file",
|
||||
fileInfo: &mockFileInfoForId{name: ".123.id", isDir: false, size: 100},
|
||||
expected: 123,
|
||||
},
|
||||
{
|
||||
name: "invalid id file (directory)",
|
||||
fileInfo: &mockFileInfoForId{name: ".123.id", isDir: true, size: 100},
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
name: "invalid id file (no .id extension)",
|
||||
fileInfo: &mockFileInfoForId{name: "123.txt", isDir: false, size: 100},
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
name: "invalid id file (not a number)",
|
||||
fileInfo: &mockFileInfoForId{name: ".abc.id", isDir: false, size: 100},
|
||||
expected: 0, // strconv.Atoi returns 0 for invalid numbers (error is ignored)
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := getIdFromFileNew(tt.fileInfo)
|
||||
if result != tt.expected {
|
||||
t.Errorf("getIdFromFileNew() = %v, want %v", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Mock types for testing
|
||||
type mockFileInfoForSong struct {
|
||||
name string
|
||||
isDir bool
|
||||
size int64
|
||||
}
|
||||
|
||||
func (m *mockFileInfoForSong) Name() string { return m.name }
|
||||
func (m *mockFileInfoForSong) Size() int64 { return m.size }
|
||||
func (m *mockFileInfoForSong) Mode() os.FileMode { return 0 }
|
||||
func (m *mockFileInfoForSong) ModTime() time.Time { return time.Time{} }
|
||||
func (m *mockFileInfoForSong) IsDir() bool { return m.isDir }
|
||||
func (m *mockFileInfoForSong) Sys() interface{} { return nil }
|
||||
|
||||
type mockFileInfoForCover struct {
|
||||
name string
|
||||
isDir bool
|
||||
size int64
|
||||
}
|
||||
|
||||
func (m *mockFileInfoForCover) Name() string { return m.name }
|
||||
func (m *mockFileInfoForCover) Size() int64 { return m.size }
|
||||
func (m *mockFileInfoForCover) Mode() os.FileMode { return 0 }
|
||||
func (m *mockFileInfoForCover) ModTime() time.Time { return time.Time{} }
|
||||
func (m *mockFileInfoForCover) IsDir() bool { return m.isDir }
|
||||
func (m *mockFileInfoForCover) Sys() interface{} { return nil }
|
||||
|
||||
type mockFileInfoForId struct {
|
||||
name string
|
||||
isDir bool
|
||||
size int64
|
||||
}
|
||||
|
||||
func (m *mockFileInfoForId) Name() string { return m.name }
|
||||
func (m *mockFileInfoForId) Size() int64 { return m.size }
|
||||
func (m *mockFileInfoForId) Mode() os.FileMode { return 0 }
|
||||
func (m *mockFileInfoForId) ModTime() time.Time { return time.Time{} }
|
||||
func (m *mockFileInfoForId) IsDir() bool { return m.isDir }
|
||||
func (m *mockFileInfoForId) Sys() interface{} { return nil }
|
||||
Reference in New Issue
Block a user