Merge lp:~karni/ubuntuone-music-java-library/v2-changes-and-playlists into lp:ubuntuone-music-java-library

Proposed by Michał Karnicki on 2012-11-12
Status: Merged
Merged at revision: 32
Proposed branch: lp:~karni/ubuntuone-music-java-library/v2-changes-and-playlists
Merge into: lp:ubuntuone-music-java-library
Prerequisite: lp:~ubuntuone-client-engineering/ubuntuone-music-java-library/playlist-args-and-request-refactor
Diff against target: 1033 lines (+371/-162)
19 files modified
src/main/com/ubuntuone/api/music/U1MusicAPI.java (+88/-21)
src/main/com/ubuntuone/api/music/client/ResourceClient.java (+1/-1)
src/main/com/ubuntuone/api/music/json/U1AlbumJson.java (+6/-2)
src/main/com/ubuntuone/api/music/json/U1ArtistJson.java (+3/-3)
src/main/com/ubuntuone/api/music/json/U1CustomJson.java (+3/-3)
src/main/com/ubuntuone/api/music/json/U1PlaylistJson.java (+22/-0)
src/main/com/ubuntuone/api/music/json/U1SongJson.java (+9/-1)
src/main/com/ubuntuone/api/music/model/U1Album.java (+2/-0)
src/main/com/ubuntuone/api/music/model/U1Artist.java (+1/-1)
src/main/com/ubuntuone/api/music/model/U1Song.java (+2/-0)
src/main/com/ubuntuone/api/music/request/U1PlaylistCreateListener.java (+44/-0)
src/main/com/ubuntuone/api/music/util/ResultRequestListener.java (+1/-1)
src/test/com/ubuntuone/api/music/CreatePlaylistTest.java (+32/-77)
src/test/com/ubuntuone/api/music/UpdatePlaylistTest.java (+76/-44)
src/test/com/ubuntuone/api/music/json/U1PlaylistJsonTest.java (+19/-0)
src/test/com/ubuntuone/music/util/U1AlbumBuilder.java (+6/-3)
src/test/com/ubuntuone/music/util/U1ArtistBuilder.java (+1/-1)
src/test/com/ubuntuone/music/util/U1ResponseBuilder.java (+49/-2)
src/test/com/ubuntuone/music/util/U1SongBuilder.java (+6/-2)
To merge this branch: bzr merge lp:~karni/ubuntuone-music-java-library/v2-changes-and-playlists
Reviewer Review Type Date Requested Status
Ubuntu One Client Engineering team 2012-11-12 Pending
Review via email: mp+133946@code.launchpad.net

Commit message

Introduced music API v2 changes. Added creating and updating playlists.

Description of the change

Introduced minor music API v2 changes (new fields in JSON response).
Added creating and updating playlists.
Renamed a few variables.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/main/com/ubuntuone/api/music/U1MusicAPI.java'
2--- src/main/com/ubuntuone/api/music/U1MusicAPI.java 2012-11-12 15:33:22 +0000
3+++ src/main/com/ubuntuone/api/music/U1MusicAPI.java 2012-11-12 15:33:23 +0000
4@@ -28,6 +28,7 @@
5 import java.io.OutputStream;
6 import java.net.URISyntaxException;
7 import java.util.ArrayList;
8+import java.util.List;
9 import java.util.logging.Level;
10 import java.util.logging.Logger;
11
12@@ -42,6 +43,7 @@
13 import org.apache.http.client.methods.HttpDelete;
14 import org.apache.http.client.methods.HttpGet;
15 import org.apache.http.client.methods.HttpPost;
16+import org.apache.http.client.methods.HttpPut;
17 import org.codehaus.jackson.JsonParseException;
18
19 import com.ubuntuone.api.music.client.BaseClient;
20@@ -53,7 +55,9 @@
21 import com.ubuntuone.api.music.json.U1CustomJson;
22 import com.ubuntuone.api.music.json.U1PlaylistJson;
23 import com.ubuntuone.api.music.json.U1SongJson;
24+import com.ubuntuone.api.music.request.U1CallbackListener;
25 import com.ubuntuone.api.music.request.U1DownloadListener;
26+import com.ubuntuone.api.music.request.U1PlaylistCreateListener;
27 import com.ubuntuone.api.music.util.CancelTrigger;
28 import com.ubuntuone.api.music.util.CancelTrigger.RequestCanceledException;
29 import com.ubuntuone.api.music.util.EntityUtils;
30@@ -65,6 +69,7 @@
31 import com.ubuntuone.api.music.util.ResultRequestListener.U1AlbumRequestListener;
32 import com.ubuntuone.api.music.util.ResultRequestListener.U1ArtRequestListener;
33 import com.ubuntuone.api.music.util.ResultRequestListener.U1ArtistRequestListener;
34+import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistCreateRequestListener;
35 import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistRequestListener;
36 import com.ubuntuone.api.music.util.ResultRequestListener.U1SongRequestListener;
37 import com.ubuntuone.api.music.util.ResultRequestListener.U1StreamRequestListener;
38@@ -381,32 +386,28 @@
39 }
40 }
41
42- public void createPlaylist(String name,
43- ArrayList<String> songIds, U1SongRequestListener callback) {
44- putPlaylist(null, name, songIds, callback);
45- }
46-
47- public void updatePlaylist(String playlistId, String name,
48- ArrayList<String> songIds, U1SongRequestListener callback) {
49- putPlaylist(playlistId, name, songIds, callback);
50- }
51-
52- public void putPlaylist(String playlistId, String name, ArrayList<String> songIds,
53- U1SongRequestListener callback) {
54+ /**
55+ * Creates a new playlist.
56+ *
57+ * @param name
58+ * The name of the playlist to be created.
59+ * @param songIdList
60+ * The song id list of the new playlist. Can be null.
61+ * @param callback
62+ * {@link U1PlaylistCreateRequestListener} result callback. Use
63+ * {@link U1PlaylistCreateListener} class for convenience.
64+ */
65+ public void createPlaylist(String name, List<String> songIdList,
66+ U1PlaylistCreateRequestListener callback) {
67 callback.onStart();
68- String path;
69- if (playlistId != null) {
70- path = resourceClient.getPath(PLAYLISTS, playlistId);
71- } else {
72- path = resourceClient.getPath(PLAYLISTS);
73- }
74+ String path = resourceClient.getPath(PLAYLISTS);
75 HttpResponse response = null;
76 try {
77- String data = U1CustomJson.toPlaylistJson(name, songIds);
78+ String data = U1CustomJson.toPlaylistJson(name, songIdList);
79 response = resourceClient.request(HttpPost.METHOD_NAME, path, null, data);
80 final int statusCode = getStatusCode(response);
81- if (statusCode == HttpStatus.SC_OK) {
82- U1SongJson.fromJson(getContentInputStream(response), callback);
83+ if (statusCode == HttpStatus.SC_CREATED) {
84+ U1PlaylistJson.fromPlaylistCreateResponse(getContentInputStream(response), callback);
85 } else {
86 handleHttpResponse(response, "Could not create playlist.", callback);
87 }
88@@ -436,6 +437,72 @@
89 }
90 }
91
92+ /**
93+ * Updates a playlist. One of name or songIdList is required.
94+ *
95+ * @param playlistId
96+ * The playlist id of the playlist to be updated.
97+ * @param name
98+ * New playlist name. Optional if songIdList provided.
99+ * @param songIdList
100+ * New playlist content. Optional if name provided.
101+ * @param callback
102+ * {@link U1RequestListener} result callback. Use
103+ * {@link U1CallbackListener} class for convenience.
104+ */
105+ public void updatePlaylist(String playlistId, String name,
106+ ArrayList<String> songIdList, U1RequestListener callback) {
107+ if (playlistId == null) {
108+ throw new IllegalArgumentException("null playlistId passed to updatePlaylist");
109+ }
110+
111+ callback.onStart();
112+ String path = resourceClient.getPath(PLAYLISTS, playlistId);
113+ HttpResponse response = null;
114+ try {
115+ String data = U1CustomJson.toPlaylistJson(name, songIdList);
116+ response = resourceClient.request(HttpPut.METHOD_NAME, path, null, data);
117+ final int statusCode = getStatusCode(response);
118+ if (statusCode == HttpStatus.SC_OK) {
119+ callback.onSuccess();
120+ } else {
121+ handleHttpResponse(response, "Could not update playlist.", callback);
122+ }
123+ } catch (JsonParseException jpe) {
124+ // Received corrupt JSON. At this stage, response != null
125+ final String bzrRev = getHeaderValue(ResponseHeader.X_BZR_REVISION_NUMBER, response);
126+ final String date = getHeaderValue(ResponseHeader.DATE, response);
127+
128+ callback.onFailure(new Failure("Could not update playlist. Corrupt JSON.",
129+ jpe, 0, null, bzrRev, date));
130+ } catch (OutOfMemoryError e) {
131+ callback.onFailure(new Failure("Out of memory!", e));
132+ throw e; // We're not expected to recover from this.
133+ } catch (SSLException sslException) {
134+ callback.onFailure(new Failure("SSL connection problem. This may be intermittent issue, " +
135+ "please try again later.", sslException));
136+ } catch (IOException ioException) {
137+ // Failed to read the response.
138+ callback.onFailure(new Failure("Could not update playlist (network error).", ioException));
139+ } catch (URISyntaxException uriSyntaxException) {
140+ // Failed due to invalid URL within the library code.
141+ throw new IllegalStateException(uriSyntaxException);
142+ } catch (AuthorizerException signingException) {
143+ callback.onFailure(new Failure("Could not update playlist (signing exception).", signingException));
144+ } finally {
145+ callback.onFinish();
146+ }
147+ }
148+
149+ /**
150+ * Deletes a playlist.
151+ *
152+ * @param playlistId
153+ * The playlist id of the playlist to be deleted.
154+ * @param callback
155+ * {@link U1RequestListener} result callback. Use
156+ * {@link U1CallbackListener} class for convenience.
157+ */
158 public void deletePlaylist(String playlistId, U1RequestListener callback) {
159 callback.onStart();
160 String path = resourceClient.getPath(PLAYLISTS, playlistId);
161
162=== modified file 'src/main/com/ubuntuone/api/music/client/ResourceClient.java'
163--- src/main/com/ubuntuone/api/music/client/ResourceClient.java 2012-09-28 02:04:22 +0000
164+++ src/main/com/ubuntuone/api/music/client/ResourceClient.java 2012-11-12 15:33:23 +0000
165@@ -85,7 +85,7 @@
166 throws IOException, SSLException, URISyntaxException, AuthorizerException {
167 final HttpClient httpClient = getHttpClient();
168 String query = null;
169- if (params != null) {
170+ if (params != null && HttpPut.METHOD_NAME.equals(method)) {
171 query = URLEncodedUtils.format(params, UTF8);
172 }
173 final URI uri = new URI(getHost().getSchemeName(), getHost().getHostName(), path, query, null);
174
175=== modified file 'src/main/com/ubuntuone/api/music/json/U1AlbumJson.java'
176--- src/main/com/ubuntuone/api/music/json/U1AlbumJson.java 2012-11-12 15:33:22 +0000
177+++ src/main/com/ubuntuone/api/music/json/U1AlbumJson.java 2012-11-12 15:33:23 +0000
178@@ -49,6 +49,7 @@
179 g.writeStringField("id", album.getId());
180 g.writeStringField("album_url", album.getAlbumUrl());
181 g.writeStringField("artist", album.getArtist());
182+ g.writeStringField("artist_id", album.getArtistId());
183 g.writeStringField("title", album.getTitle());
184 g.writeNumberField("parsed_date", album.getParsedDate());
185 g.writeStringField("album_art_url", album.getAlbumArtUrl());
186@@ -72,6 +73,7 @@
187 String id = null;
188 String albumUrl = null;
189 String artist = null;
190+ String artistId = null;
191 String title = null;
192 Long parsedDate = null;
193 String albumArtUrl = null;
194@@ -91,6 +93,8 @@
195 albumUrl = jp.getText();
196 } else if ("artist".equals(field)) {
197 artist = jp.getText();
198+ } else if ("artist_id".equals(field)) {
199+ artistId = jp.getText();
200 } else if ("title".equals(field)) {
201 title = jp.getText();
202 } else if ("parsed_date".equals(field)) {
203@@ -114,8 +118,8 @@
204 }
205 }
206
207- U1Album album = new U1Album(id, albumUrl, artist, title, parsedDate,
208- albumArtUrl, year);
209+ U1Album album = new U1Album(id, albumUrl, artist, artistId, title,
210+ parsedDate, albumArtUrl, year);
211
212 callback.onSuccess(album);
213 }
214
215=== modified file 'src/main/com/ubuntuone/api/music/json/U1ArtistJson.java'
216--- src/main/com/ubuntuone/api/music/json/U1ArtistJson.java 2012-11-12 15:33:22 +0000
217+++ src/main/com/ubuntuone/api/music/json/U1ArtistJson.java 2012-11-12 15:33:23 +0000
218@@ -51,8 +51,8 @@
219 g.writeStringField("artist_url", artist.getArtistUrl());
220 g.writeStringField("artist", artist.getArtist());
221 g.writeStringField("artist_art_url", artist.getArtistArtUrl());
222- g.writeArrayFieldStart("album_list");
223- ArrayList<String> albumList = artist.getAlbumList();
224+ g.writeArrayFieldStart("album_ids");
225+ ArrayList<String> albumList = artist.getAlbumIds();
226 for (String albumId : albumList) {
227 g.writeString(albumId);
228 }
229@@ -97,7 +97,7 @@
230 artist = jp.getText();
231 } else if ("artist_art_url".equals(field)) {
232 artistArtUrl = jp.getText();
233- } else if ("album_list".equals(field)) {
234+ } else if ("album_ids".equals(field)) {
235 albumList = new ArrayList<String>();
236 while (JsonToken.END_ARRAY != jp.nextToken()) {
237 String albumId = jp.getText();
238
239=== modified file 'src/main/com/ubuntuone/api/music/json/U1CustomJson.java'
240--- src/main/com/ubuntuone/api/music/json/U1CustomJson.java 2012-11-12 15:33:22 +0000
241+++ src/main/com/ubuntuone/api/music/json/U1CustomJson.java 2012-11-12 15:33:23 +0000
242@@ -23,7 +23,7 @@
243
244 import java.io.IOException;
245 import java.io.StringWriter;
246-import java.util.ArrayList;
247+import java.util.List;
248
249 import org.codehaus.jackson.JsonFactory;
250 import org.codehaus.jackson.JsonGenerator;
251@@ -42,8 +42,8 @@
252 * @throws IOException
253 * If JSON generation fails with IOException.
254 */
255- public static String toPlaylistJson(String name,
256- ArrayList<String> songIdList) throws IOException {
257+ public static String toPlaylistJson(String name, List<String> songIdList)
258+ throws IOException {
259 final JsonFactory factory = new JsonFactory();
260 final StringWriter writer = new StringWriter(128);
261 final JsonGenerator g = factory.createJsonGenerator(writer);
262
263=== modified file 'src/main/com/ubuntuone/api/music/json/U1PlaylistJson.java'
264--- src/main/com/ubuntuone/api/music/json/U1PlaylistJson.java 2012-11-12 15:33:22 +0000
265+++ src/main/com/ubuntuone/api/music/json/U1PlaylistJson.java 2012-11-12 15:33:23 +0000
266@@ -35,6 +35,7 @@
267
268 import com.ubuntuone.api.music.U1MusicAPI;
269 import com.ubuntuone.api.music.model.U1Playlist;
270+import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistCreateRequestListener;
271 import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistRequestListener;
272
273 public class U1PlaylistJson
274@@ -106,4 +107,25 @@
275 }
276 jp.close();
277 }
278+
279+ public static void fromPlaylistCreateResponse(InputStream stream,
280+ U1PlaylistCreateRequestListener callback) throws JsonParseException,
281+ IOException {
282+ final JsonFactory factory = new JsonFactory();
283+ final JsonParser jp = factory.createJsonParser(stream);
284+
285+ U1MetaJsonPreprocessor.getResponseMeta(jp);
286+ jp.nextToken(); // playlist id
287+ jp.nextValue();
288+
289+ final String field = jp.getCurrentName();
290+ if ("id".equals(field)) {
291+ String id = jp.getText();
292+ callback.onSuccess(id);
293+ } else {
294+ logger.warning("Unexpected JSON field: " + field);
295+ }
296+
297+ jp.close();
298+ }
299 }
300
301=== modified file 'src/main/com/ubuntuone/api/music/json/U1SongJson.java'
302--- src/main/com/ubuntuone/api/music/json/U1SongJson.java 2012-11-12 15:33:22 +0000
303+++ src/main/com/ubuntuone/api/music/json/U1SongJson.java 2012-11-12 15:33:23 +0000
304@@ -60,6 +60,7 @@
305 g.writeNumberField("size", song.getSize());
306 g.writeNumberField("bit_rate", song.getBitRate());
307 g.writeStringField("artist", song.getArtist());
308+ g.writeStringField("artist_id", song.getArtistId());
309 g.writeStringField("title", song.getTitle());
310 g.writeStringField("suffix", song.getSuffix());
311 g.writeStringField("content_type", song.getContentType());
312@@ -100,6 +101,7 @@
313 Integer size = null;
314 Integer bitRate = null;
315 String artist = null;
316+ String artistId = null;
317 String title = null;
318 String suffix = null;
319 String contentType = null;
320@@ -122,6 +124,9 @@
321 albumId = jp.getText();
322 } else if ("album_artist".equals(field)) {
323 albumArtist = jp.getText();
324+ } else if ("album_artist_id".equals(field)) {
325+ // Ignore.
326+ continue;
327 } else if ("album".equals(field)) {
328 album = jp.getText();
329 } else if ("song_art_url".equals(field)) {
330@@ -166,6 +171,8 @@
331 }
332 } else if ("artist".equals(field)) {
333 artist = jp.getText();
334+ } else if ("artist_id".equals(field)) {
335+ artistId = jp.getText();
336 } else if ("title".equals(field)) {
337 title = jp.getText();
338 } else if ("suffix".equals(field)) {
339@@ -185,7 +192,8 @@
340
341 U1Song song = new U1Song(id, songUrl, albumId, albumArtist, album,
342 songArtUrl, genre, year, discNumber, track, duration, size,
343- bitRate, artist, title, suffix, contentType, songStreamUrl, path);
344+ bitRate, artist, artistId, title, suffix, contentType,
345+ songStreamUrl, path);
346
347 callback.onSuccess(song);
348 }
349
350=== modified file 'src/main/com/ubuntuone/api/music/model/U1Album.java'
351--- src/main/com/ubuntuone/api/music/model/U1Album.java 2012-09-04 20:27:21 +0000
352+++ src/main/com/ubuntuone/api/music/model/U1Album.java 2012-11-12 15:33:23 +0000
353@@ -42,6 +42,8 @@
354
355 /** Album artist. */
356 private final String artist;
357+ /** Album artist id. */
358+ private final String artistId;
359 /** Album title. */
360 private final String title;
361 /** Timestamp when the album was parsed. */
362
363=== modified file 'src/main/com/ubuntuone/api/music/model/U1Artist.java'
364--- src/main/com/ubuntuone/api/music/model/U1Artist.java 2012-09-04 19:28:22 +0000
365+++ src/main/com/ubuntuone/api/music/model/U1Artist.java 2012-11-12 15:33:23 +0000
366@@ -46,7 +46,7 @@
367 /** Artist art URL. */
368 private final String artistArtUrl;
369 /** Artist album id list. */
370- private final ArrayList<String> albumList;
371+ private final ArrayList<String> albumIds;
372 /** Artist total song count. */
373 private final Integer songCount;
374
375
376=== modified file 'src/main/com/ubuntuone/api/music/model/U1Song.java'
377--- src/main/com/ubuntuone/api/music/model/U1Song.java 2012-08-27 17:20:36 +0000
378+++ src/main/com/ubuntuone/api/music/model/U1Song.java 2012-11-12 15:33:23 +0000
379@@ -65,6 +65,8 @@
380 private final Integer bitRate;
381 /** Track artist. */
382 private final String artist;
383+ /** Track artist id. */
384+ private final String artistId;
385 /** Track title. */
386 private final String title;
387
388
389=== added file 'src/main/com/ubuntuone/api/music/request/U1PlaylistCreateListener.java'
390--- src/main/com/ubuntuone/api/music/request/U1PlaylistCreateListener.java 1970-01-01 00:00:00 +0000
391+++ src/main/com/ubuntuone/api/music/request/U1PlaylistCreateListener.java 2012-11-12 15:33:23 +0000
392@@ -0,0 +1,44 @@
393+/*
394+ * Ubuntu One Music Java library - communicate with Ubuntu One music API
395+ *
396+ * Copyright 2012 Canonical Ltd.
397+ *
398+ * This file is part of Ubuntu One Files Java library.
399+ *
400+ * This program is free software: you can redistribute it and/or modify
401+ * it under the terms of the GNU Affero General Public License as
402+ * published by the Free Software Foundation, either version 3 of the
403+ * License, or (at your option) any later version.
404+ *
405+ * This program is distributed in the hope that it will be useful,
406+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
407+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
408+ * GNU Affero General Public License for more details.
409+ *
410+ * You should have received a copy of the GNU Affero General Public License
411+ * along with this program. If not, see http://www.gnu.org/licenses
412+ */
413+
414+package com.ubuntuone.api.music.request;
415+
416+import com.ubuntuone.api.music.client.Failure;
417+import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistCreateRequestListener;
418+
419+public abstract class U1PlaylistCreateListener
420+ implements U1PlaylistCreateRequestListener
421+{
422+ @Override
423+ public void onStart() {
424+ }
425+
426+ @Override
427+ public abstract void onSuccess(String playlistId);
428+
429+ @Override
430+ public void onFailure(Failure failure) {
431+ }
432+
433+ @Override
434+ public void onFinish() {
435+ }
436+}
437
438=== modified file 'src/main/com/ubuntuone/api/music/util/ResultRequestListener.java'
439--- src/main/com/ubuntuone/api/music/util/ResultRequestListener.java 2012-11-12 15:33:22 +0000
440+++ src/main/com/ubuntuone/api/music/util/ResultRequestListener.java 2012-11-12 15:33:23 +0000
441@@ -60,7 +60,7 @@
442 public interface U1SongRequestListener extends ResultRequestListener<U1Song> {};
443
444 public interface U1PlaylistRequestListener extends ResultRequestListener<U1Playlist> {};
445- public interface U1PlaylistSongRequestListener extends ResultRequestListener<U1Song> {};
446+ public interface U1PlaylistCreateRequestListener extends ResultRequestListener<String> {};
447
448 public interface U1ArtRequestListener extends ResultRequestListener<File> {};
449 public interface U1StreamRequestListener extends ResultRequestListener<InputStream> {};
450
451=== modified file 'src/test/com/ubuntuone/api/music/CreatePlaylistTest.java'
452--- src/test/com/ubuntuone/api/music/CreatePlaylistTest.java 2012-11-12 15:33:22 +0000
453+++ src/test/com/ubuntuone/api/music/CreatePlaylistTest.java 2012-11-12 15:33:23 +0000
454@@ -22,6 +22,7 @@
455 package com.ubuntuone.api.music;
456
457 import static com.ubuntuone.test.util.SameHttpRequestMatcher.sameRequest;
458+import static com.ubuntuone.test.util.SameStatusCodeFailureMatcher.sameStatusCodeFailure;
459
460 import java.io.IOException;
461 import java.util.ArrayList;
462@@ -47,10 +48,8 @@
463 import com.ubuntuone.api.music.client.Failure;
464 import com.ubuntuone.api.music.json.U1CustomJson;
465 import com.ubuntuone.api.music.model.U1Meta;
466-import com.ubuntuone.api.music.model.U1Song;
467-import com.ubuntuone.api.music.util.ResultRequestListener.U1SongRequestListener;
468+import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistCreateRequestListener;
469 import com.ubuntuone.music.util.U1ResponseBuilder;
470-import com.ubuntuone.music.util.U1SongBuilder;
471 import com.ubuntuone.music.util.Util;
472 import com.ubuntuone.test.util.DummyAuthorizer;
473
474@@ -67,18 +66,18 @@
475 private HttpClient httpClient;
476 private U1MusicAPI musicApi;
477
478- private U1SongRequestListener songCallback;
479+ private U1PlaylistCreateRequestListener callback;
480
481 @Before
482 public void setUp() throws IOException {
483 Logger.getLogger(U1MusicAPI.LOGGER_NAME).setLevel(Level.OFF);
484
485- httpResponse = Util.buildResponse(HttpStatus.SC_OK);
486+ httpResponse = Util.buildResponse(HttpStatus.SC_CREATED);
487
488 httpClient = context.mock(HttpClient.class);
489 musicApi = new U1MusicAPI("ua/1.0", httpClient, new DummyAuthorizer());
490
491- songCallback = context.mock(U1SongRequestListener.class);
492+ callback = context.mock(U1PlaylistCreateRequestListener.class);
493 }
494
495 @Test
496@@ -88,123 +87,79 @@
497
498 final Sequence requestSequence = context.sequence("lifecycle");
499 context.checking(new Expectations() {{
500- oneOf(songCallback).onStart();
501+ oneOf(callback).onStart();
502 inSequence(requestSequence);
503
504 ignoring(httpClient);
505- allowing(songCallback).onSuccess(with(any(U1Song.class)));
506- allowing(songCallback).onFailure(with(any(Failure.class)));
507+ allowing(callback).onSuccess(with(any(String.class)));
508+ allowing(callback).onFailure(with(any(Failure.class)));
509
510- oneOf(songCallback).onFinish();
511+ oneOf(callback).onFinish();
512 inSequence(requestSequence);
513 }});
514
515- musicApi.createPlaylist(name, songIdList, songCallback);
516+ musicApi.createPlaylist(name, songIdList, callback);
517 }
518
519 @Test
520 public void testCreatePlaylist() throws IOException {
521- final U1Meta meta = new U1Meta();
522- String id = "playlistId";
523 String name = "playlist name";
524 ArrayList<String> songIdList = new ArrayList<String>();
525-
526- final U1Song song1 = new U1SongBuilder()
527- .withId("songId1").withAlbumId("Song album 1").build();
528- songIdList.add(song1.getId());
529-
530- final U1Song song2 = new U1SongBuilder()
531- .withId("songId2").withAlbumId("Song album 2").build();
532- songIdList.add(song2.getId());
533-
534- final U1Song song3 = new U1SongBuilder()
535- .withId("songId3").withAlbumId("Song album 3").build();
536- songIdList.add(song3.getId());
537-
538+ final U1Meta meta = new U1Meta();
539+ final String playlistId = "playlistId";
540+
541 final HttpPost httpRequest = new HttpPost("https://one.ubuntu.com" +
542 "/api/music/v2/playlists/");
543-
544 httpRequest.setEntity(new StringEntity(U1CustomJson
545 .toPlaylistJson(name, songIdList)));
546
547- String responseJson = U1ResponseBuilder.toJson(
548- meta, U1MusicAPI.SONGS, id, name, song1, song2, song3);
549-
550+ String responseJson = U1ResponseBuilder.toPlaylistCreatedJson(meta, playlistId);
551 httpResponse.setEntity(new StringEntity(responseJson, "UTF-8"));
552
553 final Sequence requestSequence = context.sequence("lifecycle");
554 context.checking(new Expectations() {{
555- oneOf(songCallback).onStart();
556+ oneOf(callback).onStart();
557 inSequence(requestSequence);
558
559 oneOf(httpClient).execute(with(httpHost), with(sameRequest(httpRequest)));
560 inSequence(requestSequence);
561 will(returnValue(httpResponse));
562-
563- oneOf(songCallback).onSuccess(with(song1));
564- inSequence(requestSequence);
565- oneOf(songCallback).onSuccess(with(song2));
566- inSequence(requestSequence);
567- oneOf(songCallback).onSuccess(with(song3));
568- inSequence(requestSequence);
569-
570- oneOf(songCallback).onFinish();
571+
572+ oneOf(callback).onSuccess(playlistId);
573+ inSequence(requestSequence);
574+
575+ oneOf(callback).onFinish();
576 inSequence(requestSequence);
577 }});
578
579- musicApi.createPlaylist(name, songIdList, songCallback);
580+ musicApi.createPlaylist(name, songIdList, callback);
581 }
582
583 @Test
584- public void testUpdatePlaylist() throws IOException {
585- final U1Meta meta = new U1Meta();
586- String id = "playlistId";
587- String name = "playlist name";
588- ArrayList<String> songIdList = new ArrayList<String>();
589-
590- final U1Song song1 = new U1SongBuilder()
591- .withId("songId1").withAlbumId("Song album 1").build();
592- songIdList.add(song1.getId());
593-
594- final U1Song song2 = new U1SongBuilder()
595- .withId("songId2").withAlbumId("Song album 2").build();
596- songIdList.add(song2.getId());
597-
598- final U1Song song3 = new U1SongBuilder()
599- .withId("songId3").withAlbumId("Song album 3").build();
600- songIdList.add(song3.getId());
601-
602+ public void testNoArgCreatePlaylistFailure() throws IOException {
603 final HttpPost httpRequest = new HttpPost("https://one.ubuntu.com" +
604 "/api/music/v2/playlists/");
605-
606- httpRequest.setEntity(new StringEntity(U1CustomJson
607- .toPlaylistJson(name, songIdList)));
608-
609- String responseJson = U1ResponseBuilder.toJson(
610- meta, U1MusicAPI.SONGS, id, name, song1, song2, song3);
611-
612- httpResponse.setEntity(new StringEntity(responseJson, "UTF-8"));
613+ httpRequest.setEntity(
614+ new StringEntity(U1CustomJson.toPlaylistJson(null, null)));
615+
616+ httpResponse = Util.buildResponse(HttpStatus.SC_FORBIDDEN);
617
618 final Sequence requestSequence = context.sequence("lifecycle");
619 context.checking(new Expectations() {{
620- oneOf(songCallback).onStart();
621+ oneOf(callback).onStart();
622 inSequence(requestSequence);
623
624 oneOf(httpClient).execute(with(httpHost), with(sameRequest(httpRequest)));
625 inSequence(requestSequence);
626 will(returnValue(httpResponse));
627
628- oneOf(songCallback).onSuccess(with(song1));
629- inSequence(requestSequence);
630- oneOf(songCallback).onSuccess(with(song2));
631- inSequence(requestSequence);
632- oneOf(songCallback).onSuccess(with(song3));
633- inSequence(requestSequence);
634-
635- oneOf(songCallback).onFinish();
636+ oneOf(callback).onFailure(with(sameStatusCodeFailure(
637+ new Failure("", HttpStatus.SC_FORBIDDEN))));
638+
639+ oneOf(callback).onFinish();
640 inSequence(requestSequence);
641 }});
642
643- musicApi.createPlaylist(name, songIdList, songCallback);
644+ musicApi.createPlaylist(null, null, callback);
645 }
646 }
647
648=== modified file 'src/test/com/ubuntuone/api/music/UpdatePlaylistTest.java'
649--- src/test/com/ubuntuone/api/music/UpdatePlaylistTest.java 2012-11-12 15:33:22 +0000
650+++ src/test/com/ubuntuone/api/music/UpdatePlaylistTest.java 2012-11-12 15:33:23 +0000
651@@ -22,6 +22,7 @@
652 package com.ubuntuone.api.music;
653
654 import static com.ubuntuone.test.util.SameHttpRequestMatcher.sameRequest;
655+import static com.ubuntuone.test.util.SameStatusCodeFailureMatcher.sameStatusCodeFailure;
656
657 import java.io.IOException;
658 import java.util.ArrayList;
659@@ -32,7 +33,7 @@
660 import org.apache.http.HttpResponse;
661 import org.apache.http.HttpStatus;
662 import org.apache.http.client.HttpClient;
663-import org.apache.http.client.methods.HttpPost;
664+import org.apache.http.client.methods.HttpPut;
665 import org.apache.http.entity.StringEntity;
666 import org.jmock.Expectations;
667 import org.jmock.Mockery;
668@@ -48,7 +49,7 @@
669 import com.ubuntuone.api.music.json.U1CustomJson;
670 import com.ubuntuone.api.music.model.U1Meta;
671 import com.ubuntuone.api.music.model.U1Song;
672-import com.ubuntuone.api.music.util.ResultRequestListener.U1SongRequestListener;
673+import com.ubuntuone.api.music.util.RequestListener.U1RequestListener;
674 import com.ubuntuone.music.util.U1ResponseBuilder;
675 import com.ubuntuone.music.util.U1SongBuilder;
676 import com.ubuntuone.music.util.Util;
677@@ -67,7 +68,7 @@
678 private HttpClient httpClient;
679 private U1MusicAPI musicApi;
680
681- private U1SongRequestListener songCallback;
682+ private U1RequestListener callback;
683
684 @Before
685 public void setUp() throws IOException {
686@@ -78,34 +79,35 @@
687 httpClient = context.mock(HttpClient.class);
688 musicApi = new U1MusicAPI("ua/1.0", httpClient, new DummyAuthorizer());
689
690- songCallback = context.mock(U1SongRequestListener.class);
691+ callback = context.mock(U1RequestListener.class);
692 }
693
694 @Test
695- public void testCreatePlaylistLifeCycleCallbacks() {
696+ public void testUpdatePlaylistLifeCycleCallbacks() {
697+ String playlistId = "playlist-id";
698 String name = "playlist name";
699 ArrayList<String> songIdList = new ArrayList<String>();
700
701 final Sequence requestSequence = context.sequence("lifecycle");
702 context.checking(new Expectations() {{
703- oneOf(songCallback).onStart();
704+ oneOf(callback).onStart();
705 inSequence(requestSequence);
706
707 ignoring(httpClient);
708- allowing(songCallback).onSuccess(with(any(U1Song.class)));
709- allowing(songCallback).onFailure(with(any(Failure.class)));
710+ allowing(callback).onSuccess();
711+ allowing(callback).onFailure(with(any(Failure.class)));
712
713- oneOf(songCallback).onFinish();
714+ oneOf(callback).onFinish();
715 inSequence(requestSequence);
716 }});
717
718- musicApi.createPlaylist(name, songIdList, songCallback);
719+ musicApi.updatePlaylist(playlistId, name, songIdList, callback);
720 }
721
722 @Test
723- public void testCreatePlaylist() throws IOException {
724+ public void testUpdatePlaylist() throws IOException {
725 final U1Meta meta = new U1Meta();
726- String id = "playlistId";
727+ String playlistId = "playlist-id";
728 String name = "playlist name";
729 ArrayList<String> songList = new ArrayList<String>();
730
731@@ -121,37 +123,67 @@
732 .withId("songId3").withAlbumId("Song album 3").build();
733 songList.add(song3.getId());
734
735- final HttpPost httpRequest = new HttpPost("https://one.ubuntu.com" +
736- "/api/music/v2/playlists/");
737-
738- httpRequest.setEntity(new StringEntity(U1CustomJson
739- .toPlaylistJson(name, songList)));
740-
741- String responseJson = U1ResponseBuilder.toJson(
742- meta, U1MusicAPI.SONGS, id, name, song1, song2, song3);
743-
744- httpResponse.setEntity(new StringEntity(responseJson, "UTF-8"));
745-
746- final Sequence requestSequence = context.sequence("lifecycle");
747- context.checking(new Expectations() {{
748- oneOf(songCallback).onStart();
749- inSequence(requestSequence);
750-
751- oneOf(httpClient).execute(with(httpHost), with(sameRequest(httpRequest)));
752- inSequence(requestSequence);
753- will(returnValue(httpResponse));
754-
755- oneOf(songCallback).onSuccess(with(song1));
756- inSequence(requestSequence);
757- oneOf(songCallback).onSuccess(with(song2));
758- inSequence(requestSequence);
759- oneOf(songCallback).onSuccess(with(song3));
760- inSequence(requestSequence);
761-
762- oneOf(songCallback).onFinish();
763- inSequence(requestSequence);
764- }});
765-
766- musicApi.createPlaylist(name, songList, songCallback);
767+ final HttpPut httpRequest = new HttpPut("https://one.ubuntu.com" +
768+ "/api/music/v2/playlists/" + playlistId + "/");
769+
770+ httpRequest.setEntity(new StringEntity(U1CustomJson
771+ .toPlaylistJson(name, songList)));
772+
773+ String responseJson = U1ResponseBuilder.toPlaylistUpdatedJSON(meta);
774+ httpResponse.setEntity(new StringEntity(responseJson, "UTF-8"));
775+
776+ final Sequence requestSequence = context.sequence("lifecycle");
777+ context.checking(new Expectations() {{
778+ oneOf(callback).onStart();
779+ inSequence(requestSequence);
780+
781+ oneOf(httpClient).execute(with(httpHost), with(sameRequest(httpRequest)));
782+ inSequence(requestSequence);
783+ will(returnValue(httpResponse));
784+
785+ oneOf(callback).onSuccess();
786+ inSequence(requestSequence);
787+
788+ oneOf(callback).onFinish();
789+ inSequence(requestSequence);
790+ }});
791+
792+ musicApi.updatePlaylist(playlistId, name, songList, callback);
793+ }
794+
795+ @Test
796+ public void testNoArgsUpdatePlaylistFailure() throws IOException {
797+ final U1Meta meta = new U1Meta();
798+ String playlistId = "playlist-id";
799+ String name = null;
800+ ArrayList<String> songList = null;
801+
802+ final HttpPut httpRequest = new HttpPut("https://one.ubuntu.com" +
803+ "/api/music/v2/playlists/" + playlistId + "/");
804+
805+ httpRequest.setEntity(new StringEntity(U1CustomJson
806+ .toPlaylistJson(name, songList)));
807+
808+ String responseJson = U1ResponseBuilder.toPlaylistUpdatedJSON(meta);
809+ httpResponse = Util.buildResponse(HttpStatus.SC_FORBIDDEN);
810+ httpResponse.setEntity(new StringEntity(responseJson, "UTF-8"));
811+
812+ final Sequence requestSequence = context.sequence("lifecycle");
813+ context.checking(new Expectations() {{
814+ oneOf(callback).onStart();
815+ inSequence(requestSequence);
816+
817+ oneOf(httpClient).execute(with(httpHost), with(sameRequest(httpRequest)));
818+ inSequence(requestSequence);
819+ will(returnValue(httpResponse));
820+
821+ oneOf(callback).onFailure(with(sameStatusCodeFailure(
822+ new Failure("", HttpStatus.SC_FORBIDDEN))));
823+
824+ oneOf(callback).onFinish();
825+ inSequence(requestSequence);
826+ }});
827+
828+ musicApi.updatePlaylist(playlistId, name, songList, callback);
829 }
830 }
831
832=== modified file 'src/test/com/ubuntuone/api/music/json/U1PlaylistJsonTest.java'
833--- src/test/com/ubuntuone/api/music/json/U1PlaylistJsonTest.java 2012-11-12 15:33:22 +0000
834+++ src/test/com/ubuntuone/api/music/json/U1PlaylistJsonTest.java 2012-11-12 15:33:23 +0000
835@@ -35,6 +35,7 @@
836 import com.ubuntuone.api.music.U1MusicAPI;
837 import com.ubuntuone.api.music.model.U1Meta;
838 import com.ubuntuone.api.music.model.U1Playlist;
839+import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistCreateRequestListener;
840 import com.ubuntuone.api.music.util.ResultRequestListener.U1PlaylistRequestListener;
841 import com.ubuntuone.music.util.U1PlaylistBuilder;
842 import com.ubuntuone.music.util.U1ResponseBuilder;
843@@ -61,4 +62,22 @@
844
845 U1PlaylistJson.fromJson(stream, callback);
846 }
847+
848+ @Test
849+ public void testFromPlaylistCreateResponse() throws IOException {
850+ final U1Meta meta = new U1Meta();
851+ final String playlistId = "playlist-id";
852+
853+ String responseJson = U1ResponseBuilder
854+ .toPlaylistCreatedJson(meta, playlistId);
855+ InputStream stream = new ByteArrayInputStream(responseJson.getBytes());
856+ final U1PlaylistCreateRequestListener callback =
857+ context.mock(U1PlaylistCreateRequestListener.class);
858+
859+ context.checking(new Expectations() {{
860+ oneOf(callback).onSuccess(playlistId);
861+ }});
862+
863+ U1PlaylistJson.fromPlaylistCreateResponse(stream, callback);
864+ }
865 }
866
867=== modified file 'src/test/com/ubuntuone/music/util/U1AlbumBuilder.java'
868--- src/test/com/ubuntuone/music/util/U1AlbumBuilder.java 2012-09-28 01:45:13 +0000
869+++ src/test/com/ubuntuone/music/util/U1AlbumBuilder.java 2012-11-12 15:33:23 +0000
870@@ -25,7 +25,7 @@
871
872 public class U1AlbumBuilder
873 {
874- private String id = "1b861a8cbb0f52e99dd44054c6feb52b";
875+ private String id = "62ef37486875acd62e0ed346c4c38312";
876
877 private String albumUrl = String.format(ALBUM_URL_FMT, id);
878 private static final String ALBUM_URL_FMT =
879@@ -33,6 +33,8 @@
880
881 private String artist = "Default Artist";
882
883+ private String artistId = "52d53fd75b9907bf765d39c56330c587";
884+
885 private String title = "Default Title";
886
887 private Long parsedDate = 1327937958L;
888@@ -50,6 +52,7 @@
889 id = builder.id;
890 albumUrl = builder.albumUrl;
891 artist = builder.artist;
892+ artistId = builder.artistId;
893 title = builder.title;
894 parsedDate = builder.parsedDate;
895 albumArtUrl = builder.albumArtUrl;
896@@ -89,8 +92,8 @@
897 }
898
899 public U1Album build() {
900- U1Album album = new U1Album(id, albumUrl, artist, title, parsedDate,
901- albumArtUrl, year);
902+ U1Album album = new U1Album(id, albumUrl, artist, artistId, title,
903+ parsedDate, albumArtUrl, year);
904 return album;
905 }
906 }
907
908=== modified file 'src/test/com/ubuntuone/music/util/U1ArtistBuilder.java'
909--- src/test/com/ubuntuone/music/util/U1ArtistBuilder.java 2012-09-28 01:45:13 +0000
910+++ src/test/com/ubuntuone/music/util/U1ArtistBuilder.java 2012-11-12 15:33:23 +0000
911@@ -27,7 +27,7 @@
912
913 public class U1ArtistBuilder
914 {
915- private String id = "a5c59c0315098e6d67bb57610f7fb9b1";
916+ private String id = "0441f9e2d94c39a70e21b83829259aa4";
917
918 private String artistUrl = String.format(ARTIST_URL_FMT, id);
919 private static final String ARTIST_URL_FMT =
920
921=== modified file 'src/test/com/ubuntuone/music/util/U1ResponseBuilder.java'
922--- src/test/com/ubuntuone/music/util/U1ResponseBuilder.java 2012-11-12 15:33:22 +0000
923+++ src/test/com/ubuntuone/music/util/U1ResponseBuilder.java 2012-11-12 15:33:23 +0000
924@@ -43,7 +43,7 @@
925 return toJson(meta, title, null, null, items);
926 }
927
928- public static String toJson(U1Meta meta, String title,
929+ public static String toJson(U1Meta meta, String type,
930 String playlistId, String name, JSONString... items)
931 throws JsonGenerationException, IOException {
932 final JsonFactory factory = new JsonFactory();
933@@ -58,7 +58,7 @@
934 g.writeEndObject();
935
936 g.writeObjectFieldStart(RESPONSE); {
937- g.writeArrayFieldStart(title);
938+ g.writeArrayFieldStart(type);
939 if (items != null) {
940 for (JSONString item : items) {
941 g.writeRawValue(item.toJSONString());
942@@ -74,4 +74,51 @@
943
944 return writer.toString();
945 }
946+
947+ public static String toPlaylistCreatedJson(U1Meta meta, String playlistId)
948+ throws JsonGenerationException, IOException {
949+ final JsonFactory factory = new JsonFactory();
950+ final StringWriter writer = new StringWriter(128);
951+ final JsonGenerator g = factory.createJsonGenerator(writer);
952+
953+ g.writeStartObject(); {
954+ g.writeObjectFieldStart(META); {
955+ g.writeNumberField(STATUS, meta.getStatus());
956+ g.writeStringField(MSG, meta.getMessage());
957+ }
958+ g.writeEndObject();
959+
960+ g.writeObjectFieldStart(RESPONSE); {
961+ g.writeStringField("id", playlistId);
962+ }
963+ g.writeEndObject();
964+
965+ }
966+ g.writeEndObject();
967+ g.close();
968+
969+ return writer.toString();
970+ }
971+
972+ public static String toPlaylistUpdatedJSON(U1Meta meta)
973+ throws JsonGenerationException, IOException {
974+ final JsonFactory factory = new JsonFactory();
975+ final StringWriter writer = new StringWriter(128);
976+ final JsonGenerator g = factory.createJsonGenerator(writer);
977+
978+ g.writeStartObject(); {
979+ g.writeObjectFieldStart(META); {
980+ g.writeNumberField(STATUS, meta.getStatus());
981+ g.writeStringField(MSG, meta.getMessage());
982+ }
983+ g.writeEndObject();
984+
985+ g.writeObjectFieldStart(RESPONSE);
986+ g.writeEndObject();
987+ }
988+ g.writeEndObject();
989+ g.close();
990+
991+ return writer.toString();
992+ }
993 }
994
995=== modified file 'src/test/com/ubuntuone/music/util/U1SongBuilder.java'
996--- src/test/com/ubuntuone/music/util/U1SongBuilder.java 2012-09-28 01:45:13 +0000
997+++ src/test/com/ubuntuone/music/util/U1SongBuilder.java 2012-11-12 15:33:23 +0000
998@@ -31,7 +31,7 @@
999 private static final String SONG_URL_FMT =
1000 "https://one.ubuntu.com/api/music/v2/songs/%s/";
1001
1002- private String albumId = "cdd9dfe8c9583c60e4c69bc199cb0d7b";
1003+ private String albumId = "62ef37486875acd62e0ed346c4c38312";
1004
1005 private String albumArtist = "Default Artist";
1006
1007@@ -57,6 +57,8 @@
1008
1009 private String artist = "Default Track Artist";
1010
1011+ private String artistId = "52d53fd75b9907bf765d39c56330c587";
1012+
1013 private String title = "Default Track Title";
1014
1015 private String suffix = "mp3";
1016@@ -88,6 +90,7 @@
1017 duration = builder.size;
1018 bitRate = builder.bitRate;
1019 artist = builder.artist;
1020+ artistId = builder.artistId;
1021 title = builder.title;
1022 suffix = builder.suffix;
1023 contentType = builder.contentType;
1024@@ -113,7 +116,8 @@
1025 public U1Song build() {
1026 U1Song song = new U1Song(id, songUrl, albumId, albumArtist, album,
1027 songArtUrl, genre, year, discNumber, track, duration, size,
1028- bitRate, albumArtist, title, suffix, contentType, songStreamUrl, path);
1029+ bitRate, artist, artistId, title, suffix, contentType,
1030+ songStreamUrl, path);
1031 return song;
1032 }
1033 }

Subscribers

People subscribed via source and target branches