From a10db92c8ae1236edc4110754a06e41464195a95 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 12:33:22 -0300
Subject: [PATCH 01/27] Update page model to support search requests and to
 keep query params

---
 src/lib/models/paging/page.ts | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/src/lib/models/paging/page.ts b/src/lib/models/paging/page.ts
index 4ce5709c..9c048899 100644
--- a/src/lib/models/paging/page.ts
+++ b/src/lib/models/paging/page.ts
@@ -17,9 +17,13 @@ class Page<T> {
 
     total: number;
 
-    constructor(json: any, t: new (json: any) => T) {
+    wrapper?: string;
+
+    constructor(json: any, t: new (json: any) => T, wrapper?: string) {
+        this.wrapper = wrapper;
+        if (wrapper) json = json[wrapper];
         this.t = t;
-        this.href = json.href.split('?')[0];
+        this.href = json.href;
         this.items = json.items.map((json: any) => new t(json));
         this.limit = json.limit;
         this.next = json.next ? json.next.split('?')[1] : null;
@@ -28,9 +32,22 @@ class Page<T> {
         this.total = json.total;
     }
 
+    get queryParams(): any {
+        const queryString = this.href.split('?')[1];
+        const paramsString = queryString.split('&');
+        let queryParams: any = {};
+
+        for (const param of paramsString) {
+            const [name, value] = param.split('=');
+            queryParams[name] = value;
+        }
+
+        return queryParams;
+    }
+
     private getAxiosPageInstance() {
         const instance = getAxiosSpotifyInstance();
-        instance.defaults.baseURL = this.href;
+        instance.defaults.baseURL = this.href.split('?')[0];
         return instance;
     }
 
@@ -44,9 +61,13 @@ class Page<T> {
 
     async getNextPage() {
         if (!this.hasNext()) throw new Error('There are no more pages');
-        const params = { limit: this.limit, offset: this.offset + this.limit };
+        const params = {
+            ...this.queryParams,
+            limit: this.limit,
+            offset: this.offset + this.limit,
+        };
         const response = await this.getAxiosPageInstance().get('/', { params });
-        return new Page<T>(response.data, this.t);
+        return new Page<T>(response.data, this.t, this.wrapper);
     }
 
     async getPreviousPage(forceLimit = false) {
@@ -55,11 +76,11 @@ class Page<T> {
         if (this.offset < this.limit && !forceLimit) {
             limit = this.offset;
         }
-        const params = { limit, offset: 0 };
+        const params = { ...this.queryParams, limit, offset: 0 };
         const response = await this.getAxiosPageInstance().get('/', {
             params,
         });
-        return new Page<T>(response.data, this.t);
+        return new Page<T>(response.data, this.t, this.wrapper);
     }
 }
 

From fbcd91bf3425eef04b65514e03c89cfacffe301c Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 12:33:53 -0300
Subject: [PATCH 02/27] Correct failing test

---
 test/common/matching-attributes.test.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/common/matching-attributes.test.ts b/test/common/matching-attributes.test.ts
index 3242f2fe..ea85d125 100644
--- a/test/common/matching-attributes.test.ts
+++ b/test/common/matching-attributes.test.ts
@@ -97,7 +97,7 @@ export const checkMatchingPagingObjectAttributes = (
     response: any,
     mock: any
 ) => {
-    expect(response.href).to.be.equal(mock.href.split('?')[0]);
+    expect(response.href).to.be.equal(mock.href);
     expect(response.items).to.have.lengthOf(mock.items.length);
     expect(response.limit).to.be.equal(mock.limit);
     expect(response.offset).to.be.equal(mock.offset);

From a321d81ab0aaeb08707f9096b05ae4a058a0283e Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 14:00:58 -0300
Subject: [PATCH 03/27] Fix bug in getPreviousPage and rename parameter

---
 src/lib/models/paging/page.ts | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/lib/models/paging/page.ts b/src/lib/models/paging/page.ts
index 9c048899..01c9d049 100644
--- a/src/lib/models/paging/page.ts
+++ b/src/lib/models/paging/page.ts
@@ -70,13 +70,12 @@ class Page<T> {
         return new Page<T>(response.data, this.t, this.wrapper);
     }
 
-    async getPreviousPage(forceLimit = false) {
+    async getPreviousPage(includeRepeated = false) {
         if (!this.hasPrevious()) throw new Error('There are no more pages');
         let limit = this.limit;
-        if (this.offset < this.limit && !forceLimit) {
-            limit = this.offset;
-        }
-        const params = { ...this.queryParams, limit, offset: 0 };
+        if (this.offset < this.limit && !includeRepeated) limit = this.offset;
+        let offset = Math.max(this.offset - this.limit, 0);
+        const params = { ...this.queryParams, limit, offset };
         const response = await this.getAxiosPageInstance().get('/', {
             params,
         });

From cd8b00e92968f4fe2b97dd1e64662b687774f298 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 14:02:54 -0300
Subject: [PATCH 04/27] Implement generic search and search for artists

---
 src/lib/search.ts | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 src/lib/search.ts

diff --git a/src/lib/search.ts b/src/lib/search.ts
new file mode 100644
index 00000000..61d19aab
--- /dev/null
+++ b/src/lib/search.ts
@@ -0,0 +1,23 @@
+import { getAxiosSpotifyInstance } from './driver';
+
+import Artist from './models/artist/artist';
+import Page from './models/paging/page';
+
+const genericSearch = async (params: {
+    q: string;
+    type: string;
+    market?: string;
+    limit?: number;
+    offset?: number;
+}) => {
+    return getAxiosSpotifyInstance().get(`/search`, { params });
+};
+
+export const searchArtists = async (
+    query: string,
+    options?: { market?: string; limit?: number; offset?: number }
+) => {
+    const params = { q: query, type: 'artist', ...options };
+    const searchResults = await genericSearch(params);
+    return new Page<Artist>(searchResults.data, Artist, 'artists');
+};

From ce94aff486be726a1ba4c2f43038ea1892311662 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 14:26:03 -0300
Subject: [PATCH 05/27] Add missing implementation of search requests

---
 src/lib/search.ts | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/src/lib/search.ts b/src/lib/search.ts
index 61d19aab..fbf1d92e 100644
--- a/src/lib/search.ts
+++ b/src/lib/search.ts
@@ -1,7 +1,10 @@
 import { getAxiosSpotifyInstance } from './driver';
 
+import AlbumSimplified from './models/album/album-simplified';
 import Artist from './models/artist/artist';
 import Page from './models/paging/page';
+import PlaylistSimplified from './models/playlist/playlist-simplified';
+import Track from './models/track/track';
 
 const genericSearch = async (params: {
     q: string;
@@ -10,9 +13,23 @@ const genericSearch = async (params: {
     limit?: number;
     offset?: number;
 }) => {
+    console.log(params.type);
     return getAxiosSpotifyInstance().get(`/search`, { params });
 };
 
+export const searchAlbums = async (
+    query: string,
+    options?: { market?: string; limit?: number; offset?: number }
+) => {
+    const params = { q: query, type: 'album', ...options };
+    const searchResults = await genericSearch(params);
+    return new Page<AlbumSimplified>(
+        searchResults.data,
+        AlbumSimplified,
+        'albums'
+    );
+};
+
 export const searchArtists = async (
     query: string,
     options?: { market?: string; limit?: number; offset?: number }
@@ -21,3 +38,25 @@ export const searchArtists = async (
     const searchResults = await genericSearch(params);
     return new Page<Artist>(searchResults.data, Artist, 'artists');
 };
+
+export const searchPlaylists = async (
+    query: string,
+    options?: { market?: string; limit?: number; offset?: number }
+) => {
+    const params = { q: query, type: 'playlist', ...options };
+    const searchResults = await genericSearch(params);
+    return new Page<PlaylistSimplified>(
+        searchResults.data,
+        PlaylistSimplified,
+        'playlists'
+    );
+};
+
+export const searchTracks = async (
+    query: string,
+    options?: { market?: string; limit?: number; offset?: number }
+) => {
+    const params = { q: query, type: 'track', ...options };
+    const searchResults = await genericSearch(params);
+    return new Page<Track>(searchResults.data, Track, 'tracks');
+};

From 701c4188ca46b039d846ff54c5180409a51da14c Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 14:27:00 -0300
Subject: [PATCH 06/27] Make some of user's attributes optional due to possibly
 missing data

---
 src/lib/models/user/user-public.ts | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/lib/models/user/user-public.ts b/src/lib/models/user/user-public.ts
index a740da34..07418fbc 100644
--- a/src/lib/models/user/user-public.ts
+++ b/src/lib/models/user/user-public.ts
@@ -6,13 +6,13 @@ class PublicUser {
 
     externalUrls: any;
 
-    followers: Followers;
+    followers?: Followers;
 
     href: string;
 
     id: string;
 
-    images: Image[];
+    images?: Image[];
 
     type: 'user';
 
@@ -21,10 +21,13 @@ class PublicUser {
     constructor(json: any) {
         this.displayName = json.display_name;
         this.externalUrls = json.external_urls;
-        this.followers = new Followers(json.followers);
+        if (json.followers) this.followers = new Followers(json.followers);
         this.href = json.href;
         this.id = json.id;
-        this.images = json.images.map((imageJson: any) => new Image(imageJson));
+        if (json.images)
+            this.images = json.images.map(
+                (imageJson: any) => new Image(imageJson)
+            );
         this.type = json.type;
         this.uri = json.uri;
     }

From 917aa4fe29bdc9fea03c06cea8136fb34da2a60d Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 14:27:44 -0300
Subject: [PATCH 07/27] Export search requests through index.ts

---
 src/lib/index.ts | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/lib/index.ts b/src/lib/index.ts
index 32a86a9c..ad012a64 100644
--- a/src/lib/index.ts
+++ b/src/lib/index.ts
@@ -1,6 +1,7 @@
+export * from './albums';
+export * from './artists';
 export * from './driver';
-export * from './tracks';
 export * from './follow';
-export * from './artists';
-export * from './albums';
 export * from './playlists';
+export * from './search';
+export * from './tracks';

From bf1203ab7b35f44e9915b1d2ef9e22f9c4af696a Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 15:01:19 -0300
Subject: [PATCH 08/27] Implement tests for search requests

---
 src/lib/search.ts                   |   1 -
 test/mocks/search-albums.mock.ts    | 138 ++++++++++++++++++
 test/mocks/search-artists.mock.ts   |  82 +++++++++++
 test/mocks/search-playlists.mock.ts |  94 ++++++++++++
 test/mocks/search-tracks.mock.ts    | 214 ++++++++++++++++++++++++++++
 test/search.test.ts                 | 101 +++++++++++++
 6 files changed, 629 insertions(+), 1 deletion(-)
 create mode 100644 test/mocks/search-albums.mock.ts
 create mode 100644 test/mocks/search-artists.mock.ts
 create mode 100644 test/mocks/search-playlists.mock.ts
 create mode 100644 test/mocks/search-tracks.mock.ts
 create mode 100644 test/search.test.ts

diff --git a/src/lib/search.ts b/src/lib/search.ts
index fbf1d92e..15479353 100644
--- a/src/lib/search.ts
+++ b/src/lib/search.ts
@@ -13,7 +13,6 @@ const genericSearch = async (params: {
     limit?: number;
     offset?: number;
 }) => {
-    console.log(params.type);
     return getAxiosSpotifyInstance().get(`/search`, { params });
 };
 
diff --git a/test/mocks/search-albums.mock.ts b/test/mocks/search-albums.mock.ts
new file mode 100644
index 00000000..ad13841c
--- /dev/null
+++ b/test/mocks/search-albums.mock.ts
@@ -0,0 +1,138 @@
+export const searchAlbumsMock = {
+    albums: {
+        href:
+            'https://api.spotify.com/v1/search?query=sia&type=album&market=BR&offset=0&limit=2',
+        items: [
+            {
+                album_type: 'album',
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/5WUlDfRSoLAfcVSX1WnrxN',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/5WUlDfRSoLAfcVSX1WnrxN',
+                        id: '5WUlDfRSoLAfcVSX1WnrxN',
+                        name: 'Sia',
+                        type: 'artist',
+                        uri: 'spotify:artist:5WUlDfRSoLAfcVSX1WnrxN',
+                    },
+                ],
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/album/3xFSl9lIRaYXIYkIn3OIl9',
+                },
+                href:
+                    'https://api.spotify.com/v1/albums/3xFSl9lIRaYXIYkIn3OIl9',
+                id: '3xFSl9lIRaYXIYkIn3OIl9',
+                images: [
+                    {
+                        height: 640,
+                        url:
+                            'https://i.scdn.co/image/03d97de27e99fd8099506ea172531cea0da59654',
+                        width: 640,
+                    },
+                    {
+                        height: 300,
+                        url:
+                            'https://i.scdn.co/image/58595889bbd362182cd3ef5c3633e1c56823d859',
+                        width: 300,
+                    },
+                    {
+                        height: 64,
+                        url:
+                            'https://i.scdn.co/image/b8b3036b13b0db9108aeca2b8b779da317973c16',
+                        width: 64,
+                    },
+                ],
+                name: '1000 Forms Of Fear',
+                release_date: '2014-07-04',
+                release_date_precision: 'day',
+                total_tracks: 12,
+                type: 'album',
+                uri: 'spotify:album:3xFSl9lIRaYXIYkIn3OIl9',
+            },
+            {
+                album_type: 'single',
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/5WUlDfRSoLAfcVSX1WnrxN',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/5WUlDfRSoLAfcVSX1WnrxN',
+                        id: '5WUlDfRSoLAfcVSX1WnrxN',
+                        name: 'Sia',
+                        type: 'artist',
+                        uri: 'spotify:artist:5WUlDfRSoLAfcVSX1WnrxN',
+                    },
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/5fMUXHkw8R8eOP2RNVYEZX',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/5fMUXHkw8R8eOP2RNVYEZX',
+                        id: '5fMUXHkw8R8eOP2RNVYEZX',
+                        name: 'Diplo',
+                        type: 'artist',
+                        uri: 'spotify:artist:5fMUXHkw8R8eOP2RNVYEZX',
+                    },
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/2feDdbD5araYcm6JhFHHw7',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/2feDdbD5araYcm6JhFHHw7',
+                        id: '2feDdbD5araYcm6JhFHHw7',
+                        name: 'Labrinth',
+                        type: 'artist',
+                        uri: 'spotify:artist:2feDdbD5araYcm6JhFHHw7',
+                    },
+                ],
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/album/3dB0bCgmpEgCSr3aU1bOtv',
+                },
+                href:
+                    'https://api.spotify.com/v1/albums/3dB0bCgmpEgCSr3aU1bOtv',
+                id: '3dB0bCgmpEgCSr3aU1bOtv',
+                images: [
+                    {
+                        height: 640,
+                        url:
+                            'https://i.scdn.co/image/43224d4f43e14d3a97e20e79e9c662accc80019f',
+                        width: 640,
+                    },
+                    {
+                        height: 300,
+                        url:
+                            'https://i.scdn.co/image/e6e6d19f5def281ea2b1be6f8199774c3660ed84',
+                        width: 300,
+                    },
+                    {
+                        height: 64,
+                        url:
+                            'https://i.scdn.co/image/8b6a5449cba2593b5fd2a7dd6e434366f8b0c100',
+                        width: 64,
+                    },
+                ],
+                name: 'Mountains',
+                release_date: '2018-11-01',
+                release_date_precision: 'day',
+                total_tracks: 4,
+                type: 'album',
+                uri: 'spotify:album:3dB0bCgmpEgCSr3aU1bOtv',
+            },
+        ],
+        limit: 2,
+        next:
+            'https://api.spotify.com/v1/search?query=sia&type=album&market=BR&offset=2&limit=2',
+        offset: 0,
+        previous: null,
+        total: 708,
+    },
+};
diff --git a/test/mocks/search-artists.mock.ts b/test/mocks/search-artists.mock.ts
new file mode 100644
index 00000000..c156c75a
--- /dev/null
+++ b/test/mocks/search-artists.mock.ts
@@ -0,0 +1,82 @@
+export const searchArtistsMock = {
+    artists: {
+        href:
+            'https://api.spotify.com/v1/search?query=sia&type=artist&market=BR&offset=0&limit=2',
+        items: [
+            {
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/artist/5WUlDfRSoLAfcVSX1WnrxN',
+                },
+                followers: {
+                    href: null,
+                    total: 9001196,
+                },
+                genres: [
+                    'australian dance',
+                    'australian pop',
+                    'dance pop',
+                    'pop',
+                ],
+                href:
+                    'https://api.spotify.com/v1/artists/5WUlDfRSoLAfcVSX1WnrxN',
+                id: '5WUlDfRSoLAfcVSX1WnrxN',
+                images: [
+                    {
+                        height: 1333,
+                        url:
+                            'https://i.scdn.co/image/652b6bb0dfaf8aa444f4414ee018699260e74306',
+                        width: 1000,
+                    },
+                    {
+                        height: 853,
+                        url:
+                            'https://i.scdn.co/image/a82822ab211cbe28a0a1dbcb16902a1a8a2ea791',
+                        width: 640,
+                    },
+                    {
+                        height: 267,
+                        url:
+                            'https://i.scdn.co/image/dd3e336d456172bbda56b543c5389e1490903a30',
+                        width: 200,
+                    },
+                    {
+                        height: 85,
+                        url:
+                            'https://i.scdn.co/image/95a2aa98384b31336b8d56f8b470c45b12dcd550',
+                        width: 64,
+                    },
+                ],
+                name: 'Sia',
+                popularity: 90,
+                type: 'artist',
+                uri: 'spotify:artist:5WUlDfRSoLAfcVSX1WnrxN',
+            },
+            {
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/artist/6vYYsmA7fdkIGOCPjAM7hM',
+                },
+                followers: {
+                    href: null,
+                    total: 628,
+                },
+                genres: [],
+                href:
+                    'https://api.spotify.com/v1/artists/6vYYsmA7fdkIGOCPjAM7hM',
+                id: '6vYYsmA7fdkIGOCPjAM7hM',
+                images: [],
+                name: 'Sia Furler',
+                popularity: 26,
+                type: 'artist',
+                uri: 'spotify:artist:6vYYsmA7fdkIGOCPjAM7hM',
+            },
+        ],
+        limit: 2,
+        next:
+            'https://api.spotify.com/v1/search?query=sia&type=artist&market=BR&offset=2&limit=2',
+        offset: 0,
+        previous: null,
+        total: 81,
+    },
+};
diff --git a/test/mocks/search-playlists.mock.ts b/test/mocks/search-playlists.mock.ts
new file mode 100644
index 00000000..0cbc938d
--- /dev/null
+++ b/test/mocks/search-playlists.mock.ts
@@ -0,0 +1,94 @@
+export const searchPlaylistsMock = {
+    playlists: {
+        href:
+            'https://api.spotify.com/v1/search?query=sia&type=playlist&market=BR&offset=0&limit=2',
+        items: [
+            {
+                collaborative: false,
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/playlist/37i9dQZF1DX7wWaJYweK28',
+                },
+                href:
+                    'https://api.spotify.com/v1/playlists/37i9dQZF1DX7wWaJYweK28',
+                id: '37i9dQZF1DX7wWaJYweK28',
+                images: [
+                    {
+                        height: 300,
+                        url:
+                            'https://i.scdn.co/image/4422bab7cebb64aeeefcb9f738a3c7402351138c',
+                        width: 300,
+                    },
+                ],
+                name: 'This Is Sia',
+                owner: {
+                    display_name: 'Spotify',
+                    external_urls: {
+                        spotify: 'https://open.spotify.com/user/spotify',
+                    },
+                    href: 'https://api.spotify.com/v1/users/spotify',
+                    id: 'spotify',
+                    type: 'user',
+                    uri: 'spotify:user:spotify',
+                },
+                primary_color: null,
+                public: null,
+                snapshot_id:
+                    'MTUzMzg2MzU1MiwwMDAwMDAwZjAwMDAwMTY1MjE2NDY1ZWUwMDAwMDE2MmYyYjBlOGQ4',
+                tracks: {
+                    href:
+                        'https://api.spotify.com/v1/playlists/37i9dQZF1DX7wWaJYweK28/tracks',
+                    total: 50,
+                },
+                type: 'playlist',
+                uri: 'spotify:user:spotify:playlist:37i9dQZF1DX7wWaJYweK28',
+            },
+            {
+                collaborative: false,
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/playlist/05T1KuTCkjxifLHkawRNVX',
+                },
+                href:
+                    'https://api.spotify.com/v1/playlists/05T1KuTCkjxifLHkawRNVX',
+                id: '05T1KuTCkjxifLHkawRNVX',
+                images: [
+                    {
+                        height: null,
+                        url:
+                            'https://pl.scdn.co/images/pl/default/b15fb9124d86e7a027b9a66f09a58fc00d056a65',
+                        width: null,
+                    },
+                ],
+                name: 'Sia Discography',
+                owner: {
+                    display_name: 'Sia',
+                    external_urls: {
+                        spotify: 'https://open.spotify.com/user/siaofficial',
+                    },
+                    href: 'https://api.spotify.com/v1/users/siaofficial',
+                    id: 'siaofficial',
+                    type: 'user',
+                    uri: 'spotify:user:siaofficial',
+                },
+                primary_color: null,
+                public: null,
+                snapshot_id:
+                    'MTY1LDc4YzVhY2MwYTAzMWIxNjhmNWFlMWI4OTE3MmVlZjM1ZmE5ZTViZjQ=',
+                tracks: {
+                    href:
+                        'https://api.spotify.com/v1/playlists/05T1KuTCkjxifLHkawRNVX/tracks',
+                    total: 263,
+                },
+                type: 'playlist',
+                uri: 'spotify:user:siaofficial:playlist:05T1KuTCkjxifLHkawRNVX',
+            },
+        ],
+        limit: 2,
+        next:
+            'https://api.spotify.com/v1/search?query=sia&type=playlist&market=BR&offset=2&limit=2',
+        offset: 0,
+        previous: null,
+        total: 27596,
+    },
+};
diff --git a/test/mocks/search-tracks.mock.ts b/test/mocks/search-tracks.mock.ts
new file mode 100644
index 00000000..56b2f6cb
--- /dev/null
+++ b/test/mocks/search-tracks.mock.ts
@@ -0,0 +1,214 @@
+export const searchTracksMock = {
+    tracks: {
+        href:
+            'https://api.spotify.com/v1/search?query=sia&type=track&market=BR&offset=0&limit=2',
+        items: [
+            {
+                album: {
+                    album_type: 'single',
+                    artists: [
+                        {
+                            external_urls: {
+                                spotify:
+                                    'https://open.spotify.com/artist/5ZsFI1h6hIdQRw2ti0hz81',
+                            },
+                            href:
+                                'https://api.spotify.com/v1/artists/5ZsFI1h6hIdQRw2ti0hz81',
+                            id: '5ZsFI1h6hIdQRw2ti0hz81',
+                            name: 'ZAYN',
+                            type: 'artist',
+                            uri: 'spotify:artist:5ZsFI1h6hIdQRw2ti0hz81',
+                        },
+                        {
+                            external_urls: {
+                                spotify:
+                                    'https://open.spotify.com/artist/5WUlDfRSoLAfcVSX1WnrxN',
+                            },
+                            href:
+                                'https://api.spotify.com/v1/artists/5WUlDfRSoLAfcVSX1WnrxN',
+                            id: '5WUlDfRSoLAfcVSX1WnrxN',
+                            name: 'Sia',
+                            type: 'artist',
+                            uri: 'spotify:artist:5WUlDfRSoLAfcVSX1WnrxN',
+                        },
+                    ],
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/album/5l5gR4rh26QI3fijGFTDrp',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/albums/5l5gR4rh26QI3fijGFTDrp',
+                    id: '5l5gR4rh26QI3fijGFTDrp',
+                    images: [
+                        {
+                            height: 640,
+                            url:
+                                'https://i.scdn.co/image/53779ee060cd1618e62e7a47bf3c7645ced2ba70',
+                            width: 640,
+                        },
+                        {
+                            height: 300,
+                            url:
+                                'https://i.scdn.co/image/492de7f87c8a94d7af46a332eb3688a41f1e0b0d',
+                            width: 300,
+                        },
+                        {
+                            height: 64,
+                            url:
+                                'https://i.scdn.co/image/eb0909052dc1bf9eb2da86a79996fd1766d921d6',
+                            width: 64,
+                        },
+                    ],
+                    name: 'Dusk Till Dawn (Radio Edit)',
+                    release_date: '2017-09-07',
+                    release_date_precision: 'day',
+                    total_tracks: 1,
+                    type: 'album',
+                    uri: 'spotify:album:5l5gR4rh26QI3fijGFTDrp',
+                },
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/5ZsFI1h6hIdQRw2ti0hz81',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/5ZsFI1h6hIdQRw2ti0hz81',
+                        id: '5ZsFI1h6hIdQRw2ti0hz81',
+                        name: 'ZAYN',
+                        type: 'artist',
+                        uri: 'spotify:artist:5ZsFI1h6hIdQRw2ti0hz81',
+                    },
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/5WUlDfRSoLAfcVSX1WnrxN',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/5WUlDfRSoLAfcVSX1WnrxN',
+                        id: '5WUlDfRSoLAfcVSX1WnrxN',
+                        name: 'Sia',
+                        type: 'artist',
+                        uri: 'spotify:artist:5WUlDfRSoLAfcVSX1WnrxN',
+                    },
+                ],
+                disc_number: 1,
+                duration_ms: 239000,
+                explicit: false,
+                external_ids: {
+                    isrc: 'USRC11702155',
+                },
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/track/1j4kHkkpqZRBwE0A4CN4Yv',
+                },
+                href:
+                    'https://api.spotify.com/v1/tracks/1j4kHkkpqZRBwE0A4CN4Yv',
+                id: '1j4kHkkpqZRBwE0A4CN4Yv',
+                is_local: false,
+                is_playable: true,
+                name: 'Dusk Till Dawn - Radio Edit',
+                popularity: 84,
+                preview_url:
+                    'https://p.scdn.co/mp3-preview/e2e03acfd38d7cfa2baa924e0e9c7a80f9b49137?cid=774b29d4f13844c495f206cafdad9c86',
+                track_number: 1,
+                type: 'track',
+                uri: 'spotify:track:1j4kHkkpqZRBwE0A4CN4Yv',
+            },
+            {
+                album: {
+                    album_type: 'album',
+                    artists: [
+                        {
+                            external_urls: {
+                                spotify:
+                                    'https://open.spotify.com/artist/5WUlDfRSoLAfcVSX1WnrxN',
+                            },
+                            href:
+                                'https://api.spotify.com/v1/artists/5WUlDfRSoLAfcVSX1WnrxN',
+                            id: '5WUlDfRSoLAfcVSX1WnrxN',
+                            name: 'Sia',
+                            type: 'artist',
+                            uri: 'spotify:artist:5WUlDfRSoLAfcVSX1WnrxN',
+                        },
+                    ],
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/album/3xFSl9lIRaYXIYkIn3OIl9',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/albums/3xFSl9lIRaYXIYkIn3OIl9',
+                    id: '3xFSl9lIRaYXIYkIn3OIl9',
+                    images: [
+                        {
+                            height: 640,
+                            url:
+                                'https://i.scdn.co/image/03d97de27e99fd8099506ea172531cea0da59654',
+                            width: 640,
+                        },
+                        {
+                            height: 300,
+                            url:
+                                'https://i.scdn.co/image/58595889bbd362182cd3ef5c3633e1c56823d859',
+                            width: 300,
+                        },
+                        {
+                            height: 64,
+                            url:
+                                'https://i.scdn.co/image/b8b3036b13b0db9108aeca2b8b779da317973c16',
+                            width: 64,
+                        },
+                    ],
+                    name: '1000 Forms Of Fear',
+                    release_date: '2014-07-04',
+                    release_date_precision: 'day',
+                    total_tracks: 12,
+                    type: 'album',
+                    uri: 'spotify:album:3xFSl9lIRaYXIYkIn3OIl9',
+                },
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/5WUlDfRSoLAfcVSX1WnrxN',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/5WUlDfRSoLAfcVSX1WnrxN',
+                        id: '5WUlDfRSoLAfcVSX1WnrxN',
+                        name: 'Sia',
+                        type: 'artist',
+                        uri: 'spotify:artist:5WUlDfRSoLAfcVSX1WnrxN',
+                    },
+                ],
+                disc_number: 1,
+                duration_ms: 216120,
+                explicit: false,
+                external_ids: {
+                    isrc: 'USRC11400498',
+                },
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/track/4VrWlk8IQxevMvERoX08iC',
+                },
+                href:
+                    'https://api.spotify.com/v1/tracks/4VrWlk8IQxevMvERoX08iC',
+                id: '4VrWlk8IQxevMvERoX08iC',
+                is_local: false,
+                is_playable: true,
+                name: 'Chandelier',
+                popularity: 79,
+                preview_url:
+                    'https://p.scdn.co/mp3-preview/f1898cf5fd5640d4f0d7faafa6c572fc29db3db6?cid=774b29d4f13844c495f206cafdad9c86',
+                track_number: 1,
+                type: 'track',
+                uri: 'spotify:track:4VrWlk8IQxevMvERoX08iC',
+            },
+        ],
+        limit: 2,
+        next:
+            'https://api.spotify.com/v1/search?query=sia&type=track&market=BR&offset=2&limit=2',
+        offset: 0,
+        previous: null,
+        total: 6581,
+    },
+};
diff --git a/test/search.test.ts b/test/search.test.ts
new file mode 100644
index 00000000..bb76d1b0
--- /dev/null
+++ b/test/search.test.ts
@@ -0,0 +1,101 @@
+import { searchTracksMock } from './mocks/search-tracks.mock';
+import { searchPlaylistsMock } from './mocks/search-playlists.mock';
+import nock from 'nock';
+
+import { searchAlbumsMock } from './mocks/search-albums.mock';
+import { checkMatchingPagingObjectAttributes } from './common/matching-attributes.test';
+
+import {
+    init,
+    searchAlbums,
+    searchArtists,
+    searchPlaylists,
+    searchTracks,
+} from '../src/lib';
+import { searchArtistsMock } from './mocks/search-artists.mock';
+
+describe('Search requests', () => {
+    beforeEach(() => {
+        init('SomeToken');
+    });
+
+    describe('#searchAlbums()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/search')
+                .query({ q: 'sia', type: 'album', market: 'BR', limit: 2 })
+                .reply(200, searchAlbumsMock);
+        });
+
+        it('response should match all paging object attributes', async () => {
+            const searchAlbumsResponse = await searchAlbums('sia', {
+                market: 'BR',
+                limit: 2,
+            });
+            checkMatchingPagingObjectAttributes(
+                searchAlbumsResponse,
+                searchAlbumsMock.albums
+            );
+        });
+    });
+
+    describe('#searchArtists()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/search')
+                .query({ q: 'sia', type: 'artist', market: 'BR', limit: 2 })
+                .reply(200, searchArtistsMock);
+        });
+
+        it('response should match all paging object attributes', async () => {
+            const searchArtistsResponse = await searchArtists('sia', {
+                market: 'BR',
+                limit: 2,
+            });
+            checkMatchingPagingObjectAttributes(
+                searchArtistsResponse,
+                searchArtistsMock.artists
+            );
+        });
+    });
+
+    describe('#searchPlaylists()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/search')
+                .query({ q: 'sia', type: 'playlist', market: 'BR', limit: 2 })
+                .reply(200, searchPlaylistsMock);
+        });
+
+        it('response should match all paging object attributes', async () => {
+            const searchPlaylistsResponse = await searchPlaylists('sia', {
+                market: 'BR',
+                limit: 2,
+            });
+            checkMatchingPagingObjectAttributes(
+                searchPlaylistsResponse,
+                searchPlaylistsMock.playlists
+            );
+        });
+    });
+
+    describe('#searchTracks()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/search')
+                .query({ q: 'sia', type: 'track', market: 'BR', limit: 2 })
+                .reply(200, searchTracksMock);
+        });
+
+        it('response should match all paging object attributes', async () => {
+            const searchTracksResponse = await searchTracks('sia', {
+                market: 'BR',
+                limit: 2,
+            });
+            checkMatchingPagingObjectAttributes(
+                searchTracksResponse,
+                searchTracksMock.tracks
+            );
+        });
+    });
+});

From 9ad3ec7d37756908780d0c1d25c3bc5ba1869b13 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 15:13:19 -0300
Subject: [PATCH 09/27] Fix lint errors

---
 src/lib/models/paging/page.ts      | 25 +++++++++++++++----------
 src/lib/models/user/user-public.ts |  3 ++-
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/src/lib/models/paging/page.ts b/src/lib/models/paging/page.ts
index 01c9d049..966e9d2f 100644
--- a/src/lib/models/paging/page.ts
+++ b/src/lib/models/paging/page.ts
@@ -21,21 +21,26 @@ class Page<T> {
 
     constructor(json: any, t: new (json: any) => T, wrapper?: string) {
         this.wrapper = wrapper;
-        if (wrapper) json = json[wrapper];
+        let unwrappedJson = json;
+        if (wrapper) unwrappedJson = unwrappedJson[wrapper];
         this.t = t;
-        this.href = json.href;
-        this.items = json.items.map((json: any) => new t(json));
-        this.limit = json.limit;
-        this.next = json.next ? json.next.split('?')[1] : null;
-        this.offset = json.offset;
-        this.previous = json.previous ? json.previous.split('?')[1] : null;
-        this.total = json.total;
+        this.href = unwrappedJson.href;
+        this.items = unwrappedJson.items.map((json: any) => new t(json));
+        this.limit = unwrappedJson.limit;
+        this.next = unwrappedJson.next
+            ? unwrappedJson.next.split('?')[1]
+            : null;
+        this.offset = unwrappedJson.offset;
+        this.previous = unwrappedJson.previous
+            ? unwrappedJson.previous.split('?')[1]
+            : null;
+        this.total = unwrappedJson.total;
     }
 
     get queryParams(): any {
         const queryString = this.href.split('?')[1];
         const paramsString = queryString.split('&');
-        let queryParams: any = {};
+        const queryParams: any = {};
 
         for (const param of paramsString) {
             const [name, value] = param.split('=');
@@ -74,7 +79,7 @@ class Page<T> {
         if (!this.hasPrevious()) throw new Error('There are no more pages');
         let limit = this.limit;
         if (this.offset < this.limit && !includeRepeated) limit = this.offset;
-        let offset = Math.max(this.offset - this.limit, 0);
+        const offset = Math.max(this.offset - this.limit, 0);
         const params = { ...this.queryParams, limit, offset };
         const response = await this.getAxiosPageInstance().get('/', {
             params,
diff --git a/src/lib/models/user/user-public.ts b/src/lib/models/user/user-public.ts
index 07418fbc..321bfc25 100644
--- a/src/lib/models/user/user-public.ts
+++ b/src/lib/models/user/user-public.ts
@@ -24,10 +24,11 @@ class PublicUser {
         if (json.followers) this.followers = new Followers(json.followers);
         this.href = json.href;
         this.id = json.id;
-        if (json.images)
+        if (json.images) {
             this.images = json.images.map(
                 (imageJson: any) => new Image(imageJson)
             );
+        }
         this.type = json.type;
         this.uri = json.uri;
     }

From 1202a43b9b069e7f04dc089330008050409e492f Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 15:48:20 -0300
Subject: [PATCH 10/27] Implement personalization requests

---
 src/lib/personalization.ts | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 src/lib/personalization.ts

diff --git a/src/lib/personalization.ts b/src/lib/personalization.ts
new file mode 100644
index 00000000..8beca6e1
--- /dev/null
+++ b/src/lib/personalization.ts
@@ -0,0 +1,29 @@
+import { getAxiosSpotifyInstance } from './driver';
+
+import Page from './models/paging/page';
+import Artist from './models/artist/artist';
+import Track from './models/track/track';
+
+export const getCurrentUserTopArtists = async (params?: {
+    limit?: number;
+    offset?: number;
+    range?: string;
+}) => {
+    const response = await getAxiosSpotifyInstance().get(
+        'https://api.spotify.com/v1/me/top/artists',
+        { params }
+    );
+    return new Page<Artist>(response.data, Artist);
+};
+
+export const getCurrentUserTopTracks = async (params?: {
+    limit?: number;
+    offset?: number;
+    range?: string;
+}) => {
+    const response = await getAxiosSpotifyInstance().get(
+        'https://api.spotify.com/v1/me/top/tracks',
+        { params }
+    );
+    return new Page<Track>(response.data, Track);
+};

From c3557e0be36442e93358ac7ae09038f652d38560 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 15:48:44 -0300
Subject: [PATCH 11/27] Export personalization requests through index.ts

---
 src/lib/index.ts | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/lib/index.ts b/src/lib/index.ts
index 32a86a9c..a1436ff1 100644
--- a/src/lib/index.ts
+++ b/src/lib/index.ts
@@ -1,6 +1,7 @@
+export * from './albums';
+export * from './artists';
 export * from './driver';
-export * from './tracks';
 export * from './follow';
-export * from './artists';
-export * from './albums';
+export * from './tracks';
+export * from './personalization';
 export * from './playlists';

From 07eb45178f3cdcce82837986f4ca7258960a7a68 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 20:45:02 -0300
Subject: [PATCH 12/27] Implement tests for personalization requests

---
 test/mocks/top-artists.mock.ts |  90 ++++++++++++++++
 test/mocks/top-tracks.mock.ts  | 181 +++++++++++++++++++++++++++++++++
 test/personalization.test.ts   |  55 ++++++++++
 3 files changed, 326 insertions(+)
 create mode 100644 test/mocks/top-artists.mock.ts
 create mode 100644 test/mocks/top-tracks.mock.ts
 create mode 100644 test/personalization.test.ts

diff --git a/test/mocks/top-artists.mock.ts b/test/mocks/top-artists.mock.ts
new file mode 100644
index 00000000..e1d46fea
--- /dev/null
+++ b/test/mocks/top-artists.mock.ts
@@ -0,0 +1,90 @@
+export const topArtistsMock = {
+    items: [
+        {
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02',
+            },
+            followers: {
+                href: null,
+                total: 16168356,
+            },
+            genres: ['dance pop', 'pop', 'post-teen pop'],
+            href: 'https://api.spotify.com/v1/artists/06HL4z0CvFAxyc27GXpf02',
+            id: '06HL4z0CvFAxyc27GXpf02',
+            images: [
+                {
+                    height: 640,
+                    url:
+                        'https://i.scdn.co/image/bdaeccb035a8af87b7a70b62217ff5c633ba6c7c',
+                    width: 640,
+                },
+                {
+                    height: 320,
+                    url:
+                        'https://i.scdn.co/image/cec43c2fb746ea2a0c7546aa3408fe2f94887fe4',
+                    width: 320,
+                },
+                {
+                    height: 160,
+                    url:
+                        'https://i.scdn.co/image/33bc9128ad82f7d39847b6db6a49d5416502e7e7',
+                    width: 160,
+                },
+            ],
+            name: 'Taylor Swift',
+            popularity: 89,
+            type: 'artist',
+            uri: 'spotify:artist:06HL4z0CvFAxyc27GXpf02',
+        },
+        {
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/artist/6Xb4ezwoAQC4516kI89nWz',
+            },
+            followers: {
+                href: null,
+                total: 260793,
+            },
+            genres: ['etherpop', 'folk-pop', 'lilith', 'metropopolis'],
+            href: 'https://api.spotify.com/v1/artists/6Xb4ezwoAQC4516kI89nWz',
+            id: '6Xb4ezwoAQC4516kI89nWz',
+            images: [
+                {
+                    height: 1504,
+                    url:
+                        'https://i.scdn.co/image/d5bfa4c4fee8cf427bc15d33817764293eda8f1d',
+                    width: 1000,
+                },
+                {
+                    height: 963,
+                    url:
+                        'https://i.scdn.co/image/cc19f21be016979de6cc0b85dc873f22b1681979',
+                    width: 640,
+                },
+                {
+                    height: 301,
+                    url:
+                        'https://i.scdn.co/image/0b6016ef61b2d3c2dcb2b2277f4db99700cad1e8',
+                    width: 200,
+                },
+                {
+                    height: 96,
+                    url:
+                        'https://i.scdn.co/image/0b8b63873bbaec4e6c4094778b41528e632ddb9e',
+                    width: 64,
+                },
+            ],
+            name: 'Imogen Heap',
+            popularity: 61,
+            type: 'artist',
+            uri: 'spotify:artist:6Xb4ezwoAQC4516kI89nWz',
+        },
+    ],
+    total: 50,
+    limit: 2,
+    offset: 0,
+    href: 'https://api.spotify.com/v1/me/top/artists?limit=2&offset=0',
+    previous: null,
+    next: 'https://api.spotify.com/v1/me/top/artists?limit=2&offset=2',
+};
diff --git a/test/mocks/top-tracks.mock.ts b/test/mocks/top-tracks.mock.ts
new file mode 100644
index 00000000..9d1f8d24
--- /dev/null
+++ b/test/mocks/top-tracks.mock.ts
@@ -0,0 +1,181 @@
+export const topTracksMock = {
+    items: [
+        {
+            album: {
+                album_type: 'SINGLE',
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                        id: '1WgXqy2Dd70QQOU7Ay074N',
+                        name: 'AURORA',
+                        type: 'artist',
+                        uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+                    },
+                ],
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/album/1KqlKDBl2kuVhyXsX1vrVz',
+                },
+                href:
+                    'https://api.spotify.com/v1/albums/1KqlKDBl2kuVhyXsX1vrVz',
+                id: '1KqlKDBl2kuVhyXsX1vrVz',
+                images: [
+                    {
+                        height: 640,
+                        url:
+                            'https://i.scdn.co/image/6f4d26e065f85fd14fcafa59d43c3b5570e9f650',
+                        width: 640,
+                    },
+                    {
+                        height: 300,
+                        url:
+                            'https://i.scdn.co/image/8283ace6d5e5989f2b0127dc983f67d9531a25d5',
+                        width: 300,
+                    },
+                    {
+                        height: 64,
+                        url:
+                            'https://i.scdn.co/image/e5296c6ed295ac85746ad0ff90de18d9065fa142',
+                        width: 64,
+                    },
+                ],
+                name: 'Forgotten Love',
+                release_date: '2018-08-17',
+                release_date_precision: 'day',
+                type: 'album',
+                uri: 'spotify:album:1KqlKDBl2kuVhyXsX1vrVz',
+            },
+            artists: [
+                {
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                    id: '1WgXqy2Dd70QQOU7Ay074N',
+                    name: 'AURORA',
+                    type: 'artist',
+                    uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+                },
+            ],
+            disc_number: 1,
+            duration_ms: 208552,
+            explicit: false,
+            external_ids: {
+                isrc: 'GBUM71803967',
+            },
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/track/0nRNqasPnpHXsHbOighfaj',
+            },
+            href: 'https://api.spotify.com/v1/tracks/0nRNqasPnpHXsHbOighfaj',
+            id: '0nRNqasPnpHXsHbOighfaj',
+            is_local: false,
+            is_playable: true,
+            name: 'Forgotten Love',
+            popularity: 50,
+            preview_url: null,
+            track_number: 1,
+            type: 'track',
+            uri: 'spotify:track:0nRNqasPnpHXsHbOighfaj',
+        },
+        {
+            album: {
+                album_type: 'ALBUM',
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/6Xb4ezwoAQC4516kI89nWz',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/6Xb4ezwoAQC4516kI89nWz',
+                        id: '6Xb4ezwoAQC4516kI89nWz',
+                        name: 'Imogen Heap',
+                        type: 'artist',
+                        uri: 'spotify:artist:6Xb4ezwoAQC4516kI89nWz',
+                    },
+                ],
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/album/1H8velOQ9zUFqpuQPd2bkO',
+                },
+                href:
+                    'https://api.spotify.com/v1/albums/1H8velOQ9zUFqpuQPd2bkO',
+                id: '1H8velOQ9zUFqpuQPd2bkO',
+                images: [
+                    {
+                        height: 640,
+                        url:
+                            'https://i.scdn.co/image/e1287ba626f74622edfe7ed83f7c162cd6153c0b',
+                        width: 640,
+                    },
+                    {
+                        height: 300,
+                        url:
+                            'https://i.scdn.co/image/42e168927779f498faee2cc8550c67ae1974e7c1',
+                        width: 300,
+                    },
+                    {
+                        height: 64,
+                        url:
+                            'https://i.scdn.co/image/ea8067a3e9e586674942a434b3362b860e5e891e',
+                        width: 64,
+                    },
+                ],
+                name: 'Ellipse',
+                release_date: '2009-08-20',
+                release_date_precision: 'day',
+                type: 'album',
+                uri: 'spotify:album:1H8velOQ9zUFqpuQPd2bkO',
+            },
+            artists: [
+                {
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/artist/6Xb4ezwoAQC4516kI89nWz',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/artists/6Xb4ezwoAQC4516kI89nWz',
+                    id: '6Xb4ezwoAQC4516kI89nWz',
+                    name: 'Imogen Heap',
+                    type: 'artist',
+                    uri: 'spotify:artist:6Xb4ezwoAQC4516kI89nWz',
+                },
+            ],
+            disc_number: 1,
+            duration_ms: 253480,
+            explicit: false,
+            external_ids: {
+                isrc: 'GBJPX0900064',
+            },
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/track/6Qy5mfrRPveNNXjEDOG2iV',
+            },
+            href: 'https://api.spotify.com/v1/tracks/6Qy5mfrRPveNNXjEDOG2iV',
+            id: '6Qy5mfrRPveNNXjEDOG2iV',
+            is_local: false,
+            is_playable: true,
+            name: 'First Train Home',
+            popularity: 39,
+            preview_url:
+                'https://p.scdn.co/mp3-preview/62be3c5622a0845468524c6c2aaa061768dc2393?cid=null',
+            track_number: 1,
+            type: 'track',
+            uri: 'spotify:track:6Qy5mfrRPveNNXjEDOG2iV',
+        },
+    ],
+    total: 50,
+    limit: 2,
+    offset: 0,
+    href: 'https://api.spotify.com/v1/me/top/tracks?limit=2&offset=0',
+    previous: null,
+    next: 'https://api.spotify.com/v1/me/top/tracks?limit=2&offset=2',
+};
diff --git a/test/personalization.test.ts b/test/personalization.test.ts
new file mode 100644
index 00000000..2d9a37b1
--- /dev/null
+++ b/test/personalization.test.ts
@@ -0,0 +1,55 @@
+import nock from 'nock';
+
+import { topArtistsMock } from './mocks/top-artists.mock';
+import { topTracksMock } from './mocks/top-tracks.mock';
+import { checkMatchingPagingObjectAttributes } from './common/matching-attributes.test';
+
+import {
+    init,
+    getCurrentUserTopArtists,
+    getCurrentUserTopTracks,
+} from '../src/lib';
+
+describe('Personalization requests', () => {
+    beforeEach(() => {
+        init('SomeToken');
+    });
+
+    describe('#getCurrentUserTopArtists()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/me/top/artists')
+                .query({ limit: 2 })
+                .reply(200, topArtistsMock);
+        });
+
+        it('response should match all paging object attributes', async () => {
+            const topArtistsResponse = await getCurrentUserTopArtists({
+                limit: 2,
+            });
+            checkMatchingPagingObjectAttributes(
+                topArtistsResponse,
+                topArtistsMock
+            );
+        });
+    });
+
+    describe('#getCurrentUserTopTracks()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/me/top/tracks')
+                .query({ limit: 2 })
+                .reply(200, topTracksMock);
+        });
+
+        it('response should match all paging object attributes', async () => {
+            const topTracksResponse = await getCurrentUserTopTracks({
+                limit: 2,
+            });
+            checkMatchingPagingObjectAttributes(
+                topTracksResponse,
+                topTracksMock
+            );
+        });
+    });
+});

From 542d902d0b8ecb785f879f0fe53d2c952f31c6a6 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 21:08:08 -0300
Subject: [PATCH 13/27] Correct play history model name

---
 src/lib/models/player/play-history.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lib/models/player/play-history.ts b/src/lib/models/player/play-history.ts
index ffca1416..fb5eb25e 100644
--- a/src/lib/models/player/play-history.ts
+++ b/src/lib/models/player/play-history.ts
@@ -1,7 +1,7 @@
 import Context from './context';
 import Track from '../track/track';
 
-class PlaylistTrack {
+class PlayHistory {
     track: Track;
 
     playedAt: string; // Timestamp
@@ -15,4 +15,4 @@ class PlaylistTrack {
     }
 }
 
-export default PlaylistTrack;
+export default PlayHistory;

From cdca63b4ccc756cd9a8d1e539279510ed8895954 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 21:45:04 -0300
Subject: [PATCH 14/27] Implement cursor-based paging object model

---
 src/lib/models/paging/cursor-based-page.ts | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 src/lib/models/paging/cursor-based-page.ts

diff --git a/src/lib/models/paging/cursor-based-page.ts b/src/lib/models/paging/cursor-based-page.ts
new file mode 100644
index 00000000..accbf263
--- /dev/null
+++ b/src/lib/models/paging/cursor-based-page.ts
@@ -0,0 +1,52 @@
+import { getAxiosSpotifyInstance } from '../../driver';
+
+class CursorBasedPage<T> {
+    private t: new (json: any) => T;
+    href: string;
+    items: T[];
+    limit: number;
+    next: string;
+    cursors: any;
+    total: number;
+
+    constructor(json: any, t: new (json: any) => T) {
+        this.t = t;
+        this.href = json.href;
+        this.items = json.items.map((json: any) => new t(json));
+        this.limit = json.limit;
+        this.next = json.next ? json.next.split('?')[1] : null;
+        this.cursors = json.cursors;
+        this.total = json.total;
+    }
+
+    get queryParams(): any {
+        const queryString = this.href.split('?')[1];
+        const paramsString = queryString.split('&');
+        const queryParams: any = {};
+
+        for (const param of paramsString) {
+            const [name, value] = param.split('=');
+            queryParams[name] = value;
+        }
+
+        return queryParams;
+    }
+
+    private getAxiosPageInstance() {
+        const instance = getAxiosSpotifyInstance();
+        instance.defaults.baseURL = this.href.split('?')[0];
+        return instance;
+    }
+
+    hasNext() {
+        return Boolean(this.next);
+    }
+
+    async getNextPage() {
+        if (!this.hasNext()) throw new Error('There are no more pages');
+        const response = await this.getAxiosPageInstance().get(`?${this.next}`);
+        return new CursorBasedPage<T>(response.data, this.t);
+    }
+}
+
+export default CursorBasedPage;

From 4166787b53dbf51ab6328e3bf8c39cf6766ae1ca Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Sun, 18 Nov 2018 21:45:38 -0300
Subject: [PATCH 15/27] Implement function to request recently played tracks

---
 src/lib/index.ts  |  1 +
 src/lib/player.ts | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 src/lib/player.ts

diff --git a/src/lib/index.ts b/src/lib/index.ts
index 32a86a9c..ce5ed783 100644
--- a/src/lib/index.ts
+++ b/src/lib/index.ts
@@ -4,3 +4,4 @@ export * from './follow';
 export * from './artists';
 export * from './albums';
 export * from './playlists';
+export * from './player';
diff --git a/src/lib/player.ts b/src/lib/player.ts
new file mode 100644
index 00000000..7fb306e8
--- /dev/null
+++ b/src/lib/player.ts
@@ -0,0 +1,18 @@
+import { getAxiosSpotifyInstance } from './driver';
+
+import PlayHistory from './models/player/play-history';
+import CursorBasedPage from './models/paging/cursor-based-page';
+
+export const getCurrentUserRecentlyPlayedTracks = async (params?: {
+    limit?: number;
+    before?: string;
+    after?: string;
+}) => {
+    if (params && params.before && params.after)
+        throw new Error("Only one of 'before' or 'after' should be specified");
+    const response = await getAxiosSpotifyInstance().get(
+        `/me/player/recently-played`,
+        { params }
+    );
+    return new CursorBasedPage<PlayHistory>(response.data, PlayHistory);
+};

From d24a9e95762b5b4bc9bd8fedfea29a3d8e555eaa Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Mon, 19 Nov 2018 21:57:21 -0300
Subject: [PATCH 16/27] Create currently playing object model

---
 src/lib/models/player/currently-playing.ts | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 src/lib/models/player/currently-playing.ts

diff --git a/src/lib/models/player/currently-playing.ts b/src/lib/models/player/currently-playing.ts
new file mode 100644
index 00000000..69b34285
--- /dev/null
+++ b/src/lib/models/player/currently-playing.ts
@@ -0,0 +1,22 @@
+import Context from './context';
+import Track from '../track/track';
+
+class CurrentlyPlaying {
+    context: Context | null;
+    currentlyPlayingType: string;
+    isPlaying: boolean;
+    item: Track | null;
+    progressMs: number;
+    timestamp: number;
+
+    constructor(json: any) {
+        this.context = json.context ? new Context(json.context) : null;
+        this.currentlyPlayingType = json.currently_playing_type;
+        this.isPlaying = json.is_playing;
+        this.item = json.item ? new Track(json.item) : null;
+        this.progressMs = json.progress_ms;
+        this.timestamp = json.timestamp;
+    }
+}
+
+export default CurrentlyPlaying;

From d267b9fb1d4ac93bf1ce35b69781a20222d85b4c Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Mon, 19 Nov 2018 21:57:32 -0300
Subject: [PATCH 17/27] Implement request for current user's currently playing
 object

---
 src/lib/player.ts | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/lib/player.ts b/src/lib/player.ts
index 7fb306e8..8780eeca 100644
--- a/src/lib/player.ts
+++ b/src/lib/player.ts
@@ -2,6 +2,7 @@ import { getAxiosSpotifyInstance } from './driver';
 
 import PlayHistory from './models/player/play-history';
 import CursorBasedPage from './models/paging/cursor-based-page';
+import CurrentlyPlaying from './models/player/currently-playing';
 
 export const getCurrentUserRecentlyPlayedTracks = async (params?: {
     limit?: number;
@@ -11,8 +12,18 @@ export const getCurrentUserRecentlyPlayedTracks = async (params?: {
     if (params && params.before && params.after)
         throw new Error("Only one of 'before' or 'after' should be specified");
     const response = await getAxiosSpotifyInstance().get(
-        `/me/player/recently-played`,
+        '/me/player/recently-played',
         { params }
     );
     return new CursorBasedPage<PlayHistory>(response.data, PlayHistory);
 };
+
+export const getCurrentUserCurrentlyPlayingTrack = async (params?: {
+    market?: string;
+}) => {
+    const response = await getAxiosSpotifyInstance().get(
+        '/me/player/currently-playing',
+        { params }
+    );
+    return new CurrentlyPlaying(response.data);
+};

From e3ad6a8915da6315169db6d4f1a513efa4bc8448 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Mon, 19 Nov 2018 23:06:58 -0300
Subject: [PATCH 18/27] Implement tests for recently played tracks and
 currently playing track

---
 test/common/matching-attributes.test.ts   |  44 ++-
 test/mocks/currently-playing.mock.ts      |  99 +++++
 test/mocks/recently-played-tracks.mock.ts | 453 ++++++++++++++++++++++
 test/player.test.ts                       |  58 +++
 4 files changed, 653 insertions(+), 1 deletion(-)
 create mode 100644 test/mocks/currently-playing.mock.ts
 create mode 100644 test/mocks/recently-played-tracks.mock.ts
 create mode 100644 test/player.test.ts

diff --git a/test/common/matching-attributes.test.ts b/test/common/matching-attributes.test.ts
index 3242f2fe..79e61a19 100644
--- a/test/common/matching-attributes.test.ts
+++ b/test/common/matching-attributes.test.ts
@@ -4,6 +4,11 @@ import Album from '../../src/lib/models/album/album';
 import AlbumSimplified from '../../src/lib/models/album/album-simplified';
 import Artist from '../../src/lib/models/artist/artist';
 import Track from '../../src/lib/models/track/track';
+import Page from '../../src/lib/models/paging/page';
+import CurrentlyPlaying from '../../src/lib/models/player/currently-playing';
+import Context from '../../src/lib/models/player/context';
+import CursorBasedPage from '../../src/lib/models/paging/cursor-based-page';
+
 import { AlbumMock } from '../mocks/album.mock';
 import { ArtistMock } from '../mocks/artist.mock';
 import { TrackMock } from './../mocks/artist-top-tracks.mock';
@@ -94,7 +99,7 @@ export const checkMatchingTrackAttributes = (
 };
 
 export const checkMatchingPagingObjectAttributes = (
-    response: any,
+    response: Page<any>,
     mock: any
 ) => {
     expect(response.href).to.be.equal(mock.href.split('?')[0]);
@@ -103,3 +108,40 @@ export const checkMatchingPagingObjectAttributes = (
     expect(response.offset).to.be.equal(mock.offset);
     expect(response.total).to.be.equal(mock.total);
 };
+
+export const checkMatchingCurrentlyPlayingAttributes = (
+    response: CurrentlyPlaying,
+    mock: any
+) => {
+    if (response.context)
+        checkMatchingContextAttributes(response.context, mock.context);
+    expect(response.currentlyPlayingType).to.be.equal(
+        mock.currently_playing_type
+    );
+    expect(response.isPlaying).to.be.equal(mock.is_playing);
+    if (response.item) checkMatchingTrackAttributes(response.item, mock.item);
+    expect(response.progressMs).to.be.equal(mock.progress_ms);
+    expect(response.timestamp).to.be.equal(mock.timestamp);
+};
+
+export const checkMatchingContextAttributes = (
+    response: Context,
+    mock: any
+) => {
+    expect(response.externalUrls).to.be.eql(mock.external_urls);
+    expect(response.href).to.be.equal(mock.href);
+    expect(response.type).to.be.equal(mock.type);
+    expect(response.uri).to.be.equal(mock.uri);
+};
+
+export const checkMatchingCursorBasedPageAttributes = (
+    response: CursorBasedPage<any>,
+    mock: any
+) => {
+    expect(response.cursors).to.be.eql(mock.cursors);
+    expect(response.href).to.be.equal(mock.href);
+    expect(response.items).to.have.lengthOf(mock.items.length);
+    expect(response.limit).to.be.equal(mock.limit);
+    expect(response.next).to.be.equal(mock.next.split('?')[1]);
+    expect(response.total).to.be.equal(mock.total);
+};
diff --git a/test/mocks/currently-playing.mock.ts b/test/mocks/currently-playing.mock.ts
new file mode 100644
index 00000000..eb6c4400
--- /dev/null
+++ b/test/mocks/currently-playing.mock.ts
@@ -0,0 +1,99 @@
+export const currentlyPlayingMock = {
+    timestamp: 1542673521238,
+    context: {
+        external_urls: {
+            spotify: 'https://open.spotify.com/playlist/5D0F6KQtqd5HuAVX2sOouy',
+        },
+        href: 'https://api.spotify.com/v1/playlists/5D0F6KQtqd5HuAVX2sOouy',
+        type: 'playlist',
+        uri: 'spotify:user:jrobsonjr:playlist:5D0F6KQtqd5HuAVX2sOouy',
+    },
+    progress_ms: 17908,
+    item: {
+        album: {
+            album_type: 'album',
+            artists: [
+                {
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                    id: '1WgXqy2Dd70QQOU7Ay074N',
+                    name: 'AURORA',
+                    type: 'artist',
+                    uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+                },
+            ],
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/album/2iv4eCuGKJYsso1mDR48dt',
+            },
+            href: 'https://api.spotify.com/v1/albums/2iv4eCuGKJYsso1mDR48dt',
+            id: '2iv4eCuGKJYsso1mDR48dt',
+            images: [
+                {
+                    height: 640,
+                    url:
+                        'https://i.scdn.co/image/53a31a48a6db327175be725301ba758bb3bed354',
+                    width: 640,
+                },
+                {
+                    height: 300,
+                    url:
+                        'https://i.scdn.co/image/0c4210e5b5a44ed2dc6bb42260a4b97c0b0b46a9',
+                    width: 300,
+                },
+                {
+                    height: 64,
+                    url:
+                        'https://i.scdn.co/image/0e874917c51fe5ab7413f364b1ef1054920b9372',
+                    width: 64,
+                },
+            ],
+            name: 'Infections Of A Different Kind (Step I)',
+            release_date: '2018-09-28',
+            release_date_precision: 'day',
+            total_tracks: 8,
+            type: 'album',
+            uri: 'spotify:album:2iv4eCuGKJYsso1mDR48dt',
+        },
+        artists: [
+            {
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                },
+                href:
+                    'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                id: '1WgXqy2Dd70QQOU7Ay074N',
+                name: 'AURORA',
+                type: 'artist',
+                uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+            },
+        ],
+        disc_number: 1,
+        duration_ms: 227320,
+        explicit: false,
+        external_ids: {
+            isrc: 'GBUM71804527',
+        },
+        external_urls: {
+            spotify: 'https://open.spotify.com/track/0m8D2ocNLLDMh0N9UOECMs',
+        },
+        href: 'https://api.spotify.com/v1/tracks/0m8D2ocNLLDMh0N9UOECMs',
+        id: '0m8D2ocNLLDMh0N9UOECMs',
+        is_local: false,
+        is_playable: true,
+        name: 'Gentle Earthquakes',
+        popularity: 49,
+        preview_url:
+            'https://p.scdn.co/mp3-preview/66abfd919a67b646529a171cc35f23b4d3dc64e9?cid=774b29d4f13844c495f206cafdad9c86',
+        track_number: 3,
+        type: 'track',
+        uri: 'spotify:track:0m8D2ocNLLDMh0N9UOECMs',
+    },
+    currently_playing_type: 'track',
+    is_playing: true,
+};
diff --git a/test/mocks/recently-played-tracks.mock.ts b/test/mocks/recently-played-tracks.mock.ts
new file mode 100644
index 00000000..541f88dd
--- /dev/null
+++ b/test/mocks/recently-played-tracks.mock.ts
@@ -0,0 +1,453 @@
+export const recentlyPlayedTracksMock = {
+    items: [
+        {
+            track: {
+                album: {
+                    album_type: 'album',
+                    artists: [
+                        {
+                            external_urls: {
+                                spotify:
+                                    'https://open.spotify.com/artist/6Xb4ezwoAQC4516kI89nWz',
+                            },
+                            href:
+                                'https://api.spotify.com/v1/artists/6Xb4ezwoAQC4516kI89nWz',
+                            id: '6Xb4ezwoAQC4516kI89nWz',
+                            name: 'Imogen Heap',
+                            type: 'artist',
+                            uri: 'spotify:artist:6Xb4ezwoAQC4516kI89nWz',
+                        },
+                    ],
+                    available_markets: [
+                        'AD',
+                        'AR',
+                        'AT',
+                        'AU',
+                        'BE',
+                        'BG',
+                        'BO',
+                        'BR',
+                        'CA',
+                        'CH',
+                        'CL',
+                        'CO',
+                        'CR',
+                        'CY',
+                        'CZ',
+                        'DE',
+                        'DK',
+                        'DO',
+                        'EC',
+                        'EE',
+                        'ES',
+                        'FI',
+                        'FR',
+                        'GB',
+                        'GR',
+                        'GT',
+                        'HK',
+                        'HN',
+                        'HU',
+                        'ID',
+                        'IE',
+                        'IS',
+                        'IT',
+                        'JP',
+                        'LI',
+                        'LT',
+                        'LU',
+                        'LV',
+                        'MC',
+                        'MT',
+                        'MX',
+                        'MY',
+                        'NI',
+                        'NL',
+                        'NO',
+                        'NZ',
+                        'PA',
+                        'PE',
+                        'PH',
+                        'PL',
+                        'PT',
+                        'PY',
+                        'SE',
+                        'SG',
+                        'SK',
+                        'SV',
+                        'TR',
+                        'TW',
+                        'US',
+                        'UY',
+                    ],
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/album/0S4rmBsXso00O0Lp3mJOr9',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/albums/0S4rmBsXso00O0Lp3mJOr9',
+                    id: '0S4rmBsXso00O0Lp3mJOr9',
+                    images: [
+                        {
+                            height: 640,
+                            url:
+                                'https://i.scdn.co/image/6a957a85953eb2f2f77b1cd83cba7d0acbde1155',
+                            width: 640,
+                        },
+                        {
+                            height: 300,
+                            url:
+                                'https://i.scdn.co/image/df2b0f824b9b93365e21ef4c9d7fa9354d2eff3f',
+                            width: 300,
+                        },
+                        {
+                            height: 64,
+                            url:
+                                'https://i.scdn.co/image/d19523118f3b0695a6c9ade8bd4a8bcb7fe6eb83',
+                            width: 64,
+                        },
+                    ],
+                    name: 'Sparks',
+                    type: 'album',
+                    uri: 'spotify:album:0S4rmBsXso00O0Lp3mJOr9',
+                },
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/6Xb4ezwoAQC4516kI89nWz',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/6Xb4ezwoAQC4516kI89nWz',
+                        id: '6Xb4ezwoAQC4516kI89nWz',
+                        name: 'Imogen Heap',
+                        type: 'artist',
+                        uri: 'spotify:artist:6Xb4ezwoAQC4516kI89nWz',
+                    },
+                ],
+                available_markets: [
+                    'AD',
+                    'AR',
+                    'AT',
+                    'AU',
+                    'BE',
+                    'BG',
+                    'BO',
+                    'BR',
+                    'CA',
+                    'CH',
+                    'CL',
+                    'CO',
+                    'CR',
+                    'CY',
+                    'CZ',
+                    'DE',
+                    'DK',
+                    'DO',
+                    'EC',
+                    'EE',
+                    'ES',
+                    'FI',
+                    'FR',
+                    'GB',
+                    'GR',
+                    'GT',
+                    'HK',
+                    'HN',
+                    'HU',
+                    'ID',
+                    'IE',
+                    'IS',
+                    'IT',
+                    'JP',
+                    'LI',
+                    'LT',
+                    'LU',
+                    'LV',
+                    'MC',
+                    'MT',
+                    'MX',
+                    'MY',
+                    'NI',
+                    'NL',
+                    'NO',
+                    'NZ',
+                    'PA',
+                    'PE',
+                    'PH',
+                    'PL',
+                    'PT',
+                    'PY',
+                    'SE',
+                    'SG',
+                    'SK',
+                    'SV',
+                    'TR',
+                    'TW',
+                    'US',
+                    'UY',
+                ],
+                disc_number: 1,
+                duration_ms: 324046,
+                explicit: false,
+                external_ids: {
+                    isrc: 'GBJPX1300134',
+                },
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/track/3t11m4SVPlTlwF9Ojz99uy',
+                },
+                href:
+                    'https://api.spotify.com/v1/tracks/3t11m4SVPlTlwF9Ojz99uy',
+                id: '3t11m4SVPlTlwF9Ojz99uy',
+                name: 'The Listening Chair',
+                popularity: 12,
+                preview_url:
+                    'https://p.scdn.co/mp3-preview/a4696097530075efc816f709890b22158a272f15?cid=774b29d4f13844c495f206cafdad9c86',
+                track_number: 3,
+                type: 'track',
+                uri: 'spotify:track:3t11m4SVPlTlwF9Ojz99uy',
+            },
+            played_at: '2018-11-19T20:44:30.408Z',
+            context: {
+                uri: 'spotify:playlist:1JJAC9FwjfaGfcWRWbFNTY',
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/playlist/1JJAC9FwjfaGfcWRWbFNTY',
+                },
+                href:
+                    'https://api.spotify.com/v1/playlists/1JJAC9FwjfaGfcWRWbFNTY',
+                type: 'playlist_v2',
+            },
+        },
+        {
+            track: {
+                album: {
+                    album_type: 'album',
+                    artists: [
+                        {
+                            external_urls: {
+                                spotify:
+                                    'https://open.spotify.com/artist/6Xb4ezwoAQC4516kI89nWz',
+                            },
+                            href:
+                                'https://api.spotify.com/v1/artists/6Xb4ezwoAQC4516kI89nWz',
+                            id: '6Xb4ezwoAQC4516kI89nWz',
+                            name: 'Imogen Heap',
+                            type: 'artist',
+                            uri: 'spotify:artist:6Xb4ezwoAQC4516kI89nWz',
+                        },
+                    ],
+                    available_markets: [
+                        'AD',
+                        'AR',
+                        'AT',
+                        'AU',
+                        'BE',
+                        'BG',
+                        'BO',
+                        'BR',
+                        'CA',
+                        'CH',
+                        'CL',
+                        'CO',
+                        'CR',
+                        'CY',
+                        'CZ',
+                        'DE',
+                        'DK',
+                        'DO',
+                        'EC',
+                        'EE',
+                        'ES',
+                        'FI',
+                        'FR',
+                        'GB',
+                        'GR',
+                        'GT',
+                        'HK',
+                        'HN',
+                        'HU',
+                        'ID',
+                        'IE',
+                        'IS',
+                        'IT',
+                        'JP',
+                        'LI',
+                        'LT',
+                        'LU',
+                        'LV',
+                        'MC',
+                        'MT',
+                        'MX',
+                        'MY',
+                        'NI',
+                        'NL',
+                        'NO',
+                        'NZ',
+                        'PA',
+                        'PE',
+                        'PH',
+                        'PL',
+                        'PT',
+                        'PY',
+                        'SE',
+                        'SG',
+                        'SK',
+                        'SV',
+                        'TR',
+                        'TW',
+                        'US',
+                        'UY',
+                    ],
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/album/1H8velOQ9zUFqpuQPd2bkO',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/albums/1H8velOQ9zUFqpuQPd2bkO',
+                    id: '1H8velOQ9zUFqpuQPd2bkO',
+                    images: [
+                        {
+                            height: 640,
+                            url:
+                                'https://i.scdn.co/image/e1287ba626f74622edfe7ed83f7c162cd6153c0b',
+                            width: 640,
+                        },
+                        {
+                            height: 300,
+                            url:
+                                'https://i.scdn.co/image/42e168927779f498faee2cc8550c67ae1974e7c1',
+                            width: 300,
+                        },
+                        {
+                            height: 64,
+                            url:
+                                'https://i.scdn.co/image/ea8067a3e9e586674942a434b3362b860e5e891e',
+                            width: 64,
+                        },
+                    ],
+                    name: 'Ellipse',
+                    type: 'album',
+                    uri: 'spotify:album:1H8velOQ9zUFqpuQPd2bkO',
+                },
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/6Xb4ezwoAQC4516kI89nWz',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/6Xb4ezwoAQC4516kI89nWz',
+                        id: '6Xb4ezwoAQC4516kI89nWz',
+                        name: 'Imogen Heap',
+                        type: 'artist',
+                        uri: 'spotify:artist:6Xb4ezwoAQC4516kI89nWz',
+                    },
+                ],
+                available_markets: [
+                    'AD',
+                    'AR',
+                    'AT',
+                    'AU',
+                    'BE',
+                    'BG',
+                    'BO',
+                    'BR',
+                    'CA',
+                    'CH',
+                    'CL',
+                    'CO',
+                    'CR',
+                    'CY',
+                    'CZ',
+                    'DE',
+                    'DK',
+                    'DO',
+                    'EC',
+                    'EE',
+                    'ES',
+                    'FI',
+                    'FR',
+                    'GB',
+                    'GR',
+                    'GT',
+                    'HK',
+                    'HN',
+                    'HU',
+                    'ID',
+                    'IE',
+                    'IS',
+                    'IT',
+                    'JP',
+                    'LI',
+                    'LT',
+                    'LU',
+                    'LV',
+                    'MC',
+                    'MT',
+                    'MX',
+                    'MY',
+                    'NI',
+                    'NL',
+                    'NO',
+                    'NZ',
+                    'PA',
+                    'PE',
+                    'PH',
+                    'PL',
+                    'PT',
+                    'PY',
+                    'SE',
+                    'SG',
+                    'SK',
+                    'SV',
+                    'TR',
+                    'TW',
+                    'US',
+                    'UY',
+                ],
+                disc_number: 1,
+                duration_ms: 237453,
+                explicit: false,
+                external_ids: {
+                    isrc: 'GBJPX0900065',
+                },
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/track/3RP28uWsdXhqxJ3rguyRJb',
+                },
+                href:
+                    'https://api.spotify.com/v1/tracks/3RP28uWsdXhqxJ3rguyRJb',
+                id: '3RP28uWsdXhqxJ3rguyRJb',
+                name: 'Wait It Out',
+                popularity: 40,
+                preview_url:
+                    'https://p.scdn.co/mp3-preview/d71fd4cf00e031daccaceceb82ad23e27e1d006b?cid=774b29d4f13844c495f206cafdad9c86',
+                track_number: 2,
+                type: 'track',
+                uri: 'spotify:track:3RP28uWsdXhqxJ3rguyRJb',
+            },
+            played_at: '2018-11-19T20:39:05.819Z',
+            context: {
+                uri: 'spotify:playlist:1JJAC9FwjfaGfcWRWbFNTY',
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/playlist/1JJAC9FwjfaGfcWRWbFNTY',
+                },
+                href:
+                    'https://api.spotify.com/v1/playlists/1JJAC9FwjfaGfcWRWbFNTY',
+                type: 'playlist_v2',
+            },
+        },
+    ],
+    next:
+        'https://api.spotify.com/v1/me/player/recently-played?before=1542659945819&limit=2',
+    cursors: {
+        after: '1542660270408',
+        before: '1542659945819',
+    },
+    limit: 2,
+    href:
+        'https://api.spotify.com/v1/me/player/recently-played?before=1542660552899&limit=2',
+};
diff --git a/test/player.test.ts b/test/player.test.ts
new file mode 100644
index 00000000..0bb636e5
--- /dev/null
+++ b/test/player.test.ts
@@ -0,0 +1,58 @@
+import nock from 'nock';
+
+import { currentlyPlayingMock } from './mocks/currently-playing.mock';
+import { recentlyPlayedTracksMock } from './mocks/recently-played-tracks.mock';
+import {
+    checkMatchingCurrentlyPlayingAttributes,
+    checkMatchingCursorBasedPageAttributes,
+} from './common/matching-attributes.test';
+
+import {
+    init,
+    getCurrentUserRecentlyPlayedTracks,
+    getCurrentUserCurrentlyPlayingTrack,
+} from '../src/lib';
+
+describe('Player requests', () => {
+    beforeEach(() => {
+        init('SomeToken');
+    });
+
+    describe('#getCurrentUserRecentlyPlayedTracks()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/me/player/recently-played')
+                .query({ limit: 2 })
+                .reply(200, recentlyPlayedTracksMock);
+        });
+
+        it('response should match all cursor-based paging attributes', async () => {
+            const recentlyPlayedTracksResponse = await getCurrentUserRecentlyPlayedTracks(
+                { limit: 2 }
+            );
+            checkMatchingCursorBasedPageAttributes(
+                recentlyPlayedTracksResponse,
+                recentlyPlayedTracksMock
+            );
+        });
+    });
+
+    describe('#getCurrentUserCurrentlyPlayingTrack()', () => {
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get('/me/player/currently-playing')
+                .query({ market: 'BR' })
+                .reply(200, currentlyPlayingMock);
+        });
+
+        it('response should match all currently playing object attributes', async () => {
+            const currentlyPlayingResponse = await getCurrentUserCurrentlyPlayingTrack(
+                { market: 'BR' }
+            );
+            checkMatchingCurrentlyPlayingAttributes(
+                currentlyPlayingResponse,
+                currentlyPlayingMock
+            );
+        });
+    });
+});

From 3c28e2500c4734b35bdd6b39b3e087f57cee59bc Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Mon, 19 Nov 2018 23:20:20 -0300
Subject: [PATCH 19/27] Fix lint error

---
 src/lib/player.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/lib/player.ts b/src/lib/player.ts
index 8780eeca..b4474a34 100644
--- a/src/lib/player.ts
+++ b/src/lib/player.ts
@@ -9,8 +9,9 @@ export const getCurrentUserRecentlyPlayedTracks = async (params?: {
     before?: string;
     after?: string;
 }) => {
-    if (params && params.before && params.after)
+    if (params && params.before && params.after) {
         throw new Error("Only one of 'before' or 'after' should be specified");
+    }
     const response = await getAxiosSpotifyInstance().get(
         '/me/player/recently-played',
         { params }

From 03fc042696f3ccf702db1c9bbc188a90a12310eb Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 00:45:04 -0300
Subject: [PATCH 20/27] Create models for audio analysis and its attributes

---
 src/lib/models/track/audio-analysis.ts | 145 +++++++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 src/lib/models/track/audio-analysis.ts

diff --git a/src/lib/models/track/audio-analysis.ts b/src/lib/models/track/audio-analysis.ts
new file mode 100644
index 00000000..f0193286
--- /dev/null
+++ b/src/lib/models/track/audio-analysis.ts
@@ -0,0 +1,145 @@
+class AudioAnalysis {
+    bars: TimeInterval[];
+    beats: TimeInterval[];
+    sections: Section[];
+    segments: Segment[];
+    tatums: TimeInterval[];
+    track: TrackAnalysisData;
+
+    constructor(json: any) {
+        this.bars = json.bars.map((bar: any) => new TimeInterval(bar));
+        this.beats = json.beats.map((beat: any) => new TimeInterval(beat));
+        this.sections = json.sections.map(
+            (section: any) => new Section(section)
+        );
+        this.segments = json.segments.map(
+            (segment: any) => new Segment(segment)
+        );
+        this.tatums = json.tatums.map((tatum: any) => new TimeInterval(tatum));
+        this.track = new TrackAnalysisData(json.track);
+    }
+}
+
+class TimeInterval {
+    start: number;
+    duration: number;
+    confidence: number;
+
+    constructor(json: any) {
+        this.start = json.start;
+        this.duration = json.duration;
+        this.confidence = json.confidence;
+    }
+}
+
+class Section {
+    start: number;
+    duration: number;
+    confidence: number;
+    loudness: number;
+    tempo: number;
+    tempoConfidence: number;
+    key: number;
+    keyConfidence: number;
+    mode: number;
+    modeConfidence: number;
+    timeSignature: number;
+    timeSignatureConfidence: number;
+
+    constructor(json: any) {
+        this.start = json.start;
+        this.duration = json.duration;
+        this.confidence = json.confidence;
+        this.loudness = json.loudness;
+        this.tempo = json.tempo;
+        this.tempoConfidence = json.tempo_confidence;
+        this.key = json.key;
+        this.keyConfidence = json.key_confidence;
+        this.mode = json.mode;
+        this.modeConfidence = json.mode_confidence;
+        this.timeSignature = json.time_signature;
+        this.timeSignatureConfidence = json.time_signature_confidence;
+    }
+}
+
+class Segment {
+    start: number;
+    duration: number;
+    confidence: number;
+    loudnessStart: number;
+    loudnessMaxTime: number;
+    loudnessMax: number;
+    loudnessEnd: number;
+    pitches: number[];
+    timbre: number[];
+
+    constructor(json: any) {
+        this.start = json.start;
+        this.duration = json.duration;
+        this.confidence = json.confidence;
+        this.loudnessStart = json.loudness_start;
+        this.loudnessMaxTime = json.loudness_max_time;
+        this.loudnessMax = json.loudness_max;
+        this.loudnessEnd = json.loudness_end;
+        this.pitches = json.pitches;
+        this.timbre = json.timbre;
+    }
+}
+
+class TrackAnalysisData {
+    duration: number;
+    sampleMd5: string;
+    offsetSeconds: number;
+    windowSeconds: number;
+    analysisSampleRate: number;
+    analysisChannels: number;
+    endOfFadeIn: number;
+    startOfFadeOut: number;
+    loudness: number;
+    tempo: number;
+    tempoConfidence: number;
+    timeSignature: number;
+    timeSignatureConfidence: number;
+    key: number;
+    keyConfidence: number;
+    mode: number;
+    modeConfidence: number;
+    codeString: string;
+    codeVersion: number;
+    echoprintString: string;
+    echoprintVersion: number;
+    synchString: string;
+    synchVersion: number;
+    rhythmString: string;
+    rhythmVersion: number;
+
+    constructor(json: any) {
+        this.duration = json.duration;
+        this.sampleMd5 = json.sample_md5;
+        this.offsetSeconds = json.offset_seconds;
+        this.windowSeconds = json.window_seconds;
+        this.analysisSampleRate = json.analysis_sample_rate;
+        this.analysisChannels = json.analysis_channels;
+        this.endOfFadeIn = json.end_of_fade_in;
+        this.startOfFadeOut = json.start_of_fade_out;
+        this.loudness = json.loudness;
+        this.tempo = json.tempo;
+        this.tempoConfidence = json.tempo_confidence;
+        this.timeSignature = json.time_signature;
+        this.timeSignatureConfidence = json.time_signature_confidence;
+        this.key = json.key;
+        this.keyConfidence = json.key_confidence;
+        this.mode = json.mode;
+        this.modeConfidence = json.mode_confidence;
+        this.codeString = json.codestring;
+        this.codeVersion = json.code_version;
+        this.echoprintString = json.echoprintstring;
+        this.echoprintVersion = json.echoprint_version;
+        this.synchString = json.synchstring;
+        this.synchVersion = json.synch_version;
+        this.rhythmString = json.rhythmstring;
+        this.rhythmVersion = json.rhythm_version;
+    }
+}
+
+export default AudioAnalysis;

From 4f55ed67ee0eb1516e8fedd117a2ce17cd7f27f0 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 00:45:37 -0300
Subject: [PATCH 21/27] Implement missing track-related requests

---
 src/lib/tracks.ts | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/src/lib/tracks.ts b/src/lib/tracks.ts
index 157fb759..e1c24d07 100644
--- a/src/lib/tracks.ts
+++ b/src/lib/tracks.ts
@@ -1,5 +1,8 @@
 import { getAxiosSpotifyInstance } from './driver';
+
 import Track from './models/track/track';
+import AudioAnalysis from './models/track/audio-analysis';
+import AudioFeatures from './models/track/audio-features';
 
 export const getSeveralTracks = async (ids: string[]) => {
     if (ids.length > 50) {
@@ -9,8 +12,8 @@ export const getSeveralTracks = async (ids: string[]) => {
             `The maximum number of tracks is 50. See ${exceptionLink} for details`
         );
     }
-    const params = { params: { ids } };
-    const response = await getAxiosSpotifyInstance().get('/tracks', params);
+    const params = { ids: ids.join(',') };
+    const response = await getAxiosSpotifyInstance().get('/tracks', { params });
     return response.data.tracks.map((trackJson: any) => new Track(trackJson));
 };
 
@@ -18,3 +21,27 @@ export const getTrack = async (id: string) => {
     const response = await getAxiosSpotifyInstance().get(`/tracks/${id}`);
     return new Track(response.data);
 };
+
+export const getAudioAnalysisForTrack = async (id: string) => {
+    const response = await getAxiosSpotifyInstance().get(
+        `/audio-analysis/${id}`
+    );
+    return new AudioAnalysis(response.data);
+};
+
+export const getAudioFeaturesForTrack = async (id: string) => {
+    const response = await getAxiosSpotifyInstance().get(
+        `/audio-features/${id}`
+    );
+    return new AudioFeatures(response.data);
+};
+
+export const getAudioFeaturesForSeveralTracks = async (ids: string[]) => {
+    const params = { ids: ids.join(',') };
+    const response = await getAxiosSpotifyInstance().get(`/audio-features`, {
+        params,
+    });
+    return response.data.audio_features.map(
+        (audioFeaturesJson: any) => new AudioFeatures(audioFeaturesJson)
+    );
+};

From fb1f7cd7cc8d11d4431dbecae5e4b263f43c5c32 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 00:47:15 -0300
Subject: [PATCH 22/27] Fix typo in request

---
 src/lib/playlists.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lib/playlists.ts b/src/lib/playlists.ts
index 01d8ff10..26076796 100644
--- a/src/lib/playlists.ts
+++ b/src/lib/playlists.ts
@@ -5,7 +5,7 @@ import Page from './models/paging/page';
 import PlaylistSimplified from './models/playlist/playlist-simplified';
 
 export const getPlaylist = async (id: string) => {
-    const response = await getAxiosSpotifyInstance().get(`/plylists/${id}`);
+    const response = await getAxiosSpotifyInstance().get(`/playlists/${id}`);
     return new Playlist(response.data);
 };
 

From a17340afa130b81c0770284ef5909a9497382ab2 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 20:35:41 -0300
Subject: [PATCH 23/27] Add optional parameters to track-related requests

---
 src/lib/tracks.ts | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/lib/tracks.ts b/src/lib/tracks.ts
index e1c24d07..f16681ed 100644
--- a/src/lib/tracks.ts
+++ b/src/lib/tracks.ts
@@ -4,7 +4,10 @@ import Track from './models/track/track';
 import AudioAnalysis from './models/track/audio-analysis';
 import AudioFeatures from './models/track/audio-features';
 
-export const getSeveralTracks = async (ids: string[]) => {
+export const getSeveralTracks = async (
+    ids: string[],
+    params?: { market?: string }
+) => {
     if (ids.length > 50) {
         const exceptionLink =
             'https://developer.spotify.com/documentation/web-api/reference/tracks/get-several-tracks/';
@@ -12,13 +15,16 @@ export const getSeveralTracks = async (ids: string[]) => {
             `The maximum number of tracks is 50. See ${exceptionLink} for details`
         );
     }
-    const params = { ids: ids.join(',') };
-    const response = await getAxiosSpotifyInstance().get('/tracks', { params });
+    const response = await getAxiosSpotifyInstance().get('/tracks', {
+        params: { ids: ids.join(','), ...params },
+    });
     return response.data.tracks.map((trackJson: any) => new Track(trackJson));
 };
 
-export const getTrack = async (id: string) => {
-    const response = await getAxiosSpotifyInstance().get(`/tracks/${id}`);
+export const getTrack = async (id: string, params?: { market?: string }) => {
+    const response = await getAxiosSpotifyInstance().get(`/tracks/${id}`, {
+        params,
+    });
     return new Track(response.data);
 };
 

From 27e7a05d1fe36da97d4143b2dada7cb7e810166d Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 20:35:57 -0300
Subject: [PATCH 24/27] Implement tests for getTrack and getSeveralTracks

---
 test/mocks/several-tracks.mock.ts | 178 ++++++++++++++++++++++++++++++
 test/mocks/track.mock.ts          |  83 ++++++++++++++
 test/track.test.ts                |  51 +++++++++
 3 files changed, 312 insertions(+)
 create mode 100644 test/mocks/several-tracks.mock.ts
 create mode 100644 test/mocks/track.mock.ts
 create mode 100644 test/track.test.ts

diff --git a/test/mocks/several-tracks.mock.ts b/test/mocks/several-tracks.mock.ts
new file mode 100644
index 00000000..fd622990
--- /dev/null
+++ b/test/mocks/several-tracks.mock.ts
@@ -0,0 +1,178 @@
+export const severalTracksMock = {
+    tracks: [
+        {
+            album: {
+                album_type: 'album',
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                        id: '1WgXqy2Dd70QQOU7Ay074N',
+                        name: 'AURORA',
+                        type: 'artist',
+                        uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+                    },
+                ],
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/album/2iv4eCuGKJYsso1mDR48dt',
+                },
+                href:
+                    'https://api.spotify.com/v1/albums/2iv4eCuGKJYsso1mDR48dt',
+                id: '2iv4eCuGKJYsso1mDR48dt',
+                images: [
+                    {
+                        height: 640,
+                        url:
+                            'https://i.scdn.co/image/53a31a48a6db327175be725301ba758bb3bed354',
+                        width: 640,
+                    },
+                    {
+                        height: 300,
+                        url:
+                            'https://i.scdn.co/image/0c4210e5b5a44ed2dc6bb42260a4b97c0b0b46a9',
+                        width: 300,
+                    },
+                    {
+                        height: 64,
+                        url:
+                            'https://i.scdn.co/image/0e874917c51fe5ab7413f364b1ef1054920b9372',
+                        width: 64,
+                    },
+                ],
+                name: 'Infections Of A Different Kind (Step I)',
+                release_date: '2018-09-28',
+                release_date_precision: 'day',
+                total_tracks: 8,
+                type: 'album',
+                uri: 'spotify:album:2iv4eCuGKJYsso1mDR48dt',
+            },
+            artists: [
+                {
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                    id: '1WgXqy2Dd70QQOU7Ay074N',
+                    name: 'AURORA',
+                    type: 'artist',
+                    uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+                },
+            ],
+            disc_number: 1,
+            duration_ms: 239533,
+            explicit: false,
+            external_ids: {
+                isrc: 'GBUM71801202',
+            },
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/track/6HmBWGDgxHNlE3AvX5aNN5',
+            },
+            href: 'https://api.spotify.com/v1/tracks/6HmBWGDgxHNlE3AvX5aNN5',
+            id: '6HmBWGDgxHNlE3AvX5aNN5',
+            is_local: false,
+            is_playable: true,
+            name: 'Soft Universe',
+            popularity: 49,
+            preview_url:
+                'https://p.scdn.co/mp3-preview/b0ffc1be502212bf4832c10f063b5986ec1b11f7?cid=774b29d4f13844c495f206cafdad9c86',
+            track_number: 7,
+            type: 'track',
+            uri: 'spotify:track:6HmBWGDgxHNlE3AvX5aNN5',
+        },
+        {
+            album: {
+                album_type: 'album',
+                artists: [
+                    {
+                        external_urls: {
+                            spotify:
+                                'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                        },
+                        href:
+                            'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                        id: '1WgXqy2Dd70QQOU7Ay074N',
+                        name: 'AURORA',
+                        type: 'artist',
+                        uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+                    },
+                ],
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/album/2iv4eCuGKJYsso1mDR48dt',
+                },
+                href:
+                    'https://api.spotify.com/v1/albums/2iv4eCuGKJYsso1mDR48dt',
+                id: '2iv4eCuGKJYsso1mDR48dt',
+                images: [
+                    {
+                        height: 640,
+                        url:
+                            'https://i.scdn.co/image/53a31a48a6db327175be725301ba758bb3bed354',
+                        width: 640,
+                    },
+                    {
+                        height: 300,
+                        url:
+                            'https://i.scdn.co/image/0c4210e5b5a44ed2dc6bb42260a4b97c0b0b46a9',
+                        width: 300,
+                    },
+                    {
+                        height: 64,
+                        url:
+                            'https://i.scdn.co/image/0e874917c51fe5ab7413f364b1ef1054920b9372',
+                        width: 64,
+                    },
+                ],
+                name: 'Infections Of A Different Kind (Step I)',
+                release_date: '2018-09-28',
+                release_date_precision: 'day',
+                total_tracks: 8,
+                type: 'album',
+                uri: 'spotify:album:2iv4eCuGKJYsso1mDR48dt',
+            },
+            artists: [
+                {
+                    external_urls: {
+                        spotify:
+                            'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                    },
+                    href:
+                        'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                    id: '1WgXqy2Dd70QQOU7Ay074N',
+                    name: 'AURORA',
+                    type: 'artist',
+                    uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+                },
+            ],
+            disc_number: 1,
+            duration_ms: 326918,
+            explicit: false,
+            external_ids: {
+                isrc: 'GBUM71804531',
+            },
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/track/1ppv75fAfo5i5vB3e7kp4l',
+            },
+            href: 'https://api.spotify.com/v1/tracks/1ppv75fAfo5i5vB3e7kp4l',
+            id: '1ppv75fAfo5i5vB3e7kp4l',
+            is_local: false,
+            is_playable: true,
+            name: 'Infections Of A Different Kind',
+            popularity: 47,
+            preview_url:
+                'https://p.scdn.co/mp3-preview/aa3327b064438deb444fb6bd21208ca9d7cec72d?cid=774b29d4f13844c495f206cafdad9c86',
+            track_number: 8,
+            type: 'track',
+            uri: 'spotify:track:1ppv75fAfo5i5vB3e7kp4l',
+        },
+    ],
+};
diff --git a/test/mocks/track.mock.ts b/test/mocks/track.mock.ts
new file mode 100644
index 00000000..97ce42fa
--- /dev/null
+++ b/test/mocks/track.mock.ts
@@ -0,0 +1,83 @@
+export const trackMock = {
+    album: {
+        album_type: 'album',
+        artists: [
+            {
+                external_urls: {
+                    spotify:
+                        'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+                },
+                href:
+                    'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+                id: '1WgXqy2Dd70QQOU7Ay074N',
+                name: 'AURORA',
+                type: 'artist',
+                uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+            },
+        ],
+        external_urls: {
+            spotify: 'https://open.spotify.com/album/2iv4eCuGKJYsso1mDR48dt',
+        },
+        href: 'https://api.spotify.com/v1/albums/2iv4eCuGKJYsso1mDR48dt',
+        id: '2iv4eCuGKJYsso1mDR48dt',
+        images: [
+            {
+                height: 640,
+                url:
+                    'https://i.scdn.co/image/53a31a48a6db327175be725301ba758bb3bed354',
+                width: 640,
+            },
+            {
+                height: 300,
+                url:
+                    'https://i.scdn.co/image/0c4210e5b5a44ed2dc6bb42260a4b97c0b0b46a9',
+                width: 300,
+            },
+            {
+                height: 64,
+                url:
+                    'https://i.scdn.co/image/0e874917c51fe5ab7413f364b1ef1054920b9372',
+                width: 64,
+            },
+        ],
+        name: 'Infections Of A Different Kind (Step I)',
+        release_date: '2018-09-28',
+        release_date_precision: 'day',
+        total_tracks: 8,
+        type: 'album',
+        uri: 'spotify:album:2iv4eCuGKJYsso1mDR48dt',
+    },
+    artists: [
+        {
+            external_urls: {
+                spotify:
+                    'https://open.spotify.com/artist/1WgXqy2Dd70QQOU7Ay074N',
+            },
+            href: 'https://api.spotify.com/v1/artists/1WgXqy2Dd70QQOU7Ay074N',
+            id: '1WgXqy2Dd70QQOU7Ay074N',
+            name: 'AURORA',
+            type: 'artist',
+            uri: 'spotify:artist:1WgXqy2Dd70QQOU7Ay074N',
+        },
+    ],
+    disc_number: 1,
+    duration_ms: 239533,
+    explicit: false,
+    external_ids: {
+        isrc: 'GBUM71801202',
+    },
+    external_urls: {
+        spotify: 'https://open.spotify.com/track/6HmBWGDgxHNlE3AvX5aNN5',
+    },
+    href: 'https://api.spotify.com/v1/tracks/6HmBWGDgxHNlE3AvX5aNN5',
+    id: '6HmBWGDgxHNlE3AvX5aNN5',
+    is_local: false,
+    is_playable: true,
+    name: 'Soft Universe',
+    popularity: 49,
+    preview_url:
+        'https://p.scdn.co/mp3-preview/b0ffc1be502212bf4832c10f063b5986ec1b11f7?cid=774b29d4f13844c495f206cafdad9c86',
+    track_number: 7,
+    type: 'track',
+    uri: 'spotify:track:6HmBWGDgxHNlE3AvX5aNN5',
+};
diff --git a/test/track.test.ts b/test/track.test.ts
new file mode 100644
index 00000000..0ff0f3b0
--- /dev/null
+++ b/test/track.test.ts
@@ -0,0 +1,51 @@
+import nock from 'nock';
+
+import { trackMock } from './mocks/track.mock';
+import { severalTracksMock } from './mocks/several-tracks.mock';
+import { checkMatchingTrackAttributes } from './common/matching-attributes.test';
+
+import { init, getTrack, getSeveralTracks } from '../src/lib';
+
+describe('Track requests', () => {
+    beforeEach(() => {
+        init('SomeToken');
+    });
+
+    describe('#getTrack()', () => {
+        const trackId = '6HmBWGDgxHNlE3AvX5aNN5';
+        const params = { market: 'BR' };
+
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get(`/tracks/${trackId}`)
+                .query(params)
+                .reply(200, trackMock);
+        });
+
+        it('response should match all track attributes', async () => {
+            const trackResponse = await getTrack(trackId, params);
+            checkMatchingTrackAttributes(trackResponse, trackMock);
+        });
+    });
+
+    describe('#getSeveralTracks()', () => {
+        const tracks = ['6HmBWGDgxHNlE3AvX5aNN5', '1ppv75fAfo5i5vB3e7kp4l'];
+        const params = { ids: tracks.join(','), market: 'BR' };
+
+        beforeEach(() => {
+            nock('https://api.spotify.com/v1')
+                .get(`/tracks`)
+                .query(params)
+                .reply(200, severalTracksMock);
+        });
+
+        it('response should match all tracks attributes', async () => {
+            const tracksResponse = await getSeveralTracks(tracks, params);
+            for (let i = 0; i < tracksResponse.length; i++) {
+                const trackResponse = tracksResponse[i];
+                const trackMock = severalTracksMock.tracks[i];
+                checkMatchingTrackAttributes(trackResponse, trackMock);
+            }
+        });
+    });
+});

From b48fcb9ddf483249f86e257ed6c6fabb877f5bc1 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 22:13:22 -0300
Subject: [PATCH 25/27] Rename test files to match files under test

---
 test/{album.test.ts => albums.test.ts}   | 0
 test/{artist.test.ts => artists.test.ts} | 0
 test/{track.test.ts => tracks.test.ts}   | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 rename test/{album.test.ts => albums.test.ts} (100%)
 rename test/{artist.test.ts => artists.test.ts} (100%)
 rename test/{track.test.ts => tracks.test.ts} (100%)

diff --git a/test/album.test.ts b/test/albums.test.ts
similarity index 100%
rename from test/album.test.ts
rename to test/albums.test.ts
diff --git a/test/artist.test.ts b/test/artists.test.ts
similarity index 100%
rename from test/artist.test.ts
rename to test/artists.test.ts
diff --git a/test/track.test.ts b/test/tracks.test.ts
similarity index 100%
rename from test/track.test.ts
rename to test/tracks.test.ts

From 67c9b68aa059170de1f2f2c16242646822025d96 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 22:21:20 -0300
Subject: [PATCH 26/27] Separate mocks in different folders and update imports

---
 test/albums.test.ts                                 |  6 +++---
 test/artists.test.ts                                | 13 ++++++++-----
 test/common/matching-attributes.test.ts             |  6 +++---
 test/mocks/{ => albums}/album-tracks.mock.ts        |  0
 test/mocks/{ => albums}/album.mock.ts               |  0
 test/mocks/{ => albums}/several-albums.mock.ts      |  0
 test/mocks/{ => artists}/artist-albums.mock.ts      |  0
 .../{ => artists}/artist-related-artists.mock.ts    |  0
 test/mocks/{ => artists}/artist-top-tracks.mock.ts  |  0
 test/mocks/{ => artists}/artist.mock.ts             |  0
 test/mocks/{ => artists}/several-artists.mock.ts    |  0
 .../mocks/{ => personalization}/top-artists.mock.ts |  0
 test/mocks/{ => personalization}/top-tracks.mock.ts |  0
 test/mocks/{ => player}/currently-playing.mock.ts   |  0
 .../{ => player}/recently-played-tracks.mock.ts     |  0
 test/mocks/{ => search}/search-albums.mock.ts       |  0
 test/mocks/{ => search}/search-artists.mock.ts      |  0
 test/mocks/{ => search}/search-playlists.mock.ts    |  0
 test/mocks/{ => search}/search-tracks.mock.ts       |  0
 test/mocks/{ => tracks}/several-tracks.mock.ts      |  0
 test/mocks/{ => tracks}/track.mock.ts               |  0
 test/personalization.test.ts                        |  4 ++--
 test/player.test.ts                                 |  4 ++--
 test/search.test.ts                                 |  8 ++++----
 test/tracks.test.ts                                 |  4 ++--
 25 files changed, 24 insertions(+), 21 deletions(-)
 rename test/mocks/{ => albums}/album-tracks.mock.ts (100%)
 rename test/mocks/{ => albums}/album.mock.ts (100%)
 rename test/mocks/{ => albums}/several-albums.mock.ts (100%)
 rename test/mocks/{ => artists}/artist-albums.mock.ts (100%)
 rename test/mocks/{ => artists}/artist-related-artists.mock.ts (100%)
 rename test/mocks/{ => artists}/artist-top-tracks.mock.ts (100%)
 rename test/mocks/{ => artists}/artist.mock.ts (100%)
 rename test/mocks/{ => artists}/several-artists.mock.ts (100%)
 rename test/mocks/{ => personalization}/top-artists.mock.ts (100%)
 rename test/mocks/{ => personalization}/top-tracks.mock.ts (100%)
 rename test/mocks/{ => player}/currently-playing.mock.ts (100%)
 rename test/mocks/{ => player}/recently-played-tracks.mock.ts (100%)
 rename test/mocks/{ => search}/search-albums.mock.ts (100%)
 rename test/mocks/{ => search}/search-artists.mock.ts (100%)
 rename test/mocks/{ => search}/search-playlists.mock.ts (100%)
 rename test/mocks/{ => search}/search-tracks.mock.ts (100%)
 rename test/mocks/{ => tracks}/several-tracks.mock.ts (100%)
 rename test/mocks/{ => tracks}/track.mock.ts (100%)

diff --git a/test/albums.test.ts b/test/albums.test.ts
index c724036c..b9755c43 100644
--- a/test/albums.test.ts
+++ b/test/albums.test.ts
@@ -1,9 +1,9 @@
 import { expect } from 'chai';
 import nock from 'nock';
 
-import { albumMock, AlbumMock } from './mocks/album.mock';
-import { severalAlbumsMock } from './mocks/several-albums.mock';
-import { albumTracksMock } from './mocks/album-tracks.mock';
+import { albumMock, AlbumMock } from './mocks/albums/album.mock';
+import { severalAlbumsMock } from './mocks/albums/several-albums.mock';
+import { albumTracksMock } from './mocks/albums/album-tracks.mock';
 import {
     checkMatchingAlbumAttributes,
     checkMatchingPagingObjectAttributes,
diff --git a/test/artists.test.ts b/test/artists.test.ts
index 84ca58ca..dd0351e1 100644
--- a/test/artists.test.ts
+++ b/test/artists.test.ts
@@ -1,10 +1,13 @@
 import nock from 'nock';
 
-import { artistMock, ArtistMock } from './mocks/artist.mock';
-import { severalArtistsMock } from './mocks/several-artists.mock';
-import { artistAlbumsMock } from './mocks/artist-albums.mock';
-import { artistRelatedArtistsMock } from './mocks/artist-related-artists.mock';
-import { artistTopTracksMock, TrackMock } from './mocks/artist-top-tracks.mock';
+import { artistMock, ArtistMock } from './mocks/artists/artist.mock';
+import { severalArtistsMock } from './mocks/artists/several-artists.mock';
+import { artistAlbumsMock } from './mocks/artists/artist-albums.mock';
+import { artistRelatedArtistsMock } from './mocks/artists/artist-related-artists.mock';
+import {
+    artistTopTracksMock,
+    TrackMock,
+} from './mocks/artists/artist-top-tracks.mock';
 import {
     checkMatchingArtistAttributes,
     checkMatchingPagingObjectAttributes,
diff --git a/test/common/matching-attributes.test.ts b/test/common/matching-attributes.test.ts
index eed548e4..c2bcad46 100644
--- a/test/common/matching-attributes.test.ts
+++ b/test/common/matching-attributes.test.ts
@@ -9,9 +9,9 @@ import CurrentlyPlaying from '../../src/lib/models/player/currently-playing';
 import Context from '../../src/lib/models/player/context';
 import CursorBasedPage from '../../src/lib/models/paging/cursor-based-page';
 
-import { AlbumMock } from '../mocks/album.mock';
-import { ArtistMock } from '../mocks/artist.mock';
-import { TrackMock } from './../mocks/artist-top-tracks.mock';
+import { AlbumMock } from '../mocks/albums/album.mock';
+import { ArtistMock } from '../mocks/artists/artist.mock';
+import { TrackMock } from '../mocks/artists/artist-top-tracks.mock';
 
 export const checkMatchingAlbumAttributes = (
     response: Album,
diff --git a/test/mocks/album-tracks.mock.ts b/test/mocks/albums/album-tracks.mock.ts
similarity index 100%
rename from test/mocks/album-tracks.mock.ts
rename to test/mocks/albums/album-tracks.mock.ts
diff --git a/test/mocks/album.mock.ts b/test/mocks/albums/album.mock.ts
similarity index 100%
rename from test/mocks/album.mock.ts
rename to test/mocks/albums/album.mock.ts
diff --git a/test/mocks/several-albums.mock.ts b/test/mocks/albums/several-albums.mock.ts
similarity index 100%
rename from test/mocks/several-albums.mock.ts
rename to test/mocks/albums/several-albums.mock.ts
diff --git a/test/mocks/artist-albums.mock.ts b/test/mocks/artists/artist-albums.mock.ts
similarity index 100%
rename from test/mocks/artist-albums.mock.ts
rename to test/mocks/artists/artist-albums.mock.ts
diff --git a/test/mocks/artist-related-artists.mock.ts b/test/mocks/artists/artist-related-artists.mock.ts
similarity index 100%
rename from test/mocks/artist-related-artists.mock.ts
rename to test/mocks/artists/artist-related-artists.mock.ts
diff --git a/test/mocks/artist-top-tracks.mock.ts b/test/mocks/artists/artist-top-tracks.mock.ts
similarity index 100%
rename from test/mocks/artist-top-tracks.mock.ts
rename to test/mocks/artists/artist-top-tracks.mock.ts
diff --git a/test/mocks/artist.mock.ts b/test/mocks/artists/artist.mock.ts
similarity index 100%
rename from test/mocks/artist.mock.ts
rename to test/mocks/artists/artist.mock.ts
diff --git a/test/mocks/several-artists.mock.ts b/test/mocks/artists/several-artists.mock.ts
similarity index 100%
rename from test/mocks/several-artists.mock.ts
rename to test/mocks/artists/several-artists.mock.ts
diff --git a/test/mocks/top-artists.mock.ts b/test/mocks/personalization/top-artists.mock.ts
similarity index 100%
rename from test/mocks/top-artists.mock.ts
rename to test/mocks/personalization/top-artists.mock.ts
diff --git a/test/mocks/top-tracks.mock.ts b/test/mocks/personalization/top-tracks.mock.ts
similarity index 100%
rename from test/mocks/top-tracks.mock.ts
rename to test/mocks/personalization/top-tracks.mock.ts
diff --git a/test/mocks/currently-playing.mock.ts b/test/mocks/player/currently-playing.mock.ts
similarity index 100%
rename from test/mocks/currently-playing.mock.ts
rename to test/mocks/player/currently-playing.mock.ts
diff --git a/test/mocks/recently-played-tracks.mock.ts b/test/mocks/player/recently-played-tracks.mock.ts
similarity index 100%
rename from test/mocks/recently-played-tracks.mock.ts
rename to test/mocks/player/recently-played-tracks.mock.ts
diff --git a/test/mocks/search-albums.mock.ts b/test/mocks/search/search-albums.mock.ts
similarity index 100%
rename from test/mocks/search-albums.mock.ts
rename to test/mocks/search/search-albums.mock.ts
diff --git a/test/mocks/search-artists.mock.ts b/test/mocks/search/search-artists.mock.ts
similarity index 100%
rename from test/mocks/search-artists.mock.ts
rename to test/mocks/search/search-artists.mock.ts
diff --git a/test/mocks/search-playlists.mock.ts b/test/mocks/search/search-playlists.mock.ts
similarity index 100%
rename from test/mocks/search-playlists.mock.ts
rename to test/mocks/search/search-playlists.mock.ts
diff --git a/test/mocks/search-tracks.mock.ts b/test/mocks/search/search-tracks.mock.ts
similarity index 100%
rename from test/mocks/search-tracks.mock.ts
rename to test/mocks/search/search-tracks.mock.ts
diff --git a/test/mocks/several-tracks.mock.ts b/test/mocks/tracks/several-tracks.mock.ts
similarity index 100%
rename from test/mocks/several-tracks.mock.ts
rename to test/mocks/tracks/several-tracks.mock.ts
diff --git a/test/mocks/track.mock.ts b/test/mocks/tracks/track.mock.ts
similarity index 100%
rename from test/mocks/track.mock.ts
rename to test/mocks/tracks/track.mock.ts
diff --git a/test/personalization.test.ts b/test/personalization.test.ts
index 2d9a37b1..9b77d7f1 100644
--- a/test/personalization.test.ts
+++ b/test/personalization.test.ts
@@ -1,7 +1,7 @@
 import nock from 'nock';
 
-import { topArtistsMock } from './mocks/top-artists.mock';
-import { topTracksMock } from './mocks/top-tracks.mock';
+import { topArtistsMock } from './mocks/personalization/top-artists.mock';
+import { topTracksMock } from './mocks/personalization/top-tracks.mock';
 import { checkMatchingPagingObjectAttributes } from './common/matching-attributes.test';
 
 import {
diff --git a/test/player.test.ts b/test/player.test.ts
index 0bb636e5..07a532bf 100644
--- a/test/player.test.ts
+++ b/test/player.test.ts
@@ -1,7 +1,7 @@
 import nock from 'nock';
 
-import { currentlyPlayingMock } from './mocks/currently-playing.mock';
-import { recentlyPlayedTracksMock } from './mocks/recently-played-tracks.mock';
+import { currentlyPlayingMock } from './mocks/player/currently-playing.mock';
+import { recentlyPlayedTracksMock } from './mocks/player/recently-played-tracks.mock';
 import {
     checkMatchingCurrentlyPlayingAttributes,
     checkMatchingCursorBasedPageAttributes,
diff --git a/test/search.test.ts b/test/search.test.ts
index bb76d1b0..ba8b6198 100644
--- a/test/search.test.ts
+++ b/test/search.test.ts
@@ -1,8 +1,9 @@
-import { searchTracksMock } from './mocks/search-tracks.mock';
-import { searchPlaylistsMock } from './mocks/search-playlists.mock';
 import nock from 'nock';
 
-import { searchAlbumsMock } from './mocks/search-albums.mock';
+import { searchAlbumsMock } from './mocks/search/search-albums.mock';
+import { searchArtistsMock } from './mocks/search/search-artists.mock';
+import { searchPlaylistsMock } from './mocks/search/search-playlists.mock';
+import { searchTracksMock } from './mocks/search/search-tracks.mock';
 import { checkMatchingPagingObjectAttributes } from './common/matching-attributes.test';
 
 import {
@@ -12,7 +13,6 @@ import {
     searchPlaylists,
     searchTracks,
 } from '../src/lib';
-import { searchArtistsMock } from './mocks/search-artists.mock';
 
 describe('Search requests', () => {
     beforeEach(() => {
diff --git a/test/tracks.test.ts b/test/tracks.test.ts
index 0ff0f3b0..f57a8d37 100644
--- a/test/tracks.test.ts
+++ b/test/tracks.test.ts
@@ -1,7 +1,7 @@
 import nock from 'nock';
 
-import { trackMock } from './mocks/track.mock';
-import { severalTracksMock } from './mocks/several-tracks.mock';
+import { trackMock } from './mocks/tracks/track.mock';
+import { severalTracksMock } from './mocks/tracks/several-tracks.mock';
 import { checkMatchingTrackAttributes } from './common/matching-attributes.test';
 
 import { init, getTrack, getSeveralTracks } from '../src/lib';

From 29f5563e7b14188b24a95999c39c4232c164c2c1 Mon Sep 17 00:00:00 2001
From: JRobsonJr <jrobsonjr16@gmail.com>
Date: Tue, 20 Nov 2018 22:46:20 -0300
Subject: [PATCH 27/27] Update version in package.json

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index f233a023..78afa8dc 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
         "Robson Junior <jrobsonjr16@gmail.com> (https://github.com/JRobsonJr)"
     ],
     "license": "MIT",
-    "version": "0.1.3",
+    "version": "0.2.0",
     "dependencies": {
         "axios": "^0.18.0"
     },