/**
* Unit tests for Spotify API wrapper error handling
* Tests error handling without making actual API calls
*/
import { describe, it, expect } from 'vitest';
describe('Spotify API Wrapper', () => {
describe('Error Handling', () => {
it('should handle 401 unauthorized errors', () => {
const error401 = {
response: {
status: 401,
data: {
error: {
message: 'The access token expired'
}
}
}
};
const expectedMessage = "Spotify Authentication Error: The access token expired. Try re-running 'npm run auth'.";
expect(error401.response.status).toBe(401);
expect(expectedMessage).toContain('npm run auth');
});
it('should handle 403 forbidden errors', () => {
const error403 = {
response: {
status: 403,
data: {
error: {
message: 'Player command failed: Premium required'
}
}
}
};
const expectedMessage = 'Spotify Forbidden: Player command failed: Premium required. This may require Spotify Premium or specific device settings.';
expect(error403.response.status).toBe(403);
expect(expectedMessage).toContain('Premium');
});
it('should handle 404 not found errors', () => {
const error404 = {
response: {
status: 404,
data: {
error: {
message: 'No active device found'
}
}
}
};
const expectedMessage = 'Spotify Not Found: No active device found. Is a device active and playing?';
expect(error404.response.status).toBe(404);
expect(expectedMessage).toContain('device active');
});
it('should handle 429 rate limit errors', () => {
const error429 = {
response: {
status: 429,
data: {
error: {
message: 'API rate limit exceeded'
}
}
}
};
const expectedMessage = 'Spotify Rate Limit: Too many requests. Please wait a moment.';
expect(error429.response.status).toBe(429);
expect(expectedMessage).toContain('Rate Limit');
});
it('should handle errors with missing error message', () => {
const errorNoMessage = {
response: {
status: 500,
data: {}
},
message: 'Network Error'
};
expect(errorNoMessage.response.status).toBe(500);
expect(errorNoMessage.message).toBeTruthy();
});
});
describe('API Request Construction', () => {
it('should construct GET request config correctly', () => {
const config = {
method: 'GET',
url: 'https://api.spotify.com/v1/me/player',
headers: {
'Authorization': 'Bearer test_token',
'Content-Type': 'application/json',
},
params: { market: 'US' }
};
expect(config.method).toBe('GET');
expect(config.url).toContain('/me/player');
expect(config.headers.Authorization).toContain('Bearer');
expect(config.params).toEqual({ market: 'US' });
});
it('should construct PUT request config correctly', () => {
const config = {
method: 'PUT',
url: 'https://api.spotify.com/v1/me/player/play',
headers: {
'Authorization': 'Bearer test_token',
'Content-Type': 'application/json',
},
data: { uris: ['spotify:track:123'] }
};
expect(config.method).toBe('PUT');
expect(config.url).toContain('/play');
expect(config.data).toHaveProperty('uris');
});
it('should construct POST request config correctly', () => {
const config = {
method: 'POST',
url: 'https://api.spotify.com/v1/me/player/next',
headers: {
'Authorization': 'Bearer test_token',
'Content-Type': 'application/json',
}
};
expect(config.method).toBe('POST');
expect(config.url).toContain('/next');
});
it('should construct DELETE request config correctly', () => {
const config = {
method: 'DELETE',
url: 'https://api.spotify.com/v1/me/tracks',
headers: {
'Authorization': 'Bearer test_token',
'Content-Type': 'application/json',
},
data: { ids: ['track123'] }
};
expect(config.method).toBe('DELETE');
expect(config.url).toContain('/tracks');
expect(config.data).toHaveProperty('ids');
});
});
describe('Base URL Construction', () => {
it('should use correct Spotify API base URL', () => {
const baseUrl = 'https://api.spotify.com/v1';
expect(baseUrl).toBe('https://api.spotify.com/v1');
});
it('should construct full endpoint URLs correctly', () => {
const baseUrl = 'https://api.spotify.com/v1';
const endpoints = [
'/me/player',
'/me/player/currently-playing',
'/me/player/play',
'/me/player/pause',
'/me/player/next',
'/me/player/previous',
'/me/player/queue',
'/search',
'/tracks/123',
'/albums/456',
'/artists/789',
];
endpoints.forEach(endpoint => {
const fullUrl = `${baseUrl}${endpoint}`;
expect(fullUrl).toContain('api.spotify.com/v1');
expect(fullUrl).toContain(endpoint);
});
});
});
});