(), responseBody);
68 | }
69 |
70 | public static String readTestData(String fileName) {
71 | try {
72 | String path = Robolectric.class.getResource("/fixtures/" + fileName).toURI().getPath();
73 | return readFromFile(new File(path));
74 | } catch (Exception e) {
75 | throw new RuntimeException(e);
76 | }
77 | }
78 |
79 | private static String readFromFile(File file) throws IOException {
80 | Reader reader = new FileReader(file);
81 | CharBuffer charBuffer = CharBuffer.allocate(MAX_TEST_DATA_FILE_SIZE);
82 | reader.read(charBuffer);
83 | charBuffer.position(0);
84 | return charBuffer.toString().trim();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/spotify-api/src/main/java/kaaes/spotify/webapi/android/SpotifyError.java:
--------------------------------------------------------------------------------
1 | package kaaes.spotify.webapi.android;
2 |
3 | import kaaes.spotify.webapi.android.models.*;
4 | import retrofit.RetrofitError;
5 |
6 | /**
7 | * This object wraps error responses from the Web API
8 | * and provides access to details returned by the request that are usually more
9 | * descriptive than default Retrofit error messages.
10 | *
11 | * To use with asynchronous requests pass {@link SpotifyCallback}
12 | * instead of {@link retrofit.Callback} when making the request:
13 | *
{@code
14 | * spotify.getMySavedTracks(new SpotifyCallback>() {
15 | * public void success(Pager savedTrackPager, Response response) {
16 | * // handle successful response
17 | * }
18 | *
19 | * public void failure(SpotifyError error) {
20 | * // handle error
21 | * }
22 | * });
23 | * }
24 | *
25 | * To use with synchronous requests:
26 | *
{@code
27 | * try {
28 | * Pager mySavedTracks = spotify.getMySavedTracks();
29 | * } catch (RetrofitError error) {
30 | * SpotifyError spotifyError = SpotifyError.fromRetrofitError(error);
31 | * }
32 | * }
33 | */
34 | public class SpotifyError extends Exception {
35 |
36 | private final RetrofitError mRetrofitError;
37 | private final ErrorDetails mErrorDetails;
38 |
39 | public static SpotifyError fromRetrofitError(RetrofitError error) {
40 | ErrorResponse errorResponse = null;
41 |
42 | try {
43 | errorResponse = (ErrorResponse) error.getBodyAs(ErrorResponse.class);
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | }
47 |
48 | if (errorResponse != null && errorResponse.error != null) {
49 | String message = errorResponse.error.status + " " + errorResponse.error.message;
50 | return new SpotifyError(error, errorResponse.error, message);
51 | } else {
52 | return new SpotifyError(error);
53 | }
54 | }
55 |
56 | public SpotifyError(RetrofitError retrofitError, ErrorDetails errorDetails, String message) {
57 | super(message, retrofitError);
58 | mRetrofitError = retrofitError;
59 | mErrorDetails = errorDetails;
60 | }
61 |
62 | public SpotifyError(RetrofitError retrofitError) {
63 | super(retrofitError);
64 | mRetrofitError = retrofitError;
65 | mErrorDetails = null;
66 | }
67 |
68 | /**
69 | * @return the original {@link retrofit.RetrofitError} that was returned for this request.
70 | */
71 | public RetrofitError getRetrofitError() {
72 | return mRetrofitError;
73 | }
74 |
75 | /**
76 | * @return true if there are {@link kaaes.spotify.webapi.android.models.ErrorDetails}
77 | * associated with this error. False otherwise.
78 | */
79 | public boolean hasErrorDetails() {
80 | return mErrorDetails != null;
81 | }
82 |
83 | /**
84 | * @return Details returned from the Web API associated with this error if present.
85 | */
86 | public ErrorDetails getErrorDetails() {
87 | return mErrorDetails;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/spotify-api/src/test/resources/fixtures/track.json:
--------------------------------------------------------------------------------
1 | {
2 | "album": {
3 | "album_type": "album",
4 | "available_markets": [ "AD", "AR", "AT", "AU", "BE", "BG", "BO", "BR", "CH", "CL", "CO",
5 | "CR", "CY", "CZ", "DE", "DK", "DO", "EC", "EE", "ES", "FI", "FR",
6 | "GR", "GT", "HK", "HN", "HU", "IE", "IS", "IT", "LI", "LT", "LU",
7 | "LV", "MC", "MT", "MY", "NI", "NL", "NO", "NZ", "PA", "PE", "PH",
8 | "PL", "PT", "PY", "RO", "SE", "SG", "SI", "SK", "SV", "TR", "TW",
9 | "UY" ],
10 | "external_urls": {
11 | "spotify": "https://open.spotify.com/album/6TJmQnO44YE5BtTxH8pop1"
12 | },
13 | "href": "https://api.spotify.com/v1/albums/6TJmQnO44YE5BtTxH8pop1",
14 | "id": "6TJmQnO44YE5BtTxH8pop1",
15 | "images": [
16 | {
17 | "height": 640,
18 | "url": "https://i.scdn.co/image/8e13218039f81b000553e25522a7f0d7a0600f2e",
19 | "width": 629
20 | },
21 | {
22 | "height": 300,
23 | "url": "https://i.scdn.co/image/8c1e066b5d1045038437d92815d49987f519e44f",
24 | "width": 295
25 | },
26 | {
27 | "height": 64,
28 | "url": "https://i.scdn.co/image/d49268a8fc0768084f4750cf1647709e89a27172",
29 | "width": 63
30 | }
31 | ],
32 | "name": "Hot Fuss",
33 | "type": "album",
34 | "uri": "spotify:album:6TJmQnO44YE5BtTxH8pop1"
35 | },
36 | "artists": [
37 | {
38 | "external_urls": {
39 | "spotify": "https://open.spotify.com/artist/0C0XlULifJtAgn6ZNCW2eu"
40 | },
41 | "href": "https://api.spotify.com/v1/artists/0C0XlULifJtAgn6ZNCW2eu",
42 | "id": "0C0XlULifJtAgn6ZNCW2eu",
43 | "name": "The Killers",
44 | "type": "artist",
45 | "uri": "spotify:artist:0C0XlULifJtAgn6ZNCW2eu"
46 | }
47 | ],
48 | "available_markets": [ "AD", "AR", "AT", "AU", "BE", "BG", "BO", "BR", "CH", "CL", "CO", "CR",
49 | "CY", "CZ", "DE", "DK", "DO", "EC", "EE", "ES", "FI", "FR", "GR", "GT",
50 | "HK", "HN", "HU", "IE", "IS", "IT", "LI", "LT", "LU", "LV", "MC", "MT",
51 | "MY", "NI", "NL", "NO", "NZ", "PA", "PE", "PH", "PL", "PT", "PY", "RO",
52 | "SE", "SG", "SI", "SK", "SV", "TR", "TW", "UY" ],
53 | "disc_number": 1,
54 | "duration_ms": 222075,
55 | "explicit": false,
56 | "external_ids": {
57 | "isrc": "USIR20400274"
58 | },
59 | "external_urls": {
60 | "spotify": "https://open.spotify.com/track/0eGsygTp906u18L0Oimnem"
61 | },
62 | "href": "https://api.spotify.com/v1/tracks/0eGsygTp906u18L0Oimnem",
63 | "id": "0eGsygTp906u18L0Oimnem",
64 | "name": "Mr. Brightside",
65 | "popularity": 77,
66 | "preview_url": "https://p.scdn.co/mp3-preview/f454c8224828e21fa146af84916fd22cb89cedc6",
67 | "track_number": 2,
68 | "type": "track",
69 | "uri": "spotify:track:0eGsygTp906u18L0Oimnem"
70 | }
--------------------------------------------------------------------------------
/spotify-api/src/test/resources/fixtures/artist-album.json:
--------------------------------------------------------------------------------
1 | {
2 | "href": "https://api.spotify.com/v1/artists/1vCWHaC5f2uS3yhpwWbIA6/albums?offset=0&limit=2&album_type=single",
3 | "items": [
4 | {
5 | "album_type": "single",
6 | "available_markets": [ "AD", "AR", "AT", "AU", "BE", "BG", "BO", "BR", "CH", "CL", "CO",
7 | "CR", "CY", "CZ", "DE", "DK", "DO", "EC", "EE", "ES", "FI", "GR",
8 | "GT", "HK", "HN", "HU", "IS", "IT", "LI", "LT", "LU", "LV", "MC",
9 | "MT", "MY", "NI", "NL", "NO", "NZ", "PA", "PE", "PH", "PL", "PT",
10 | "PY", "RO", "SE", "SG", "SI", "SK", "SV", "TR", "TW", "UY" ],
11 | "external_urls": {
12 | "spotify": "https://open.spotify.com/album/1moqjcU7BoanAsSKRdHnP1"
13 | },
14 | "href": "https://api.spotify.com/v1/albums/1moqjcU7BoanAsSKRdHnP1",
15 | "id": "1moqjcU7BoanAsSKRdHnP1",
16 | "images": [
17 | {
18 | "height": 640,
19 | "url": "https://i.scdn.co/image/5f8349e8e4ed81b48f033a9818939c835520f150",
20 | "width": 640
21 | },
22 | {
23 | "height": 300,
24 | "url": "https://i.scdn.co/image/8a5e05379add83b787a4cf0c3909a415e60b93ef",
25 | "width": 300
26 | },
27 | {
28 | "height": 64,
29 | "url": "https://i.scdn.co/image/84f3422d4946c71c8891c0f0fcbe78d6e7395f5f",
30 | "width": 64
31 | }
32 | ],
33 | "name": "Lay Me Down (Black Coffee Remix)",
34 | "type": "album",
35 | "uri": "spotify:album:1moqjcU7BoanAsSKRdHnP1"
36 | },
37 | {
38 | "album_type": "single",
39 | "available_markets": [ ],
40 | "external_urls": {
41 | "spotify": "https://open.spotify.com/album/6HVPLh1TXzPnMqY7tAWLoL"
42 | },
43 | "href": "https://api.spotify.com/v1/albums/6HVPLh1TXzPnMqY7tAWLoL",
44 | "id": "6HVPLh1TXzPnMqY7tAWLoL",
45 | "images": [
46 | {
47 | "height": 640,
48 | "url": "https://i.scdn.co/image/4c252ea56b0276df6043db10747f4daf89714a93",
49 | "width": 640
50 | },
51 | {
52 | "height": 300,
53 | "url": "https://i.scdn.co/image/cc3db8170a3833140800a2cb291ed51977c6696a",
54 | "width": 300
55 | },
56 | {
57 | "height": 64,
58 | "url": "https://i.scdn.co/image/12a32170ff25f0e825472d20161cd75db433ee58",
59 | "width": 64
60 | }
61 | ],
62 | "name": "Addicted To You",
63 | "type": "album",
64 | "uri": "spotify:album:6HVPLh1TXzPnMqY7tAWLoL"
65 | }
66 | ],
67 | "limit": 2,
68 | "next": "https://api.spotify.com/v1/artists/1vCWHaC5f2uS3yhpwWbIA6/albums?offset=2&limit=2&album_type=single",
69 | "offset": 0,
70 | "previous": null,
71 | "total": 181
72 | }
--------------------------------------------------------------------------------
/sample-search/src/main/java/kaaes/spotify/webapi/samplesearch/SearchResultsAdapter.java:
--------------------------------------------------------------------------------
1 | package kaaes.spotify.webapi.samplesearch;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import com.google.common.base.Joiner;
12 | import com.squareup.picasso.Picasso;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | import kaaes.spotify.webapi.android.models.ArtistSimple;
18 | import kaaes.spotify.webapi.android.models.Image;
19 | import kaaes.spotify.webapi.android.models.Track;
20 |
21 | public class SearchResultsAdapter extends RecyclerView.Adapter {
22 |
23 | private final List