package server import ( "encoding/json" "net/http" "testing" "music-server/internal/backend" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestLibraryEndpoints(t *testing.T) { e := newTestEnv(t) song := e.addSong("Game A", "Song", "0123456789") e.addSong("Game B", "Other", "x") var soundtracks []backend.Soundtrack rec := e.do(http.MethodGet, "/api/v1/soundtracks") require.Equal(t, http.StatusOK, rec.Code) require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &soundtracks)) require.Len(t, soundtracks, 2) assert.Equal(t, "Game A", soundtracks[0].Name) assert.Equal(t, song.SoundtrackUuid, soundtracks[0].Uuid) var soundtrack backend.SoundtrackWithSongList require.NoError(t, json.Unmarshal(e.do(http.MethodGet, "/api/v1/soundtracks/"+song.SoundtrackUuid.String()).Body.Bytes(), &soundtrack)) require.Len(t, soundtrack.Songs, 1) assert.Equal(t, song.Uuid, soundtrack.Songs[0].Uuid) var info backend.Song require.NoError(t, json.Unmarshal(e.do(http.MethodGet, "/api/v1/songs/"+song.Uuid.String()).Body.Bytes(), &info)) assert.Equal(t, "Song", info.Name) assert.Equal(t, "Game A", info.SoundtrackName) rec = e.do(http.MethodGet, "/api/v1/songs/"+song.Uuid.String()+"/file", "Range", "bytes=0-3") assert.Equal(t, http.StatusPartialContent, rec.Code) assert.Equal(t, "0123", rec.Body.String()) assert.Equal(t, "audio/mpeg", rec.Header().Get("Content-Type")) } func TestLibraryEndpointErrors(t *testing.T) { e := newTestEnv(t) missing := uuid.New().String() for _, path := range []string{"/api/v1/soundtracks/" + missing, "/api/v1/songs/" + missing, "/api/v1/songs/" + missing + "/file"} { assert.Equal(t, http.StatusNotFound, e.do(http.MethodGet, path).Code, path) } for _, path := range []string{"/api/v1/soundtracks/not-a-uuid", "/api/v1/songs/123", "/api/v1/songs/123/file"} { assert.Equal(t, http.StatusUnprocessableEntity, e.do(http.MethodGet, path).Code, path) } } func TestLibraryEndpointsRequireToken(t *testing.T) { e := newTestEnv(t, withAuth("secret")) assert.Equal(t, http.StatusUnauthorized, e.do(http.MethodGet, "/api/v1/soundtracks").Code) } func TestSongFileLockedDuringSync(t *testing.T) { e := newTestEnv(t) song := e.addSong("Game A", "Song", "x") release := e.blockSync() defer release() require.Equal(t, http.StatusOK, e.do(http.MethodPost, "/api/v1/sync").Code) assert.Equal(t, http.StatusLocked, e.do(http.MethodGet, "/api/v1/songs/"+song.Uuid.String()+"/file").Code) assert.Equal(t, http.StatusOK, e.do(http.MethodGet, "/api/v1/songs/"+song.Uuid.String()).Code, "song info stays available") } func TestQueueResponsesIncludeUUIDs(t *testing.T) { e := newTestEnv(t) song := e.addSong("Game A", "Song", "x") require.Equal(t, http.StatusOK, e.do(http.MethodGet, "/api/v1/music/rand").Code) require.Equal(t, http.StatusOK, e.do(http.MethodGet, "/api/v1/music/addQue").Code) var info map[string]any require.NoError(t, json.Unmarshal(e.do(http.MethodGet, "/api/v1/music/info").Body.Bytes(), &info)) assert.Equal(t, song.Uuid.String(), info["SongUuid"]) assert.Equal(t, song.SoundtrackUuid.String(), info["SoundtrackUuid"]) var list []map[string]any require.NoError(t, json.Unmarshal(e.do(http.MethodGet, "/api/v1/music/list").Body.Bytes(), &list)) require.Len(t, list, 1) assert.Equal(t, song.Uuid.String(), list[0]["SongUuid"]) }