Initial commit
This commit is contained in:
commit
02a6dabcfb
62 files changed
+15751
No files matched your search
@@ -0,0 +1,494 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils"
|
||||
)
|
||||
|
||||
// playlistResponse creates a JSON response for a playlist list
|
||||
func playlistResponse(playlists []map[string]any) []byte {
|
||||
resp := map[string]any{
|
||||
"result": playlists,
|
||||
}
|
||||
data, _ := json.Marshal(resp)
|
||||
return data
|
||||
}
|
||||
|
||||
// singlePlaylistResponse creates a JSON response for a single playlist
|
||||
func singlePlaylistResponse(playlist map[string]any) []byte {
|
||||
resp := map[string]any{
|
||||
"result": playlist,
|
||||
}
|
||||
data, _ := json.Marshal(resp)
|
||||
return data
|
||||
}
|
||||
|
||||
// errorResponse creates an error JSON response
|
||||
func errorResponse(errMsg string) []byte {
|
||||
resp := map[string]any{
|
||||
"error": errMsg,
|
||||
}
|
||||
data, _ := json.Marshal(resp)
|
||||
return data
|
||||
}
|
||||
|
||||
func TestClient_GetPlaylists(t *testing.T) {
|
||||
// Sample playlist data
|
||||
playlists := []map[string]any{
|
||||
{
|
||||
"kind": 1,
|
||||
"title": "Playlist 1",
|
||||
"description": "First playlist",
|
||||
"cover_uri": "https://example.com/cover1.jpg",
|
||||
"created": "2023-01-01T00:00:00+03:00",
|
||||
"modified": "2023-01-02T00:00:00+03:00",
|
||||
"track_count": 10,
|
||||
"duration_ms": 1800000,
|
||||
"likes_count": 5,
|
||||
"is_public": true,
|
||||
"revision": 1,
|
||||
"uuid": "uuid-1",
|
||||
"tags": []string{"rock", "pop"},
|
||||
"access_type": "full",
|
||||
"available": true,
|
||||
"content_warning": "",
|
||||
"genre": "rock",
|
||||
"owner_uid": 12345,
|
||||
"shared": false,
|
||||
"snapshot_id": "snap-1",
|
||||
"owner": map[string]any{
|
||||
"uid": 12345,
|
||||
"login": "user1",
|
||||
"display_name": "User One",
|
||||
"cover_uri": "https://example.com/user1.jpg",
|
||||
"sex": "m",
|
||||
"public_playlists": 10,
|
||||
"followers_count": 100,
|
||||
"followings_count": 50,
|
||||
"has_playlists": true,
|
||||
"available": true,
|
||||
},
|
||||
"tracks": []any{},
|
||||
"similar_playlists": []any{},
|
||||
},
|
||||
{
|
||||
"kind": 2,
|
||||
"title": "Playlist 2",
|
||||
"description": "Second playlist",
|
||||
"cover_uri": "https://example.com/cover2.jpg",
|
||||
"created": "2023-02-01T00:00:00+03:00",
|
||||
"modified": "2023-02-02T00:00:00+03:00",
|
||||
"track_count": 5,
|
||||
"duration_ms": 900000,
|
||||
"likes_count": 3,
|
||||
"is_public": false,
|
||||
"revision": 2,
|
||||
"uuid": "uuid-2",
|
||||
"tags": []string{"jazz"},
|
||||
"access_type": "full",
|
||||
"available": true,
|
||||
"content_warning": "",
|
||||
"genre": "jazz",
|
||||
"owner_uid": 12345,
|
||||
"shared": false,
|
||||
"snapshot_id": "snap-2",
|
||||
"owner": map[string]any{
|
||||
"uid": 12345,
|
||||
"login": "user1",
|
||||
"display_name": "User One",
|
||||
"cover_uri": "https://example.com/user1.jpg",
|
||||
"sex": "m",
|
||||
"public_playlists": 10,
|
||||
"followers_count": 100,
|
||||
"followings_count": 50,
|
||||
"has_playlists": true,
|
||||
"available": true,
|
||||
},
|
||||
"tracks": []any{},
|
||||
"similar_playlists": []any{},
|
||||
},
|
||||
}
|
||||
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/playlists" {
|
||||
t.Errorf("Expected path /playlists, got %s", r.URL.Path)
|
||||
}
|
||||
if r.URL.Query().Get("kinds") != "1,2" {
|
||||
t.Errorf("Expected kinds=1,2, got %s", r.URL.Query().Get("kinds"))
|
||||
}
|
||||
if r.Header.Get("Authorization") != "OAuth test-token" {
|
||||
t.Errorf("Expected Authorization header, got %s", r.Header.Get("Authorization"))
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(playlistResponse(playlists))
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
result, err := client.GetPlaylists(context.Background(), []int{1, 2})
|
||||
if err != nil {
|
||||
t.Fatalf("GetPlaylists failed: %v", err)
|
||||
}
|
||||
|
||||
if len(result) != 2 {
|
||||
t.Fatalf("Expected 2 playlists, got %d", len(result))
|
||||
}
|
||||
|
||||
if result[0].Kind != 1 {
|
||||
t.Errorf("Expected first playlist kind 1, got %d", result[0].Kind)
|
||||
}
|
||||
if result[0].Title != "Playlist 1" {
|
||||
t.Errorf("Expected first playlist title 'Playlist 1', got '%s'", result[0].Title)
|
||||
}
|
||||
if result[0].Description != "First playlist" {
|
||||
t.Errorf("Expected first playlist description 'First playlist', got '%s'", result[0].Description)
|
||||
}
|
||||
if result[0].TrackCount != 10 {
|
||||
t.Errorf("Expected first playlist track_count 10, got %d", result[0].TrackCount)
|
||||
}
|
||||
if result[0].Owner == nil || result[0].Owner.UID != 12345 {
|
||||
t.Errorf("Expected owner UID 12345")
|
||||
}
|
||||
if result[0].Owner.Login != "user1" {
|
||||
t.Errorf("Expected owner login 'user1', got '%s'", result[0].Owner.Login)
|
||||
}
|
||||
|
||||
if result[1].Kind != 2 {
|
||||
t.Errorf("Expected second playlist kind 2, got %d", result[1].Kind)
|
||||
}
|
||||
if result[1].Title != "Playlist 2" {
|
||||
t.Errorf("Expected second playlist title 'Playlist 2', got '%s'", result[1].Title)
|
||||
}
|
||||
if result[1].IsPublic != false {
|
||||
t.Errorf("Expected second playlist is_public false, got %v", result[1].IsPublic)
|
||||
}
|
||||
|
||||
// Verify client is set on playlists
|
||||
for _, p := range result {
|
||||
if p.GetClient() != client {
|
||||
t.Error("Expected client to be set on playlist")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_GetPlaylists_Empty(t *testing.T) {
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Error("Server should not be called for empty kinds")
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
result, err := client.GetPlaylists(context.Background(), []int{})
|
||||
if err != nil {
|
||||
t.Fatalf("GetPlaylists failed: %v", err)
|
||||
}
|
||||
if result != nil {
|
||||
t.Errorf("Expected nil for empty kinds, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_GetPlaylist(t *testing.T) {
|
||||
playlist := map[string]any{
|
||||
"kind": 42,
|
||||
"title": "My Playlist",
|
||||
"description": "A test playlist",
|
||||
"cover_uri": "https://example.com/cover.jpg",
|
||||
"created": "2023-01-01T00:00:00+03:00",
|
||||
"modified": "2023-01-02T00:00:00+03:00",
|
||||
"track_count": 15,
|
||||
"duration_ms": 2700000,
|
||||
"likes_count": 10,
|
||||
"is_public": true,
|
||||
"revision": 5,
|
||||
"uuid": "uuid-42",
|
||||
"tags": []string{"rock", "metal"},
|
||||
"access_type": "full",
|
||||
"available": true,
|
||||
"content_warning": "",
|
||||
"genre": "rock",
|
||||
"owner_uid": 999,
|
||||
"shared": false,
|
||||
"snapshot_id": "snap-42",
|
||||
"owner": map[string]any{
|
||||
"uid": 999,
|
||||
"login": "testuser",
|
||||
"display_name": "Test User",
|
||||
"cover_uri": "https://example.com/user.jpg",
|
||||
"sex": "f",
|
||||
"public_playlists": 5,
|
||||
"followers_count": 200,
|
||||
"followings_count": 100,
|
||||
"has_playlists": true,
|
||||
"available": true,
|
||||
},
|
||||
"tracks": []any{},
|
||||
"similar_playlists": []any{},
|
||||
}
|
||||
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/playlists" {
|
||||
t.Errorf("Expected path /playlists, got %s", r.URL.Path)
|
||||
}
|
||||
if r.URL.Query().Get("kinds") != "42" {
|
||||
t.Errorf("Expected kinds=42, got %s", r.URL.Query().Get("kinds"))
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(playlistResponse([]map[string]any{playlist}))
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
result, err := client.GetPlaylist(context.Background(), 42)
|
||||
if err != nil {
|
||||
t.Fatalf("GetPlaylist failed: %v", err)
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
t.Fatal("Expected playlist, got nil")
|
||||
}
|
||||
|
||||
if result.Kind != 42 {
|
||||
t.Errorf("Expected kind 42, got %d", result.Kind)
|
||||
}
|
||||
if result.Title != "My Playlist" {
|
||||
t.Errorf("Expected title 'My Playlist', got '%s'", result.Title)
|
||||
}
|
||||
if result.Description != "A test playlist" {
|
||||
t.Errorf("Expected description 'A test playlist', got '%s'", result.Description)
|
||||
}
|
||||
if result.TrackCount != 15 {
|
||||
t.Errorf("Expected track_count 15, got %d", result.TrackCount)
|
||||
}
|
||||
if result.Revision != 5 {
|
||||
t.Errorf("Expected revision 5, got %d", result.Revision)
|
||||
}
|
||||
if result.Owner == nil || result.Owner.Login != "testuser" {
|
||||
t.Errorf("Expected owner login 'testuser'")
|
||||
}
|
||||
if result.GetClient() != client {
|
||||
t.Error("Expected client to be set on playlist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_GetPlaylist_NotFound(t *testing.T) {
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(playlistResponse([]map[string]any{}))
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
result, err := client.GetPlaylist(context.Background(), 999)
|
||||
if err == nil {
|
||||
t.Fatal("Expected error for not found playlist")
|
||||
}
|
||||
if result != nil {
|
||||
t.Errorf("Expected nil playlist, got %v", result)
|
||||
}
|
||||
// Check that it's a not found error
|
||||
if err.Error() != "playlist not found" && err.Error() != "playlist not found: not found" {
|
||||
t.Errorf("Expected 'playlist not found' error, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_GetPlaylist_Error(t *testing.T) {
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(errorResponse("Internal server error"))
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
_, err := client.GetPlaylist(context.Background(), 1)
|
||||
if err == nil {
|
||||
t.Fatal("Expected error")
|
||||
}
|
||||
if err.Error() == "" {
|
||||
t.Errorf("Expected non-empty error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_CreatePlaylist(t *testing.T) {
|
||||
createdPlaylist := map[string]any{
|
||||
"kind": 100,
|
||||
"title": "New Playlist",
|
||||
"description": "",
|
||||
"cover_uri": "",
|
||||
"created": "2024-01-01T00:00:00+03:00",
|
||||
"modified": "2024-01-01T00:00:00+03:00",
|
||||
"track_count": 0,
|
||||
"duration_ms": 0,
|
||||
"likes_count": 0,
|
||||
"is_public": true,
|
||||
"revision": 1,
|
||||
"uuid": "new-uuid-100",
|
||||
"tags": []any{},
|
||||
"access_type": "full",
|
||||
"available": true,
|
||||
"content_warning": "",
|
||||
"genre": "",
|
||||
"owner_uid": 12345,
|
||||
"shared": false,
|
||||
"snapshot_id": "snap-new-100",
|
||||
"owner": map[string]any{
|
||||
"uid": 12345,
|
||||
"login": "me",
|
||||
"display_name": "Me",
|
||||
"cover_uri": "",
|
||||
"sex": "",
|
||||
"public_playlists": 1,
|
||||
"followers_count": 0,
|
||||
"followings_count": 0,
|
||||
"has_playlists": true,
|
||||
"available": true,
|
||||
},
|
||||
"tracks": []any{},
|
||||
"similar_playlists": []any{},
|
||||
}
|
||||
|
||||
var capturedBody map[string]any
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
t.Errorf("Expected POST method, got %s", r.Method)
|
||||
}
|
||||
if r.URL.Path != "/users/me/playlists" {
|
||||
t.Errorf("Expected path /users/me/playlists, got %s", r.URL.Path)
|
||||
}
|
||||
// Read and parse request body
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
if err := decoder.Decode(&capturedBody); err != nil {
|
||||
t.Errorf("Failed to decode request body: %v", err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(singlePlaylistResponse(createdPlaylist))
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
result, err := client.CreatePlaylist(context.Background(), "New Playlist", "public")
|
||||
if err != nil {
|
||||
t.Fatalf("CreatePlaylist failed: %v", err)
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
t.Fatal("Expected playlist, got nil")
|
||||
}
|
||||
|
||||
if result.Kind != 100 {
|
||||
t.Errorf("Expected kind 100, got %d", result.Kind)
|
||||
}
|
||||
if result.Title != "New Playlist" {
|
||||
t.Errorf("Expected title 'New Playlist', got '%s'", result.Title)
|
||||
}
|
||||
if result.IsPublic != true {
|
||||
t.Errorf("Expected is_public true, got %v", result.IsPublic)
|
||||
}
|
||||
if result.GetClient() != client {
|
||||
t.Error("Expected client to be set on playlist")
|
||||
}
|
||||
|
||||
// Verify the request body
|
||||
if capturedBody == nil {
|
||||
t.Fatal("Request body not captured")
|
||||
}
|
||||
if capturedBody["title"] != "New Playlist" {
|
||||
t.Errorf("Expected title 'New Playlist' in body, got %v", capturedBody["title"])
|
||||
}
|
||||
if capturedBody["visibility"] != "public" {
|
||||
t.Errorf("Expected visibility 'public' in body, got %v", capturedBody["visibility"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_CreatePlaylist_Private(t *testing.T) {
|
||||
createdPlaylist := map[string]any{
|
||||
"kind": 101,
|
||||
"title": "Private Playlist",
|
||||
"description": "",
|
||||
"cover_uri": "",
|
||||
"created": "2024-01-01T00:00:00+03:00",
|
||||
"modified": "2024-01-01T00:00:00+03:00",
|
||||
"track_count": 0,
|
||||
"duration_ms": 0,
|
||||
"likes_count": 0,
|
||||
"is_public": false,
|
||||
"revision": 1,
|
||||
"uuid": "new-uuid-101",
|
||||
"tags": []any{},
|
||||
"access_type": "full",
|
||||
"available": true,
|
||||
"content_warning": "",
|
||||
"genre": "",
|
||||
"owner_uid": 12345,
|
||||
"shared": false,
|
||||
"snapshot_id": "snap-new-101",
|
||||
"owner": map[string]any{
|
||||
"uid": 12345,
|
||||
"login": "me",
|
||||
"display_name": "Me",
|
||||
"cover_uri": "",
|
||||
"sex": "",
|
||||
"public_playlists": 1,
|
||||
"followers_count": 0,
|
||||
"followings_count": 0,
|
||||
"has_playlists": true,
|
||||
"available": true,
|
||||
},
|
||||
"tracks": []any{},
|
||||
"similar_playlists": []any{},
|
||||
}
|
||||
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(singlePlaylistResponse(createdPlaylist))
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
result, err := client.CreatePlaylist(context.Background(), "Private Playlist", "private")
|
||||
if err != nil {
|
||||
t.Fatalf("CreatePlaylist failed: %v", err)
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
t.Fatal("Expected playlist, got nil")
|
||||
}
|
||||
|
||||
if result.Title != "Private Playlist" {
|
||||
t.Errorf("Expected title 'Private Playlist', got '%s'", result.Title)
|
||||
}
|
||||
if result.IsPublic != false {
|
||||
t.Errorf("Expected is_public false for private playlist, got %v", result.IsPublic)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_CreatePlaylist_Error(t *testing.T) {
|
||||
server := testServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(errorResponse("unauthorized"))
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
client := newTestClient(server.URL)
|
||||
|
||||
_, err := client.CreatePlaylist(context.Background(), "Test", "public")
|
||||
if err == nil {
|
||||
t.Fatal("Expected error")
|
||||
}
|
||||
// Check that it's an unauthorized error
|
||||
if !utils.IsUnauthorizedError(err) {
|
||||
t.Errorf("Expected unauthorized error, got: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user