├── .coveralls ├── .eslintrc.json ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── build.yaml │ └── docs.yaml ├── .gitignore ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── __test__ ├── fixtures.js ├── fixtures │ ├── album.json │ ├── album_tracks.json │ ├── albums.json │ ├── artist.json │ ├── artist_albums.json │ ├── artist_albums_limit_2.json │ ├── artist_related_artists.json │ ├── artist_top_tracks.json │ ├── artists.json │ ├── available_devices.json │ ├── browse_categories.json │ ├── category.json │ ├── category_playlists.json │ ├── current_playback.json │ ├── current_playing_track.json │ ├── episode.json │ ├── episodes.json │ ├── error_id_not_found.json │ ├── featured_playlists.json │ ├── follow_are_following_playlist.json │ ├── follow_is_following_artists.json │ ├── follow_is_following_users.json │ ├── followed_artists.json │ ├── genre_seeds.json │ ├── me.json │ ├── new_releases.json │ ├── playlist.json │ ├── playlist_cover_image.json │ ├── playlist_tracks.json │ ├── recently_played_tracks.json │ ├── recommendations.json │ ├── search.json │ ├── search_album.json │ ├── search_artist.json │ ├── search_episode.json │ ├── search_playlist.json │ ├── search_show.json │ ├── search_track.json │ ├── show.json │ ├── show_episodes.json │ ├── shows.json │ ├── track.json │ ├── track_audio_analysis.json │ ├── track_audio_features.json │ ├── tracks.json │ ├── tracks_audio_features.json │ ├── user.json │ ├── user_new_playlist.json │ ├── user_playlists.json │ ├── user_saved_albums.json │ ├── user_saved_shows.json │ ├── user_saved_tracks.json │ ├── user_top_artists.json │ └── user_top_tracks.json └── spotify-web-api.spec.js ├── package-lock.json ├── package.json ├── src ├── spotify-web-api.js └── typings │ ├── spotify-api-tests.ts │ ├── spotify-api.d.ts │ └── spotify-web-api.d.ts └── typings-example.gif /.coveralls: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | repo_token: 4i5ziqSIpZOQF4fp1EjzJjkTGoeg0lZhC 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true 4 | }, 5 | "extends": ["prettier"], 6 | "rules": { 7 | "brace-style": [2, "1tbs"], 8 | "comma-style": [2, "last"], 9 | "camelcase": 0, 10 | "curly": 2, 11 | "default-case": 2, 12 | "eqeqeq": 2, 13 | "guard-for-in": 2, 14 | "indent": [2, 2], 15 | "keyword-spacing": ["error", { "before": true }], 16 | "new-cap": 0, 17 | "no-console": 0, 18 | "no-debugger": 2, 19 | "no-empty": 2, 20 | "no-floating-decimal": 2, 21 | "no-nested-ternary": 2, 22 | "no-undefined": 2, 23 | "no-underscore-dangle": 0, 24 | "no-unreachable": 2, 25 | "radix": 2, 26 | "quotes": [2, "single"], 27 | "space-before-blocks": 2, 28 | "spaced-comment": [2, "always", { "exceptions": ["-"] }], 29 | "strict": [2, "global"], 30 | "valid-jsdoc": [2], 31 | "wrap-iife": [2, "any"] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [JMPerez] 4 | custom: ['https://www.buymeacoffee.com/jmp'] 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Run code '...' 16 | 2. See error 17 | 18 | **Expected behavior** 19 | A clear and concise description of what you expected to happen. 20 | 21 | **Screenshots** 22 | If applicable, add screenshots to help explain your problem. 23 | 24 | **Desktop (please complete the following information):** 25 | - OS: [e.g. iOS] 26 | - Browser [e.g. chrome, safari] 27 | - Version [e.g. 22] 28 | 29 | **Smartphone (please complete the following information):** 30 | - Device: [e.g. iPhone6] 31 | - OS: [e.g. iOS8.1] 32 | - Browser [e.g. stock browser, safari] 33 | - Version [e.g. 22] 34 | 35 | **Additional context** 36 | Add any other context about the problem here. 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: '12.x' 19 | - name: Install dependencies 20 | run: npm install 21 | - name: Build library and test 22 | run: npm test 23 | env: 24 | CI: true 25 | -------------------------------------------------------------------------------- /.github/workflows/docs.yaml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Use Node.js 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: '12.x' 17 | - name: Install dependencies 18 | run: npm install 19 | - name: Build docs 20 | run: npm run docs 21 | - name: Deploy to GitHub Pages 22 | if: success() 23 | uses: crazy-max/ghaction-github-pages@v2 24 | with: 25 | target_branch: gh-pages 26 | build_dir: docs 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .eslintcache 2 | coverage 3 | node_modules 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Feel free to send your PR to fix any bug or add new functionality! 4 | Follow these steps: 5 | 6 | 1. Fork the repository. 7 | 2. Make the changes. Follow the coding standards define in the ESLint configuration 8 | file. 9 | 3. Remember to add tests. Have a look at the `__tests__` folder to see the test 10 | suite covering the code. Want to run the tests? Run `npm test`. You will also get a code coverage report for free. 11 | 4. Send a Pull Request. 12 | 13 | # Releasing a new version 14 | 15 | 1. Update npm module version in the `package.json` file, using `npm version` 16 | 2. Push with tags: `git push --follow-tags` 17 | 3. Draft a new release 18 | 4. Publish a new npm package: `npm publish` 19 | 5. Profit 20 | 21 | Thanks for collaborating! 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 José Manuel Pérez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spotify Web API JS [![Build Status](https://travis-ci.org/JMPerez/spotify-web-api-js.svg?branch=master)](https://travis-ci.org/JMPerez/spotify-web-api-js) [![Coverage Status](https://coveralls.io/repos/JMPerez/spotify-web-api-js/badge.svg)](https://coveralls.io/r/JMPerez/spotify-web-api-js) [![Greenkeeper badge](https://badges.greenkeeper.io/JMPerez/spotify-web-api-js.svg)](https://greenkeeper.io/) 2 | 3 | This is a lightweight wrapper for the [Spotify Web API](https://developer.spotify.com/web-api/) ([2.6kB gzipped + compressed](https://cost-of-modules.herokuapp.com/result?p=spotify-web-api-js)). It includes helper functions for **all Spotify's endpoints**, such as fetching metadata (search and look-up of albums, artists, tracks, playlists, new releases, podcasts) and user's information (follow users, artists and playlists, and saved tracks management). 4 | 5 | It doesn't have any dependencies and supports callbacks and promises. It is intended to be run on a browser, but if you want to use Node.JS to make the requests, please check [spotify-web-api-node](https://github.com/thelinmichael/spotify-web-api-node). 6 | 7 | A list of selected wrappers for different languages and environments is available on the Developer site's [Libraries page](https://developer.spotify.com/web-api/code-examples/). 8 | 9 | The wrapper includes helper functions to do the following: 10 | 11 | #### Music and Podcast metadata 12 | 13 | - Albums, artists, tracks and playlists 14 | - Audio features and audio analysis for tracks 15 | - Albums for a specific artist 16 | - Top tracks for a specific artist 17 | - Artists similar to a specific artist 18 | - Shows and episodes (podcasts) 19 | 20 | #### Profiles 21 | 22 | - User's emails, product type, display name, birthdate, image 23 | 24 | #### Search 25 | 26 | - Albums, artists, tracks, playlists, shows, and episodes 27 | 28 | #### Playlist Management 29 | 30 | - Get a user's playlists 31 | - Create playlists 32 | - Change playlist details 33 | - Add tracks to a playlist 34 | - Remove tracks from a playlist 35 | - Replace tracks in a playlist 36 | - Reorder tracks in a playlist 37 | - Upload custom playlist cover image 38 | 39 | #### User's Library 40 | 41 | - Add, remove, and get tracks on a user's library 42 | - Check if a track is in the signed in user's library 43 | - Add, remove, and get shows (podcasts) on a user's library 44 | 45 | #### Personalization 46 | 47 | - Get a user’s top artists and tracks based on calculated affinity 48 | - Get current user’s recently played tracks 49 | 50 | #### Browse 51 | 52 | - Get new releases 53 | - Get featured playlists 54 | - Get a list of categories 55 | - Get a category 56 | - Get a category's playlists 57 | - Get recommendations based on seeds 58 | - Get available genre seeds 59 | 60 | #### Follow 61 | 62 | - Follow and unfollow users 63 | - Follow and unfollow artists 64 | - Check if the logged in user follows a user or artist 65 | - Follow a playlist 66 | - Unfollow a playlist 67 | - Get followed artists 68 | - Check if users are following a Playlist 69 | 70 | #### Player 71 | 72 | - Get a user's available devices 73 | - Get information about the user's current playback 74 | - Get the user's currently playing track 75 | - Transfer a user's playback 76 | - Start/Resume a user's playback 77 | - Pause a user's playback 78 | - Skip user's playback to next track 79 | - Skip user's playback to previous track 80 | - Seek to position in currently playing track 81 | - Set repeat mode on user's playback 82 | - Set volume for user's playback 83 | - Toggle shuffle for user's playback 84 | - Queue a track or an episode 85 | 86 | ## Installation 87 | 88 | Install via node (since the requests are made using XMLHttpRequest, you will need a tool like Browserify to run this on a browser): 89 | 90 | $ npm install -S spotify-web-api-js 91 | 92 | Then, in your javascript file 93 | 94 | ```js 95 | var Spotify = require('spotify-web-api-js'); 96 | var s = new Spotify(); 97 | //s.searchTracks()... 98 | ``` 99 | 100 | or by making a copy of the `src/spotify-web-api.js` file 101 | 102 | ## Usage 103 | 104 | We recommend you have a look at the [documentation](https://jmperezperez.com/spotify-web-api-js/) to get an overview of the supported 105 | . 106 | 107 | The wrapper supports callback functions, as well as [Promises](http://www.html5rocks.com/en/tutorials/es6/promises/) (you can also use [a polyfill](https://github.com/jakearchibald/es6-promise)), and Promises/A+ libraries such as [Q](https://github.com/kriskowal/q) and [when](https://github.com/cujojs/when). 108 | 109 | First, instantiate the wrapper. 110 | 111 | ```js 112 | var spotifyApi = new SpotifyWebApi(); 113 | ``` 114 | 115 | If you have an access token, you can set it doing: 116 | 117 | ```js 118 | spotifyApi.setAccessToken(''); 119 | ``` 120 | 121 | When you set an access token, it will be used for signing your requests. An access token is required for all endpoints. 122 | 123 | If you want to use a Promises/A+ library, you can set it: 124 | 125 | ```js 126 | spotifyApi.setPromiseImplementation(Q); 127 | ``` 128 | 129 | Here you see how to get basic information using a function like `getArtistAlbums`: 130 | 131 | ```js 132 | // get Elvis' albums, passing a callback. When a callback is passed, no Promise is returned 133 | spotifyApi.getArtistAlbums('43ZHCT0cAZBISjO8DG9PnE', function (err, data) { 134 | if (err) console.error(err); 135 | else console.log('Artist albums', data); 136 | }); 137 | 138 | // get Elvis' albums, using Promises through Promise, Q or when 139 | spotifyApi.getArtistAlbums('43ZHCT0cAZBISjO8DG9PnE').then( 140 | function (data) { 141 | console.log('Artist albums', data); 142 | }, 143 | function (err) { 144 | console.error(err); 145 | } 146 | ); 147 | ``` 148 | 149 | The promises also expose an `abort` method that aborts the XMLHttpRequest. This is useful to cancel 150 | requests that were made earlier and could be resolved out-of-sync: 151 | 152 | ```js 153 | var prev = null; 154 | 155 | function onUserInput(queryTerm) { 156 | // abort previous request, if any 157 | if (prev !== null) { 158 | prev.abort(); 159 | } 160 | 161 | // store the current promise in case we need to abort it 162 | prev = spotifyApi.searchTracks(queryTerm, { limit: 5 }); 163 | prev.then( 164 | function (data) { 165 | // clean the promise so it doesn't call abort 166 | prev = null; 167 | 168 | // ...render list of search results... 169 | }, 170 | function (err) { 171 | console.error(err); 172 | } 173 | ); 174 | } 175 | ``` 176 | 177 | The functions that fetch data from the API support also an optional JSON object with a set of options, such as the ones regarding pagination. These options will be sent as query parameters: 178 | 179 | ```js 180 | // passing a callback - get Elvis' albums in range [20...29] 181 | spotifyApi.getArtistAlbums( 182 | '43ZHCT0cAZBISjO8DG9PnE', 183 | { limit: 10, offset: 20 }, 184 | function (err, data) { 185 | if (err) console.error(err); 186 | else console.log('Artist albums', data); 187 | } 188 | ); 189 | 190 | // using Promises through Promise, Q or when - get Elvis' albums in range [20...29] 191 | spotifyApi 192 | .getArtistAlbums('43ZHCT0cAZBISjO8DG9PnE', { limit: 10, offset: 20 }) 193 | .then( 194 | function (data) { 195 | console.log('Album information', data); 196 | }, 197 | function (err) { 198 | console.error(err); 199 | } 200 | ); 201 | ``` 202 | 203 | ### More examples 204 | 205 | _Note: The following examples use Promises/Q/when as the return object._ 206 | 207 | Here you can see more examples of the usage of this wrapper: 208 | 209 | ```js 210 | // get multiple albums 211 | spotifyApi.getAlbums(['5U4W9E5WsYb2jUQWePT8Xm', '3KyVcddATClQKIdtaap4bV']).then( 212 | function (data) { 213 | console.log('Albums information', data); 214 | }, 215 | function (err) { 216 | console.error(err); 217 | } 218 | ); 219 | 220 | // get an artists 221 | spotifyApi.getArtist('2hazSY4Ef3aB9ATXW7F5w3').then( 222 | function (data) { 223 | console.log('Artist information', data); 224 | }, 225 | function (err) { 226 | console.error(err); 227 | } 228 | ); 229 | 230 | // get multiple artists 231 | spotifyApi 232 | .getArtists(['2hazSY4Ef3aB9ATXW7F5w3', '6J6yx1t3nwIDyPXk5xa7O8']) 233 | .then( 234 | function (data) { 235 | console.log('Artists information', data); 236 | }, 237 | function (err) { 238 | console.error(err); 239 | } 240 | ); 241 | 242 | // get albums by a certain artist 243 | spotifyApi.getArtistAlbums('43ZHCT0cAZBISjO8DG9PnE').then( 244 | function (data) { 245 | console.log('Artist albums', data); 246 | }, 247 | function (err) { 248 | console.error(err); 249 | } 250 | ); 251 | 252 | // search tracks whose name, album or artist contains 'Love' 253 | spotifyApi.searchTracks('Love').then( 254 | function (data) { 255 | console.log('Search by "Love"', data); 256 | }, 257 | function (err) { 258 | console.error(err); 259 | } 260 | ); 261 | 262 | // search artists whose name contains 'Love' 263 | spotifyApi.searchArtists('Love').then( 264 | function (data) { 265 | console.log('Search artists by "Love"', data); 266 | }, 267 | function (err) { 268 | console.error(err); 269 | } 270 | ); 271 | 272 | // search tracks whose artist's name contains 'Love' 273 | spotifyApi.searchTracks('artist:Love').then( 274 | function (data) { 275 | console.log('Search tracks by "Love" in the artist name', data); 276 | }, 277 | function (err) { 278 | console.error(err); 279 | } 280 | ); 281 | ``` 282 | 283 | ### Nesting calls 284 | 285 | When you need to make multiple calls to get some dataset, you can take advantage of the Promises to get a cleaner code: 286 | 287 | ```js 288 | // track detail information for album tracks 289 | spotifyApi 290 | .getAlbum('5U4W9E5WsYb2jUQWePT8Xm') 291 | .then(function (data) { 292 | return data.tracks.map(function (t) { 293 | return t.id; 294 | }); 295 | }) 296 | .then(function (trackIds) { 297 | return spotifyApi.getTracks(trackIds); 298 | }) 299 | .then(function (tracksInfo) { 300 | console.log(tracksInfo); 301 | }) 302 | .catch(function (error) { 303 | console.error(error); 304 | }); 305 | 306 | // album detail for the first 10 Elvis' albums 307 | spotifyApi 308 | .getArtistAlbums('43ZHCT0cAZBISjO8DG9PnE', { limit: 10 }) 309 | .then(function (data) { 310 | return data.albums.map(function (a) { 311 | return a.id; 312 | }); 313 | }) 314 | .then(function (albums) { 315 | return spotifyApi.getAlbums(albums); 316 | }) 317 | .then(function (data) { 318 | console.log(data); 319 | }); 320 | ``` 321 | 322 | ### Getting user's information 323 | 324 | In order to get user's information you need to request a user-signed access token, from either the Implicit Grant or Authorization Code flow. Say for instance you want to get user's playlists. Once you get an access token, set it and fetch the data: 325 | 326 | ```js 327 | // get an access token 328 | ... 329 | 330 | // set it in the wrapper 331 | var spotifyApi = new SpotifyWebApi(); 332 | spotifyApi.setAccessToken(''); 333 | spotifyApi.getUserPlaylists('jmperezperez') 334 | .then(function(data) { 335 | console.log('User playlists', data); 336 | }, function(err) { 337 | console.error(err); 338 | }); 339 | 340 | spotifyApi.getPlaylist('4vHIKV7j4QcZwgzGQcZg1x') 341 | .then(function(data) { 342 | console.log('User playlist', data); 343 | }, function(err) { 344 | console.error(err); 345 | }); 346 | ``` 347 | 348 | Some functions don't need to receive the user's id as a parameter, and will use the 349 | user's information from the access token: 350 | 351 | ```js 352 | var spotifyApi = new SpotifyWebApi(); 353 | spotifyApi.setAccessToken(''); 354 | spotifyApi 355 | .getUserPlaylists() // note that we don't pass a user id 356 | .then( 357 | function (data) { 358 | console.log('User playlists', data); 359 | }, 360 | function (err) { 361 | console.error(err); 362 | } 363 | ); 364 | ``` 365 | 366 | ## Integrated Typescript Typings 367 | 368 | Get great code completion for this package using the integrated typescript typings. It includes the complete typings of the Spotify Web Api too, so you'll know both how to the navigate the API as well as the response you are getting. 369 | 370 | ![Typings Example](https://raw.githubusercontent.com/JMPerez/spotify-web-api-js/master/typings-example.gif) 371 | 372 | ### When bundling the library 373 | 374 | If you are bundling spotify-web-api-js using e.g. webpack you can include the library and the typings into a typescript file like this: 375 | 376 | ```typescript 377 | import SpotifyWebApi from 'spotify-web-api-js'; 378 | 379 | let spotify = new SpotifyWebApi(); 380 | ``` 381 | 382 | ### When using the library globally 383 | 384 | If you are using the library globally, for example including directly from index.html, include the typings in the top of your typescript file. Typescript will then assume the library is already present globally. Adjust the path to `node_modules`. 385 | 386 | ```typescript 387 | /// 388 | 389 | let spotify = new SpotifyWebApi(); 390 | ``` 391 | 392 | ## Running tests 393 | 394 | In order to run the tests, run: 395 | 396 | $ npm test 397 | 398 | If you want to check out the coverage, run: 399 | 400 | $ npm run test:coverage 401 | -------------------------------------------------------------------------------- /__test__/fixtures.js: -------------------------------------------------------------------------------- 1 | /* global module */ 2 | 'use strict'; 3 | 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | 7 | function loadFixture(fixtureName) { 8 | return fs.readFileSync( 9 | path.join(__dirname, 'fixtures/' + fixtureName + '.json'), 10 | 'UTF8' 11 | ); 12 | } 13 | 14 | module.exports = { 15 | track: loadFixture('track'), 16 | tracks: loadFixture('tracks'), 17 | track_audio_features: loadFixture('track_audio_features'), 18 | tracks_audio_features: loadFixture('tracks_audio_features'), 19 | track_audio_analysis: loadFixture('track_audio_analysis'), 20 | album: loadFixture('album'), 21 | album_tracks: loadFixture('album_tracks'), 22 | albums: loadFixture('albums'), 23 | artist: loadFixture('artist'), 24 | artists: loadFixture('artists'), 25 | artist_albums: loadFixture('artist_albums'), 26 | artist_albums_limit_2: loadFixture('artist_albums_limit_2'), 27 | artist_related_artists: loadFixture('artist_related_artists'), 28 | artist_top_tracks: loadFixture('artist_top_tracks'), 29 | search: loadFixture('search'), 30 | search_album: loadFixture('search_album'), 31 | search_artist: loadFixture('search_artist'), 32 | search_track: loadFixture('search_track'), 33 | search_playlist: loadFixture('search_playlist'), 34 | search_show: loadFixture('search_show'), 35 | search_episode: loadFixture('search_episode'), 36 | user: loadFixture('user'), 37 | me: loadFixture('me'), 38 | user_playlists: loadFixture('user_playlists'), 39 | user_new_playlist: loadFixture('user_new_playlist'), 40 | user_saved_tracks: loadFixture('user_saved_tracks'), 41 | user_saved_albums: loadFixture('user_saved_albums'), 42 | user_saved_shows: loadFixture('user_saved_shows'), 43 | user_top_artists: loadFixture('user_top_artists'), 44 | user_top_tracks: loadFixture('user_top_tracks'), 45 | playlist: loadFixture('playlist'), 46 | playlist_tracks: loadFixture('playlist_tracks'), 47 | playlist_cover_image: loadFixture('playlist_cover_image'), 48 | featured_playlists: loadFixture('featured_playlists'), 49 | browse_categories: loadFixture('browse_categories'), 50 | category: loadFixture('category'), 51 | category_playlists: loadFixture('category_playlists'), 52 | new_releases: loadFixture('new_releases'), 53 | follow_is_following_users: loadFixture('follow_is_following_users'), 54 | follow_is_following_artists: loadFixture('follow_is_following_artists'), 55 | follow_are_following_playlist: loadFixture('follow_are_following_playlist'), 56 | followed_artists: loadFixture('followed_artists'), 57 | recommendations: loadFixture('recommendations'), 58 | genre_seeds: loadFixture('genre_seeds'), 59 | recently_played_tracks: loadFixture('recently_played_tracks'), 60 | available_devices: loadFixture('available_devices'), 61 | current_playback: loadFixture('current_playback'), 62 | current_playing_track: loadFixture('current_playing_track'), 63 | show: loadFixture('show'), 64 | shows: loadFixture('shows'), 65 | show_episodes: loadFixture('show_episodes'), 66 | episode: loadFixture('episode'), 67 | episodes: loadFixture('episodes') 68 | }; 69 | -------------------------------------------------------------------------------- /__test__/fixtures/album.json: -------------------------------------------------------------------------------- 1 | { 2 | "album_type": "album", 3 | "artists": [ 4 | { 5 | "external_urls": { 6 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 7 | }, 8 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 9 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 10 | "name": "Cyndi Lauper", 11 | "type": "artist", 12 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 13 | } 14 | ], 15 | "available_markets": [ 16 | "AD", 17 | "AR", 18 | "AT", 19 | "AU", 20 | "BE", 21 | "BG", 22 | "BO", 23 | "BR", 24 | "CA", 25 | "CH", 26 | "CL", 27 | "CO", 28 | "CR", 29 | "CY", 30 | "CZ", 31 | "DE", 32 | "DK", 33 | "DO", 34 | "EC", 35 | "EE", 36 | "ES", 37 | "FI", 38 | "FR", 39 | "GB", 40 | "GR", 41 | "GT", 42 | "HK", 43 | "HN", 44 | "HU", 45 | "IE", 46 | "IS", 47 | "IT", 48 | "LI", 49 | "LT", 50 | "LU", 51 | "LV", 52 | "MC", 53 | "MT", 54 | "MX", 55 | "MY", 56 | "NI", 57 | "NL", 58 | "NO", 59 | "NZ", 60 | "PA", 61 | "PE", 62 | "PH", 63 | "PT", 64 | "PY", 65 | "RO", 66 | "SE", 67 | "SG", 68 | "SI", 69 | "SK", 70 | "SV", 71 | "TW", 72 | "UY" 73 | ], 74 | "external_ids": { 75 | "upc": "5099749994324" 76 | }, 77 | "external_urls": { 78 | "spotify": "https://open.spotify.com/album/0sNOF9WDwhWunNAHPD3Baj" 79 | }, 80 | "genres": [], 81 | "href": "https://api.spotify.com/v1/albums/0sNOF9WDwhWunNAHPD3Baj", 82 | "id": "0sNOF9WDwhWunNAHPD3Baj", 83 | "images": [ 84 | { 85 | "height": 640, 86 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/07c323340e03e25a8e5dd5b9a8ec72b69c50089d", 87 | "width": 640 88 | }, 89 | { 90 | "height": 300, 91 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8b662d81966a0ec40dc10563807696a8479cd48b", 92 | "width": 300 93 | }, 94 | { 95 | "height": 64, 96 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/54b3222c8aaa77890d1ac37b3aaaa1fc9ba630ae", 97 | "width": 64 98 | } 99 | ], 100 | "name": "She's So Unusual", 101 | "popularity": 38, 102 | "release_date": { 103 | "day": null, 104 | "month": null, 105 | "year": 1983 106 | }, 107 | "tracks": { 108 | "href": "https://api.spotify.com/v1/albums/0sNOF9WDwhWunNAHPD3Baj/tracks?offset=0&limit=50", 109 | "items": [ 110 | { 111 | "artists": [ 112 | { 113 | "external_urls": { 114 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 115 | }, 116 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 117 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 118 | "name": "Cyndi Lauper", 119 | "type": "artist", 120 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 121 | } 122 | ], 123 | "disc_number": 1, 124 | "duration_ms": 305560, 125 | "explicit": false, 126 | "external_urls": { 127 | "spotify": "https://open.spotify.com/track/3f9zqUnrnIq0LANhmnaF0V" 128 | }, 129 | "href": "https://api.spotify.com/v1/tracks/3f9zqUnrnIq0LANhmnaF0V", 130 | "id": "3f9zqUnrnIq0LANhmnaF0V", 131 | "name": "Money Changes Everything", 132 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/01bb2a6c9a89c05a4300aea427241b1719a26b06", 133 | "track_number": 1, 134 | "type": "track", 135 | "uri": "spotify:track:3f9zqUnrnIq0LANhmnaF0V" 136 | }, 137 | { 138 | "artists": [ 139 | { 140 | "external_urls": { 141 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 142 | }, 143 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 144 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 145 | "name": "Cyndi Lauper", 146 | "type": "artist", 147 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 148 | } 149 | ], 150 | "disc_number": 1, 151 | "duration_ms": 238266, 152 | "explicit": false, 153 | "external_urls": { 154 | "spotify": "https://open.spotify.com/track/2joHDtKFVDDyWDHnOxZMAX" 155 | }, 156 | "href": "https://api.spotify.com/v1/tracks/2joHDtKFVDDyWDHnOxZMAX", 157 | "id": "2joHDtKFVDDyWDHnOxZMAX", 158 | "name": "Girls Just Want to Have Fun", 159 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/4fb5dfb0f1d60d23d1072548847e26906951ead9", 160 | "track_number": 2, 161 | "type": "track", 162 | "uri": "spotify:track:2joHDtKFVDDyWDHnOxZMAX" 163 | }, 164 | { 165 | "artists": [ 166 | { 167 | "external_urls": { 168 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 169 | }, 170 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 171 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 172 | "name": "Cyndi Lauper", 173 | "type": "artist", 174 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 175 | } 176 | ], 177 | "disc_number": 1, 178 | "duration_ms": 306706, 179 | "explicit": false, 180 | "external_urls": { 181 | "spotify": "https://open.spotify.com/track/6ClztHzretmPHCeiNqR5wD" 182 | }, 183 | "href": "https://api.spotify.com/v1/tracks/6ClztHzretmPHCeiNqR5wD", 184 | "id": "6ClztHzretmPHCeiNqR5wD", 185 | "name": "When You Were Mine", 186 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/7ce74522fabed32d7310084541bf38f906bb33bc", 187 | "track_number": 3, 188 | "type": "track", 189 | "uri": "spotify:track:6ClztHzretmPHCeiNqR5wD" 190 | }, 191 | { 192 | "artists": [ 193 | { 194 | "external_urls": { 195 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 196 | }, 197 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 198 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 199 | "name": "Cyndi Lauper", 200 | "type": "artist", 201 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 202 | } 203 | ], 204 | "disc_number": 1, 205 | "duration_ms": 241333, 206 | "explicit": false, 207 | "external_urls": { 208 | "spotify": "https://open.spotify.com/track/2tVHvZK4YYzTloSCBPm2tg" 209 | }, 210 | "href": "https://api.spotify.com/v1/tracks/2tVHvZK4YYzTloSCBPm2tg", 211 | "id": "2tVHvZK4YYzTloSCBPm2tg", 212 | "name": "Time After Time", 213 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/0b0b522f1412996c5c0c8d44f886d76d43f33f6c", 214 | "track_number": 4, 215 | "type": "track", 216 | "uri": "spotify:track:2tVHvZK4YYzTloSCBPm2tg" 217 | }, 218 | { 219 | "artists": [ 220 | { 221 | "external_urls": { 222 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 223 | }, 224 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 225 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 226 | "name": "Cyndi Lauper", 227 | "type": "artist", 228 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 229 | } 230 | ], 231 | "disc_number": 1, 232 | "duration_ms": 229266, 233 | "explicit": false, 234 | "external_urls": { 235 | "spotify": "https://open.spotify.com/track/6iLhMDtOr52OVXaZdha5M6" 236 | }, 237 | "href": "https://api.spotify.com/v1/tracks/6iLhMDtOr52OVXaZdha5M6", 238 | "id": "6iLhMDtOr52OVXaZdha5M6", 239 | "name": "She Bop", 240 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/95bbe8eb0ea9d64c8bed6a95a0484250068ffd57", 241 | "track_number": 5, 242 | "type": "track", 243 | "uri": "spotify:track:6iLhMDtOr52OVXaZdha5M6" 244 | }, 245 | { 246 | "artists": [ 247 | { 248 | "external_urls": { 249 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 250 | }, 251 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 252 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 253 | "name": "Cyndi Lauper", 254 | "type": "artist", 255 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 256 | } 257 | ], 258 | "disc_number": 1, 259 | "duration_ms": 272840, 260 | "explicit": false, 261 | "external_urls": { 262 | "spotify": "https://open.spotify.com/track/3csiLr2B2wRj4lsExn6jLf" 263 | }, 264 | "href": "https://api.spotify.com/v1/tracks/3csiLr2B2wRj4lsExn6jLf", 265 | "id": "3csiLr2B2wRj4lsExn6jLf", 266 | "name": "All Through the Night", 267 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/e2dfc024cc4653ecc07f9c9e14fd882f8150cdb7", 268 | "track_number": 6, 269 | "type": "track", 270 | "uri": "spotify:track:3csiLr2B2wRj4lsExn6jLf" 271 | }, 272 | { 273 | "artists": [ 274 | { 275 | "external_urls": { 276 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 277 | }, 278 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 279 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 280 | "name": "Cyndi Lauper", 281 | "type": "artist", 282 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 283 | } 284 | ], 285 | "disc_number": 1, 286 | "duration_ms": 220333, 287 | "explicit": false, 288 | "external_urls": { 289 | "spotify": "https://open.spotify.com/track/4mRAnuBGYsW4WGbpW0QUkp" 290 | }, 291 | "href": "https://api.spotify.com/v1/tracks/4mRAnuBGYsW4WGbpW0QUkp", 292 | "id": "4mRAnuBGYsW4WGbpW0QUkp", 293 | "name": "Witness", 294 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/9be78ca9a07914db151f1e970c068970769d2731", 295 | "track_number": 7, 296 | "type": "track", 297 | "uri": "spotify:track:4mRAnuBGYsW4WGbpW0QUkp" 298 | }, 299 | { 300 | "artists": [ 301 | { 302 | "external_urls": { 303 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 304 | }, 305 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 306 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 307 | "name": "Cyndi Lauper", 308 | "type": "artist", 309 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 310 | } 311 | ], 312 | "disc_number": 1, 313 | "duration_ms": 252626, 314 | "explicit": false, 315 | "external_urls": { 316 | "spotify": "https://open.spotify.com/track/3AIeUnffkLQaUaX1pkHyeD" 317 | }, 318 | "href": "https://api.spotify.com/v1/tracks/3AIeUnffkLQaUaX1pkHyeD", 319 | "id": "3AIeUnffkLQaUaX1pkHyeD", 320 | "name": "I'll Kiss You", 321 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/9031f915fbe2d62cbac7e22eb4e17c69bbcc72b8", 322 | "track_number": 8, 323 | "type": "track", 324 | "uri": "spotify:track:3AIeUnffkLQaUaX1pkHyeD" 325 | }, 326 | { 327 | "artists": [ 328 | { 329 | "external_urls": { 330 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 331 | }, 332 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 333 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 334 | "name": "Cyndi Lauper", 335 | "type": "artist", 336 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 337 | } 338 | ], 339 | "disc_number": 1, 340 | "duration_ms": 45933, 341 | "explicit": false, 342 | "external_urls": { 343 | "spotify": "https://open.spotify.com/track/53eCpAFNbA9MQNfLilN3CH" 344 | }, 345 | "href": "https://api.spotify.com/v1/tracks/53eCpAFNbA9MQNfLilN3CH", 346 | "id": "53eCpAFNbA9MQNfLilN3CH", 347 | "name": "He's so Unusual", 348 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/3b86ffe73440aeb1dca36ab9edb4245e0d7124c7", 349 | "track_number": 9, 350 | "type": "track", 351 | "uri": "spotify:track:53eCpAFNbA9MQNfLilN3CH" 352 | }, 353 | { 354 | "artists": [ 355 | { 356 | "external_urls": { 357 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 358 | }, 359 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 360 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 361 | "name": "Cyndi Lauper", 362 | "type": "artist", 363 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 364 | } 365 | ], 366 | "disc_number": 1, 367 | "duration_ms": 196373, 368 | "explicit": false, 369 | "external_urls": { 370 | "spotify": "https://open.spotify.com/track/51JS0KXziu9U1T8EBdRTUF" 371 | }, 372 | "href": "https://api.spotify.com/v1/tracks/51JS0KXziu9U1T8EBdRTUF", 373 | "id": "51JS0KXziu9U1T8EBdRTUF", 374 | "name": "Yeah Yeah", 375 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/113b4d4b560cddd344fe9ea7d3704d8f8f1600a5", 376 | "track_number": 10, 377 | "type": "track", 378 | "uri": "spotify:track:51JS0KXziu9U1T8EBdRTUF" 379 | }, 380 | { 381 | "artists": [ 382 | { 383 | "external_urls": { 384 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 385 | }, 386 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 387 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 388 | "name": "Cyndi Lauper", 389 | "type": "artist", 390 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 391 | } 392 | ], 393 | "disc_number": 1, 394 | "duration_ms": 275560, 395 | "explicit": false, 396 | "external_urls": { 397 | "spotify": "https://open.spotify.com/track/2BGJvRarwOa2kiIGpLjIXT" 398 | }, 399 | "href": "https://api.spotify.com/v1/tracks/2BGJvRarwOa2kiIGpLjIXT", 400 | "id": "2BGJvRarwOa2kiIGpLjIXT", 401 | "name": "Money Changes Everything", 402 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/76ac67ccd4f27eb0deaf9d789436def22def2304", 403 | "track_number": 11, 404 | "type": "track", 405 | "uri": "spotify:track:2BGJvRarwOa2kiIGpLjIXT" 406 | }, 407 | { 408 | "artists": [ 409 | { 410 | "external_urls": { 411 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 412 | }, 413 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 414 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 415 | "name": "Cyndi Lauper", 416 | "type": "artist", 417 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 418 | } 419 | ], 420 | "disc_number": 1, 421 | "duration_ms": 320400, 422 | "explicit": false, 423 | "external_urls": { 424 | "spotify": "https://open.spotify.com/track/5ggatiDTbCIJsUAa7IUP65" 425 | }, 426 | "href": "https://api.spotify.com/v1/tracks/5ggatiDTbCIJsUAa7IUP65", 427 | "id": "5ggatiDTbCIJsUAa7IUP65", 428 | "name": "She Bop - Live", 429 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/ea6b57b35d2bcf5caddc7e6e3655fc3215eec8a4", 430 | "track_number": 12, 431 | "type": "track", 432 | "uri": "spotify:track:5ggatiDTbCIJsUAa7IUP65" 433 | }, 434 | { 435 | "artists": [ 436 | { 437 | "external_urls": { 438 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 439 | }, 440 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 441 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 442 | "name": "Cyndi Lauper", 443 | "type": "artist", 444 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 445 | } 446 | ], 447 | "disc_number": 1, 448 | "duration_ms": 288240, 449 | "explicit": false, 450 | "external_urls": { 451 | "spotify": "https://open.spotify.com/track/5ZBxoa2kBrBah3qNIV4rm7" 452 | }, 453 | "href": "https://api.spotify.com/v1/tracks/5ZBxoa2kBrBah3qNIV4rm7", 454 | "id": "5ZBxoa2kBrBah3qNIV4rm7", 455 | "name": "All Through The Night - Live", 456 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/cc8d13b1ce2e41f915a126bc6723a9cf7c491e08", 457 | "track_number": 13, 458 | "type": "track", 459 | "uri": "spotify:track:5ZBxoa2kBrBah3qNIV4rm7" 460 | } 461 | ], 462 | "limit": 50, 463 | "next": null, 464 | "offset": 0, 465 | "previous": null, 466 | "total": 13 467 | }, 468 | "type": "album", 469 | "uri": "spotify:album:0sNOF9WDwhWunNAHPD3Baj" 470 | } 471 | -------------------------------------------------------------------------------- /__test__/fixtures/album_tracks.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/albums/0sNOF9WDwhWunNAHPD3Baj/tracks?offset=0&limit=50", 3 | "items": [ 4 | { 5 | "artists": [ 6 | { 7 | "external_urls": { 8 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 9 | }, 10 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 11 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 12 | "name": "Cyndi Lauper", 13 | "type": "artist", 14 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 15 | } 16 | ], 17 | "disc_number": 1, 18 | "duration_ms": 305560, 19 | "explicit": false, 20 | "external_urls": { 21 | "spotify": "https://open.spotify.com/track/3f9zqUnrnIq0LANhmnaF0V" 22 | }, 23 | "href": "https://api.spotify.com/v1/tracks/3f9zqUnrnIq0LANhmnaF0V", 24 | "id": "3f9zqUnrnIq0LANhmnaF0V", 25 | "name": "Money Changes Everything", 26 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/01bb2a6c9a89c05a4300aea427241b1719a26b06", 27 | "track_number": 1, 28 | "type": "track", 29 | "uri": "spotify:track:3f9zqUnrnIq0LANhmnaF0V" 30 | }, 31 | { 32 | "artists": [ 33 | { 34 | "external_urls": { 35 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 36 | }, 37 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 38 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 39 | "name": "Cyndi Lauper", 40 | "type": "artist", 41 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 42 | } 43 | ], 44 | "disc_number": 1, 45 | "duration_ms": 238266, 46 | "explicit": false, 47 | "external_urls": { 48 | "spotify": "https://open.spotify.com/track/2joHDtKFVDDyWDHnOxZMAX" 49 | }, 50 | "href": "https://api.spotify.com/v1/tracks/2joHDtKFVDDyWDHnOxZMAX", 51 | "id": "2joHDtKFVDDyWDHnOxZMAX", 52 | "name": "Girls Just Want to Have Fun", 53 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/4fb5dfb0f1d60d23d1072548847e26906951ead9", 54 | "track_number": 2, 55 | "type": "track", 56 | "uri": "spotify:track:2joHDtKFVDDyWDHnOxZMAX" 57 | }, 58 | { 59 | "artists": [ 60 | { 61 | "external_urls": { 62 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 63 | }, 64 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 65 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 66 | "name": "Cyndi Lauper", 67 | "type": "artist", 68 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 69 | } 70 | ], 71 | "disc_number": 1, 72 | "duration_ms": 306706, 73 | "explicit": false, 74 | "external_urls": { 75 | "spotify": "https://open.spotify.com/track/6ClztHzretmPHCeiNqR5wD" 76 | }, 77 | "href": "https://api.spotify.com/v1/tracks/6ClztHzretmPHCeiNqR5wD", 78 | "id": "6ClztHzretmPHCeiNqR5wD", 79 | "name": "When You Were Mine", 80 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/7ce74522fabed32d7310084541bf38f906bb33bc", 81 | "track_number": 3, 82 | "type": "track", 83 | "uri": "spotify:track:6ClztHzretmPHCeiNqR5wD" 84 | }, 85 | { 86 | "artists": [ 87 | { 88 | "external_urls": { 89 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 90 | }, 91 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 92 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 93 | "name": "Cyndi Lauper", 94 | "type": "artist", 95 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 96 | } 97 | ], 98 | "disc_number": 1, 99 | "duration_ms": 241333, 100 | "explicit": false, 101 | "external_urls": { 102 | "spotify": "https://open.spotify.com/track/2tVHvZK4YYzTloSCBPm2tg" 103 | }, 104 | "href": "https://api.spotify.com/v1/tracks/2tVHvZK4YYzTloSCBPm2tg", 105 | "id": "2tVHvZK4YYzTloSCBPm2tg", 106 | "name": "Time After Time", 107 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/0b0b522f1412996c5c0c8d44f886d76d43f33f6c", 108 | "track_number": 4, 109 | "type": "track", 110 | "uri": "spotify:track:2tVHvZK4YYzTloSCBPm2tg" 111 | }, 112 | { 113 | "artists": [ 114 | { 115 | "external_urls": { 116 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 117 | }, 118 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 119 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 120 | "name": "Cyndi Lauper", 121 | "type": "artist", 122 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 123 | } 124 | ], 125 | "disc_number": 1, 126 | "duration_ms": 229266, 127 | "explicit": false, 128 | "external_urls": { 129 | "spotify": "https://open.spotify.com/track/6iLhMDtOr52OVXaZdha5M6" 130 | }, 131 | "href": "https://api.spotify.com/v1/tracks/6iLhMDtOr52OVXaZdha5M6", 132 | "id": "6iLhMDtOr52OVXaZdha5M6", 133 | "name": "She Bop", 134 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/95bbe8eb0ea9d64c8bed6a95a0484250068ffd57", 135 | "track_number": 5, 136 | "type": "track", 137 | "uri": "spotify:track:6iLhMDtOr52OVXaZdha5M6" 138 | }, 139 | { 140 | "artists": [ 141 | { 142 | "external_urls": { 143 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 144 | }, 145 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 146 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 147 | "name": "Cyndi Lauper", 148 | "type": "artist", 149 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 150 | } 151 | ], 152 | "disc_number": 1, 153 | "duration_ms": 272840, 154 | "explicit": false, 155 | "external_urls": { 156 | "spotify": "https://open.spotify.com/track/3csiLr2B2wRj4lsExn6jLf" 157 | }, 158 | "href": "https://api.spotify.com/v1/tracks/3csiLr2B2wRj4lsExn6jLf", 159 | "id": "3csiLr2B2wRj4lsExn6jLf", 160 | "name": "All Through the Night", 161 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/e2dfc024cc4653ecc07f9c9e14fd882f8150cdb7", 162 | "track_number": 6, 163 | "type": "track", 164 | "uri": "spotify:track:3csiLr2B2wRj4lsExn6jLf" 165 | }, 166 | { 167 | "artists": [ 168 | { 169 | "external_urls": { 170 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 171 | }, 172 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 173 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 174 | "name": "Cyndi Lauper", 175 | "type": "artist", 176 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 177 | } 178 | ], 179 | "disc_number": 1, 180 | "duration_ms": 220333, 181 | "explicit": false, 182 | "external_urls": { 183 | "spotify": "https://open.spotify.com/track/4mRAnuBGYsW4WGbpW0QUkp" 184 | }, 185 | "href": "https://api.spotify.com/v1/tracks/4mRAnuBGYsW4WGbpW0QUkp", 186 | "id": "4mRAnuBGYsW4WGbpW0QUkp", 187 | "name": "Witness", 188 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/9be78ca9a07914db151f1e970c068970769d2731", 189 | "track_number": 7, 190 | "type": "track", 191 | "uri": "spotify:track:4mRAnuBGYsW4WGbpW0QUkp" 192 | }, 193 | { 194 | "artists": [ 195 | { 196 | "external_urls": { 197 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 198 | }, 199 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 200 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 201 | "name": "Cyndi Lauper", 202 | "type": "artist", 203 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 204 | } 205 | ], 206 | "disc_number": 1, 207 | "duration_ms": 252626, 208 | "explicit": false, 209 | "external_urls": { 210 | "spotify": "https://open.spotify.com/track/3AIeUnffkLQaUaX1pkHyeD" 211 | }, 212 | "href": "https://api.spotify.com/v1/tracks/3AIeUnffkLQaUaX1pkHyeD", 213 | "id": "3AIeUnffkLQaUaX1pkHyeD", 214 | "name": "I'll Kiss You", 215 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/9031f915fbe2d62cbac7e22eb4e17c69bbcc72b8", 216 | "track_number": 8, 217 | "type": "track", 218 | "uri": "spotify:track:3AIeUnffkLQaUaX1pkHyeD" 219 | }, 220 | { 221 | "artists": [ 222 | { 223 | "external_urls": { 224 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 225 | }, 226 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 227 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 228 | "name": "Cyndi Lauper", 229 | "type": "artist", 230 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 231 | } 232 | ], 233 | "disc_number": 1, 234 | "duration_ms": 45933, 235 | "explicit": false, 236 | "external_urls": { 237 | "spotify": "https://open.spotify.com/track/53eCpAFNbA9MQNfLilN3CH" 238 | }, 239 | "href": "https://api.spotify.com/v1/tracks/53eCpAFNbA9MQNfLilN3CH", 240 | "id": "53eCpAFNbA9MQNfLilN3CH", 241 | "name": "He's so Unusual", 242 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/3b86ffe73440aeb1dca36ab9edb4245e0d7124c7", 243 | "track_number": 9, 244 | "type": "track", 245 | "uri": "spotify:track:53eCpAFNbA9MQNfLilN3CH" 246 | }, 247 | { 248 | "artists": [ 249 | { 250 | "external_urls": { 251 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 252 | }, 253 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 254 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 255 | "name": "Cyndi Lauper", 256 | "type": "artist", 257 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 258 | } 259 | ], 260 | "disc_number": 1, 261 | "duration_ms": 196373, 262 | "explicit": false, 263 | "external_urls": { 264 | "spotify": "https://open.spotify.com/track/51JS0KXziu9U1T8EBdRTUF" 265 | }, 266 | "href": "https://api.spotify.com/v1/tracks/51JS0KXziu9U1T8EBdRTUF", 267 | "id": "51JS0KXziu9U1T8EBdRTUF", 268 | "name": "Yeah Yeah", 269 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/113b4d4b560cddd344fe9ea7d3704d8f8f1600a5", 270 | "track_number": 10, 271 | "type": "track", 272 | "uri": "spotify:track:51JS0KXziu9U1T8EBdRTUF" 273 | }, 274 | { 275 | "artists": [ 276 | { 277 | "external_urls": { 278 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 279 | }, 280 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 281 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 282 | "name": "Cyndi Lauper", 283 | "type": "artist", 284 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 285 | } 286 | ], 287 | "disc_number": 1, 288 | "duration_ms": 275560, 289 | "explicit": false, 290 | "external_urls": { 291 | "spotify": "https://open.spotify.com/track/2BGJvRarwOa2kiIGpLjIXT" 292 | }, 293 | "href": "https://api.spotify.com/v1/tracks/2BGJvRarwOa2kiIGpLjIXT", 294 | "id": "2BGJvRarwOa2kiIGpLjIXT", 295 | "name": "Money Changes Everything", 296 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/76ac67ccd4f27eb0deaf9d789436def22def2304", 297 | "track_number": 11, 298 | "type": "track", 299 | "uri": "spotify:track:2BGJvRarwOa2kiIGpLjIXT" 300 | }, 301 | { 302 | "artists": [ 303 | { 304 | "external_urls": { 305 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 306 | }, 307 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 308 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 309 | "name": "Cyndi Lauper", 310 | "type": "artist", 311 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 312 | } 313 | ], 314 | "disc_number": 1, 315 | "duration_ms": 320400, 316 | "explicit": false, 317 | "external_urls": { 318 | "spotify": "https://open.spotify.com/track/5ggatiDTbCIJsUAa7IUP65" 319 | }, 320 | "href": "https://api.spotify.com/v1/tracks/5ggatiDTbCIJsUAa7IUP65", 321 | "id": "5ggatiDTbCIJsUAa7IUP65", 322 | "name": "She Bop - Live", 323 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/ea6b57b35d2bcf5caddc7e6e3655fc3215eec8a4", 324 | "track_number": 12, 325 | "type": "track", 326 | "uri": "spotify:track:5ggatiDTbCIJsUAa7IUP65" 327 | }, 328 | { 329 | "artists": [ 330 | { 331 | "external_urls": { 332 | "spotify": "https://open.spotify.com/artist/2BTZIqw0ntH9MvilQ3ewNY" 333 | }, 334 | "href": "https://api.spotify.com/v1/artists/2BTZIqw0ntH9MvilQ3ewNY", 335 | "id": "2BTZIqw0ntH9MvilQ3ewNY", 336 | "name": "Cyndi Lauper", 337 | "type": "artist", 338 | "uri": "spotify:artist:2BTZIqw0ntH9MvilQ3ewNY" 339 | } 340 | ], 341 | "disc_number": 1, 342 | "duration_ms": 288240, 343 | "explicit": false, 344 | "external_urls": { 345 | "spotify": "https://open.spotify.com/track/5ZBxoa2kBrBah3qNIV4rm7" 346 | }, 347 | "href": "https://api.spotify.com/v1/tracks/5ZBxoa2kBrBah3qNIV4rm7", 348 | "id": "5ZBxoa2kBrBah3qNIV4rm7", 349 | "name": "All Through The Night - Live", 350 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/cc8d13b1ce2e41f915a126bc6723a9cf7c491e08", 351 | "track_number": 13, 352 | "type": "track", 353 | "uri": "spotify:track:5ZBxoa2kBrBah3qNIV4rm7" 354 | } 355 | ], 356 | "limit": 50, 357 | "next": null, 358 | "offset": 0, 359 | "previous": null, 360 | "total": 13 361 | } 362 | -------------------------------------------------------------------------------- /__test__/fixtures/artist.json: -------------------------------------------------------------------------------- 1 | { 2 | "external_urls": { 3 | "spotify": "https://open.spotify.com/artist/0LcJLqbBmaGUft1e9Mm8HV" 4 | }, 5 | "genres": [ 6 | "AM Pop", 7 | "Club/Dance", 8 | "Contemporary Pop/Rock", 9 | "Dance-Pop", 10 | "Early Pop/Rock", 11 | "Euro-Pop", 12 | "Pop/Rock", 13 | "Punk/New Wave", 14 | "Rock", 15 | "Soft Rock", 16 | "Swedish Pop/Rock", 17 | "Synth Pop" 18 | ], 19 | "href": "https://api.spotify.com/v1/artists/0LcJLqbBmaGUft1e9Mm8HV", 20 | "id": "0LcJLqbBmaGUft1e9Mm8HV", 21 | "images": [ 22 | { 23 | "height": 934, 24 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/1ace43eddbf6010d417d53ce77b584bd6aa11428", 25 | "width": 936 26 | }, 27 | { 28 | "height": 639, 29 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/c8bf08f8ffc0402b930154368258369612b67e88", 30 | "width": 640 31 | }, 32 | { 33 | "height": 200, 34 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/2e4302151e258b731a731d909f148c99606a0e3c", 35 | "width": 200 36 | }, 37 | { 38 | "height": 64, 39 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/7cccb8fe572f8d76e7d3e11e249688ed3c028aed", 40 | "width": 64 41 | } 42 | ], 43 | "name": "ABBA", 44 | "popularity": 66, 45 | "type": "artist", 46 | "uri": "spotify:artist:0LcJLqbBmaGUft1e9Mm8HV" 47 | } 48 | -------------------------------------------------------------------------------- /__test__/fixtures/artist_albums.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/artists/5YyScSZOuBHpoFhGvHFedc/albums?offset=0&limit=20&album_type=single,album,compilation,appears_on", 3 | "items": [ 4 | { 5 | "album_type": "album", 6 | "external_urls": { 7 | "spotify": "https://open.spotify.com/album/45P1TztZZFbxpmMNuQdR21" 8 | }, 9 | "href": "https://api.spotify.com/v1/albums/45P1TztZZFbxpmMNuQdR21", 10 | "id": "45P1TztZZFbxpmMNuQdR21", 11 | "images": [ 12 | { 13 | "height": 640, 14 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/54533347f41c7d0afaa3e51f127ec93ea5e70311", 15 | "width": 640 16 | }, 17 | { 18 | "height": 300, 19 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/23e03d404f2b2e203022240d0b555b0ef953c757", 20 | "width": 300 21 | }, 22 | { 23 | "height": 64, 24 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/92cc17359e1c3f4a2faf42ff8dfc98390c9550b4", 25 | "width": 64 26 | } 27 | ], 28 | "name": "Mas de Cien Amaneceres", 29 | "type": "album", 30 | "uri": "spotify:album:45P1TztZZFbxpmMNuQdR21" 31 | }, 32 | { 33 | "album_type": "album", 34 | "external_urls": { 35 | "spotify": "https://open.spotify.com/album/6M9uDidhgXknM1AIO5Pkb4" 36 | }, 37 | "href": "https://api.spotify.com/v1/albums/6M9uDidhgXknM1AIO5Pkb4", 38 | "id": "6M9uDidhgXknM1AIO5Pkb4", 39 | "images": [ 40 | { 41 | "height": 640, 42 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/abe64732d0d16bef25dd27e35870dae76fb9eafb", 43 | "width": 640 44 | }, 45 | { 46 | "height": 300, 47 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/9e47cff4b5dc38ab6fb836ea3109e8046cad4d2b", 48 | "width": 300 49 | }, 50 | { 51 | "height": 64, 52 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/c8cd3b5e20281000e28682f2fc5313cf21b594f6", 53 | "width": 64 54 | } 55 | ], 56 | "name": "Mas de Cien Amaneceres", 57 | "type": "album", 58 | "uri": "spotify:album:6M9uDidhgXknM1AIO5Pkb4" 59 | }, 60 | { 61 | "album_type": "album", 62 | "external_urls": { 63 | "spotify": "https://open.spotify.com/album/1TYQD5E50a3Csg7So0qKiO" 64 | }, 65 | "href": "https://api.spotify.com/v1/albums/1TYQD5E50a3Csg7So0qKiO", 66 | "id": "1TYQD5E50a3Csg7So0qKiO", 67 | "images": [ 68 | { 69 | "height": 640, 70 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/edbdaea5d63d272b5d824e1e6006c286b2cb1331", 71 | "width": 640 72 | }, 73 | { 74 | "height": 300, 75 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/1bef3119361825ad1956379fc022c394cbca24f8", 76 | "width": 300 77 | }, 78 | { 79 | "height": 64, 80 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/dbdfe988b037f5f9ca3d5f5f660f9b48f5ba268f", 81 | "width": 64 82 | } 83 | ], 84 | "name": "Raices", 85 | "type": "album", 86 | "uri": "spotify:album:1TYQD5E50a3Csg7So0qKiO" 87 | }, 88 | { 89 | "album_type": "album", 90 | "external_urls": { 91 | "spotify": "https://open.spotify.com/album/2kpb7D2hUNrzJF7DPaxFyZ" 92 | }, 93 | "href": "https://api.spotify.com/v1/albums/2kpb7D2hUNrzJF7DPaxFyZ", 94 | "id": "2kpb7D2hUNrzJF7DPaxFyZ", 95 | "images": [ 96 | { 97 | "height": 640, 98 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/edbdaea5d63d272b5d824e1e6006c286b2cb1331", 99 | "width": 640 100 | }, 101 | { 102 | "height": 300, 103 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/1bef3119361825ad1956379fc022c394cbca24f8", 104 | "width": 300 105 | }, 106 | { 107 | "height": 64, 108 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/dbdfe988b037f5f9ca3d5f5f660f9b48f5ba268f", 109 | "width": 64 110 | } 111 | ], 112 | "name": "Raices", 113 | "type": "album", 114 | "uri": "spotify:album:2kpb7D2hUNrzJF7DPaxFyZ" 115 | }, 116 | { 117 | "album_type": "album", 118 | "external_urls": { 119 | "spotify": "https://open.spotify.com/album/2qZt4hXKcszH8qS3pesaI7" 120 | }, 121 | "href": "https://api.spotify.com/v1/albums/2qZt4hXKcszH8qS3pesaI7", 122 | "id": "2qZt4hXKcszH8qS3pesaI7", 123 | "images": [ 124 | { 125 | "height": 640, 126 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/b42728aa1cf2bc1211b8b6b13f7ce26a7e243020", 127 | "width": 621 128 | }, 129 | { 130 | "height": 300, 131 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/2d2aa4ee7a42598797376e044122243c8ed9e1aa", 132 | "width": 291 133 | }, 134 | { 135 | "height": 64, 136 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/4a1494cbeffd96eba7c06f1eee18881141c81ca2", 137 | "width": 62 138 | } 139 | ], 140 | "name": "Asuntos pendientes", 141 | "type": "album", 142 | "uri": "spotify:album:2qZt4hXKcszH8qS3pesaI7" 143 | }, 144 | { 145 | "album_type": "album", 146 | "external_urls": { 147 | "spotify": "https://open.spotify.com/album/5TS9CJQ4nbmzenjv1WOG9J" 148 | }, 149 | "href": "https://api.spotify.com/v1/albums/5TS9CJQ4nbmzenjv1WOG9J", 150 | "id": "5TS9CJQ4nbmzenjv1WOG9J", 151 | "images": [ 152 | { 153 | "height": 634, 154 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/83acce73648c5019ce961ed9512da08d0f0dd08d", 155 | "width": 640 156 | }, 157 | { 158 | "height": 297, 159 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/c4913259971d1b75d65b590e9a0b2c01acc2a17f", 160 | "width": 300 161 | }, 162 | { 163 | "height": 63, 164 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/fef203f2e674a804992c28a6a15c1b0e0a3d4ea4", 165 | "width": 64 166 | } 167 | ], 168 | "name": "Nubes y claros- Acustico 2006-", 169 | "type": "album", 170 | "uri": "spotify:album:5TS9CJQ4nbmzenjv1WOG9J" 171 | }, 172 | { 173 | "album_type": "album", 174 | "external_urls": { 175 | "spotify": "https://open.spotify.com/album/6Y1HdCcAfs6Oawt73kuKpx" 176 | }, 177 | "href": "https://api.spotify.com/v1/albums/6Y1HdCcAfs6Oawt73kuKpx", 178 | "id": "6Y1HdCcAfs6Oawt73kuKpx", 179 | "images": [ 180 | { 181 | "height": 640, 182 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/53bc47ee843490570199789915ae233be71c3d08", 183 | "width": 630 184 | }, 185 | { 186 | "height": 300, 187 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/94a8324bff9a8695ffac957f03b916144c3ebd42", 188 | "width": 295 189 | }, 190 | { 191 | "height": 64, 192 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/d076ab98e29615e0d0c8fab4d49a9d95bea79afa", 193 | "width": 63 194 | } 195 | ], 196 | "name": "En directo", 197 | "type": "album", 198 | "uri": "spotify:album:6Y1HdCcAfs6Oawt73kuKpx" 199 | }, 200 | { 201 | "album_type": "album", 202 | "external_urls": { 203 | "spotify": "https://open.spotify.com/album/1hCwejZJomHEdOP7sZmGUR" 204 | }, 205 | "href": "https://api.spotify.com/v1/albums/1hCwejZJomHEdOP7sZmGUR", 206 | "id": "1hCwejZJomHEdOP7sZmGUR", 207 | "images": [ 208 | { 209 | "height": 640, 210 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/74dfaa37903f73ad94088c9daac6fd8d556d99fd", 211 | "width": 640 212 | }, 213 | { 214 | "height": 300, 215 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/88fb3247c3e4e5db094e01375e76929fe1cbde51", 216 | "width": 300 217 | }, 218 | { 219 | "height": 64, 220 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/7e04567fd71483b35ed7c3a7cc3f2f20d7daff16", 221 | "width": 64 222 | } 223 | ], 224 | "name": "Negociando gasolina", 225 | "type": "album", 226 | "uri": "spotify:album:1hCwejZJomHEdOP7sZmGUR" 227 | }, 228 | { 229 | "album_type": "album", 230 | "external_urls": { 231 | "spotify": "https://open.spotify.com/album/4HNiEBlDqik3hvD1D5Gptx" 232 | }, 233 | "href": "https://api.spotify.com/v1/albums/4HNiEBlDqik3hvD1D5Gptx", 234 | "id": "4HNiEBlDqik3hvD1D5Gptx", 235 | "images": [ 236 | { 237 | "height": 632, 238 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/c2d0a176e80f01ed6a9295b3818567d164033652", 239 | "width": 640 240 | }, 241 | { 242 | "height": 296, 243 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/9dee070734448f1fd589dc9eb54d4f96862763a0", 244 | "width": 300 245 | }, 246 | { 247 | "height": 63, 248 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/ee6f7437a97ff155284c2996be1a8daf2714e068", 249 | "width": 64 250 | } 251 | ], 252 | "name": "Calles de Papel", 253 | "type": "album", 254 | "uri": "spotify:album:4HNiEBlDqik3hvD1D5Gptx" 255 | }, 256 | { 257 | "album_type": "album", 258 | "external_urls": { 259 | "spotify": "https://open.spotify.com/album/3dg7xWe5EU25bFZQMW0hFP" 260 | }, 261 | "href": "https://api.spotify.com/v1/albums/3dg7xWe5EU25bFZQMW0hFP", 262 | "id": "3dg7xWe5EU25bFZQMW0hFP", 263 | "images": [ 264 | { 265 | "height": 640, 266 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/91be30e13aa15bf20172d496eb992006b350a442", 267 | "width": 640 268 | }, 269 | { 270 | "height": 300, 271 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8f536eb3839b6b34c90d6cee419f70d75148e982", 272 | "width": 300 273 | }, 274 | { 275 | "height": 64, 276 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/3db81afbb5ce855ea42684d53a9c666d381533ec", 277 | "width": 64 278 | } 279 | ], 280 | "name": "A las 12", 281 | "type": "album", 282 | "uri": "spotify:album:3dg7xWe5EU25bFZQMW0hFP" 283 | }, 284 | { 285 | "album_type": "album", 286 | "external_urls": { 287 | "spotify": "https://open.spotify.com/album/7hwGksKIvfyqDj6iAAm1LV" 288 | }, 289 | "href": "https://api.spotify.com/v1/albums/7hwGksKIvfyqDj6iAAm1LV", 290 | "id": "7hwGksKIvfyqDj6iAAm1LV", 291 | "images": [ 292 | { 293 | "height": 640, 294 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/cd0edbe758a4f4329e005be8379171eb04e65111", 295 | "width": 640 296 | }, 297 | { 298 | "height": 300, 299 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/2ba17331b432cd01d4b157d9071ae81719447cd9", 300 | "width": 300 301 | }, 302 | { 303 | "height": 64, 304 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/79e009a2067a17a4905009e05977534ec57db371", 305 | "width": 64 306 | } 307 | ], 308 | "name": "A golpes de Rock'n'Roll", 309 | "type": "album", 310 | "uri": "spotify:album:7hwGksKIvfyqDj6iAAm1LV" 311 | }, 312 | { 313 | "album_type": "album", 314 | "external_urls": { 315 | "spotify": "https://open.spotify.com/album/7EpE7UsapcAWKmuzWVNa18" 316 | }, 317 | "href": "https://api.spotify.com/v1/albums/7EpE7UsapcAWKmuzWVNa18", 318 | "id": "7EpE7UsapcAWKmuzWVNa18", 319 | "images": [ 320 | { 321 | "height": 640, 322 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/dff7abe81ba3faca88fa74c31798b25935eca72e", 323 | "width": 640 324 | }, 325 | { 326 | "height": 300, 327 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/e0b960e265c9b46331848493686e8f8e3a2e8a5f", 328 | "width": 300 329 | }, 330 | { 331 | "height": 64, 332 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/b1ebbd7556100693e0c916245e0a147ac7f42350", 333 | "width": 64 334 | } 335 | ], 336 | "name": "Mira", 337 | "type": "album", 338 | "uri": "spotify:album:7EpE7UsapcAWKmuzWVNa18" 339 | }, 340 | { 341 | "album_type": "single", 342 | "external_urls": { 343 | "spotify": "https://open.spotify.com/album/6yA6LLpparGE1OYSUHbsya" 344 | }, 345 | "href": "https://api.spotify.com/v1/albums/6yA6LLpparGE1OYSUHbsya", 346 | "id": "6yA6LLpparGE1OYSUHbsya", 347 | "images": [ 348 | { 349 | "height": 640, 350 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8e7e0365aacd414fd012ddb6833c4943f0f5c96f", 351 | "width": 640 352 | }, 353 | { 354 | "height": 300, 355 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/10ce04e98bf2915b2488a517a3f4b383e94f9a1b", 356 | "width": 300 357 | }, 358 | { 359 | "height": 64, 360 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/79174847b703dfede79ea388a053adc7f4bf8f17", 361 | "width": 64 362 | } 363 | ], 364 | "name": "Camarote", 365 | "type": "album", 366 | "uri": "spotify:album:6yA6LLpparGE1OYSUHbsya" 367 | }, 368 | { 369 | "album_type": "single", 370 | "external_urls": { 371 | "spotify": "https://open.spotify.com/album/4uLSj4AhMO86FUiWSmQY85" 372 | }, 373 | "href": "https://api.spotify.com/v1/albums/4uLSj4AhMO86FUiWSmQY85", 374 | "id": "4uLSj4AhMO86FUiWSmQY85", 375 | "images": [ 376 | { 377 | "height": 640, 378 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/a236fc9e36f403b4386a6757e8c81dc140c4fd0d", 379 | "width": 640 380 | }, 381 | { 382 | "height": 300, 383 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/2f426b7d56223b2987cf54dbdf4fddea1ec0d972", 384 | "width": 300 385 | }, 386 | { 387 | "height": 64, 388 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/4662fda2a8a31fee83769409b2d973c18d6a6135", 389 | "width": 64 390 | } 391 | ], 392 | "name": "Lunes de Olvido", 393 | "type": "album", 394 | "uri": "spotify:album:4uLSj4AhMO86FUiWSmQY85" 395 | }, 396 | { 397 | "album_type": "single", 398 | "external_urls": { 399 | "spotify": "https://open.spotify.com/album/19cvmOoDSrQSeWrewHpItq" 400 | }, 401 | "href": "https://api.spotify.com/v1/albums/19cvmOoDSrQSeWrewHpItq", 402 | "id": "19cvmOoDSrQSeWrewHpItq", 403 | "images": [ 404 | { 405 | "height": 640, 406 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/fa964187fc31c8b9d147ac87f6dc25d227462499", 407 | "width": 640 408 | }, 409 | { 410 | "height": 300, 411 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/5192f08e7f6f377fb589ebca652c1f6f1dae3f06", 412 | "width": 300 413 | }, 414 | { 415 | "height": 64, 416 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/156eae72c3c9e6a32fd578d53b8ee0ff612b792f", 417 | "width": 64 418 | } 419 | ], 420 | "name": "Lunes de Olvido", 421 | "type": "album", 422 | "uri": "spotify:album:19cvmOoDSrQSeWrewHpItq" 423 | }, 424 | { 425 | "album_type": "single", 426 | "external_urls": { 427 | "spotify": "https://open.spotify.com/album/4Jkf8mvWG3Ck3fR6ITtbia" 428 | }, 429 | "href": "https://api.spotify.com/v1/albums/4Jkf8mvWG3Ck3fR6ITtbia", 430 | "id": "4Jkf8mvWG3Ck3fR6ITtbia", 431 | "images": [ 432 | { 433 | "height": 640, 434 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/549f41a6f955cdb6137e7356da71a2c8f1b7f931", 435 | "width": 640 436 | }, 437 | { 438 | "height": 300, 439 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/fd4b1d6835e9ec2d7975c77c7b919472eec67b0e", 440 | "width": 300 441 | }, 442 | { 443 | "height": 64, 444 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/303d39684a21ba61a43b04e534d8af9ef3aa7883", 445 | "width": 64 446 | } 447 | ], 448 | "name": "Ganas", 449 | "type": "album", 450 | "uri": "spotify:album:4Jkf8mvWG3Ck3fR6ITtbia" 451 | }, 452 | { 453 | "album_type": "single", 454 | "external_urls": { 455 | "spotify": "https://open.spotify.com/album/010mTPPbvCLqTkMrcPXmh2" 456 | }, 457 | "href": "https://api.spotify.com/v1/albums/010mTPPbvCLqTkMrcPXmh2", 458 | "id": "010mTPPbvCLqTkMrcPXmh2", 459 | "images": [ 460 | { 461 | "height": 640, 462 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/00159cdb83398ea261f317087d77d304c8485e33", 463 | "width": 640 464 | }, 465 | { 466 | "height": 300, 467 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/bd1d588ee377ee99e831d09025b3f3f695a8c35b", 468 | "width": 300 469 | }, 470 | { 471 | "height": 64, 472 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/6f32ab09762c127980c50ad067fcd1af6796ce95", 473 | "width": 64 474 | } 475 | ], 476 | "name": "Opciones", 477 | "type": "album", 478 | "uri": "spotify:album:010mTPPbvCLqTkMrcPXmh2" 479 | }, 480 | { 481 | "album_type": "album", 482 | "external_urls": { 483 | "spotify": "https://open.spotify.com/album/4yemN6Hd7jibsKraFT6Jbz" 484 | }, 485 | "href": "https://api.spotify.com/v1/albums/4yemN6Hd7jibsKraFT6Jbz", 486 | "id": "4yemN6Hd7jibsKraFT6Jbz", 487 | "images": [ 488 | { 489 | "height": 640, 490 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/cd0c2f91a04bb131c9928606787019b18c02cb51", 491 | "width": 640 492 | }, 493 | { 494 | "height": 300, 495 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/0c8090ef628b0a3624af861513425e737e081764", 496 | "width": 300 497 | }, 498 | { 499 | "height": 64, 500 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/ecbdfdf8ffd98d334b59b41e4d2c406dbd5e296c", 501 | "width": 64 502 | } 503 | ], 504 | "name": "Que siga la función", 505 | "type": "album", 506 | "uri": "spotify:album:4yemN6Hd7jibsKraFT6Jbz" 507 | }, 508 | { 509 | "album_type": "album", 510 | "external_urls": { 511 | "spotify": "https://open.spotify.com/album/4UWMB8sGHR1HzwwgX3knpZ" 512 | }, 513 | "href": "https://api.spotify.com/v1/albums/4UWMB8sGHR1HzwwgX3knpZ", 514 | "id": "4UWMB8sGHR1HzwwgX3knpZ", 515 | "images": [ 516 | { 517 | "height": 582, 518 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/18c48170fe71d7f7264f5e16de6da6be182d4951", 519 | "width": 640 520 | }, 521 | { 522 | "height": 273, 523 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/23de2ac5ec3f1dfd6435b102bbf5fa9b245bd920", 524 | "width": 300 525 | }, 526 | { 527 | "height": 58, 528 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/3c2f1d5f793058e6a7e41556bf260656c006acef", 529 | "width": 64 530 | } 531 | ], 532 | "name": "Aquí huele a romero", 533 | "type": "album", 534 | "uri": "spotify:album:4UWMB8sGHR1HzwwgX3knpZ" 535 | }, 536 | { 537 | "album_type": "album", 538 | "external_urls": { 539 | "spotify": "https://open.spotify.com/album/6ERD7RXP7URF4LadMa17M1" 540 | }, 541 | "href": "https://api.spotify.com/v1/albums/6ERD7RXP7URF4LadMa17M1", 542 | "id": "6ERD7RXP7URF4LadMa17M1", 543 | "images": [ 544 | { 545 | "height": 640, 546 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/5658820aaee39be3a4e9dd755dda38b20c778b07", 547 | "width": 640 548 | }, 549 | { 550 | "height": 300, 551 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/a76a637cc0526182b13fc783a288c2bce1fbc6af", 552 | "width": 300 553 | }, 554 | { 555 | "height": 64, 556 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/b3ced46c79ca52a6087165a645fdebfc5e24f73c", 557 | "width": 64 558 | } 559 | ], 560 | "name": "Todos Fuimos Heroes", 561 | "type": "album", 562 | "uri": "spotify:album:6ERD7RXP7URF4LadMa17M1" 563 | } 564 | ], 565 | "limit": 20, 566 | "next": "https://api.spotify.com/v1/artists/5YyScSZOuBHpoFhGvHFedc/albums?offset=20&limit=11&album_type=single,album,compilation,appears_on", 567 | "offset": 0, 568 | "previous": null, 569 | "total": 31 570 | } 571 | -------------------------------------------------------------------------------- /__test__/fixtures/artist_albums_limit_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/artists/5YyScSZOuBHpoFhGvHFedc/albums?offset=0&limit=2&album_type=single,album,compilation,appears_on", 3 | "items": [ 4 | { 5 | "album_type": "album", 6 | "available_markets": [], 7 | "external_urls": { 8 | "spotify": "https://open.spotify.com/album/45P1TztZZFbxpmMNuQdR21" 9 | }, 10 | "href": "https://api.spotify.com/v1/albums/45P1TztZZFbxpmMNuQdR21", 11 | "id": "45P1TztZZFbxpmMNuQdR21", 12 | "images": [ 13 | { 14 | "height": 640, 15 | "url": "https://i.scdn.co/image/54533347f41c7d0afaa3e51f127ec93ea5e70311", 16 | "width": 640 17 | }, 18 | { 19 | "height": 300, 20 | "url": "https://i.scdn.co/image/23e03d404f2b2e203022240d0b555b0ef953c757", 21 | "width": 300 22 | }, 23 | { 24 | "height": 64, 25 | "url": "https://i.scdn.co/image/92cc17359e1c3f4a2faf42ff8dfc98390c9550b4", 26 | "width": 64 27 | } 28 | ], 29 | "name": "Mas de Cien Amaneceres", 30 | "type": "album", 31 | "uri": "spotify:album:45P1TztZZFbxpmMNuQdR21" 32 | }, 33 | { 34 | "album_type": "album", 35 | "available_markets": [ 36 | "AD", 37 | "AR", 38 | "AT", 39 | "AU", 40 | "BE", 41 | "BG", 42 | "BO", 43 | "BR", 44 | "CA", 45 | "CH", 46 | "CL", 47 | "CO", 48 | "CR", 49 | "CY", 50 | "CZ", 51 | "DE", 52 | "DK", 53 | "DO", 54 | "EC", 55 | "EE", 56 | "ES", 57 | "FI", 58 | "FR", 59 | "GB", 60 | "GR", 61 | "GT", 62 | "HK", 63 | "HN", 64 | "HU", 65 | "IE", 66 | "IS", 67 | "IT", 68 | "LI", 69 | "LT", 70 | "LU", 71 | "LV", 72 | "MC", 73 | "MT", 74 | "MX", 75 | "MY", 76 | "NI", 77 | "NL", 78 | "NO", 79 | "NZ", 80 | "PA", 81 | "PE", 82 | "PH", 83 | "PL", 84 | "PT", 85 | "PY", 86 | "RO", 87 | "SE", 88 | "SG", 89 | "SI", 90 | "SK", 91 | "SV", 92 | "TR", 93 | "TW", 94 | "US", 95 | "UY" 96 | ], 97 | "external_urls": { 98 | "spotify": "https://open.spotify.com/album/6M9uDidhgXknM1AIO5Pkb4" 99 | }, 100 | "href": "https://api.spotify.com/v1/albums/6M9uDidhgXknM1AIO5Pkb4", 101 | "id": "6M9uDidhgXknM1AIO5Pkb4", 102 | "images": [ 103 | { 104 | "height": 640, 105 | "url": "https://i.scdn.co/image/abe64732d0d16bef25dd27e35870dae76fb9eafb", 106 | "width": 640 107 | }, 108 | { 109 | "height": 300, 110 | "url": "https://i.scdn.co/image/9e47cff4b5dc38ab6fb836ea3109e8046cad4d2b", 111 | "width": 300 112 | }, 113 | { 114 | "height": 64, 115 | "url": "https://i.scdn.co/image/c8cd3b5e20281000e28682f2fc5313cf21b594f6", 116 | "width": 64 117 | } 118 | ], 119 | "name": "Mas de Cien Amaneceres", 120 | "type": "album", 121 | "uri": "spotify:album:6M9uDidhgXknM1AIO5Pkb4" 122 | } 123 | ], 124 | "limit": 2, 125 | "next": "https://api.spotify.com/v1/artists/5YyScSZOuBHpoFhGvHFedc/albums?offset=2&limit=2&album_type=single,album,compilation,appears_on", 126 | "offset": 0, 127 | "previous": null, 128 | "total": 33 129 | } 130 | -------------------------------------------------------------------------------- /__test__/fixtures/artists.json: -------------------------------------------------------------------------------- 1 | { 2 | "external_urls": { 3 | "spotify": "https://open.spotify.com/artist/0oSGxfWSnnOXhD2fKuz2Gy" 4 | }, 5 | "genres": [ 6 | "Adult Alternative Pop/Rock", 7 | "Album Rock", 8 | "Alternative Pop/Rock", 9 | "Alternative/Indie Rock", 10 | "Art Rock", 11 | "Avant-Garde", 12 | "Blue-Eyed Soul", 13 | "British Folk", 14 | "British Folk-Rock", 15 | "British Invasion", 16 | "British Psychedelia", 17 | "Christmas", 18 | "Club/Dance", 19 | "Contemporary Folk", 20 | "Contemporary Pop/Rock", 21 | "Dance-Pop", 22 | "Dance-Rock", 23 | "Experimental", 24 | "Experimental Rock", 25 | "Film Music", 26 | "Folk-Rock", 27 | "Glam Rock", 28 | "Hard Rock", 29 | "Holiday", 30 | "Holidays", 31 | "Mod", 32 | "Original Score", 33 | "Pop/Rock", 34 | "Post-Punk", 35 | "Progressive Country", 36 | "Proto-Punk", 37 | "Psychedelic", 38 | "Punk/New Wave", 39 | "Singer/Songwriter", 40 | "Sophisti-Pop", 41 | "Soundtracks", 42 | "Stage & Screen" 43 | ], 44 | "href": "https://api.spotify.com/v1/artists/0oSGxfWSnnOXhD2fKuz2Gy", 45 | "id": "0oSGxfWSnnOXhD2fKuz2Gy", 46 | "images": [ 47 | { 48 | "height": 1000, 49 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/32bd9707b42a2c081482ec9cd3ffa8879f659f95", 50 | "width": 1000 51 | }, 52 | { 53 | "height": 640, 54 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/865f24753e5e4f40a383bf24a9cdda598a4559a8", 55 | "width": 640 56 | }, 57 | { 58 | "height": 200, 59 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/7ddd6fa5cf78aee2f2e8b347616151393022b7d9", 60 | "width": 200 61 | }, 62 | { 63 | "height": 64, 64 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/c8dc28c191432862afce298216458a6f00bbfbd8", 65 | "width": 64 66 | } 67 | ], 68 | "name": "David Bowie", 69 | "popularity": 77, 70 | "type": "artist", 71 | "uri": "spotify:artist:0oSGxfWSnnOXhD2fKuz2Gy" 72 | } 73 | -------------------------------------------------------------------------------- /__test__/fixtures/available_devices.json: -------------------------------------------------------------------------------- 1 | { 2 | "devices": [ 3 | { 4 | "id": "5fbb3ba6aa454b5534c4ba43a8c7e8e45a63ad0e", 5 | "is_active": false, 6 | "is_restricted": false, 7 | "name": "My fridge", 8 | "type": "Computer", 9 | "volume_percent": 100 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /__test__/fixtures/browse_categories.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": { 3 | "href": "https://api.spotify.com/v1/browse/categories?country=SE&locale=sv_SE&offset=0&limit=20", 4 | "items": [ 5 | { 6 | "href": "https://api.spotify.com/v1/browse/categories/toplists", 7 | "icons": [ 8 | { 9 | "height": 275, 10 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/toplists_11160599e6a04ac5d6f2757f5511778f_0_0_275_275.jpg", 11 | "width": 275 12 | } 13 | ], 14 | "id": "toplists", 15 | "name": "Topplistor" 16 | }, 17 | { 18 | "href": "https://api.spotify.com/v1/browse/categories/mood", 19 | "icons": [ 20 | { 21 | "height": 274, 22 | "url": "https://datsnxq1rwndn.cloudfront.net/media/original/mood-274x274_976986a31ac8c49794cbdc7246fd5ad7_274x274.jpg", 23 | "width": 274 24 | } 25 | ], 26 | "id": "mood", 27 | "name": "Humör" 28 | }, 29 | { 30 | "href": "https://api.spotify.com/v1/browse/categories/party", 31 | "icons": [ 32 | { 33 | "height": 274, 34 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/party-274x274_73d1907a7371c3bb96a288390a96ee27_0_0_274_274.jpg", 35 | "width": 274 36 | } 37 | ], 38 | "id": "party", 39 | "name": "Party" 40 | }, 41 | { 42 | "href": "https://api.spotify.com/v1/browse/categories/pop", 43 | "icons": [ 44 | { 45 | "height": 274, 46 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/pop-274x274_447148649685019f5e2a03a39e78ba52_0_0_274_274.jpg", 47 | "width": 274 48 | } 49 | ], 50 | "id": "pop", 51 | "name": "Pop" 52 | }, 53 | { 54 | "href": "https://api.spotify.com/v1/browse/categories/workout", 55 | "icons": [ 56 | { 57 | "height": 275, 58 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/workout_856581c1c545a5305e49a3cd8be804a0_0_0_275_275.jpg", 59 | "width": 275 60 | } 61 | ], 62 | "id": "workout", 63 | "name": "Träning" 64 | }, 65 | { 66 | "href": "https://api.spotify.com/v1/browse/categories/focus", 67 | "icons": [ 68 | { 69 | "height": 274, 70 | "url": "https://datsnxq1rwndn.cloudfront.net/media/original/genre-images-square-274x274_5e50d72b846a198fcd2ca9b3aef5f0c8_274x274.jpg", 71 | "width": 274 72 | } 73 | ], 74 | "id": "focus", 75 | "name": "Fokus" 76 | }, 77 | { 78 | "href": "https://api.spotify.com/v1/browse/categories/rock", 79 | "icons": [ 80 | { 81 | "height": 274, 82 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/rock_9ce79e0a4ef901bbd10494f5b855d3cc_0_0_274_274.jpg", 83 | "width": 274 84 | } 85 | ], 86 | "id": "rock", 87 | "name": "Rock & roll" 88 | }, 89 | { 90 | "href": "https://api.spotify.com/v1/browse/categories/indie_alt", 91 | "icons": [ 92 | { 93 | "height": 274, 94 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/indie-274x274_add35b2b767ff7f3897262ad86809bdb_0_0_274_274.jpg", 95 | "width": 274 96 | } 97 | ], 98 | "id": "indie_alt", 99 | "name": "Indie/alternativ" 100 | }, 101 | { 102 | "href": "https://api.spotify.com/v1/browse/categories/edm_dance", 103 | "icons": [ 104 | { 105 | "height": 274, 106 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/edm-274x274_0ef612604200a9c14995432994455a6d_0_0_274_274.jpg", 107 | "width": 274 108 | } 109 | ], 110 | "id": "edm_dance", 111 | "name": "EDM/dance" 112 | }, 113 | { 114 | "href": "https://api.spotify.com/v1/browse/categories/chill", 115 | "icons": [ 116 | { 117 | "height": 274, 118 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/chill-274x274_4c46374f007813dd10b37e8d8fd35b4b_0_0_274_274.jpg", 119 | "width": 274 120 | } 121 | ], 122 | "id": "chill", 123 | "name": "Chill" 124 | }, 125 | { 126 | "href": "https://api.spotify.com/v1/browse/categories/dinner", 127 | "icons": [ 128 | { 129 | "height": 274, 130 | "url": "https://datsnxq1rwndn.cloudfront.net/media/original/dinner_1b6506abba0ba52c54e6d695c8571078_274x274.jpg", 131 | "width": 274 132 | } 133 | ], 134 | "id": "dinner", 135 | "name": "Middag" 136 | }, 137 | { 138 | "href": "https://api.spotify.com/v1/browse/categories/sleep", 139 | "icons": [ 140 | { 141 | "height": 274, 142 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/sleep-274x274_0d4f836af8fab7bf31526968073e671c_0_0_274_274.jpg", 143 | "width": 274 144 | } 145 | ], 146 | "id": "sleep", 147 | "name": "Sova" 148 | }, 149 | { 150 | "href": "https://api.spotify.com/v1/browse/categories/hiphop", 151 | "icons": [ 152 | { 153 | "height": 274, 154 | "url": "https://datsnxq1rwndn.cloudfront.net/media/original/hip-274_0a661854d61e29eace5fe63f73495e68_274x274.jpg", 155 | "width": 274 156 | } 157 | ], 158 | "id": "hiphop", 159 | "name": "Hip Hop" 160 | }, 161 | { 162 | "href": "https://api.spotify.com/v1/browse/categories/rnb", 163 | "icons": [ 164 | { 165 | "height": 274, 166 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/rb-274x274_a0e7a187f9449dd7722e1ddbd6191f48_0_0_274_274.jpg", 167 | "width": 274 168 | } 169 | ], 170 | "id": "rnb", 171 | "name": "R&B" 172 | }, 173 | { 174 | "href": "https://api.spotify.com/v1/browse/categories/country", 175 | "icons": [ 176 | { 177 | "height": 274, 178 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/country-folk_dd35e932222c37ea75623a5788a12935_0_0_274_274.jpg", 179 | "width": 274 180 | } 181 | ], 182 | "id": "country", 183 | "name": "Country" 184 | }, 185 | { 186 | "href": "https://api.spotify.com/v1/browse/categories/folk_americana", 187 | "icons": [ 188 | { 189 | "height": 274, 190 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/folk-icon_1682b3a3e59b9a351243e6b7b26129fb_0_0_274_274.jpg", 191 | "width": 274 192 | } 193 | ], 194 | "id": "folk_americana", 195 | "name": "Folk & Americana" 196 | }, 197 | { 198 | "href": "https://api.spotify.com/v1/browse/categories/metal", 199 | "icons": [ 200 | { 201 | "height": 274, 202 | "url": "https://datsnxq1rwndn.cloudfront.net/media/original/metal_27c921443fd0a5ba95b1b2c2ae654b2b_274x274.jpg", 203 | "width": 274 204 | } 205 | ], 206 | "id": "metal", 207 | "name": "Metal" 208 | }, 209 | { 210 | "href": "https://api.spotify.com/v1/browse/categories/soul", 211 | "icons": [ 212 | { 213 | "height": 274, 214 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/soul-274x274_266bc900b35dda8956380cffc73a4d8c_0_0_274_274.jpg", 215 | "width": 274 216 | } 217 | ], 218 | "id": "soul", 219 | "name": "Soul" 220 | }, 221 | { 222 | "href": "https://api.spotify.com/v1/browse/categories/travel", 223 | "icons": [ 224 | { 225 | "height": 274, 226 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/travel-274x274_1e89cd5b42cf8bd2ff8fc4fb26f2e955_0_0_274_274.jpg", 227 | "width": 274 228 | } 229 | ], 230 | "id": "travel", 231 | "name": "Resor" 232 | }, 233 | { 234 | "href": "https://api.spotify.com/v1/browse/categories/decades", 235 | "icons": [ 236 | { 237 | "height": 274, 238 | "url": "https://datsnxq1rwndn.cloudfront.net/media/derived/decades_9ad8e458242b2ac8b184e79ef336c455_0_0_274_274.jpg", 239 | "width": 274 240 | } 241 | ], 242 | "id": "decades", 243 | "name": "Årtionden" 244 | } 245 | ], 246 | "limit": 20, 247 | "next": "https://api.spotify.com/v1/browse/categories?country=SE&locale=sv_SE&offset=20&limit=20", 248 | "offset": 0, 249 | "previous": null, 250 | "total": 31 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /__test__/fixtures/category.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/browse/categories/dinner", 3 | "icons": [ 4 | { 5 | "height": 274, 6 | "url": "https://datsnxq1rwndn.cloudfront.net/media/original/dinner_1b6506abba0ba52c54e6d695c8571078_274x274.jpg", 7 | "width": 274 8 | } 9 | ], 10 | "id": "dinner", 11 | "name": "Middag" 12 | } 13 | -------------------------------------------------------------------------------- /__test__/fixtures/current_playback.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": 1490252122574, 3 | "device": { 4 | "id": "3f228e06c8562e2f439e22932da6c3231715ed53", 5 | "is_active": false, 6 | "is_restricted": false, 7 | "name": "Xperia Z5 Compact", 8 | "type": "Smartphone", 9 | "volume_percent": 54 10 | }, 11 | "progress_ms": "44272", 12 | "is_playing": true, 13 | "item": { 14 | "track": null 15 | }, 16 | "shuffle_state": false, 17 | "repeat_state": "off", 18 | "context": { 19 | "external_urls": { 20 | "spotify": "http://open.spotify.com/user/spotify/playlist/49znshcYJROspEqBoHg3Sv" 21 | }, 22 | "href": "https://api.spotify.com/v1/users/spotify/playlists/49znshcYJROspEqBoHg3Sv", 23 | "type": "playlist", 24 | "uri": "spotify:user:spotify:playlist:49znshcYJROspEqBoHg3Sv" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /__test__/fixtures/current_playing_track.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": { 3 | "external_urls": { 4 | "spotify": "http://open.spotify.com/user/spotify/playlist/49znshcYJROspEqBoHg3Sv" 5 | }, 6 | "href": "https://api.spotify.com/v1/users/spotify/playlists/49znshcYJROspEqBoHg3Sv", 7 | "type": "playlist", 8 | "uri": "spotify:user:spotify:playlist:49znshcYJROspEqBoHg3Sv" 9 | }, 10 | "timestamp": 1490252122574, 11 | "progress_ms": 44272, 12 | "is_playing": true, 13 | "item": { 14 | "album": { 15 | "album_type": "album", 16 | "external_urls": { 17 | "spotify": "https://open.spotify.com/album/6TJmQnO44YE5BtTxH8pop1" 18 | }, 19 | "href": "https://api.spotify.com/v1/albums/6TJmQnO44YE5BtTxH8pop1", 20 | "id": "6TJmQnO44YE5BtTxH8pop1", 21 | "images": [ 22 | { 23 | "height": 640, 24 | "url": "https://i.scdn.co/image/8e13218039f81b000553e25522a7f0d7a0600f2e", 25 | "width": 629 26 | }, 27 | { 28 | "height": 300, 29 | "url": "https://i.scdn.co/image/8c1e066b5d1045038437d92815d49987f519e44f", 30 | "width": 295 31 | }, 32 | { 33 | "height": 64, 34 | "url": "https://i.scdn.co/image/d49268a8fc0768084f4750cf1647709e89a27172", 35 | "width": 63 36 | } 37 | ], 38 | "name": "Hot Fuss", 39 | "type": "album", 40 | "uri": "spotify:album:6TJmQnO44YE5BtTxH8pop1" 41 | }, 42 | "artists": [ 43 | { 44 | "external_urls": { 45 | "spotify": "https://open.spotify.com/artist/0C0XlULifJtAgn6ZNCW2eu" 46 | }, 47 | "href": "https://api.spotify.com/v1/artists/0C0XlULifJtAgn6ZNCW2eu", 48 | "id": "0C0XlULifJtAgn6ZNCW2eu", 49 | "name": "The Killers", 50 | "type": "artist", 51 | "uri": "spotify:artist:0C0XlULifJtAgn6ZNCW2eu" 52 | } 53 | ], 54 | "available_markets": ["AD", "AR", "TW", "UY"], 55 | "disc_number": 1, 56 | "duration_ms": 222075, 57 | "explicit": false, 58 | "external_ids": { 59 | "isrc": "USIR20400274" 60 | }, 61 | "external_urls": { 62 | "spotify": "https://open.spotify.com/track/0eGsygTp906u18L0Oimnem" 63 | }, 64 | "href": "https://api.spotify.com/v1/tracks/0eGsygTp906u18L0Oimnem", 65 | "id": "0eGsygTp906u18L0Oimnem", 66 | "name": "Mr. Brightside", 67 | "popularity": 0, 68 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/f454c8224828e21fa146af84916fd22cb89cedc6", 69 | "track_number": 2, 70 | "type": "track", 71 | "uri": "spotify:track:0eGsygTp906u18L0Oimnem" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /__test__/fixtures/episode.json: -------------------------------------------------------------------------------- 1 | { 2 | "audio_preview_url": "https://p.scdn.co/mp3-preview/3852fac7b64ee43c62b6557d78c8c12300cd8f98", 3 | "description": "Företag som har förlorat mycket pengar nu ska få hjälp av staten. | Idag är det Valborg. Men i år är inte firandet som vanligt. | Hur vet man om man har pollenallergi eller covid-19? | Läs texterna till nyheterna på webbsidan: www.sverigesradio.se/lattsvenska Ingrid Forsberg och Jenny Hallberg.", 4 | "duration_ms": 729000, 5 | "explicit": false, 6 | "external_urls": { 7 | "spotify": "https://open.spotify.com/episode/47nrkWxUkjYqkfJrAIYeAI" 8 | }, 9 | "href": "https://api.spotify.com/v1/episodes/47nrkWxUkjYqkfJrAIYeAI", 10 | "id": "47nrkWxUkjYqkfJrAIYeAI", 11 | "images": [ 12 | { 13 | "height": 640, 14 | "url": "https://i.scdn.co/image/1fb1e3b0bbea8c77780eef0a901098ccf15ca1e8", 15 | "width": 640 16 | }, 17 | { 18 | "height": 300, 19 | "url": "https://i.scdn.co/image/fdf2ab20a685ff4da727251cea6b553df398e2c7", 20 | "width": 300 21 | }, 22 | { 23 | "height": 64, 24 | "url": "https://i.scdn.co/image/e838bd9a770aa1229ba1216b32f06cb85a28a716", 25 | "width": 64 26 | } 27 | ], 28 | "is_externally_hosted": false, 29 | "is_playable": true, 30 | "language": "sv", 31 | "languages": ["sv"], 32 | "name": "Torsdag 30 april 2020", 33 | "release_date": "2020-04-30", 34 | "release_date_precision": "day", 35 | "show": { 36 | "available_markets": [ 37 | "AD", 38 | "AE", 39 | "AR", 40 | "AT", 41 | "AU", 42 | "BE", 43 | "BG", 44 | "BH", 45 | "BO", 46 | "BR", 47 | "CA", 48 | "CH", 49 | "CL", 50 | "CO", 51 | "CR", 52 | "CY", 53 | "CZ", 54 | "DE", 55 | "DK", 56 | "DO", 57 | "DZ", 58 | "EC", 59 | "EE", 60 | "ES", 61 | "FI", 62 | "FR", 63 | "GB", 64 | "GR", 65 | "GT", 66 | "HK", 67 | "HN", 68 | "HU", 69 | "ID", 70 | "IE", 71 | "IL", 72 | "IN", 73 | "IS", 74 | "IT", 75 | "JO", 76 | "JP", 77 | "KW", 78 | "LB", 79 | "LI", 80 | "LT", 81 | "LU", 82 | "LV", 83 | "MA", 84 | "MC", 85 | "MT", 86 | "MX", 87 | "MY", 88 | "NI", 89 | "NL", 90 | "NO", 91 | "NZ", 92 | "OM", 93 | "PA", 94 | "PE", 95 | "PH", 96 | "PL", 97 | "PS", 98 | "PT", 99 | "PY", 100 | "QA", 101 | "RO", 102 | "SE", 103 | "SG", 104 | "SK", 105 | "SV", 106 | "TH", 107 | "TN", 108 | "TR", 109 | "TW", 110 | "US", 111 | "UY", 112 | "VN", 113 | "ZA" 114 | ], 115 | "copyrights": [], 116 | "description": "Nyheter på lätt svenska för dig som är ny i Sverige. Ansvarig utgivare: Klas Wolf-Watz", 117 | "explicit": false, 118 | "external_urls": { 119 | "spotify": "https://open.spotify.com/show/7qV2tMPbnZu18p2h0w6vvR" 120 | }, 121 | "href": "https://api.spotify.com/v1/shows/7qV2tMPbnZu18p2h0w6vvR", 122 | "id": "7qV2tMPbnZu18p2h0w6vvR", 123 | "images": [ 124 | { 125 | "height": 640, 126 | "url": "https://i.scdn.co/image/29126c05d08eac150b0e9a4cc61f13885c555ff1", 127 | "width": 640 128 | }, 129 | { 130 | "height": 300, 131 | "url": "https://i.scdn.co/image/1ec0eba6e85fb1bc30221fe10092488111533a15", 132 | "width": 300 133 | }, 134 | { 135 | "height": 64, 136 | "url": "https://i.scdn.co/image/8870c75630935db5290d2162245b611f0fb40b14", 137 | "width": 64 138 | } 139 | ], 140 | "is_externally_hosted": false, 141 | "languages": ["sv"], 142 | "media_type": "audio", 143 | "name": "Radio Sweden på lätt svenska", 144 | "publisher": "Sveriges Radio", 145 | "type": "show", 146 | "uri": "spotify:show:7qV2tMPbnZu18p2h0w6vvR" 147 | }, 148 | "type": "episode", 149 | "uri": "spotify:episode:47nrkWxUkjYqkfJrAIYeAI" 150 | } 151 | -------------------------------------------------------------------------------- /__test__/fixtures/episodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "episodes": [ 3 | { 4 | "audio_preview_url": "https://p.scdn.co/mp3-preview/7e8f7a00f1425d495bcb992bae48a19c31342490", 5 | "description": "Följ med till Riddarhuset och hör om dråpliga motiv och billiga lösningar på husets drygt 2 300 vapensköldar som nu studerats. Och hör hur stormakten Sveriges krig finansierades av Frankrike. Skelögda ugglor och halshuggna troll är några av motiven på de drygt 2 300 vapensköldar som hänger i Riddarhuset i Stockholm. Den svenska adelns grafiska profiler har nu hamnat under luppen när heraldikern Magnus Bäckmark som förste forskare skärskådat detta bortglömda kulturarvs estetik och historia. Vetenskapsradion Historia följer med honom till Riddarhuset för att fascineras av både vackra och tokfula motiv. Dessutom om att den svenska stormaktstiden nu måste omvärderas efter att historikern Svante Norrhem undersökt de enorma summor som Sverige erhöll av Frankrike. Under närmare 170 år var Sverige närmast en klientstat till Frankrike, där närmare 20 procent av svensk ekonomi bestod av franska subsidier. Tobias Svanelid undersöker hur förhållandet påverkade länderna och hur mycket av den svenska stormaktstiden som egentligen var fransk.", 6 | "duration_ms": 2685023, 7 | "explicit": false, 8 | "external_urls": { 9 | "spotify": "https://open.spotify.com/episode/77o6BIVlYM3msb4MMIL1jH" 10 | }, 11 | "href": "https://api.spotify.com/v1/episodes/77o6BIVlYM3msb4MMIL1jH", 12 | "id": "77o6BIVlYM3msb4MMIL1jH", 13 | "images": [ 14 | { 15 | "height": 640, 16 | "url": "https://i.scdn.co/image/8092469858486ff19eeefcea7ec5c17b72c9590a", 17 | "width": 640 18 | }, 19 | { 20 | "height": 300, 21 | "url": "https://i.scdn.co/image/7e921e844f4deb5a8fbdacba7abb6210357237e5", 22 | "width": 300 23 | }, 24 | { 25 | "height": 64, 26 | "url": "https://i.scdn.co/image/729df823ef7f9a6f8aaf57d532490c9aab43e0dc", 27 | "width": 64 28 | } 29 | ], 30 | "is_externally_hosted": false, 31 | "is_playable": true, 32 | "language": "sv", 33 | "languages": ["sv"], 34 | "name": "Riddarnas vapensköldar under lupp", 35 | "release_date": "2019-09-10", 36 | "release_date_precision": "day", 37 | "show": { 38 | "available_markets": [ 39 | "AD", 40 | "AE", 41 | "AR", 42 | "AT", 43 | "AU", 44 | "BE", 45 | "BG", 46 | "BH", 47 | "BO", 48 | "BR", 49 | "CA", 50 | "CH", 51 | "CL", 52 | "CO", 53 | "CR", 54 | "CY", 55 | "CZ", 56 | "DE", 57 | "DK", 58 | "DO", 59 | "DZ", 60 | "EC", 61 | "EE", 62 | "ES", 63 | "FI", 64 | "FR", 65 | "GB", 66 | "GR", 67 | "GT", 68 | "HK", 69 | "HN", 70 | "HU", 71 | "ID", 72 | "IE", 73 | "IL", 74 | "IN", 75 | "IS", 76 | "IT", 77 | "JO", 78 | "JP", 79 | "KW", 80 | "LB", 81 | "LI", 82 | "LT", 83 | "LU", 84 | "LV", 85 | "MA", 86 | "MC", 87 | "MT", 88 | "MX", 89 | "MY", 90 | "NI", 91 | "NL", 92 | "NO", 93 | "NZ", 94 | "OM", 95 | "PA", 96 | "PE", 97 | "PH", 98 | "PL", 99 | "PS", 100 | "PT", 101 | "PY", 102 | "QA", 103 | "RO", 104 | "SE", 105 | "SG", 106 | "SK", 107 | "SV", 108 | "TH", 109 | "TN", 110 | "TR", 111 | "TW", 112 | "US", 113 | "UY", 114 | "VN", 115 | "ZA" 116 | ], 117 | "copyrights": [], 118 | "description": "Vi är där historien är. Ansvarig utgivare: Nina Glans", 119 | "explicit": false, 120 | "external_urls": { 121 | "spotify": "https://open.spotify.com/show/38bS44xjbVVZ3No3ByF1dJ" 122 | }, 123 | "href": "https://api.spotify.com/v1/shows/38bS44xjbVVZ3No3ByF1dJ", 124 | "id": "38bS44xjbVVZ3No3ByF1dJ", 125 | "images": [ 126 | { 127 | "height": 640, 128 | "url": "https://i.scdn.co/image/f19a5ed45a33a964ea664fa328a010047d6f23d8", 129 | "width": 640 130 | }, 131 | { 132 | "height": 300, 133 | "url": "https://i.scdn.co/image/46f47b6259f1784aafd545cb038302b84ea74f43", 134 | "width": 300 135 | }, 136 | { 137 | "height": 64, 138 | "url": "https://i.scdn.co/image/20746dadce643c4a8a096adbea62ee300e62a993", 139 | "width": 64 140 | } 141 | ], 142 | "is_externally_hosted": false, 143 | "languages": ["sv"], 144 | "media_type": "audio", 145 | "name": "Vetenskapsradion Historia", 146 | "publisher": "Sveriges Radio", 147 | "type": "show", 148 | "uri": "spotify:show:38bS44xjbVVZ3No3ByF1dJ" 149 | }, 150 | "type": "episode", 151 | "uri": "spotify:episode:77o6BIVlYM3msb4MMIL1jH" 152 | }, 153 | { 154 | "audio_preview_url": "https://p.scdn.co/mp3-preview/83bc7f2d40e850582a4ca118b33c256358de06ff", 155 | "description": "Följ med Tobias Svanelid till Sveriges äldsta tegelkyrka, till Edsleskog mitt i den dalsländska granskogen, där ett religiöst skrytbygge skulle resas över ett skändligt brott. I Edsleskog i Dalsland gräver arkeologerna nu ut vad som en gång verkar ha varit en av Sveriges största medeltidskyrkor, och kanske också den äldsta som byggts i tegel, 1200-talets high-tech-material. Tobias Svanelid reser dit för att höra historien om den märkliga och bortglömda kyrkan som grundlades på platsen för ett prästmord och dessutom kan ha varit Skarabiskopens försök att lägga beslag på det vilda Dalsland. Dessutom om sjudagarsveckan idag ett välkänt koncept runt hela världen, men hur gammal är egentligen veckans historia? Dick Harrison vet svaret.", 156 | "duration_ms": 2685023, 157 | "explicit": false, 158 | "external_urls": { 159 | "spotify": "https://open.spotify.com/episode/0Q86acNRm6V9GYx55SXKwf" 160 | }, 161 | "href": "https://api.spotify.com/v1/episodes/0Q86acNRm6V9GYx55SXKwf", 162 | "id": "0Q86acNRm6V9GYx55SXKwf", 163 | "images": [ 164 | { 165 | "height": 640, 166 | "url": "https://i.scdn.co/image/b2398424d6158a21fe8677e2de5f6f3d1dc4a04f", 167 | "width": 640 168 | }, 169 | { 170 | "height": 300, 171 | "url": "https://i.scdn.co/image/a52780a1d7e1bc42619413c3dea7042396c87f49", 172 | "width": 300 173 | }, 174 | { 175 | "height": 64, 176 | "url": "https://i.scdn.co/image/88e21be860cf11f0b95ee8dfb47ddb08a13319a7", 177 | "width": 64 178 | } 179 | ], 180 | "is_externally_hosted": false, 181 | "is_playable": true, 182 | "language": "sv", 183 | "languages": ["sv"], 184 | "name": "Okända katedralen i Dalsland", 185 | "release_date": "2019-09-03", 186 | "release_date_precision": "day", 187 | "show": { 188 | "available_markets": [ 189 | "AD", 190 | "AE", 191 | "AR", 192 | "AT", 193 | "AU", 194 | "BE", 195 | "BG", 196 | "BH", 197 | "BO", 198 | "BR", 199 | "CA", 200 | "CH", 201 | "CL", 202 | "CO", 203 | "CR", 204 | "CY", 205 | "CZ", 206 | "DE", 207 | "DK", 208 | "DO", 209 | "DZ", 210 | "EC", 211 | "EE", 212 | "ES", 213 | "FI", 214 | "FR", 215 | "GB", 216 | "GR", 217 | "GT", 218 | "HK", 219 | "HN", 220 | "HU", 221 | "ID", 222 | "IE", 223 | "IL", 224 | "IN", 225 | "IS", 226 | "IT", 227 | "JO", 228 | "JP", 229 | "KW", 230 | "LB", 231 | "LI", 232 | "LT", 233 | "LU", 234 | "LV", 235 | "MA", 236 | "MC", 237 | "MT", 238 | "MX", 239 | "MY", 240 | "NI", 241 | "NL", 242 | "NO", 243 | "NZ", 244 | "OM", 245 | "PA", 246 | "PE", 247 | "PH", 248 | "PL", 249 | "PS", 250 | "PT", 251 | "PY", 252 | "QA", 253 | "RO", 254 | "SE", 255 | "SG", 256 | "SK", 257 | "SV", 258 | "TH", 259 | "TN", 260 | "TR", 261 | "TW", 262 | "US", 263 | "UY", 264 | "VN", 265 | "ZA" 266 | ], 267 | "copyrights": [], 268 | "description": "Vi är där historien är. Ansvarig utgivare: Nina Glans", 269 | "explicit": false, 270 | "external_urls": { 271 | "spotify": "https://open.spotify.com/show/38bS44xjbVVZ3No3ByF1dJ" 272 | }, 273 | "href": "https://api.spotify.com/v1/shows/38bS44xjbVVZ3No3ByF1dJ", 274 | "id": "38bS44xjbVVZ3No3ByF1dJ", 275 | "images": [ 276 | { 277 | "height": 640, 278 | "url": "https://i.scdn.co/image/f19a5ed45a33a964ea664fa328a010047d6f23d8", 279 | "width": 640 280 | }, 281 | { 282 | "height": 300, 283 | "url": "https://i.scdn.co/image/46f47b6259f1784aafd545cb038302b84ea74f43", 284 | "width": 300 285 | }, 286 | { 287 | "height": 64, 288 | "url": "https://i.scdn.co/image/20746dadce643c4a8a096adbea62ee300e62a993", 289 | "width": 64 290 | } 291 | ], 292 | "is_externally_hosted": false, 293 | "languages": ["sv"], 294 | "media_type": "audio", 295 | "name": "Vetenskapsradion Historia", 296 | "publisher": "Sveriges Radio", 297 | "type": "show", 298 | "uri": "spotify:show:38bS44xjbVVZ3No3ByF1dJ" 299 | }, 300 | "type": "episode", 301 | "uri": "spotify:episode:0Q86acNRm6V9GYx55SXKwf" 302 | } 303 | ] 304 | } 305 | -------------------------------------------------------------------------------- /__test__/fixtures/error_id_not_found.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": { 3 | "type": "not_found", 4 | "description": "non existing id" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /__test__/fixtures/featured_playlists.json: -------------------------------------------------------------------------------- 1 | { 2 | "message": "Feeling nostalgic this afternoon?", 3 | "playlists": { 4 | "href": "https://api.spotify.com/v1/browse/featured-playlists?timestamp=2014-10-23T15:37:39&offset=0&limit=20", 5 | "items": [ 6 | { 7 | "collaborative": false, 8 | "external_urls": { 9 | "spotify": "http://open.spotify.com/user/spotify/playlist/4ORiMCgOe6UxBDqW8SF1Lm" 10 | }, 11 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4ORiMCgOe6UxBDqW8SF1Lm", 12 | "id": "4ORiMCgOe6UxBDqW8SF1Lm", 13 | "images": [ 14 | { 15 | "url": "https://i.scdn.co/image/de9f55660bc0abbbd36ac43acb80ced3c03da768" 16 | } 17 | ], 18 | "name": "#ThrowbackThursday", 19 | "owner": { 20 | "external_urls": { 21 | "spotify": "http://open.spotify.com/user/spotify" 22 | }, 23 | "href": "https://api.spotify.com/v1/users/spotify", 24 | "id": "spotify", 25 | "type": "user", 26 | "uri": "spotify:user:spotify" 27 | }, 28 | "public": null, 29 | "tracks": { 30 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4ORiMCgOe6UxBDqW8SF1Lm/tracks", 31 | "total": 24 32 | }, 33 | "type": "playlist", 34 | "uri": "spotify:user:spotify:playlist:4ORiMCgOe6UxBDqW8SF1Lm" 35 | }, 36 | { 37 | "collaborative": false, 38 | "external_urls": { 39 | "spotify": "http://open.spotify.com/user/spotify/playlist/51HFHO33vXhvUElwtD9eBD" 40 | }, 41 | "href": "https://api.spotify.com/v1/users/spotify/playlists/51HFHO33vXhvUElwtD9eBD", 42 | "id": "51HFHO33vXhvUElwtD9eBD", 43 | "images": [ 44 | { 45 | "url": "https://i.scdn.co/image/d64625b16b7ca5077e84af83a4700cdf1761ee6d" 46 | } 47 | ], 48 | "name": "Neo Soul", 49 | "owner": { 50 | "external_urls": { 51 | "spotify": "http://open.spotify.com/user/spotify" 52 | }, 53 | "href": "https://api.spotify.com/v1/users/spotify", 54 | "id": "spotify", 55 | "type": "user", 56 | "uri": "spotify:user:spotify" 57 | }, 58 | "public": null, 59 | "tracks": { 60 | "href": "https://api.spotify.com/v1/users/spotify/playlists/51HFHO33vXhvUElwtD9eBD/tracks", 61 | "total": 66 62 | }, 63 | "type": "playlist", 64 | "uri": "spotify:user:spotify:playlist:51HFHO33vXhvUElwtD9eBD" 65 | }, 66 | { 67 | "collaborative": false, 68 | "external_urls": { 69 | "spotify": "http://open.spotify.com/user/spotify/playlist/16BpjqQV1Ey0HeDueNDSYz" 70 | }, 71 | "href": "https://api.spotify.com/v1/users/spotify/playlists/16BpjqQV1Ey0HeDueNDSYz", 72 | "id": "16BpjqQV1Ey0HeDueNDSYz", 73 | "images": [ 74 | { 75 | "url": "https://i.scdn.co/image/a7814e486f761990c9c73672aaa0cbdbaa5983e7" 76 | } 77 | ], 78 | "name": "Afternoon Acoustic", 79 | "owner": { 80 | "external_urls": { 81 | "spotify": "http://open.spotify.com/user/spotify" 82 | }, 83 | "href": "https://api.spotify.com/v1/users/spotify", 84 | "id": "spotify", 85 | "type": "user", 86 | "uri": "spotify:user:spotify" 87 | }, 88 | "public": null, 89 | "tracks": { 90 | "href": "https://api.spotify.com/v1/users/spotify/playlists/16BpjqQV1Ey0HeDueNDSYz/tracks", 91 | "total": 116 92 | }, 93 | "type": "playlist", 94 | "uri": "spotify:user:spotify:playlist:16BpjqQV1Ey0HeDueNDSYz" 95 | }, 96 | { 97 | "collaborative": false, 98 | "external_urls": { 99 | "spotify": "http://open.spotify.com/user/spotify/playlist/4PVvyd4T99XWeIZOFMbT7k" 100 | }, 101 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4PVvyd4T99XWeIZOFMbT7k", 102 | "id": "4PVvyd4T99XWeIZOFMbT7k", 103 | "images": [ 104 | { 105 | "url": "https://i.scdn.co/image/9c3aaec17296bd06a93cf3b8af2c1ea31a099293" 106 | } 107 | ], 108 | "name": "Retro Pop", 109 | "owner": { 110 | "external_urls": { 111 | "spotify": "http://open.spotify.com/user/spotify" 112 | }, 113 | "href": "https://api.spotify.com/v1/users/spotify", 114 | "id": "spotify", 115 | "type": "user", 116 | "uri": "spotify:user:spotify" 117 | }, 118 | "public": null, 119 | "tracks": { 120 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4PVvyd4T99XWeIZOFMbT7k/tracks", 121 | "total": 135 122 | }, 123 | "type": "playlist", 124 | "uri": "spotify:user:spotify:playlist:4PVvyd4T99XWeIZOFMbT7k" 125 | }, 126 | { 127 | "collaborative": false, 128 | "external_urls": { 129 | "spotify": "http://open.spotify.com/user/spotify/playlist/7iiRP3LZPuuoE4dBWWufkw" 130 | }, 131 | "href": "https://api.spotify.com/v1/users/spotify/playlists/7iiRP3LZPuuoE4dBWWufkw", 132 | "id": "7iiRP3LZPuuoE4dBWWufkw", 133 | "images": [ 134 | { 135 | "url": "https://i.scdn.co/image/ab4f838da13bb0b2929accdaa9a0f11cefb0e7a1" 136 | } 137 | ], 138 | "name": "Bring Back the 90s", 139 | "owner": { 140 | "external_urls": { 141 | "spotify": "http://open.spotify.com/user/spotify" 142 | }, 143 | "href": "https://api.spotify.com/v1/users/spotify", 144 | "id": "spotify", 145 | "type": "user", 146 | "uri": "spotify:user:spotify" 147 | }, 148 | "public": null, 149 | "tracks": { 150 | "href": "https://api.spotify.com/v1/users/spotify/playlists/7iiRP3LZPuuoE4dBWWufkw/tracks", 151 | "total": 61 152 | }, 153 | "type": "playlist", 154 | "uri": "spotify:user:spotify:playlist:7iiRP3LZPuuoE4dBWWufkw" 155 | }, 156 | { 157 | "collaborative": false, 158 | "external_urls": { 159 | "spotify": "http://open.spotify.com/user/spotify/playlist/2Qi8yAzfj1KavAhWz1gaem" 160 | }, 161 | "href": "https://api.spotify.com/v1/users/spotify/playlists/2Qi8yAzfj1KavAhWz1gaem", 162 | "id": "2Qi8yAzfj1KavAhWz1gaem", 163 | "images": [ 164 | { 165 | "url": "https://i.scdn.co/image/9d820048e10707dc0ac7ddae33a34bb2b0d10a2a" 166 | } 167 | ], 168 | "name": "Rock Classics", 169 | "owner": { 170 | "external_urls": { 171 | "spotify": "http://open.spotify.com/user/spotify" 172 | }, 173 | "href": "https://api.spotify.com/v1/users/spotify", 174 | "id": "spotify", 175 | "type": "user", 176 | "uri": "spotify:user:spotify" 177 | }, 178 | "public": null, 179 | "tracks": { 180 | "href": "https://api.spotify.com/v1/users/spotify/playlists/2Qi8yAzfj1KavAhWz1gaem/tracks", 181 | "total": 92 182 | }, 183 | "type": "playlist", 184 | "uri": "spotify:user:spotify:playlist:2Qi8yAzfj1KavAhWz1gaem" 185 | }, 186 | { 187 | "collaborative": false, 188 | "external_urls": { 189 | "spotify": "http://open.spotify.com/user/spotify/playlist/44XJR1i3Vl2B3acOEYwinE" 190 | }, 191 | "href": "https://api.spotify.com/v1/users/spotify/playlists/44XJR1i3Vl2B3acOEYwinE", 192 | "id": "44XJR1i3Vl2B3acOEYwinE", 193 | "images": [ 194 | { 195 | "url": "https://i.scdn.co/image/78280176866b4438f27acc7950555d3155876ecd" 196 | } 197 | ], 198 | "name": "Power Ballads", 199 | "owner": { 200 | "external_urls": { 201 | "spotify": "http://open.spotify.com/user/spotify" 202 | }, 203 | "href": "https://api.spotify.com/v1/users/spotify", 204 | "id": "spotify", 205 | "type": "user", 206 | "uri": "spotify:user:spotify" 207 | }, 208 | "public": null, 209 | "tracks": { 210 | "href": "https://api.spotify.com/v1/users/spotify/playlists/44XJR1i3Vl2B3acOEYwinE/tracks", 211 | "total": 79 212 | }, 213 | "type": "playlist", 214 | "uri": "spotify:user:spotify:playlist:44XJR1i3Vl2B3acOEYwinE" 215 | }, 216 | { 217 | "collaborative": false, 218 | "external_urls": { 219 | "spotify": "http://open.spotify.com/user/spotify/playlist/2NFOUmp2wyR5CrXtKDkUkB" 220 | }, 221 | "href": "https://api.spotify.com/v1/users/spotify/playlists/2NFOUmp2wyR5CrXtKDkUkB", 222 | "id": "2NFOUmp2wyR5CrXtKDkUkB", 223 | "images": [ 224 | { 225 | "url": "https://i.scdn.co/image/9ae8f6bf396c435adc6a3288f22beea89f96c099" 226 | } 227 | ], 228 | "name": "Bring Back the 60's", 229 | "owner": { 230 | "external_urls": { 231 | "spotify": "http://open.spotify.com/user/spotify" 232 | }, 233 | "href": "https://api.spotify.com/v1/users/spotify", 234 | "id": "spotify", 235 | "type": "user", 236 | "uri": "spotify:user:spotify" 237 | }, 238 | "public": null, 239 | "tracks": { 240 | "href": "https://api.spotify.com/v1/users/spotify/playlists/2NFOUmp2wyR5CrXtKDkUkB/tracks", 241 | "total": 67 242 | }, 243 | "type": "playlist", 244 | "uri": "spotify:user:spotify:playlist:2NFOUmp2wyR5CrXtKDkUkB" 245 | }, 246 | { 247 | "collaborative": false, 248 | "external_urls": { 249 | "spotify": "http://open.spotify.com/user/spotify/playlist/4jONxQje1Fmw9AFHT7bCp8" 250 | }, 251 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4jONxQje1Fmw9AFHT7bCp8", 252 | "id": "4jONxQje1Fmw9AFHT7bCp8", 253 | "images": [ 254 | { 255 | "url": "https://i.scdn.co/image/1fb8c82d01eef0dd860c7a74e604e0d332bd50dc" 256 | } 257 | ], 258 | "name": "Old School Hip Hop", 259 | "owner": { 260 | "external_urls": { 261 | "spotify": "http://open.spotify.com/user/spotify" 262 | }, 263 | "href": "https://api.spotify.com/v1/users/spotify", 264 | "id": "spotify", 265 | "type": "user", 266 | "uri": "spotify:user:spotify" 267 | }, 268 | "public": null, 269 | "tracks": { 270 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4jONxQje1Fmw9AFHT7bCp8/tracks", 271 | "total": 84 272 | }, 273 | "type": "playlist", 274 | "uri": "spotify:user:spotify:playlist:4jONxQje1Fmw9AFHT7bCp8" 275 | }, 276 | { 277 | "collaborative": false, 278 | "external_urls": { 279 | "spotify": "http://open.spotify.com/user/spotify/playlist/0c8Y6trDz57umvTPFlo1zF" 280 | }, 281 | "href": "https://api.spotify.com/v1/users/spotify/playlists/0c8Y6trDz57umvTPFlo1zF", 282 | "id": "0c8Y6trDz57umvTPFlo1zF", 283 | "images": [ 284 | { 285 | "url": "https://i.scdn.co/image/a4ac931e334d14c24579dbda0c1716b31d2e0f91" 286 | } 287 | ], 288 | "name": "Femme Fatale", 289 | "owner": { 290 | "external_urls": { 291 | "spotify": "http://open.spotify.com/user/spotify" 292 | }, 293 | "href": "https://api.spotify.com/v1/users/spotify", 294 | "id": "spotify", 295 | "type": "user", 296 | "uri": "spotify:user:spotify" 297 | }, 298 | "public": null, 299 | "tracks": { 300 | "href": "https://api.spotify.com/v1/users/spotify/playlists/0c8Y6trDz57umvTPFlo1zF/tracks", 301 | "total": 79 302 | }, 303 | "type": "playlist", 304 | "uri": "spotify:user:spotify:playlist:0c8Y6trDz57umvTPFlo1zF" 305 | }, 306 | { 307 | "collaborative": false, 308 | "external_urls": { 309 | "spotify": "http://open.spotify.com/user/spotify/playlist/42zGB0WsGn8nb1SCS3xtQr" 310 | }, 311 | "href": "https://api.spotify.com/v1/users/spotify/playlists/42zGB0WsGn8nb1SCS3xtQr", 312 | "id": "42zGB0WsGn8nb1SCS3xtQr", 313 | "images": [ 314 | { 315 | "url": "https://i.scdn.co/image/96454a691a1170f21d77f9802521ddfcf9d085f1" 316 | } 317 | ], 318 | "name": "California Sun", 319 | "owner": { 320 | "external_urls": { 321 | "spotify": "http://open.spotify.com/user/spotify" 322 | }, 323 | "href": "https://api.spotify.com/v1/users/spotify", 324 | "id": "spotify", 325 | "type": "user", 326 | "uri": "spotify:user:spotify" 327 | }, 328 | "public": null, 329 | "tracks": { 330 | "href": "https://api.spotify.com/v1/users/spotify/playlists/42zGB0WsGn8nb1SCS3xtQr/tracks", 331 | "total": 26 332 | }, 333 | "type": "playlist", 334 | "uri": "spotify:user:spotify:playlist:42zGB0WsGn8nb1SCS3xtQr" 335 | }, 336 | { 337 | "collaborative": false, 338 | "external_urls": { 339 | "spotify": "http://open.spotify.com/user/spotify/playlist/4bWgWsz9p9eZVtpIvBgbsj" 340 | }, 341 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4bWgWsz9p9eZVtpIvBgbsj", 342 | "id": "4bWgWsz9p9eZVtpIvBgbsj", 343 | "images": [ 344 | { 345 | "url": "https://i.scdn.co/image/abb30d1f84ff24ab8c7cb2887814e53ff164a3e9" 346 | } 347 | ], 348 | "name": "From a Smokey Bar ", 349 | "owner": { 350 | "external_urls": { 351 | "spotify": "http://open.spotify.com/user/spotify" 352 | }, 353 | "href": "https://api.spotify.com/v1/users/spotify", 354 | "id": "spotify", 355 | "type": "user", 356 | "uri": "spotify:user:spotify" 357 | }, 358 | "public": null, 359 | "tracks": { 360 | "href": "https://api.spotify.com/v1/users/spotify/playlists/4bWgWsz9p9eZVtpIvBgbsj/tracks", 361 | "total": 47 362 | }, 363 | "type": "playlist", 364 | "uri": "spotify:user:spotify:playlist:4bWgWsz9p9eZVtpIvBgbsj" 365 | } 366 | ], 367 | "limit": 20, 368 | "next": null, 369 | "offset": 0, 370 | "previous": null, 371 | "total": 12 372 | } 373 | } 374 | -------------------------------------------------------------------------------- /__test__/fixtures/follow_are_following_playlist.json: -------------------------------------------------------------------------------- 1 | [true, false] 2 | -------------------------------------------------------------------------------- /__test__/fixtures/follow_is_following_artists.json: -------------------------------------------------------------------------------- 1 | [true] 2 | -------------------------------------------------------------------------------- /__test__/fixtures/follow_is_following_users.json: -------------------------------------------------------------------------------- 1 | [true, false] 2 | -------------------------------------------------------------------------------- /__test__/fixtures/genre_seeds.json: -------------------------------------------------------------------------------- 1 | { 2 | "genres": [ 3 | "acoustic", 4 | "afrobeat", 5 | "alt-rock", 6 | "alternative", 7 | "ambient", 8 | "anime", 9 | "black-metal", 10 | "bluegrass", 11 | "blues", 12 | "bossanova", 13 | "brazil", 14 | "breakbeat", 15 | "british", 16 | "cantopop", 17 | "chicago-house", 18 | "children", 19 | "chill", 20 | "classical", 21 | "club", 22 | "comedy", 23 | "country", 24 | "dance", 25 | "dancehall", 26 | "death-metal", 27 | "deep-house", 28 | "detroit-techno", 29 | "disco", 30 | "disney", 31 | "drum-and-bass", 32 | "dub", 33 | "dubstep", 34 | "edm", 35 | "electro", 36 | "electronic", 37 | "emo", 38 | "folk", 39 | "forro", 40 | "french", 41 | "funk", 42 | "garage", 43 | "german", 44 | "gospel", 45 | "goth", 46 | "grindcore", 47 | "groove", 48 | "grunge", 49 | "guitar", 50 | "happy", 51 | "hard-rock", 52 | "hardcore", 53 | "hardstyle", 54 | "heavy-metal", 55 | "hip-hop", 56 | "holidays", 57 | "honky-tonk", 58 | "house", 59 | "idm", 60 | "indian", 61 | "indie", 62 | "indie-pop", 63 | "industrial", 64 | "iranian", 65 | "j-dance", 66 | "j-idol", 67 | "j-pop", 68 | "j-rock", 69 | "jazz", 70 | "k-pop", 71 | "kids", 72 | "latin", 73 | "latino", 74 | "malay", 75 | "mandopop", 76 | "metal", 77 | "metal-misc", 78 | "metalcore", 79 | "minimal-techno", 80 | "movies", 81 | "mpb", 82 | "new-age", 83 | "new-release", 84 | "opera", 85 | "pagode", 86 | "party", 87 | "philippines-opm", 88 | "piano", 89 | "pop", 90 | "pop-film", 91 | "post-dubstep", 92 | "power-pop", 93 | "progressive-house", 94 | "psych-rock", 95 | "punk", 96 | "punk-rock", 97 | "r-n-b", 98 | "rainy-day", 99 | "reggae", 100 | "reggaeton", 101 | "road-trip", 102 | "rock", 103 | "rock-n-roll", 104 | "rockabilly", 105 | "romance", 106 | "sad", 107 | "salsa", 108 | "samba", 109 | "sertanejo", 110 | "show-tunes", 111 | "singer-songwriter", 112 | "ska", 113 | "sleep", 114 | "songwriter", 115 | "soul", 116 | "soundtracks", 117 | "spanish", 118 | "study", 119 | "summer", 120 | "swedish", 121 | "synth-pop", 122 | "tango", 123 | "techno", 124 | "trance", 125 | "trip-hop", 126 | "turkish", 127 | "work-out", 128 | "world-music" 129 | ] 130 | } 131 | -------------------------------------------------------------------------------- /__test__/fixtures/me.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Some Random User", 3 | "external_urls": { 4 | "spotify": "https://open.spotify.com/user/some_random_user" 5 | }, 6 | "href": "https://api.spotify.com/v1/users/some_random_user", 7 | "id": "some_random_user", 8 | "images": [ 9 | { 10 | "height": null, 11 | "url": "http://profile-images.scdn.co/images/userprofile/default/xx", 12 | "width": null 13 | } 14 | ], 15 | "product": "premium", 16 | "type": "user", 17 | "uri": "spotify:user:some_random_user" 18 | } 19 | -------------------------------------------------------------------------------- /__test__/fixtures/playlist_cover_image.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "height": 640, 4 | "url": "https://u.scdn.co/images/pl/default/438f9b65ac4eb48681351593142daeb070986293", 5 | "width": 640 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /__test__/fixtures/playlist_tracks.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/users/wizzler/playlists/0EIVqzEcrY2a8vO0AUJar2/tracks", 3 | "items": [ 4 | { 5 | "added_at": "2013-08-21T15:10:32Z", 6 | "added_by": { 7 | "external_urls": { 8 | "spotify": "http://open.spotify.com/user/wizzler" 9 | }, 10 | "href": "https://api.spotify.com/v1/users/wizzler", 11 | "id": "wizzler", 12 | "type": "user", 13 | "uri": "spotify:user:wizzler" 14 | }, 15 | "track": { 16 | "album": { 17 | "album_type": "compilation", 18 | "external_urls": { 19 | "spotify": "https://open.spotify.com/album/1tlMz7hGkgAvwfSkBjjKaX" 20 | }, 21 | "href": "https://api.spotify.com/v1/albums/1tlMz7hGkgAvwfSkBjjKaX", 22 | "id": "1tlMz7hGkgAvwfSkBjjKaX", 23 | "images": [ 24 | { 25 | "height": 640, 26 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/d3a61153502e003eeb7f3fe24a14c4da21d59c27", 27 | "width": 640 28 | }, 29 | { 30 | "height": 300, 31 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/fbc5f6bbaf63ed3aad3b2f9fd7a039ce41575d37", 32 | "width": 300 33 | }, 34 | { 35 | "height": 64, 36 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/37f6f93843792d7cda0c705c0d8c407f588a98cb", 37 | "width": 64 38 | } 39 | ], 40 | "name": "Archive #2 (1976-1992)", 41 | "type": "album", 42 | "uri": "spotify:album:1tlMz7hGkgAvwfSkBjjKaX" 43 | }, 44 | "artists": [ 45 | { 46 | "external_urls": { 47 | "spotify": "https://open.spotify.com/artist/3CkvROUTQ6nRi9yQOcsB50" 48 | }, 49 | "href": "https://api.spotify.com/v1/artists/3CkvROUTQ6nRi9yQOcsB50", 50 | "id": "3CkvROUTQ6nRi9yQOcsB50", 51 | "name": "Genesis", 52 | "type": "artist", 53 | "uri": "spotify:artist:3CkvROUTQ6nRi9yQOcsB50" 54 | } 55 | ], 56 | "available_markets": [ 57 | "AD", 58 | "AR", 59 | "AT", 60 | "AU", 61 | "BE", 62 | "BG", 63 | "BO", 64 | "BR", 65 | "CH", 66 | "CL", 67 | "CO", 68 | "CR", 69 | "CY", 70 | "CZ", 71 | "DE", 72 | "DK", 73 | "DO", 74 | "EC", 75 | "EE", 76 | "ES", 77 | "FI", 78 | "FR", 79 | "GB", 80 | "GR", 81 | "GT", 82 | "HK", 83 | "HN", 84 | "HU", 85 | "IE", 86 | "IS", 87 | "IT", 88 | "LI", 89 | "LT", 90 | "LU", 91 | "LV", 92 | "MC", 93 | "MT", 94 | "MX", 95 | "MY", 96 | "NI", 97 | "NL", 98 | "NO", 99 | "NZ", 100 | "PA", 101 | "PE", 102 | "PH", 103 | "PL", 104 | "PT", 105 | "PY", 106 | "RO", 107 | "SE", 108 | "SG", 109 | "SI", 110 | "SK", 111 | "SV", 112 | "TR", 113 | "TW", 114 | "UY" 115 | ], 116 | "disc_number": 1, 117 | "duration_ms": 234066, 118 | "explicit": false, 119 | "external_ids": { 120 | "isrc": "GBAAA0000806" 121 | }, 122 | "external_urls": { 123 | "spotify": "https://open.spotify.com/track/0ktyIiKtDZS71pIykdHZ08" 124 | }, 125 | "href": "https://api.spotify.com/v1/tracks/0ktyIiKtDZS71pIykdHZ08", 126 | "id": "0ktyIiKtDZS71pIykdHZ08", 127 | "name": "Naminanu - 2000 Digital Remaster", 128 | "popularity": 0, 129 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/f8982594262e8cdc158a7b0caede12723f84016a", 130 | "track_number": 8, 131 | "type": "track", 132 | "uri": "spotify:track:0ktyIiKtDZS71pIykdHZ08" 133 | } 134 | } 135 | ], 136 | "limit": 100, 137 | "next": null, 138 | "offset": 0, 139 | "previous": null, 140 | "total": 2 141 | } 142 | -------------------------------------------------------------------------------- /__test__/fixtures/recently_played_tracks.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | { 4 | "track": { 5 | "artists": [ 6 | { 7 | "external_urls": { 8 | "spotify": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb" 9 | }, 10 | "href": "https://api.spotify.com/v1/artists/5INjqkS1o8h1imAzPqGZBb", 11 | "id": "5INjqkS1o8h1imAzPqGZBb", 12 | "name": "Tame Impala", 13 | "type": "artist", 14 | "uri": "spotify:artist:5INjqkS1o8h1imAzPqGZBb" 15 | } 16 | ], 17 | "available_markets": ["CA", "MX", "US"], 18 | "disc_number": 1, 19 | "duration_ms": 108546, 20 | "explicit": false, 21 | "external_urls": { 22 | "spotify": "https://open.spotify.com/track/2gNfxysfBRfl9Lvi9T3v6R" 23 | }, 24 | "href": "https://api.spotify.com/v1/tracks/2gNfxysfBRfl9Lvi9T3v6R", 25 | "id": "2gNfxysfBRfl9Lvi9T3v6R", 26 | "name": "Disciples", 27 | "preview_url": "https://p.scdn.co/mp3-preview/6023e5aac2123d098ce490488966b28838b14fa2", 28 | "track_number": 9, 29 | "type": "track", 30 | "uri": "spotify:track:2gNfxysfBRfl9Lvi9T3v6R" 31 | }, 32 | "played_at": "2016-12-13T20:44:04.589Z", 33 | "context": { 34 | "uri": "spotify:artist:5INjqkS1o8h1imAzPqGZBb", 35 | "external_urls": { 36 | "spotify": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb" 37 | }, 38 | "href": "https://api.spotify.com/v1/artists/5INjqkS1o8h1imAzPqGZBb", 39 | "type": "artist" 40 | } 41 | }, 42 | { 43 | "track": { 44 | "artists": [ 45 | { 46 | "external_urls": { 47 | "spotify": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb" 48 | }, 49 | "href": "https://api.spotify.com/v1/artists/5INjqkS1o8h1imAzPqGZBb", 50 | "id": "5INjqkS1o8h1imAzPqGZBb", 51 | "name": "Tame Impala", 52 | "type": "artist", 53 | "uri": "spotify:artist:5INjqkS1o8h1imAzPqGZBb" 54 | } 55 | ], 56 | "available_markets": ["CA", "MX", "US"], 57 | "disc_number": 1, 58 | "duration_ms": 467586, 59 | "explicit": false, 60 | "external_urls": { 61 | "spotify": "https://open.spotify.com/track/2X485T9Z5Ly0xyaghN73ed" 62 | }, 63 | "href": "https://api.spotify.com/v1/tracks/2X485T9Z5Ly0xyaghN73ed", 64 | "id": "2X485T9Z5Ly0xyaghN73ed", 65 | "name": "Let It Happen", 66 | "preview_url": "https://p.scdn.co/mp3-preview/05dee1ad0d2a6fa4ad07fbd24ae49d58468e8194", 67 | "track_number": 1, 68 | "type": "track", 69 | "uri": "spotify:track:2X485T9Z5Ly0xyaghN73ed" 70 | }, 71 | "played_at": "2016-12-13T20:42:17.016Z", 72 | "context": { 73 | "uri": "spotify:artist:5INjqkS1o8h1imAzPqGZBb", 74 | "external_urls": { 75 | "spotify": "https://open.spotify.com/artist/5INjqkS1o8h1imAzPqGZBb" 76 | }, 77 | "href": "https://api.spotify.com/v1/artists/5INjqkS1o8h1imAzPqGZBb", 78 | "type": "artist" 79 | } 80 | } 81 | ], 82 | "next": "https://api.spotify.com/v1/me/player/recently-played?before=1481661737016&limit=2", 83 | "cursors": { 84 | "after": "1481661844589", 85 | "before": "1481661737016" 86 | }, 87 | "limit": 2, 88 | "href": "https://api.spotify.com/v1/me/player/recently-played?limit=2" 89 | } 90 | -------------------------------------------------------------------------------- /__test__/fixtures/recommendations.json: -------------------------------------------------------------------------------- 1 | { 2 | "tracks": [ 3 | { 4 | "album": { 5 | "album_type": "ALBUM", 6 | "external_urls": { 7 | "spotify": "https://open.spotify.com/album/3Oc7TFerme2LybRGVAcESO" 8 | }, 9 | "href": "https://api.spotify.com/v1/albums/3Oc7TFerme2LybRGVAcESO", 10 | "id": "3Oc7TFerme2LybRGVAcESO", 11 | "images": [ 12 | { 13 | "height": 640, 14 | "url": "https://i.scdn.co/image/793cdbdaeb491081d0848183e09b4ffc24df8359", 15 | "width": 640 16 | }, 17 | { 18 | "height": 300, 19 | "url": "https://i.scdn.co/image/f71aff71567661308a557d6e0fcc572fdc0d4ca7", 20 | "width": 300 21 | }, 22 | { 23 | "height": 64, 24 | "url": "https://i.scdn.co/image/d218669d0590afa5d7ad4ce5c16b40d22ce5ae1f", 25 | "width": 64 26 | } 27 | ], 28 | "name": "El Regreso del Sobreviviente (Deluxe Edition)", 29 | "type": "album", 30 | "uri": "spotify:album:3Oc7TFerme2LybRGVAcESO" 31 | }, 32 | "artists": [ 33 | { 34 | "external_urls": { 35 | "spotify": "https://open.spotify.com/artist/3E6xrwgnVfYCrCs0ePERDz" 36 | }, 37 | "href": "https://api.spotify.com/v1/artists/3E6xrwgnVfYCrCs0ePERDz", 38 | "id": "3E6xrwgnVfYCrCs0ePERDz", 39 | "name": "Wisin", 40 | "type": "artist", 41 | "uri": "spotify:artist:3E6xrwgnVfYCrCs0ePERDz" 42 | }, 43 | { 44 | "external_urls": { 45 | "spotify": "https://open.spotify.com/artist/2DlGxzQSjYe5N6G9nkYghR" 46 | }, 47 | "href": "https://api.spotify.com/v1/artists/2DlGxzQSjYe5N6G9nkYghR", 48 | "id": "2DlGxzQSjYe5N6G9nkYghR", 49 | "name": "Jennifer Lopez", 50 | "type": "artist", 51 | "uri": "spotify:artist:2DlGxzQSjYe5N6G9nkYghR" 52 | }, 53 | { 54 | "external_urls": { 55 | "spotify": "https://open.spotify.com/artist/7slfeZO9LsJbWgpkIoXBUJ" 56 | }, 57 | "href": "https://api.spotify.com/v1/artists/7slfeZO9LsJbWgpkIoXBUJ", 58 | "id": "7slfeZO9LsJbWgpkIoXBUJ", 59 | "name": "Ricky Martin", 60 | "type": "artist", 61 | "uri": "spotify:artist:7slfeZO9LsJbWgpkIoXBUJ" 62 | } 63 | ], 64 | "disc_number": 1, 65 | "duration_ms": 235546, 66 | "explicit": false, 67 | "external_ids": { 68 | "isrc": "USSD11300395" 69 | }, 70 | "external_urls": { 71 | "spotify": "https://open.spotify.com/track/2eqDUxbd0JPEhNrJdPlHLs" 72 | }, 73 | "href": "https://api.spotify.com/v1/tracks/2eqDUxbd0JPEhNrJdPlHLs", 74 | "id": "2eqDUxbd0JPEhNrJdPlHLs", 75 | "is_playable": true, 76 | "name": "Adrenalina", 77 | "popularity": 71, 78 | "preview_url": "https://p.scdn.co/mp3-preview/887e90341f351d2fc5e204e39729141780251ae0", 79 | "track_number": 3, 80 | "type": "track", 81 | "uri": "spotify:track:2eqDUxbd0JPEhNrJdPlHLs" 82 | }, 83 | { 84 | "album": { 85 | "album_type": "ALBUM", 86 | "external_urls": { 87 | "spotify": "https://open.spotify.com/album/5YByMSqR8kLoigJ3h8xgGD" 88 | }, 89 | "href": "https://api.spotify.com/v1/albums/5YByMSqR8kLoigJ3h8xgGD", 90 | "id": "5YByMSqR8kLoigJ3h8xgGD", 91 | "images": [ 92 | { 93 | "height": 640, 94 | "url": "https://i.scdn.co/image/e7a0990a0ff0c32acf9fe6653efefdbf7caf2357", 95 | "width": 640 96 | }, 97 | { 98 | "height": 300, 99 | "url": "https://i.scdn.co/image/6a27c9e27c2f84678cb487917edc4a16b82c8c30", 100 | "width": 300 101 | }, 102 | { 103 | "height": 64, 104 | "url": "https://i.scdn.co/image/21b38b6ffc5b76b1203df47a96f37e5df14fbcf6", 105 | "width": 64 106 | } 107 | ], 108 | "name": "Antes de que cuente diez", 109 | "type": "album", 110 | "uri": "spotify:album:5YByMSqR8kLoigJ3h8xgGD" 111 | }, 112 | "artists": [ 113 | { 114 | "external_urls": { 115 | "spotify": "https://open.spotify.com/artist/1tZ99AnqyjgrmPwLfGU5eo" 116 | }, 117 | "href": "https://api.spotify.com/v1/artists/1tZ99AnqyjgrmPwLfGU5eo", 118 | "id": "1tZ99AnqyjgrmPwLfGU5eo", 119 | "name": "Fito y Fitipaldis", 120 | "type": "artist", 121 | "uri": "spotify:artist:1tZ99AnqyjgrmPwLfGU5eo" 122 | } 123 | ], 124 | "disc_number": 1, 125 | "duration_ms": 245213, 126 | "explicit": false, 127 | "external_ids": { 128 | "isrc": "ES5150901070" 129 | }, 130 | "external_urls": { 131 | "spotify": "https://open.spotify.com/track/0HYj1k4x1awDQLNZW96MYA" 132 | }, 133 | "href": "https://api.spotify.com/v1/tracks/0HYj1k4x1awDQLNZW96MYA", 134 | "id": "0HYj1k4x1awDQLNZW96MYA", 135 | "is_playable": true, 136 | "name": "Me acorde de ti", 137 | "popularity": 53, 138 | "preview_url": "https://p.scdn.co/mp3-preview/a171cb88e05ec69932f534ac6cf0b56c098f1a4f", 139 | "track_number": 2, 140 | "type": "track", 141 | "uri": "spotify:track:0HYj1k4x1awDQLNZW96MYA" 142 | }, 143 | { 144 | "album": { 145 | "album_type": "ALBUM", 146 | "external_urls": { 147 | "spotify": "https://open.spotify.com/album/3jdYDg5KQ9d8uBGleBlGYY" 148 | }, 149 | "href": "https://api.spotify.com/v1/albums/3jdYDg5KQ9d8uBGleBlGYY", 150 | "id": "3jdYDg5KQ9d8uBGleBlGYY", 151 | "images": [ 152 | { 153 | "height": 640, 154 | "url": "https://i.scdn.co/image/fe9c4f17a657f3490ccdf0779e319b3684294bdc", 155 | "width": 640 156 | }, 157 | { 158 | "height": 300, 159 | "url": "https://i.scdn.co/image/da75790f86aba84e15b592746de35bcc30579af4", 160 | "width": 300 161 | }, 162 | { 163 | "height": 64, 164 | "url": "https://i.scdn.co/image/c745b92cc19f25b17a63fb44a1091e405038225c", 165 | "width": 64 166 | } 167 | ], 168 | "name": "Sentimiento, Elegancia Y Maldad", 169 | "type": "album", 170 | "uri": "spotify:album:3jdYDg5KQ9d8uBGleBlGYY" 171 | }, 172 | "artists": [ 173 | { 174 | "external_urls": { 175 | "spotify": "https://open.spotify.com/artist/4SsVbpTthjScTS7U2hmr1X" 176 | }, 177 | "href": "https://api.spotify.com/v1/artists/4SsVbpTthjScTS7U2hmr1X", 178 | "id": "4SsVbpTthjScTS7U2hmr1X", 179 | "name": "Arcangel", 180 | "type": "artist", 181 | "uri": "spotify:artist:4SsVbpTthjScTS7U2hmr1X" 182 | } 183 | ], 184 | "disc_number": 1, 185 | "duration_ms": 244120, 186 | "explicit": false, 187 | "external_ids": { 188 | "isrc": "USB271311017" 189 | }, 190 | "external_urls": { 191 | "spotify": "https://open.spotify.com/track/3D1WVvSo2Mjc4Nf9rF4XqW" 192 | }, 193 | "href": "https://api.spotify.com/v1/tracks/3D1WVvSo2Mjc4Nf9rF4XqW", 194 | "id": "3D1WVvSo2Mjc4Nf9rF4XqW", 195 | "is_playable": true, 196 | "name": "Como Tiene Que Ser", 197 | "popularity": 51, 198 | "preview_url": "https://p.scdn.co/mp3-preview/28b8f76703da1687ae0abb8e0eecfb99fc5214a1", 199 | "track_number": 8, 200 | "type": "track", 201 | "uri": "spotify:track:3D1WVvSo2Mjc4Nf9rF4XqW" 202 | }, 203 | { 204 | "album": { 205 | "album_type": "ALBUM", 206 | "external_urls": { 207 | "spotify": "https://open.spotify.com/album/6WnU9fIvoqP5R2O2KFiif7" 208 | }, 209 | "href": "https://api.spotify.com/v1/albums/6WnU9fIvoqP5R2O2KFiif7", 210 | "id": "6WnU9fIvoqP5R2O2KFiif7", 211 | "images": [ 212 | { 213 | "height": 640, 214 | "url": "https://i.scdn.co/image/ef5d857a209472cbb297b6517ccfe6ef46a75a64", 215 | "width": 640 216 | }, 217 | { 218 | "height": 300, 219 | "url": "https://i.scdn.co/image/498b179fe6da039430ff26534ac14d39648a3af7", 220 | "width": 300 221 | }, 222 | { 223 | "height": 64, 224 | "url": "https://i.scdn.co/image/5e9123608882a7dac5bc3ed596719da28204984d", 225 | "width": 64 226 | } 227 | ], 228 | "name": "Señal de Vida", 229 | "type": "album", 230 | "uri": "spotify:album:6WnU9fIvoqP5R2O2KFiif7" 231 | }, 232 | "artists": [ 233 | { 234 | "external_urls": { 235 | "spotify": "https://open.spotify.com/artist/2OHKEe204spO7G7NcbeO2o" 236 | }, 237 | "href": "https://api.spotify.com/v1/artists/2OHKEe204spO7G7NcbeO2o", 238 | "id": "2OHKEe204spO7G7NcbeO2o", 239 | "name": "Ñejo", 240 | "type": "artist", 241 | "uri": "spotify:artist:2OHKEe204spO7G7NcbeO2o" 242 | }, 243 | { 244 | "external_urls": { 245 | "spotify": "https://open.spotify.com/artist/3jGlU8UMMo44I2xeLQ6FD3" 246 | }, 247 | "href": "https://api.spotify.com/v1/artists/3jGlU8UMMo44I2xeLQ6FD3", 248 | "id": "3jGlU8UMMo44I2xeLQ6FD3", 249 | "name": "Dalmata", 250 | "type": "artist", 251 | "uri": "spotify:artist:3jGlU8UMMo44I2xeLQ6FD3" 252 | } 253 | ], 254 | "disc_number": 1, 255 | "duration_ms": 240240, 256 | "explicit": false, 257 | "external_ids": { 258 | "isrc": "QMFME1393106" 259 | }, 260 | "external_urls": { 261 | "spotify": "https://open.spotify.com/track/4KAk2OscoVby5SKtNxEeI3" 262 | }, 263 | "href": "https://api.spotify.com/v1/tracks/4KAk2OscoVby5SKtNxEeI3", 264 | "id": "4KAk2OscoVby5SKtNxEeI3", 265 | "is_playable": true, 266 | "name": "Señal de Vida - Radio Edit", 267 | "popularity": 57, 268 | "preview_url": "https://p.scdn.co/mp3-preview/5ae502392e37e87e94ed7a8072e8cfbf0bd1a24a", 269 | "track_number": 1, 270 | "type": "track", 271 | "uri": "spotify:track:4KAk2OscoVby5SKtNxEeI3" 272 | }, 273 | { 274 | "album": { 275 | "album_type": "ALBUM", 276 | "external_urls": { 277 | "spotify": "https://open.spotify.com/album/2hdR2Eahz36zXqC62LhmGo" 278 | }, 279 | "href": "https://api.spotify.com/v1/albums/2hdR2Eahz36zXqC62LhmGo", 280 | "id": "2hdR2Eahz36zXqC62LhmGo", 281 | "images": [ 282 | { 283 | "height": 556, 284 | "url": "https://i.scdn.co/image/957ddf7862ce8fde240664bf16a1996be12fa8be", 285 | "width": 640 286 | }, 287 | { 288 | "height": 261, 289 | "url": "https://i.scdn.co/image/0d91da3a0c308a98be67123cccc420aafe24d150", 290 | "width": 300 291 | }, 292 | { 293 | "height": 56, 294 | "url": "https://i.scdn.co/image/d45c7dd098447a9fcbc1b911ac20256484c3ee3a", 295 | "width": 64 296 | } 297 | ], 298 | "name": "Algo para Cantar", 299 | "type": "album", 300 | "uri": "spotify:album:2hdR2Eahz36zXqC62LhmGo" 301 | }, 302 | "artists": [ 303 | { 304 | "external_urls": { 305 | "spotify": "https://open.spotify.com/artist/6mfK6Q2tzLMEchAr0e9Uzu" 306 | }, 307 | "href": "https://api.spotify.com/v1/artists/6mfK6Q2tzLMEchAr0e9Uzu", 308 | "id": "6mfK6Q2tzLMEchAr0e9Uzu", 309 | "name": "Pereza", 310 | "type": "artist", 311 | "uri": "spotify:artist:6mfK6Q2tzLMEchAr0e9Uzu" 312 | } 313 | ], 314 | "disc_number": 1, 315 | "duration_ms": 172600, 316 | "explicit": false, 317 | "external_ids": { 318 | "isrc": "ES5020200442" 319 | }, 320 | "external_urls": { 321 | "spotify": "https://open.spotify.com/track/5dncXckT4fSDlyEL9QgzuY" 322 | }, 323 | "href": "https://api.spotify.com/v1/tracks/5dncXckT4fSDlyEL9QgzuY", 324 | "id": "5dncXckT4fSDlyEL9QgzuY", 325 | "is_playable": true, 326 | "name": "Pienso en Aquella Tarde", 327 | "popularity": 51, 328 | "preview_url": "https://p.scdn.co/mp3-preview/9428bf8f4b9b615d100aae1d61dd39d9a18703ad", 329 | "track_number": 1, 330 | "type": "track", 331 | "uri": "spotify:track:5dncXckT4fSDlyEL9QgzuY" 332 | } 333 | ], 334 | "seeds": [ 335 | { 336 | "initialPoolSize": 250, 337 | "afterFilteringSize": 129, 338 | "afterRelinkingSize": 129, 339 | "id": "6mfK6Q2tzLMEchAr0e9Uzu", 340 | "type": "ARTIST", 341 | "href": "https://api.spotify.com/v1/artists/6mfK6Q2tzLMEchAr0e9Uzu" 342 | }, 343 | { 344 | "initialPoolSize": 250, 345 | "afterFilteringSize": 225, 346 | "afterRelinkingSize": 222, 347 | "id": "4DYFVNKZ1uixa6SQTvzQwJ", 348 | "type": "ARTIST", 349 | "href": "https://api.spotify.com/v1/artists/4DYFVNKZ1uixa6SQTvzQwJ" 350 | } 351 | ] 352 | } 353 | -------------------------------------------------------------------------------- /__test__/fixtures/search.json: -------------------------------------------------------------------------------- 1 | { 2 | "artists": { 3 | "href": "https://api.spotify.com/v1/search?query=muse&offset=0&limit=1&type=artist", 4 | "items": [ 5 | { 6 | "external_urls": { 7 | "spotify": "https://open.spotify.com/artist/12Chz98pHFMPJEknJQMWvI" 8 | }, 9 | "followers": { 10 | "href": null, 11 | "total": 2052604 12 | }, 13 | "genres": [], 14 | "href": "https://api.spotify.com/v1/artists/12Chz98pHFMPJEknJQMWvI", 15 | "id": "12Chz98pHFMPJEknJQMWvI", 16 | "images": [ 17 | { 18 | "height": 667, 19 | "url": "https://i.scdn.co/image/0b3c04473aa6a2db8235e5092ec3413f35752b8d", 20 | "width": 1000 21 | }, 22 | { 23 | "height": 427, 24 | "url": "https://i.scdn.co/image/cf54c2d4a4549fb484862a9c475fc897bb5ce707", 25 | "width": 640 26 | }, 27 | { 28 | "height": 133, 29 | "url": "https://i.scdn.co/image/837c977024362a7f6d1873027e2a8664e21f911a", 30 | "width": 200 31 | }, 32 | { 33 | "height": 43, 34 | "url": "https://i.scdn.co/image/0b14ff7b9c9fcfaf6b662fe439576c531b0aa8d8", 35 | "width": 64 36 | } 37 | ], 38 | "name": "Muse", 39 | "popularity": 81, 40 | "type": "artist", 41 | "uri": "spotify:artist:12Chz98pHFMPJEknJQMWvI" 42 | } 43 | ], 44 | "limit": 1, 45 | "next": "https://api.spotify.com/v1/search?query=muse&offset=1&limit=1&type=artist", 46 | "offset": 0, 47 | "previous": null, 48 | "total": 405 49 | }, 50 | "tracks": { 51 | "href": "https://api.spotify.com/v1/search?query=muse&offset=0&limit=1&type=track", 52 | "items": [ 53 | { 54 | "album": { 55 | "album_type": "album", 56 | "available_markets": [ 57 | "AR", 58 | "AU", 59 | "AT", 60 | "BE", 61 | "BO", 62 | "BR", 63 | "BG", 64 | "CA", 65 | "CL", 66 | "CO", 67 | "CR", 68 | "CY", 69 | "CZ", 70 | "DK", 71 | "DO", 72 | "DE", 73 | "EC", 74 | "EE", 75 | "SV", 76 | "FI", 77 | "FR", 78 | "GR", 79 | "GT", 80 | "HN", 81 | "HK", 82 | "HU", 83 | "IS", 84 | "IE", 85 | "IT", 86 | "LV", 87 | "LT", 88 | "LU", 89 | "MY", 90 | "MT", 91 | "MX", 92 | "NL", 93 | "NZ", 94 | "NI", 95 | "NO", 96 | "PA", 97 | "PY", 98 | "PE", 99 | "PH", 100 | "PL", 101 | "PT", 102 | "SG", 103 | "SK", 104 | "ES", 105 | "SE", 106 | "CH", 107 | "TW", 108 | "TR", 109 | "UY", 110 | "US", 111 | "GB", 112 | "AD", 113 | "MC", 114 | "ID" 115 | ], 116 | "external_urls": { 117 | "spotify": "https://open.spotify.com/album/6s2isojT7rGZUgJyymjjKU" 118 | }, 119 | "href": "https://api.spotify.com/v1/albums/6s2isojT7rGZUgJyymjjKU", 120 | "id": "6s2isojT7rGZUgJyymjjKU", 121 | "images": [ 122 | { 123 | "height": 640, 124 | "url": "https://i.scdn.co/image/dee2b853269efd27747d8ac68020cc620248dc4e", 125 | "width": 640 126 | }, 127 | { 128 | "height": 300, 129 | "url": "https://i.scdn.co/image/a31a9eb4ea2850f01136d61f7b837ddd81e4292d", 130 | "width": 300 131 | }, 132 | { 133 | "height": 64, 134 | "url": "https://i.scdn.co/image/dd4022f7be53c35543209258b74f09b4581d7361", 135 | "width": 64 136 | } 137 | ], 138 | "name": "PARTYNEXTDOOR TWO", 139 | "type": "album", 140 | "uri": "spotify:album:6s2isojT7rGZUgJyymjjKU" 141 | }, 142 | "artists": [ 143 | { 144 | "external_urls": { 145 | "spotify": "https://open.spotify.com/artist/2HPaUgqeutzr3jx5a9WyDV" 146 | }, 147 | "href": "https://api.spotify.com/v1/artists/2HPaUgqeutzr3jx5a9WyDV", 148 | "id": "2HPaUgqeutzr3jx5a9WyDV", 149 | "name": "PARTYNEXTDOOR", 150 | "type": "artist", 151 | "uri": "spotify:artist:2HPaUgqeutzr3jx5a9WyDV" 152 | } 153 | ], 154 | "available_markets": [ 155 | "AR", 156 | "AU", 157 | "AT", 158 | "BE", 159 | "BO", 160 | "BR", 161 | "BG", 162 | "CA", 163 | "CL", 164 | "CO", 165 | "CR", 166 | "CY", 167 | "CZ", 168 | "DK", 169 | "DO", 170 | "DE", 171 | "EC", 172 | "EE", 173 | "SV", 174 | "FI", 175 | "FR", 176 | "GR", 177 | "GT", 178 | "HN", 179 | "HK", 180 | "HU", 181 | "IS", 182 | "IE", 183 | "IT", 184 | "LV", 185 | "LT", 186 | "LU", 187 | "MY", 188 | "MT", 189 | "MX", 190 | "NL", 191 | "NZ", 192 | "NI", 193 | "NO", 194 | "PA", 195 | "PY", 196 | "PE", 197 | "PH", 198 | "PL", 199 | "PT", 200 | "SG", 201 | "SK", 202 | "ES", 203 | "SE", 204 | "CH", 205 | "TW", 206 | "TR", 207 | "UY", 208 | "US", 209 | "GB", 210 | "AD", 211 | "MC", 212 | "ID" 213 | ], 214 | "disc_number": 1, 215 | "duration_ms": 203324, 216 | "explicit": true, 217 | "external_ids": { 218 | "isrc": "USWB11401870" 219 | }, 220 | "external_urls": { 221 | "spotify": "https://open.spotify.com/track/41ipOYFGT2MW4dvOPkoK1f" 222 | }, 223 | "href": "https://api.spotify.com/v1/tracks/41ipOYFGT2MW4dvOPkoK1f", 224 | "id": "41ipOYFGT2MW4dvOPkoK1f", 225 | "name": "Muse", 226 | "popularity": 58, 227 | "preview_url": "https://p.scdn.co/mp3-preview/d03f4da489977e44fe92e95f771b2ace9607fbcc", 228 | "track_number": 12, 229 | "type": "track", 230 | "uri": "spotify:track:41ipOYFGT2MW4dvOPkoK1f" 231 | } 232 | ], 233 | "limit": 1, 234 | "next": "https://api.spotify.com/v1/search?query=muse&offset=1&limit=1&type=track", 235 | "offset": 0, 236 | "previous": null, 237 | "total": 32436 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /__test__/fixtures/search_album.json: -------------------------------------------------------------------------------- 1 | { 2 | "albums": { 3 | "href": "https://api.spotify.com/v1/search?query=gatan&offset=1&limit=1&type=album", 4 | "items": [ 5 | { 6 | "album_type": "single", 7 | "external_urls": { 8 | "spotify": "https://open.spotify.com/album/5CCjGmIH483h4J9UvME0eR" 9 | }, 10 | "href": "https://api.spotify.com/v1/albums/5CCjGmIH483h4J9UvME0eR", 11 | "id": "5CCjGmIH483h4J9UvME0eR", 12 | "images": [ 13 | { 14 | "height": 640, 15 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/743f134a97aa904f90674be6f304db28c8be91f7", 16 | "width": 640 17 | }, 18 | { 19 | "height": 300, 20 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/09ff1e1144cc297d42acaaa839e0ad422ba7abe5", 21 | "width": 300 22 | }, 23 | { 24 | "height": 64, 25 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/66d320404c8f56bb7dd0c53da61f794a70a7e07c", 26 | "width": 64 27 | } 28 | ], 29 | "name": "Lyckliga gatan", 30 | "type": "album", 31 | "uri": "spotify:album:5CCjGmIH483h4J9UvME0eR" 32 | } 33 | ], 34 | "limit": 1, 35 | "next": "https://api.spotify.com/v1/search?query=gatan&offset=2&limit=1&type=album", 36 | "offset": 1, 37 | "previous": "https://api.spotify.com/v1/search?query=gatan&offset=0&limit=1&type=album", 38 | "total": 17 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /__test__/fixtures/search_artist.json: -------------------------------------------------------------------------------- 1 | { 2 | "artists": { 3 | "href": "https://api.spotify.com/v1/search?query=gatan&offset=0&limit=20&type=artist", 4 | "items": [ 5 | { 6 | "external_urls": { 7 | "spotify": "https://open.spotify.com/artist/2Bw6FyyzgCc8OD7MX59TEQ" 8 | }, 9 | "genres": [], 10 | "href": "https://api.spotify.com/v1/artists/2Bw6FyyzgCc8OD7MX59TEQ", 11 | "id": "2Bw6FyyzgCc8OD7MX59TEQ", 12 | "images": [ 13 | { 14 | "height": 640, 15 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/26ca12528f16760d71c6e304a747c827b6baea50", 16 | "width": 640 17 | }, 18 | { 19 | "height": 300, 20 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/7fc613b33c2c2cdb8b30ebb4cb989917096bff0f", 21 | "width": 300 22 | }, 23 | { 24 | "height": 64, 25 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/4b88a1eb9e5c9d3f72d4902d43ea342e51ace932", 26 | "width": 64 27 | } 28 | ], 29 | "name": "Satan I Gatan", 30 | "popularity": 0, 31 | "type": "artist", 32 | "uri": "spotify:artist:2Bw6FyyzgCc8OD7MX59TEQ" 33 | } 34 | ], 35 | "limit": 20, 36 | "next": null, 37 | "offset": 0, 38 | "previous": null, 39 | "total": 1 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /__test__/fixtures/search_episode.json: -------------------------------------------------------------------------------- 1 | { 2 | "episodes": { 3 | "href": "https://api.spotify.com/v1/search?query=web+performance&type=episode&offset=0&limit=1", 4 | "items": [ 5 | { 6 | "audio_preview_url": "https://p.scdn.co/mp3-preview/dae0d881ddb23971b4273e44752b0f5db2d3b2de", 7 | "description": "\"เว็บเร็ว\" เป็นเรื่องสำคัญมากๆ ที่ตะถูกพูดถงหนักเข้าไปอีกในปีนี้ วันนี้ผมจะมาเล่าให้ฟังครับว่า เรื่อง web performance ในปี 2020 นี้ มีอะไรเปลี่ยนไปบ้าง แล้วเราควรจะเริ่มลองศึกษาหรือปรับตัวยังไงบ้าง", 8 | "duration_ms": 915422, 9 | "explicit": false, 10 | "external_urls": { 11 | "spotify": "https://open.spotify.com/episode/7xx0sAk9qmb71XGLedK56d" 12 | }, 13 | "href": "https://api.spotify.com/v1/episodes/7xx0sAk9qmb71XGLedK56d", 14 | "id": "7xx0sAk9qmb71XGLedK56d", 15 | "images": [ 16 | { 17 | "height": 500, 18 | "url": "https://i.scdn.co/image/a53db5fecf206500131753deed4c6c486e1105bb", 19 | "width": 500 20 | }, 21 | { 22 | "height": 300, 23 | "url": "https://i.scdn.co/image/63fd374093d49a2578fe696d92c12d1baed88b59", 24 | "width": 300 25 | }, 26 | { 27 | "height": 64, 28 | "url": "https://i.scdn.co/image/427d5a9834a21a955a7dc252e5996d95c7752417", 29 | "width": 64 30 | } 31 | ], 32 | "is_externally_hosted": false, 33 | "is_playable": true, 34 | "language": "en", 35 | "languages": ["en"], 36 | "name": "EP.20 - Web performance ใน ปี 2020 จะเปลี่ยนไปยังไงบ้าง", 37 | "release_date": "2020-03-30", 38 | "release_date_precision": "day", 39 | "type": "episode", 40 | "uri": "spotify:episode:7xx0sAk9qmb71XGLedK56d" 41 | } 42 | ], 43 | "limit": 1, 44 | "next": "https://api.spotify.com/v1/search?query=web+performance&type=episode&offset=1&limit=1", 45 | "offset": 0, 46 | "previous": null, 47 | "total": 299 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /__test__/fixtures/search_playlist.json: -------------------------------------------------------------------------------- 1 | { 2 | "playlists": { 3 | "href": "https://api.spotify.com/v1/search?query=music&offset=0&limit=5&type=playlist", 4 | "items": [ 5 | { 6 | "collaborative": false, 7 | "external_urls": { 8 | "spotify": "http://open.spotify.com/user/chillls/playlist/6OUo9M97qj4lmSTbnkNm35" 9 | }, 10 | "href": "https://api.spotify.com/v1/users/chillls/playlists/6OUo9M97qj4lmSTbnkNm35", 11 | "id": "6OUo9M97qj4lmSTbnkNm35", 12 | "images": [], 13 | "name": "Christmas Music", 14 | "owner": { 15 | "external_urls": { 16 | "spotify": "http://open.spotify.com/user/chillls" 17 | }, 18 | "href": "https://api.spotify.com/v1/users/chillls", 19 | "id": "chillls", 20 | "type": "user", 21 | "uri": "spotify:user:chillls" 22 | }, 23 | "public": null, 24 | "tracks": { 25 | "href": "https://api.spotify.com/v1/users/chillls/playlists/6OUo9M97qj4lmSTbnkNm35/tracks", 26 | "total": 102 27 | }, 28 | "type": "playlist", 29 | "uri": "spotify:user:chillls:playlist:6OUo9M97qj4lmSTbnkNm35" 30 | }, 31 | { 32 | "collaborative": false, 33 | "external_urls": { 34 | "spotify": "http://open.spotify.com/user/igreene21/playlist/5iQ0qBTxtuSZYsVDsBYxHQ" 35 | }, 36 | "href": "https://api.spotify.com/v1/users/igreene21/playlists/5iQ0qBTxtuSZYsVDsBYxHQ", 37 | "id": "5iQ0qBTxtuSZYsVDsBYxHQ", 38 | "images": [], 39 | "name": "Pre-Game Music", 40 | "owner": { 41 | "external_urls": { 42 | "spotify": "http://open.spotify.com/user/igreene21" 43 | }, 44 | "href": "https://api.spotify.com/v1/users/igreene21", 45 | "id": "igreene21", 46 | "type": "user", 47 | "uri": "spotify:user:igreene21" 48 | }, 49 | "public": null, 50 | "tracks": { 51 | "href": "https://api.spotify.com/v1/users/igreene21/playlists/5iQ0qBTxtuSZYsVDsBYxHQ/tracks", 52 | "total": 270 53 | }, 54 | "type": "playlist", 55 | "uri": "spotify:user:igreene21:playlist:5iQ0qBTxtuSZYsVDsBYxHQ" 56 | }, 57 | { 58 | "collaborative": false, 59 | "external_urls": { 60 | "spotify": "http://open.spotify.com/user/spotify/playlist/5FJXhjdILmRA2z5bvz4nzf" 61 | }, 62 | "href": "https://api.spotify.com/v1/users/spotify/playlists/5FJXhjdILmRA2z5bvz4nzf", 63 | "id": "5FJXhjdILmRA2z5bvz4nzf", 64 | "images": [ 65 | { 66 | "url": "https://i.scdn.co/image/4669088eb741254479f9eb340bf1f93165b93288" 67 | } 68 | ], 69 | "name": "Today's Top Hits", 70 | "owner": { 71 | "external_urls": { 72 | "spotify": "http://open.spotify.com/user/spotify" 73 | }, 74 | "href": "https://api.spotify.com/v1/users/spotify", 75 | "id": "spotify", 76 | "type": "user", 77 | "uri": "spotify:user:spotify" 78 | }, 79 | "public": null, 80 | "tracks": { 81 | "href": "https://api.spotify.com/v1/users/spotify/playlists/5FJXhjdILmRA2z5bvz4nzf/tracks", 82 | "total": 51 83 | }, 84 | "type": "playlist", 85 | "uri": "spotify:user:spotify:playlist:5FJXhjdILmRA2z5bvz4nzf" 86 | }, 87 | { 88 | "collaborative": false, 89 | "external_urls": { 90 | "spotify": "http://open.spotify.com/user/mcs1992/playlist/4HiLVQvLMFLOZBiDGThuOX" 91 | }, 92 | "href": "https://api.spotify.com/v1/users/mcs1992/playlists/4HiLVQvLMFLOZBiDGThuOX", 93 | "id": "4HiLVQvLMFLOZBiDGThuOX", 94 | "images": [ 95 | { 96 | "url": "https://i.scdn.co/image/d7c96c229c76af84b031cd1ed6ef41dd8c5bf3ff" 97 | } 98 | ], 99 | "name": "Relaxed Driving Music - last update: 17-11-'14 (acoustic, vocalist, laid back, chilled out, road trip, unplugged, easy listening, cover, singer-songwriter)", 100 | "owner": { 101 | "external_urls": { 102 | "spotify": "http://open.spotify.com/user/mcs1992" 103 | }, 104 | "href": "https://api.spotify.com/v1/users/mcs1992", 105 | "id": "mcs1992", 106 | "type": "user", 107 | "uri": "spotify:user:mcs1992" 108 | }, 109 | "public": null, 110 | "tracks": { 111 | "href": "https://api.spotify.com/v1/users/mcs1992/playlists/4HiLVQvLMFLOZBiDGThuOX/tracks", 112 | "total": 219 113 | }, 114 | "type": "playlist", 115 | "uri": "spotify:user:mcs1992:playlist:4HiLVQvLMFLOZBiDGThuOX" 116 | }, 117 | { 118 | "collaborative": false, 119 | "external_urls": { 120 | "spotify": "http://open.spotify.com/user/spotify/playlist/65y98W0UItf73DJKVgylTP" 121 | }, 122 | "href": "https://api.spotify.com/v1/users/spotify/playlists/65y98W0UItf73DJKVgylTP", 123 | "id": "65y98W0UItf73DJKVgylTP", 124 | "images": [ 125 | { 126 | "url": "https://i.scdn.co/image/223eaea3d44938b833a86651267db608bea1c5a3" 127 | } 128 | ], 129 | "name": "ESM | Electronic Study Music", 130 | "owner": { 131 | "external_urls": { 132 | "spotify": "http://open.spotify.com/user/spotify" 133 | }, 134 | "href": "https://api.spotify.com/v1/users/spotify", 135 | "id": "spotify", 136 | "type": "user", 137 | "uri": "spotify:user:spotify" 138 | }, 139 | "public": null, 140 | "tracks": { 141 | "href": "https://api.spotify.com/v1/users/spotify/playlists/65y98W0UItf73DJKVgylTP/tracks", 142 | "total": 53 143 | }, 144 | "type": "playlist", 145 | "uri": "spotify:user:spotify:playlist:65y98W0UItf73DJKVgylTP" 146 | } 147 | ], 148 | "limit": 5, 149 | "next": "https://api.spotify.com/v1/search?query=music&offset=5&limit=5&type=playlist", 150 | "offset": 0, 151 | "previous": null, 152 | "total": 106349 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /__test__/fixtures/search_show.json: -------------------------------------------------------------------------------- 1 | { 2 | "shows": { 3 | "href": "https://api.spotify.com/v1/search?query=sweden&type=show&offset=0&limit=1", 4 | "items": [ 5 | { 6 | "available_markets": [ 7 | "AD", 8 | "AE", 9 | "AR", 10 | "AT", 11 | "AU", 12 | "BE", 13 | "BG", 14 | "BH", 15 | "BO", 16 | "BR", 17 | "CA", 18 | "CH", 19 | "CL", 20 | "CO", 21 | "CR", 22 | "CY", 23 | "CZ", 24 | "DE", 25 | "DK", 26 | "DO", 27 | "DZ", 28 | "EC", 29 | "EE", 30 | "ES", 31 | "FI", 32 | "FR", 33 | "GB", 34 | "GR", 35 | "GT", 36 | "HK", 37 | "HN", 38 | "HU", 39 | "ID", 40 | "IE", 41 | "IL", 42 | "IN", 43 | "IS", 44 | "IT", 45 | "JO", 46 | "JP", 47 | "KW", 48 | "LB", 49 | "LI", 50 | "LT", 51 | "LU", 52 | "LV", 53 | "MA", 54 | "MC", 55 | "MT", 56 | "MX", 57 | "MY", 58 | "NI", 59 | "NL", 60 | "NO", 61 | "NZ", 62 | "OM", 63 | "PA", 64 | "PE", 65 | "PH", 66 | "PL", 67 | "PS", 68 | "PT", 69 | "PY", 70 | "QA", 71 | "RO", 72 | "SE", 73 | "SG", 74 | "SK", 75 | "SV", 76 | "TH", 77 | "TN", 78 | "TR", 79 | "TW", 80 | "US", 81 | "UY", 82 | "VN", 83 | "ZA" 84 | ], 85 | "copyrights": [], 86 | "description": "Nyheter på lätt svenska för dig som är ny i Sverige. Ansvarig utgivare: Klas Wolf-Watz", 87 | "explicit": false, 88 | "external_urls": { 89 | "spotify": "https://open.spotify.com/show/7qV2tMPbnZu18p2h0w6vvR" 90 | }, 91 | "href": "https://api.spotify.com/v1/shows/7qV2tMPbnZu18p2h0w6vvR", 92 | "id": "7qV2tMPbnZu18p2h0w6vvR", 93 | "images": [ 94 | { 95 | "height": 640, 96 | "url": "https://i.scdn.co/image/29126c05d08eac150b0e9a4cc61f13885c555ff1", 97 | "width": 640 98 | }, 99 | { 100 | "height": 300, 101 | "url": "https://i.scdn.co/image/1ec0eba6e85fb1bc30221fe10092488111533a15", 102 | "width": 300 103 | }, 104 | { 105 | "height": 64, 106 | "url": "https://i.scdn.co/image/8870c75630935db5290d2162245b611f0fb40b14", 107 | "width": 64 108 | } 109 | ], 110 | "is_externally_hosted": false, 111 | "languages": ["sv"], 112 | "media_type": "audio", 113 | "name": "Radio Sweden på lätt svenska", 114 | "publisher": "Sveriges Radio", 115 | "type": "show", 116 | "uri": "spotify:show:7qV2tMPbnZu18p2h0w6vvR" 117 | } 118 | ], 119 | "limit": 1, 120 | "next": "https://api.spotify.com/v1/search?query=sweden&type=show&offset=1&limit=1", 121 | "offset": 0, 122 | "previous": null, 123 | "total": 198 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /__test__/fixtures/show_episodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/shows/7qV2tMPbnZu18p2h0w6vvR/episodes?offset=0&limit=2", 3 | "items": [ 4 | { 5 | "audio_preview_url": "https://p.scdn.co/mp3-preview/3852fac7b64ee43c62b6557d78c8c12300cd8f98", 6 | "description": "Företag som har förlorat mycket pengar nu ska få hjälp av staten. | Idag är det Valborg. Men i år är inte firandet som vanligt. | Hur vet man om man har pollenallergi eller covid-19? | Läs texterna till nyheterna på webbsidan: www.sverigesradio.se/lattsvenska Ingrid Forsberg och Jenny Hallberg.", 7 | "duration_ms": 729000, 8 | "explicit": false, 9 | "external_urls": { 10 | "spotify": "https://open.spotify.com/episode/47nrkWxUkjYqkfJrAIYeAI" 11 | }, 12 | "href": "https://api.spotify.com/v1/episodes/47nrkWxUkjYqkfJrAIYeAI", 13 | "id": "47nrkWxUkjYqkfJrAIYeAI", 14 | "images": [ 15 | { 16 | "height": 640, 17 | "url": "https://i.scdn.co/image/1fb1e3b0bbea8c77780eef0a901098ccf15ca1e8", 18 | "width": 640 19 | }, 20 | { 21 | "height": 300, 22 | "url": "https://i.scdn.co/image/fdf2ab20a685ff4da727251cea6b553df398e2c7", 23 | "width": 300 24 | }, 25 | { 26 | "height": 64, 27 | "url": "https://i.scdn.co/image/e838bd9a770aa1229ba1216b32f06cb85a28a716", 28 | "width": 64 29 | } 30 | ], 31 | "is_externally_hosted": false, 32 | "is_playable": true, 33 | "language": "sv", 34 | "languages": ["sv"], 35 | "name": "Torsdag 30 april 2020", 36 | "release_date": "2020-04-30", 37 | "release_date_precision": "day", 38 | "type": "episode", 39 | "uri": "spotify:episode:47nrkWxUkjYqkfJrAIYeAI" 40 | }, 41 | { 42 | "audio_preview_url": "https://p.scdn.co/mp3-preview/960ff53ed602c8c54cbcb16cd192b55b0e01f949", 43 | "description": "Våldet i hemmen har ökat under coronakrisen. | En sjuksköterska som smittats av coronaviruset dog. Nu utreder en åklagare om det var ett brott mot arbetsmiljön. | Sverige har valt en annan strategi mot coronasmittan än många andra länder. | Här kan du läsa texten till nyheterna: https://sverigesradio.se/radioswedenpalattsvenska Programledare: Ingrid Forsberg och Jenny Hallberg", 44 | "duration_ms": 721895, 45 | "explicit": false, 46 | "external_urls": { 47 | "spotify": "https://open.spotify.com/episode/6eV4cQt2Du8shnRjj6vO7o" 48 | }, 49 | "href": "https://api.spotify.com/v1/episodes/6eV4cQt2Du8shnRjj6vO7o", 50 | "id": "6eV4cQt2Du8shnRjj6vO7o", 51 | "images": [ 52 | { 53 | "height": 640, 54 | "url": "https://i.scdn.co/image/e2052620e7546ff3b0f85838db60f1d3568fd487", 55 | "width": 640 56 | }, 57 | { 58 | "height": 300, 59 | "url": "https://i.scdn.co/image/0d152a30be3dbfea0a1ea3ca73507e5ff67338ad", 60 | "width": 300 61 | }, 62 | { 63 | "height": 64, 64 | "url": "https://i.scdn.co/image/9a2e417c6b27c243919c8b0f41b49286bc2e82e0", 65 | "width": 64 66 | } 67 | ], 68 | "is_externally_hosted": false, 69 | "is_playable": true, 70 | "language": "sv", 71 | "languages": ["sv"], 72 | "name": "Onsdag 29 april 2020", 73 | "release_date": "2020-04-29", 74 | "release_date_precision": "day", 75 | "type": "episode", 76 | "uri": "spotify:episode:6eV4cQt2Du8shnRjj6vO7o" 77 | } 78 | ], 79 | "limit": 2, 80 | "next": "https://api.spotify.com/v1/shows/7qV2tMPbnZu18p2h0w6vvR/episodes?offset=2&limit=2", 81 | "offset": 0, 82 | "previous": null, 83 | "total": 500 84 | } 85 | -------------------------------------------------------------------------------- /__test__/fixtures/shows.json: -------------------------------------------------------------------------------- 1 | { 2 | "shows": [ 3 | { 4 | "available_markets": [ 5 | "AD", 6 | "AE", 7 | "AR", 8 | "AT", 9 | "AU", 10 | "BE", 11 | "BG", 12 | "BH", 13 | "BO", 14 | "BR", 15 | "CA", 16 | "CH", 17 | "CL", 18 | "CO", 19 | "CR", 20 | "CY", 21 | "CZ", 22 | "DE", 23 | "DK", 24 | "DO", 25 | "DZ", 26 | "EC", 27 | "EE", 28 | "ES", 29 | "FI", 30 | "FR", 31 | "GB", 32 | "GR", 33 | "GT", 34 | "HK", 35 | "HN", 36 | "HU", 37 | "ID", 38 | "IE", 39 | "IL", 40 | "IN", 41 | "IS", 42 | "IT", 43 | "JO", 44 | "JP", 45 | "KW", 46 | "LB", 47 | "LI", 48 | "LT", 49 | "LU", 50 | "LV", 51 | "MA", 52 | "MC", 53 | "MT", 54 | "MX", 55 | "MY", 56 | "NI", 57 | "NL", 58 | "NO", 59 | "NZ", 60 | "OM", 61 | "PA", 62 | "PE", 63 | "PH", 64 | "PL", 65 | "PS", 66 | "PT", 67 | "PY", 68 | "QA", 69 | "RO", 70 | "SE", 71 | "SG", 72 | "SK", 73 | "SV", 74 | "TH", 75 | "TN", 76 | "TR", 77 | "TW", 78 | "US", 79 | "UY", 80 | "VN", 81 | "ZA" 82 | ], 83 | "copyrights": [], 84 | "description": "Candid conversations with entrepreneurs, artists, athletes, visionaries of all kinds—about their successes, and their failures, and what they learned from both. Hosted by Alex Blumberg, from Gimlet Media.", 85 | "explicit": true, 86 | "external_urls": { 87 | "spotify": "https://open.spotify.com/show/5CfCWKI5pZ28U0uOzXkDHe" 88 | }, 89 | "href": "https://api.spotify.com/v1/shows/5CfCWKI5pZ28U0uOzXkDHe", 90 | "id": "5CfCWKI5pZ28U0uOzXkDHe", 91 | "images": [ 92 | { 93 | "height": 640, 94 | "url": "https://i.scdn.co/image/ab180c752502970e567f43cd755c23152ba49596", 95 | "width": 640 96 | }, 97 | { 98 | "height": 300, 99 | "url": "https://i.scdn.co/image/734ac4dc19b49e1c72b98b349a5687880d8ee5d5", 100 | "width": 300 101 | }, 102 | { 103 | "height": 64, 104 | "url": "https://i.scdn.co/image/72bbd00b35f8f33f7ed2ca48cbbff0b50bc86f78", 105 | "width": 64 106 | } 107 | ], 108 | "is_externally_hosted": false, 109 | "languages": ["en"], 110 | "media_type": "audio", 111 | "name": "Without Fail", 112 | "publisher": "Gimlet", 113 | "type": "show", 114 | "uri": "spotify:show:5CfCWKI5pZ28U0uOzXkDHe" 115 | }, 116 | { 117 | "available_markets": [ 118 | "AD", 119 | "AE", 120 | "AR", 121 | "AT", 122 | "AU", 123 | "BE", 124 | "BG", 125 | "BH", 126 | "BO", 127 | "BR", 128 | "CA", 129 | "CH", 130 | "CL", 131 | "CO", 132 | "CR", 133 | "CY", 134 | "CZ", 135 | "DE", 136 | "DK", 137 | "DO", 138 | "DZ", 139 | "EC", 140 | "EE", 141 | "ES", 142 | "FI", 143 | "FR", 144 | "GB", 145 | "GR", 146 | "GT", 147 | "HK", 148 | "HN", 149 | "HU", 150 | "ID", 151 | "IE", 152 | "IL", 153 | "IN", 154 | "IS", 155 | "IT", 156 | "JO", 157 | "JP", 158 | "KW", 159 | "LB", 160 | "LI", 161 | "LT", 162 | "LU", 163 | "LV", 164 | "MA", 165 | "MC", 166 | "MT", 167 | "MX", 168 | "MY", 169 | "NI", 170 | "NL", 171 | "NO", 172 | "NZ", 173 | "OM", 174 | "PA", 175 | "PE", 176 | "PH", 177 | "PL", 178 | "PS", 179 | "PT", 180 | "PY", 181 | "QA", 182 | "RO", 183 | "SE", 184 | "SG", 185 | "SK", 186 | "SV", 187 | "TH", 188 | "TN", 189 | "TR", 190 | "TW", 191 | "US", 192 | "UY", 193 | "VN", 194 | "ZA" 195 | ], 196 | "copyrights": [], 197 | "description": "Giant Bomb discusses the latest video game news and new releases, taste-test questionable beverages, and get wildly off-topic in this weekly podcast.", 198 | "explicit": false, 199 | "external_urls": { 200 | "spotify": "https://open.spotify.com/show/5as3aKmN2k11yfDDDSrvaZ" 201 | }, 202 | "href": "https://api.spotify.com/v1/shows/5as3aKmN2k11yfDDDSrvaZ", 203 | "id": "5as3aKmN2k11yfDDDSrvaZ", 204 | "images": [ 205 | { 206 | "height": 640, 207 | "url": "https://i.scdn.co/image/9bd9b3be1111810a91cd768115a57ee5a08c7145", 208 | "width": 640 209 | }, 210 | { 211 | "height": 300, 212 | "url": "https://i.scdn.co/image/1f5c122086aa4602742ba2301302f2f9bc1f0345", 213 | "width": 300 214 | }, 215 | { 216 | "height": 64, 217 | "url": "https://i.scdn.co/image/b97f288023e547f40862976c89a5c342eacaaac1", 218 | "width": 64 219 | } 220 | ], 221 | "is_externally_hosted": false, 222 | "languages": ["en-US"], 223 | "media_type": "audio", 224 | "name": "Giant Bombcast", 225 | "publisher": "Giant Bomb", 226 | "type": "show", 227 | "uri": "spotify:show:5as3aKmN2k11yfDDDSrvaZ" 228 | } 229 | ] 230 | } 231 | -------------------------------------------------------------------------------- /__test__/fixtures/track.json: -------------------------------------------------------------------------------- 1 | { 2 | "album": { 3 | "album_type": "album", 4 | "external_urls": { 5 | "spotify": "https://open.spotify.com/album/6TJmQnO44YE5BtTxH8pop1" 6 | }, 7 | "href": "https://api.spotify.com/v1/albums/6TJmQnO44YE5BtTxH8pop1", 8 | "id": "6TJmQnO44YE5BtTxH8pop1", 9 | "images": [ 10 | { 11 | "height": 640, 12 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8e13218039f81b000553e25522a7f0d7a0600f2e", 13 | "width": 629 14 | }, 15 | { 16 | "height": 300, 17 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8c1e066b5d1045038437d92815d49987f519e44f", 18 | "width": 295 19 | }, 20 | { 21 | "height": 64, 22 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/d49268a8fc0768084f4750cf1647709e89a27172", 23 | "width": 63 24 | } 25 | ], 26 | "name": "Hot Fuss", 27 | "type": "album", 28 | "uri": "spotify:album:6TJmQnO44YE5BtTxH8pop1" 29 | }, 30 | "artists": [ 31 | { 32 | "external_urls": { 33 | "spotify": "https://open.spotify.com/artist/0C0XlULifJtAgn6ZNCW2eu" 34 | }, 35 | "href": "https://api.spotify.com/v1/artists/0C0XlULifJtAgn6ZNCW2eu", 36 | "id": "0C0XlULifJtAgn6ZNCW2eu", 37 | "name": "The Killers", 38 | "type": "artist", 39 | "uri": "spotify:artist:0C0XlULifJtAgn6ZNCW2eu" 40 | } 41 | ], 42 | "available_markets": [ 43 | "AD", 44 | "AR", 45 | "AT", 46 | "AU", 47 | "BE", 48 | "BG", 49 | "BO", 50 | "BR", 51 | "CH", 52 | "CL", 53 | "CO", 54 | "CR", 55 | "CY", 56 | "CZ", 57 | "DE", 58 | "DK", 59 | "DO", 60 | "EC", 61 | "EE", 62 | "ES", 63 | "FI", 64 | "FR", 65 | "GR", 66 | "GT", 67 | "HK", 68 | "HN", 69 | "HU", 70 | "IE", 71 | "IS", 72 | "IT", 73 | "LI", 74 | "LT", 75 | "LU", 76 | "LV", 77 | "MC", 78 | "MT", 79 | "MY", 80 | "NI", 81 | "NL", 82 | "NO", 83 | "NZ", 84 | "PA", 85 | "PE", 86 | "PH", 87 | "PL", 88 | "PT", 89 | "PY", 90 | "RO", 91 | "SE", 92 | "SG", 93 | "SI", 94 | "SK", 95 | "SV", 96 | "TR", 97 | "TW", 98 | "UY" 99 | ], 100 | "disc_number": 1, 101 | "duration_ms": 222075, 102 | "explicit": false, 103 | "external_ids": { 104 | "isrc": "USIR20400274" 105 | }, 106 | "external_urls": { 107 | "spotify": "https://open.spotify.com/track/0eGsygTp906u18L0Oimnem" 108 | }, 109 | "href": "https://api.spotify.com/v1/tracks/0eGsygTp906u18L0Oimnem", 110 | "id": "0eGsygTp906u18L0Oimnem", 111 | "name": "Mr. Brightside", 112 | "popularity": 0, 113 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/f454c8224828e21fa146af84916fd22cb89cedc6", 114 | "track_number": 2, 115 | "type": "track", 116 | "uri": "spotify:track:0eGsygTp906u18L0Oimnem" 117 | } 118 | -------------------------------------------------------------------------------- /__test__/fixtures/track_audio_features.json: -------------------------------------------------------------------------------- 1 | { 2 | "danceability": 0.735, 3 | "energy": 0.578, 4 | "key": 5, 5 | "loudness": -11.84, 6 | "mode": 0, 7 | "speechiness": 0.0461, 8 | "acousticness": 0.514, 9 | "instrumentalness": 0.0902, 10 | "liveness": 0.159, 11 | "valence": 0.624, 12 | "tempo": 98.002, 13 | "type": "audio_features", 14 | "id": "06AKEBrKUckW0KREUWRnvT", 15 | "uri": "spotify:track:06AKEBrKUckW0KREUWRnvT", 16 | "track_href": "https://api.spotify.com/v1/tracks/06AKEBrKUckW0KREUWRnvT", 17 | "analysis_url": "http://echonest-analysis.s3.amazonaws.com/TR/xZIVRgimIx9_iJFqTriVhCm_4unjh7tZAglpO5D-xS4xNkvxq70uCFAtuoVYTaIeHbWoLKvCB6W-kvd9E=/3/full.json?AWSAccessKeyId=AKIAJRDFEY23UEVW42BQ&Expires=1455893394&Signature=rmceqCXLMbPrXt9RTIJwk%2BQzxoY%3D", 18 | "duration_ms": 255349, 19 | "time_signature": 4 20 | } 21 | -------------------------------------------------------------------------------- /__test__/fixtures/tracks.json: -------------------------------------------------------------------------------- 1 | { 2 | "tracks": [ 3 | { 4 | "album": { 5 | "album_type": "album", 6 | "external_urls": { 7 | "spotify": "https://open.spotify.com/album/6TJmQnO44YE5BtTxH8pop1" 8 | }, 9 | "href": "https://api.spotify.com/v1/albums/6TJmQnO44YE5BtTxH8pop1", 10 | "id": "6TJmQnO44YE5BtTxH8pop1", 11 | "images": [ 12 | { 13 | "height": 640, 14 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8e13218039f81b000553e25522a7f0d7a0600f2e", 15 | "width": 629 16 | }, 17 | { 18 | "height": 300, 19 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8c1e066b5d1045038437d92815d49987f519e44f", 20 | "width": 295 21 | }, 22 | { 23 | "height": 64, 24 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/d49268a8fc0768084f4750cf1647709e89a27172", 25 | "width": 63 26 | } 27 | ], 28 | "name": "Hot Fuss", 29 | "type": "album", 30 | "uri": "spotify:album:6TJmQnO44YE5BtTxH8pop1" 31 | }, 32 | "artists": [ 33 | { 34 | "external_urls": { 35 | "spotify": "https://open.spotify.com/artist/0C0XlULifJtAgn6ZNCW2eu" 36 | }, 37 | "href": "https://api.spotify.com/v1/artists/0C0XlULifJtAgn6ZNCW2eu", 38 | "id": "0C0XlULifJtAgn6ZNCW2eu", 39 | "name": "The Killers", 40 | "type": "artist", 41 | "uri": "spotify:artist:0C0XlULifJtAgn6ZNCW2eu" 42 | } 43 | ], 44 | "available_markets": [ 45 | "AD", 46 | "AR", 47 | "AT", 48 | "AU", 49 | "BE", 50 | "BG", 51 | "BO", 52 | "BR", 53 | "CH", 54 | "CL", 55 | "CO", 56 | "CR", 57 | "CY", 58 | "CZ", 59 | "DE", 60 | "DK", 61 | "DO", 62 | "EC", 63 | "EE", 64 | "ES", 65 | "FI", 66 | "FR", 67 | "GR", 68 | "GT", 69 | "HK", 70 | "HN", 71 | "HU", 72 | "IE", 73 | "IS", 74 | "IT", 75 | "LI", 76 | "LT", 77 | "LU", 78 | "LV", 79 | "MC", 80 | "MT", 81 | "MY", 82 | "NI", 83 | "NL", 84 | "NO", 85 | "NZ", 86 | "PA", 87 | "PE", 88 | "PH", 89 | "PL", 90 | "PT", 91 | "PY", 92 | "RO", 93 | "SE", 94 | "SG", 95 | "SI", 96 | "SK", 97 | "SV", 98 | "TR", 99 | "TW", 100 | "UY" 101 | ], 102 | "disc_number": 1, 103 | "duration_ms": 197160, 104 | "explicit": false, 105 | "external_ids": { 106 | "isrc": "USIR20400195" 107 | }, 108 | "external_urls": { 109 | "spotify": "https://open.spotify.com/track/1lDWb6b6ieDQ2xT7ewTC3G" 110 | }, 111 | "href": "https://api.spotify.com/v1/tracks/1lDWb6b6ieDQ2xT7ewTC3G", 112 | "id": "1lDWb6b6ieDQ2xT7ewTC3G", 113 | "name": "Somebody Told Me", 114 | "popularity": 0, 115 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/4c63a3d4eaf7f8f86cfdb8bf46ef3974f4092357", 116 | "track_number": 4, 117 | "type": "track", 118 | "uri": "spotify:track:1lDWb6b6ieDQ2xT7ewTC3G" 119 | }, 120 | { 121 | "album": { 122 | "album_type": "album", 123 | "external_urls": { 124 | "spotify": "https://open.spotify.com/album/6TJmQnO44YE5BtTxH8pop1" 125 | }, 126 | "href": "https://api.spotify.com/v1/albums/6TJmQnO44YE5BtTxH8pop1", 127 | "id": "6TJmQnO44YE5BtTxH8pop1", 128 | "images": [ 129 | { 130 | "height": 640, 131 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8e13218039f81b000553e25522a7f0d7a0600f2e", 132 | "width": 629 133 | }, 134 | { 135 | "height": 300, 136 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/8c1e066b5d1045038437d92815d49987f519e44f", 137 | "width": 295 138 | }, 139 | { 140 | "height": 64, 141 | "url": "https://d3rt1990lpmkn.cloudfront.net/original/d49268a8fc0768084f4750cf1647709e89a27172", 142 | "width": 63 143 | } 144 | ], 145 | "name": "Hot Fuss", 146 | "type": "album", 147 | "uri": "spotify:album:6TJmQnO44YE5BtTxH8pop1" 148 | }, 149 | "artists": [ 150 | { 151 | "external_urls": { 152 | "spotify": "https://open.spotify.com/artist/0C0XlULifJtAgn6ZNCW2eu" 153 | }, 154 | "href": "https://api.spotify.com/v1/artists/0C0XlULifJtAgn6ZNCW2eu", 155 | "id": "0C0XlULifJtAgn6ZNCW2eu", 156 | "name": "The Killers", 157 | "type": "artist", 158 | "uri": "spotify:artist:0C0XlULifJtAgn6ZNCW2eu" 159 | } 160 | ], 161 | "available_markets": [ 162 | "AD", 163 | "AR", 164 | "AT", 165 | "AU", 166 | "BE", 167 | "BG", 168 | "BO", 169 | "BR", 170 | "CH", 171 | "CL", 172 | "CO", 173 | "CR", 174 | "CY", 175 | "CZ", 176 | "DE", 177 | "DK", 178 | "DO", 179 | "EC", 180 | "EE", 181 | "ES", 182 | "FI", 183 | "FR", 184 | "GR", 185 | "GT", 186 | "HK", 187 | "HN", 188 | "HU", 189 | "IE", 190 | "IS", 191 | "IT", 192 | "LI", 193 | "LT", 194 | "LU", 195 | "LV", 196 | "MC", 197 | "MT", 198 | "MY", 199 | "NI", 200 | "NL", 201 | "NO", 202 | "NZ", 203 | "PA", 204 | "PE", 205 | "PH", 206 | "PL", 207 | "PT", 208 | "PY", 209 | "RO", 210 | "SE", 211 | "SG", 212 | "SI", 213 | "SK", 214 | "SV", 215 | "TR", 216 | "TW", 217 | "UY" 218 | ], 219 | "disc_number": 1, 220 | "duration_ms": 222075, 221 | "explicit": false, 222 | "external_ids": { 223 | "isrc": "USIR20400274" 224 | }, 225 | "external_urls": { 226 | "spotify": "https://open.spotify.com/track/0eGsygTp906u18L0Oimnem" 227 | }, 228 | "href": "https://api.spotify.com/v1/tracks/0eGsygTp906u18L0Oimnem", 229 | "id": "0eGsygTp906u18L0Oimnem", 230 | "name": "Mr. Brightside", 231 | "popularity": 0, 232 | "preview_url": "http://d318706lgtcm8e.cloudfront.net/mp3-preview/f454c8224828e21fa146af84916fd22cb89cedc6", 233 | "track_number": 2, 234 | "type": "track", 235 | "uri": "spotify:track:0eGsygTp906u18L0Oimnem" 236 | } 237 | ] 238 | } 239 | -------------------------------------------------------------------------------- /__test__/fixtures/tracks_audio_features.json: -------------------------------------------------------------------------------- 1 | { 2 | "audio_features": [ 3 | { 4 | "danceability": 0.735, 5 | "energy": 0.578, 6 | "key": 5, 7 | "loudness": -11.84, 8 | "mode": 0, 9 | "speechiness": 0.0461, 10 | "acousticness": 0.514, 11 | "instrumentalness": 0.0902, 12 | "liveness": 0.159, 13 | "valence": 0.624, 14 | "tempo": 98.002, 15 | "type": "audio_features", 16 | "id": "06AKEBrKUckW0KREUWRnvT", 17 | "uri": "spotify:track:06AKEBrKUckW0KREUWRnvT", 18 | "track_href": "https://api.spotify.com/v1/tracks/06AKEBrKUckW0KREUWRnvT", 19 | "analysis_url": "http://echonest-analysis.s3.amazonaws.com/TR/xZIVRgimIx9_iJFqTriVhCm_4unjh7tZAglpO5D-xS4xNkvxq70uCFAtuoVYTaIeHbWoLKvCB6W-kvd9E=/3/full.json?AWSAccessKeyId=AKIAJRDFEY23UEVW42BQ&Expires=1455893394&Signature=rmceqCXLMbPrXt9RTIJwk%2BQzxoY%3D", 20 | "duration_ms": 255349, 21 | "time_signature": 4 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /__test__/fixtures/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "external_urls": { 3 | "spotify": "https://open.spotify.com/user/jmperezperez" 4 | }, 5 | "href": "https://api.spotify.com/v1/users/jmperezperez", 6 | "id": "jmperezperez", 7 | "type": "user", 8 | "uri": "spotify:user:jmperezperez" 9 | } 10 | -------------------------------------------------------------------------------- /__test__/fixtures/user_new_playlist.json: -------------------------------------------------------------------------------- 1 | { 2 | "collaborative": false, 3 | "description": null, 4 | "external_urls": { 5 | "spotify": "http://open.spotify.com/user/jmperezperez/playlists/7Kud0O2IdWLbEGgvBkW9di" 6 | }, 7 | "followers": null, 8 | "href": "https://api.spotify.com/v1/users/jmperezperez/playlists/7Kud0O2IdWLbEGgvBkW9di", 9 | "id": "7Kud0O2IdWLbEGgvBkW9di", 10 | "images": [null], 11 | "name": "Test from API 3.0", 12 | "owner": { 13 | "external_urls": { 14 | "spotify": "http://open.spotify.com/user/jmperezperez" 15 | }, 16 | "href": "https://api.spotify.com/v1/users/jmperezperez", 17 | "id": "jmperezperez", 18 | "type": "user", 19 | "uri": "spotify:user:jmperezperez" 20 | }, 21 | "public": true, 22 | "tracks": null, 23 | "type": "playlist", 24 | "uri": "spotify:user:jmperezperez:playlist:7Kud0O2IdWLbEGgvBkW9di" 25 | } 26 | -------------------------------------------------------------------------------- /__test__/fixtures/user_playlists.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/users/some_random_user/playlists", 3 | "total": 4, 4 | "items": [ 5 | { 6 | "name": "Starred", 7 | "collaborative": false, 8 | "tracks": { 9 | "href": "https://api.spotify.com/v1/users/some_random_user/starred/tracks", 10 | "total": 33 11 | }, 12 | "public": true, 13 | "href": "https://api.spotify.com/v1/users/some_random_user/starred/", 14 | "id": null, 15 | "type": "playlist", 16 | "owner": { 17 | "id": "some_random_user", 18 | "uri": "spotify:user:some_random_user", 19 | "type": "user", 20 | "href": "https://api.spotify.com/v1/users/some_random_user", 21 | "external_urls": { 22 | "spotify": "http://open.spotify.com/user/some_random_user" 23 | } 24 | }, 25 | "uri": "spotify:user:some_random_user:starred", 26 | "external_urls": { 27 | "spotify": "http://open.spotify.com/user/some_random_user/starred/" 28 | } 29 | }, 30 | { 31 | "name": "Brit Awards 2010", 32 | "collaborative": false, 33 | "tracks": { 34 | "href": "https://api.spotify.com/v1/users/brit-awards/playlists/4ONAkfFuy4HXrsDUXpaqqw/tracks", 35 | "total": 68 36 | }, 37 | "public": true, 38 | "href": "https://api.spotify.com/v1/users/brit-awards/playlists/4ONAkfFuy4HXrsDUXpaqqw", 39 | "id": "4ONAkfFuy4HXrsDUXpaqqw", 40 | "type": "playlist", 41 | "owner": { 42 | "id": "brit-awards", 43 | "uri": "spotify:user:brit-awards", 44 | "type": "user", 45 | "href": "https://api.spotify.com/v1/users/brit-awards", 46 | "external_urls": { 47 | "spotify": "http://open.spotify.com/user/brit-awards" 48 | } 49 | }, 50 | "uri": "spotify:user:brit-awards:playlist:4ONAkfFuy4HXrsDUXpaqqw", 51 | "external_urls": { 52 | "spotify": "http://open.spotify.com/user/brit-awards/playlists/4ONAkfFuy4HXrsDUXpaqqw" 53 | } 54 | }, 55 | { 56 | "name": "groove", 57 | "collaborative": false, 58 | "tracks": { 59 | "href": "https://api.spotify.com/v1/users/mapachespotify/playlists/02FePCZXzu6rIhUxAsvFJ0/tracks", 60 | "total": 9 61 | }, 62 | "public": true, 63 | "href": "https://api.spotify.com/v1/users/mapachespotify/playlists/02FePCZXzu6rIhUxAsvFJ0", 64 | "id": "02FePCZXzu6rIhUxAsvFJ0", 65 | "type": "playlist", 66 | "owner": { 67 | "id": "mapachespotify", 68 | "uri": "spotify:user:mapachespotify", 69 | "type": "user", 70 | "href": "https://api.spotify.com/v1/users/mapachespotify", 71 | "external_urls": { 72 | "spotify": "http://open.spotify.com/user/mapachespotify" 73 | } 74 | }, 75 | "uri": "spotify:user:mapachespotify:playlist:02FePCZXzu6rIhUxAsvFJ0", 76 | "external_urls": { 77 | "spotify": "http://open.spotify.com/user/mapachespotify/playlists/02FePCZXzu6rIhUxAsvFJ0" 78 | } 79 | }, 80 | { 81 | "name": "Indie", 82 | "collaborative": false, 83 | "tracks": { 84 | "href": "https://api.spotify.com/v1/users/some_random_user/playlists/6GtlPiJzs7zxtmcjKMz7fr/tracks", 85 | "total": 3 86 | }, 87 | "public": true, 88 | "href": "https://api.spotify.com/v1/users/some_random_user/playlists/6GtlPiJzs7zxtmcjKMz7fr", 89 | "id": "6GtlPiJzs7zxtmcjKMz7fr", 90 | "type": "playlist", 91 | "owner": { 92 | "id": "some_random_user", 93 | "uri": "spotify:user:some_random_user", 94 | "type": "user", 95 | "href": "https://api.spotify.com/v1/users/some_random_user", 96 | "external_urls": { 97 | "spotify": "http://open.spotify.com/user/some_random_user" 98 | } 99 | }, 100 | "uri": "spotify:user:some_random_user:playlist:6GtlPiJzs7zxtmcjKMz7fr", 101 | "external_urls": { 102 | "spotify": "http://open.spotify.com/user/some_random_user/playlists/6GtlPiJzs7zxtmcjKMz7fr" 103 | } 104 | } 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /__test__/fixtures/user_saved_shows.json: -------------------------------------------------------------------------------- 1 | { 2 | "href": "https://api.spotify.com/v1/me/shows?offset=0&limit=2", 3 | "items": [ 4 | { 5 | "added_at": "2018-01-02T14:54:51Z", 6 | "show": { 7 | "available_markets": [ 8 | "AD", 9 | "AE", 10 | "AR", 11 | "AT", 12 | "AU", 13 | "BE", 14 | "BG", 15 | "BH", 16 | "BO", 17 | "BR", 18 | "CA", 19 | "CH", 20 | "CL", 21 | "CO", 22 | "CR", 23 | "CY", 24 | "CZ", 25 | "DE", 26 | "DK", 27 | "DO", 28 | "DZ", 29 | "EC", 30 | "EE", 31 | "ES", 32 | "FI", 33 | "FR", 34 | "GB", 35 | "GR", 36 | "GT", 37 | "HK", 38 | "HN", 39 | "HU", 40 | "ID", 41 | "IE", 42 | "IL", 43 | "IN", 44 | "IS", 45 | "IT", 46 | "JO", 47 | "JP", 48 | "KW", 49 | "LB", 50 | "LI", 51 | "LT", 52 | "LU", 53 | "LV", 54 | "MA", 55 | "MC", 56 | "MT", 57 | "MX", 58 | "MY", 59 | "NI", 60 | "NL", 61 | "NO", 62 | "NZ", 63 | "OM", 64 | "PA", 65 | "PE", 66 | "PH", 67 | "PL", 68 | "PS", 69 | "PT", 70 | "PY", 71 | "QA", 72 | "RO", 73 | "SE", 74 | "SG", 75 | "SK", 76 | "SV", 77 | "TH", 78 | "TN", 79 | "TR", 80 | "TW", 81 | "US", 82 | "UY", 83 | "VN", 84 | "ZA" 85 | ], 86 | "copyrights": [], 87 | "description": "The Pursuit Podcast offers advice and new perspectives on getting things done in tech through half hour conversations with tech's great thinkers each week. Want to learn to code? Land that great new job? Learn about how to manage your new reports? We've got you covered. This weekly podcast and carefully curated resources aims to leave you inspired and prepared to tackle that cool new thing.", 88 | "explicit": false, 89 | "external_urls": { 90 | "spotify": "https://open.spotify.com/show/3eVlgrnLC9fDRyTZMtTg88" 91 | }, 92 | "href": "https://api.spotify.com/v1/shows/3eVlgrnLC9fDRyTZMtTg88", 93 | "id": "3eVlgrnLC9fDRyTZMtTg88", 94 | "images": [ 95 | { 96 | "height": 640, 97 | "url": "https://i.scdn.co/image/bdec05f63cd6494bccaa78298398fa3162583fbb", 98 | "width": 640 99 | }, 100 | { 101 | "height": 300, 102 | "url": "https://i.scdn.co/image/8bba6753054f68fff159e58da25ed9c48d3c1f09", 103 | "width": 300 104 | }, 105 | { 106 | "height": 64, 107 | "url": "https://i.scdn.co/image/21658e432e9f5784339972e75dd49df9cbae6148", 108 | "width": 64 109 | } 110 | ], 111 | "is_externally_hosted": false, 112 | "languages": ["en-GB"], 113 | "media_type": "audio", 114 | "name": "Pursuit Podcast", 115 | "publisher": "Jessica Rose", 116 | "type": "show", 117 | "uri": "spotify:show:3eVlgrnLC9fDRyTZMtTg88" 118 | } 119 | }, 120 | { 121 | "added_at": "2016-12-23T15:49:01Z", 122 | "show": { 123 | "available_markets": [ 124 | "AD", 125 | "AE", 126 | "AR", 127 | "AT", 128 | "AU", 129 | "BE", 130 | "BG", 131 | "BH", 132 | "BO", 133 | "BR", 134 | "CA", 135 | "CH", 136 | "CL", 137 | "CO", 138 | "CR", 139 | "CY", 140 | "CZ", 141 | "DE", 142 | "DK", 143 | "DO", 144 | "DZ", 145 | "EC", 146 | "EE", 147 | "ES", 148 | "FI", 149 | "FR", 150 | "GB", 151 | "GR", 152 | "GT", 153 | "HK", 154 | "HN", 155 | "HU", 156 | "ID", 157 | "IE", 158 | "IL", 159 | "IN", 160 | "IS", 161 | "IT", 162 | "JO", 163 | "JP", 164 | "KW", 165 | "LB", 166 | "LI", 167 | "LT", 168 | "LU", 169 | "LV", 170 | "MA", 171 | "MC", 172 | "MT", 173 | "MX", 174 | "MY", 175 | "NI", 176 | "NL", 177 | "NO", 178 | "NZ", 179 | "OM", 180 | "PA", 181 | "PE", 182 | "PH", 183 | "PL", 184 | "PS", 185 | "PT", 186 | "PY", 187 | "QA", 188 | "RO", 189 | "SE", 190 | "SG", 191 | "SK", 192 | "SV", 193 | "TH", 194 | "TN", 195 | "TR", 196 | "TW", 197 | "US", 198 | "UY", 199 | "VN", 200 | "ZA" 201 | ], 202 | "copyrights": [], 203 | "description": "A weekly conversation that looks at the way technology is changing our economies, societies and daily lives. Hosted by John Thornhill, innovation editor at the Financial Times.", 204 | "explicit": false, 205 | "external_urls": { 206 | "spotify": "https://open.spotify.com/show/0euILJ8WEEmIG7UeZi1VtM" 207 | }, 208 | "href": "https://api.spotify.com/v1/shows/0euILJ8WEEmIG7UeZi1VtM", 209 | "id": "0euILJ8WEEmIG7UeZi1VtM", 210 | "images": [ 211 | { 212 | "height": 640, 213 | "url": "https://i.scdn.co/image/f9629d2802f2a0d4d9a4f8390fdf33275b55e885", 214 | "width": 640 215 | }, 216 | { 217 | "height": 300, 218 | "url": "https://i.scdn.co/image/5cfe9c4bfc53649cd4ee3ddee58e6377d2a321cb", 219 | "width": 300 220 | }, 221 | { 222 | "height": 64, 223 | "url": "https://i.scdn.co/image/0d7ff6bd0bcb145a1560b0e2b3f5eaf71dbf239c", 224 | "width": 64 225 | } 226 | ], 227 | "is_externally_hosted": false, 228 | "languages": ["en"], 229 | "media_type": "audio", 230 | "name": "FT Tech Tonic", 231 | "publisher": "Financial Times", 232 | "type": "show", 233 | "uri": "spotify:show:0euILJ8WEEmIG7UeZi1VtM" 234 | } 235 | } 236 | ], 237 | "limit": 2, 238 | "next": "https://api.spotify.com/v1/me/shows?offset=2&limit=2", 239 | "offset": 0, 240 | "previous": null, 241 | "total": 4 242 | } 243 | -------------------------------------------------------------------------------- /__test__/fixtures/user_top_artists.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | { 4 | "external_urls": { 5 | "spotify": "https://open.spotify.com/artist/6J6yx1t3nwIDyPXk5xa7O8" 6 | }, 7 | "followers": { 8 | "href": null, 9 | "total": null 10 | }, 11 | "genres": [], 12 | "href": "https://api.spotify.com/v1/artists/6J6yx1t3nwIDyPXk5xa7O8", 13 | "id": "6J6yx1t3nwIDyPXk5xa7O8", 14 | "images": [ 15 | { 16 | "height": 563, 17 | "url": "https://i.scdn.co/image/85c7a46805712da40280ebe7ab095142c40fc053", 18 | "width": 1000 19 | }, 20 | { 21 | "height": 360, 22 | "url": "https://i.scdn.co/image/8825bbd51658f2e5b6dfe29aafd56c9d6e74131d", 23 | "width": 640 24 | }, 25 | { 26 | "height": 113, 27 | "url": "https://i.scdn.co/image/2994fde9ed3ac3511f3da11293c47b45e02926a0", 28 | "width": 200 29 | }, 30 | { 31 | "height": 36, 32 | "url": "https://i.scdn.co/image/38a8d956352a0a255f4bea90aa0c0a00d46cd07d", 33 | "width": 64 34 | } 35 | ], 36 | "name": "Vetusta Morla", 37 | "popularity": 64, 38 | "type": "artist", 39 | "uri": "spotify:artist:6J6yx1t3nwIDyPXk5xa7O8" 40 | }, 41 | { 42 | "external_urls": { 43 | "spotify": "https://open.spotify.com/artist/3bgsNtcf5d5h9jbQbohfBK" 44 | }, 45 | "followers": { 46 | "href": null, 47 | "total": null 48 | }, 49 | "genres": [], 50 | "href": "https://api.spotify.com/v1/artists/3bgsNtcf5d5h9jbQbohfBK", 51 | "id": "3bgsNtcf5d5h9jbQbohfBK", 52 | "images": [ 53 | { 54 | "height": 480, 55 | "url": "https://i.scdn.co/image/b606d5e5ec99288277aa3466880f54060ff66cef", 56 | "width": 640 57 | }, 58 | { 59 | "height": 150, 60 | "url": "https://i.scdn.co/image/4e24afd44d8f59006d382bc7a49252fb2ea06c8f", 61 | "width": 200 62 | }, 63 | { 64 | "height": 48, 65 | "url": "https://i.scdn.co/image/2a647ff503020a5aa11de8802dccda5955889a32", 66 | "width": 64 67 | } 68 | ], 69 | "name": "Extremoduro", 70 | "popularity": 63, 71 | "type": "artist", 72 | "uri": "spotify:artist:3bgsNtcf5d5h9jbQbohfBK" 73 | }, 74 | { 75 | "external_urls": { 76 | "spotify": "https://open.spotify.com/artist/61C3cEhdoJ9YiQSQSwYB4K" 77 | }, 78 | "followers": { 79 | "href": null, 80 | "total": null 81 | }, 82 | "genres": [], 83 | "href": "https://api.spotify.com/v1/artists/61C3cEhdoJ9YiQSQSwYB4K", 84 | "id": "61C3cEhdoJ9YiQSQSwYB4K", 85 | "images": [ 86 | { 87 | "height": 1000, 88 | "url": "https://i.scdn.co/image/3ad300c354b155c2e1b2b128a1adb0102daf18c2", 89 | "width": 1000 90 | }, 91 | { 92 | "height": 640, 93 | "url": "https://i.scdn.co/image/04cea48c8f166ab5620c1378058af9d7f82d7f3c", 94 | "width": 640 95 | }, 96 | { 97 | "height": 200, 98 | "url": "https://i.scdn.co/image/0cf094441a8c30252153085859979a1e51a3529c", 99 | "width": 200 100 | }, 101 | { 102 | "height": 64, 103 | "url": "https://i.scdn.co/image/e7136999a1ea1ba77dbec6872b095cf6658b7d2a", 104 | "width": 64 105 | } 106 | ], 107 | "name": "Supersubmarina", 108 | "popularity": 61, 109 | "type": "artist", 110 | "uri": "spotify:artist:61C3cEhdoJ9YiQSQSwYB4K" 111 | }, 112 | { 113 | "external_urls": { 114 | "spotify": "https://open.spotify.com/artist/6mfK6Q2tzLMEchAr0e9Uzu" 115 | }, 116 | "followers": { 117 | "href": null, 118 | "total": null 119 | }, 120 | "genres": [], 121 | "href": "https://api.spotify.com/v1/artists/6mfK6Q2tzLMEchAr0e9Uzu", 122 | "id": "6mfK6Q2tzLMEchAr0e9Uzu", 123 | "images": [ 124 | { 125 | "height": 480, 126 | "url": "https://i.scdn.co/image/82b46784f513d02e0ceed3ddf1451be1a0b4a556", 127 | "width": 640 128 | }, 129 | { 130 | "height": 150, 131 | "url": "https://i.scdn.co/image/115c3e5e03db67f82776104a7ab8faa4b5007288", 132 | "width": 200 133 | }, 134 | { 135 | "height": 48, 136 | "url": "https://i.scdn.co/image/5f0182d4c08b989e5d5943900ebcdb386b539502", 137 | "width": 64 138 | } 139 | ], 140 | "name": "Pereza", 141 | "popularity": 61, 142 | "type": "artist", 143 | "uri": "spotify:artist:6mfK6Q2tzLMEchAr0e9Uzu" 144 | }, 145 | { 146 | "external_urls": { 147 | "spotify": "https://open.spotify.com/artist/6VCoG3MG7ZKRxDjaYOvtrF" 148 | }, 149 | "followers": { 150 | "href": null, 151 | "total": null 152 | }, 153 | "genres": [], 154 | "href": "https://api.spotify.com/v1/artists/6VCoG3MG7ZKRxDjaYOvtrF", 155 | "id": "6VCoG3MG7ZKRxDjaYOvtrF", 156 | "images": [ 157 | { 158 | "height": 563, 159 | "url": "https://i.scdn.co/image/5dd60cf14352b2dd28d06ba88ff63a0b2a68a5a4", 160 | "width": 1000 161 | }, 162 | { 163 | "height": 360, 164 | "url": "https://i.scdn.co/image/86b30c52e36ee20a7016f80ecb11914283057199", 165 | "width": 640 166 | }, 167 | { 168 | "height": 113, 169 | "url": "https://i.scdn.co/image/fb6edbe5c2593c6e84fbb655d2f7bbc1a9e75427", 170 | "width": 200 171 | }, 172 | { 173 | "height": 36, 174 | "url": "https://i.scdn.co/image/15f59169f3491bb49055f6d462d12dc8c7d49391", 175 | "width": 64 176 | } 177 | ], 178 | "name": "Love of Lesbian", 179 | "popularity": 67, 180 | "type": "artist", 181 | "uri": "spotify:artist:6VCoG3MG7ZKRxDjaYOvtrF" 182 | } 183 | ], 184 | "total": 50, 185 | "limit": 5, 186 | "offset": 0, 187 | "href": "https://api.spotify.com/v1/me/top/artists?limit=5", 188 | "previous": null, 189 | "next": "https://api.spotify.com/v1/me/top/artists?limit=5&offset=5" 190 | } 191 | -------------------------------------------------------------------------------- /__test__/fixtures/user_top_tracks.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | { 4 | "album": { 5 | "album_type": "ALBUM", 6 | "external_urls": { 7 | "spotify": "https://open.spotify.com/album/1GYJUlbVr5FuNU7awwMGzu" 8 | }, 9 | "href": "https://api.spotify.com/v1/albums/1GYJUlbVr5FuNU7awwMGzu", 10 | "id": "1GYJUlbVr5FuNU7awwMGzu", 11 | "images": [ 12 | { 13 | "height": 640, 14 | "url": "https://i.scdn.co/image/f04389d964fbf82f01ac142b3dff73962e00214e", 15 | "width": 640 16 | }, 17 | { 18 | "height": 300, 19 | "url": "https://i.scdn.co/image/9e07d674397310e8873fb54303ae622f90cd1556", 20 | "width": 300 21 | }, 22 | { 23 | "height": 64, 24 | "url": "https://i.scdn.co/image/3081b6247b809ac8466e71513b19be750da6063c", 25 | "width": 64 26 | } 27 | ], 28 | "name": "La ley innata", 29 | "type": "album", 30 | "uri": "spotify:album:1GYJUlbVr5FuNU7awwMGzu" 31 | }, 32 | "artists": [ 33 | { 34 | "external_urls": { 35 | "spotify": "https://open.spotify.com/artist/3bgsNtcf5d5h9jbQbohfBK" 36 | }, 37 | "href": "https://api.spotify.com/v1/artists/3bgsNtcf5d5h9jbQbohfBK", 38 | "id": "3bgsNtcf5d5h9jbQbohfBK", 39 | "name": "Extremoduro", 40 | "type": "artist", 41 | "uri": "spotify:artist:3bgsNtcf5d5h9jbQbohfBK" 42 | } 43 | ], 44 | "disc_number": 1, 45 | "duration_ms": 462013, 46 | "explicit": false, 47 | "external_ids": { 48 | "isrc": "ES5150800589" 49 | }, 50 | "external_urls": { 51 | "spotify": "https://open.spotify.com/track/1aDeaDooAd79p2sdImGG4a" 52 | }, 53 | "href": "https://api.spotify.com/v1/tracks/1aDeaDooAd79p2sdImGG4a", 54 | "id": "1aDeaDooAd79p2sdImGG4a", 55 | "is_playable": true, 56 | "name": "Dulce introduccion al caos", 57 | "popularity": 52, 58 | "preview_url": "https://p.scdn.co/mp3-preview/ee5cac4bf374a9c1fc188957870818e89ace9e8e", 59 | "track_number": 1, 60 | "type": "track", 61 | "uri": "spotify:track:1aDeaDooAd79p2sdImGG4a" 62 | }, 63 | { 64 | "album": { 65 | "album_type": "ALBUM", 66 | "external_urls": { 67 | "spotify": "https://open.spotify.com/album/5QHJB2blBbAL8BjrD9hrhG" 68 | }, 69 | "href": "https://api.spotify.com/v1/albums/5QHJB2blBbAL8BjrD9hrhG", 70 | "id": "5QHJB2blBbAL8BjrD9hrhG", 71 | "images": [ 72 | { 73 | "height": 637, 74 | "url": "https://i.scdn.co/image/e69a081f833086461a85b9ed07cf688dd19b53b2", 75 | "width": 640 76 | }, 77 | { 78 | "height": 299, 79 | "url": "https://i.scdn.co/image/d3c047a066a1ea2e22b617df83fd2aff683b7735", 80 | "width": 300 81 | }, 82 | { 83 | "height": 64, 84 | "url": "https://i.scdn.co/image/f05bd6a5f6579a0a928b52ed0118b12fd8a0a28e", 85 | "width": 64 86 | } 87 | ], 88 | "name": "Canciones Prohibidas", 89 | "type": "album", 90 | "uri": "spotify:album:5QHJB2blBbAL8BjrD9hrhG" 91 | }, 92 | "artists": [ 93 | { 94 | "external_urls": { 95 | "spotify": "https://open.spotify.com/artist/3bgsNtcf5d5h9jbQbohfBK" 96 | }, 97 | "href": "https://api.spotify.com/v1/artists/3bgsNtcf5d5h9jbQbohfBK", 98 | "id": "3bgsNtcf5d5h9jbQbohfBK", 99 | "name": "Extremoduro", 100 | "type": "artist", 101 | "uri": "spotify:artist:3bgsNtcf5d5h9jbQbohfBK" 102 | } 103 | ], 104 | "disc_number": 1, 105 | "duration_ms": 318986, 106 | "explicit": false, 107 | "external_ids": { 108 | "isrc": "ES5019814000" 109 | }, 110 | "external_urls": { 111 | "spotify": "https://open.spotify.com/track/4z2EeFUp5Lhai9qhHtA6IF" 112 | }, 113 | "href": "https://api.spotify.com/v1/tracks/4z2EeFUp5Lhai9qhHtA6IF", 114 | "id": "4z2EeFUp5Lhai9qhHtA6IF", 115 | "is_playable": true, 116 | "name": "Salir", 117 | "popularity": 51, 118 | "preview_url": "https://p.scdn.co/mp3-preview/2f59c92f21040e96f82572015e2de557f58d6af7", 119 | "track_number": 1, 120 | "type": "track", 121 | "uri": "spotify:track:4z2EeFUp5Lhai9qhHtA6IF" 122 | }, 123 | { 124 | "album": { 125 | "album_type": "ALBUM", 126 | "external_urls": { 127 | "spotify": "https://open.spotify.com/album/7dNZmdcPLsUh929GLnvvsU" 128 | }, 129 | "href": "https://api.spotify.com/v1/albums/7dNZmdcPLsUh929GLnvvsU", 130 | "id": "7dNZmdcPLsUh929GLnvvsU", 131 | "images": [ 132 | { 133 | "height": 640, 134 | "url": "https://i.scdn.co/image/698b40a4946892822ee7f0bb5bedff7c6b080a05", 135 | "width": 640 136 | }, 137 | { 138 | "height": 300, 139 | "url": "https://i.scdn.co/image/e5f36092d85e53cba2302e33c5148d7670654bcb", 140 | "width": 300 141 | }, 142 | { 143 | "height": 64, 144 | "url": "https://i.scdn.co/image/601e2416c08b335741705df457a0c04f7969d14b", 145 | "width": 64 146 | } 147 | ], 148 | "name": "15151 (En Directo)", 149 | "type": "album", 150 | "uri": "spotify:album:7dNZmdcPLsUh929GLnvvsU" 151 | }, 152 | "artists": [ 153 | { 154 | "external_urls": { 155 | "spotify": "https://open.spotify.com/artist/6J6yx1t3nwIDyPXk5xa7O8" 156 | }, 157 | "href": "https://api.spotify.com/v1/artists/6J6yx1t3nwIDyPXk5xa7O8", 158 | "id": "6J6yx1t3nwIDyPXk5xa7O8", 159 | "name": "Vetusta Morla", 160 | "type": "artist", 161 | "uri": "spotify:artist:6J6yx1t3nwIDyPXk5xa7O8" 162 | } 163 | ], 164 | "disc_number": 1, 165 | "duration_ms": 236650, 166 | "explicit": false, 167 | "external_ids": { 168 | "isrc": "ES55Z1060050" 169 | }, 170 | "external_urls": { 171 | "spotify": "https://open.spotify.com/track/20Z8eduNdbyQyBNn7xAB72" 172 | }, 173 | "href": "https://api.spotify.com/v1/tracks/20Z8eduNdbyQyBNn7xAB72", 174 | "id": "20Z8eduNdbyQyBNn7xAB72", 175 | "is_playable": true, 176 | "name": "La Deriva - En Directo", 177 | "popularity": 44, 178 | "preview_url": "https://p.scdn.co/mp3-preview/617066a1319b8c6bca31688231f60041b4f28ed0", 179 | "track_number": 1, 180 | "type": "track", 181 | "uri": "spotify:track:20Z8eduNdbyQyBNn7xAB72" 182 | }, 183 | { 184 | "album": { 185 | "album_type": "ALBUM", 186 | "external_urls": { 187 | "spotify": "https://open.spotify.com/album/01Jkf7OzOSC8qVbTQzJEMp" 188 | }, 189 | "href": "https://api.spotify.com/v1/albums/01Jkf7OzOSC8qVbTQzJEMp", 190 | "id": "01Jkf7OzOSC8qVbTQzJEMp", 191 | "images": [ 192 | { 193 | "height": 640, 194 | "url": "https://i.scdn.co/image/de0bcae8f078a886ba7d280138c5a723c984bbbd", 195 | "width": 640 196 | }, 197 | { 198 | "height": 300, 199 | "url": "https://i.scdn.co/image/d22d2d47b1e29e02530f5d7549471f6526ae8ee0", 200 | "width": 300 201 | }, 202 | { 203 | "height": 64, 204 | "url": "https://i.scdn.co/image/8cb9168ea2f2ae41451f595ead4c0553da191d39", 205 | "width": 64 206 | } 207 | ], 208 | "name": "La Deriva", 209 | "type": "album", 210 | "uri": "spotify:album:01Jkf7OzOSC8qVbTQzJEMp" 211 | }, 212 | "artists": [ 213 | { 214 | "external_urls": { 215 | "spotify": "https://open.spotify.com/artist/6J6yx1t3nwIDyPXk5xa7O8" 216 | }, 217 | "href": "https://api.spotify.com/v1/artists/6J6yx1t3nwIDyPXk5xa7O8", 218 | "id": "6J6yx1t3nwIDyPXk5xa7O8", 219 | "name": "Vetusta Morla", 220 | "type": "artist", 221 | "uri": "spotify:artist:6J6yx1t3nwIDyPXk5xa7O8" 222 | } 223 | ], 224 | "disc_number": 1, 225 | "duration_ms": 228258, 226 | "explicit": false, 227 | "external_ids": { 228 | "isrc": "ES55C1060102" 229 | }, 230 | "external_urls": { 231 | "spotify": "https://open.spotify.com/track/4Wgx9SRbKwhL65eMsDPdmR" 232 | }, 233 | "href": "https://api.spotify.com/v1/tracks/4Wgx9SRbKwhL65eMsDPdmR", 234 | "id": "4Wgx9SRbKwhL65eMsDPdmR", 235 | "is_playable": true, 236 | "name": "Golpe Maestro", 237 | "popularity": 50, 238 | "preview_url": "https://p.scdn.co/mp3-preview/e0fddb0715749d0daf4668e13252585abfdb5c6d", 239 | "track_number": 2, 240 | "type": "track", 241 | "uri": "spotify:track:4Wgx9SRbKwhL65eMsDPdmR" 242 | }, 243 | { 244 | "album": { 245 | "album_type": "SINGLE", 246 | "external_urls": { 247 | "spotify": "https://open.spotify.com/album/4T0PFSo6B3zBzcb6oQi9Sj" 248 | }, 249 | "href": "https://api.spotify.com/v1/albums/4T0PFSo6B3zBzcb6oQi9Sj", 250 | "id": "4T0PFSo6B3zBzcb6oQi9Sj", 251 | "images": [ 252 | { 253 | "height": 640, 254 | "url": "https://i.scdn.co/image/7299d7f23b013fd5f0572bdc43726053534488d9", 255 | "width": 640 256 | }, 257 | { 258 | "height": 300, 259 | "url": "https://i.scdn.co/image/d28691fd84f2a512d06e95716bcea557d6e2b992", 260 | "width": 300 261 | }, 262 | { 263 | "height": 64, 264 | "url": "https://i.scdn.co/image/96413c6265810b94278aa4e54dcce87a7e18a135", 265 | "width": 64 266 | } 267 | ], 268 | "name": "Puntos Suspensivos / Profetas de la Mañana", 269 | "type": "album", 270 | "uri": "spotify:album:4T0PFSo6B3zBzcb6oQi9Sj" 271 | }, 272 | "artists": [ 273 | { 274 | "external_urls": { 275 | "spotify": "https://open.spotify.com/artist/6J6yx1t3nwIDyPXk5xa7O8" 276 | }, 277 | "href": "https://api.spotify.com/v1/artists/6J6yx1t3nwIDyPXk5xa7O8", 278 | "id": "6J6yx1t3nwIDyPXk5xa7O8", 279 | "name": "Vetusta Morla", 280 | "type": "artist", 281 | "uri": "spotify:artist:6J6yx1t3nwIDyPXk5xa7O8" 282 | } 283 | ], 284 | "disc_number": 1, 285 | "duration_ms": 195696, 286 | "explicit": false, 287 | "external_ids": { 288 | "isrc": "ES55C1060117" 289 | }, 290 | "external_urls": { 291 | "spotify": "https://open.spotify.com/track/60ovquXFpaYpKkzJBgk2dv" 292 | }, 293 | "href": "https://api.spotify.com/v1/tracks/60ovquXFpaYpKkzJBgk2dv", 294 | "id": "60ovquXFpaYpKkzJBgk2dv", 295 | "is_playable": true, 296 | "name": "Puntos Suspensivos", 297 | "popularity": 52, 298 | "preview_url": "https://p.scdn.co/mp3-preview/6d793acff2e5a86f87a8ed1092f45f5dfa34b3ab", 299 | "track_number": 1, 300 | "type": "track", 301 | "uri": "spotify:track:60ovquXFpaYpKkzJBgk2dv" 302 | } 303 | ], 304 | "total": 50, 305 | "limit": 5, 306 | "offset": 0, 307 | "previous": null, 308 | "href": "https://api.spotify.com/v1/me/top/tracks?limit=5", 309 | "next": "https://api.spotify.com/v1/me/top/tracks?limit=5&offset=5" 310 | } 311 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spotify-web-api-js", 3 | "description": "A client-side JS wrapper for the Spotify Web API", 4 | "version": "1.5.2", 5 | "homepage": "https://github.com/JMPerez/spotify-web-api-js", 6 | "author": { 7 | "name": "José M. Pérez" 8 | }, 9 | "license": "MIT", 10 | "main": "src/spotify-web-api.js", 11 | "typings": "src/typings/spotify-web-api.d.ts", 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/JMPerez/spotify-web-api-js" 15 | }, 16 | "devDependencies": { 17 | "coveralls": "^3.1.0", 18 | "doxdox": "^3.0.0", 19 | "eslint": "^7.15.0", 20 | "eslint-config-prettier": "^7.0.0", 21 | "husky": "^4.3.5", 22 | "jest": "^26.6.3", 23 | "lint-staged": "^10.5.3", 24 | "prettier": "^2.2.1", 25 | "q": "^1.4.1", 26 | "sinon": "^9.2.1" 27 | }, 28 | "jest": { 29 | "verbose": true, 30 | "testURL": "http://localhost/" 31 | }, 32 | "scripts": { 33 | "lint": "eslint src/*.js", 34 | "test": "npm run lint && jest --coverage", 35 | "travis": "npm test && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", 36 | "docs": "mkdir -p docs && doxdox 'src/**/*.js' --layout bootstrap --output docs/index.html" 37 | }, 38 | "files": [ 39 | "src/*.js", 40 | "src/typings/*.d.ts" 41 | ], 42 | "keywords": [ 43 | "spotify" 44 | ], 45 | "husky": { 46 | "hooks": { 47 | "pre-commit": "lint-staged" 48 | } 49 | }, 50 | "lint-staged": { 51 | "*.js": "eslint --cache --fix", 52 | "*.{js,css,md,json}": "prettier --single-quote --trailing-comma none --write '{**/*.ts,**/*.js,*.md,__test__/**/*.json}'" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /typings-example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMPerez/spotify-web-api-js/983961640bd429ba6577d1deab1f836182af3059/typings-example.gif --------------------------------------------------------------------------------