TrackLover { public synchronized void loveTrack(Track track) { if (scroballDB.isLoved(track)) { return; } LovedTracksEntry entry = scroballDB.writeLove(track, 0); pending.add(entry); lovePending(); eventBus.post(TrackLovedEvent.create()); } TrackLover(
      LastfmClient lastfmClient, ScroballDB scroballDB, ConnectivityManager connectivityManager); synchronized void loveTrack(Track track); synchronized void lovePending();  }
@Test public void loveTrack_performsNoActionIfAlreadyLoved() { when(scroballDB.isLoved(any())).thenReturn(true); trackLover.loveTrack(track1); verify(scroballDB, never()).writeLove(any(), anyInt()); verifyZeroInteractions(lastfmClient); }
@Test public void loveTrack_writesPendingLoveToDatabase() { trackLover.loveTrack(track1); verify(scroballDB).writeLove(track1, 0); }
@Test public void loveTrack_callsTheApi() { trackLover.loveTrack(track1); verify(lastfmClient).loveTrack(eq(track1), any()); }
@Test public void loveTrack_storesUpdatedStatusOnCompletion() { LastfmClient.Result result = LastfmClient.Result.success(); doAnswer(invocation -> { Handler.Callback callback = invocation.getArgument(1); message.obj = result; callback.handleMessage(message); return null; }).when(lastfmClient).loveTrack(any(), any()); trackLover.loveTrack(track1); verify(entry1).save(); assertThat(entry1.status).isEqualTo(result.errorCode()); }
@Test public void loveTrack_queuesParallelLikeRequests() { List<Handler.Callback> callbacks = new ArrayList<>(); doAnswer(invocation -> { callbacks.add(invocation.getArgument(1)); return null; }).when(lastfmClient).loveTrack(any(), any()); trackLover.loveTrack(track1); trackLover.loveTrack(track2); assertThat(callbacks.size()).isEqualTo(1); verify(lastfmClient).loveTrack(eq(track1), any()); verifyNoMoreInteractions(lastfmClient); message.obj = LastfmClient.Result.success(); callbacks.get(0).handleMessage(message); verify(lastfmClient).loveTrack(eq(track2), any()); }