public void testLoginHappyPath() throws IOException, URISyntaxException {
    RestResponse googleLoginResponse = mock(RestResponse.class);

    // mock the call to login to Google
    when(restClient.doPost(
            Const.USE_HTTPS, HostName.GOOGLE, Path.GOOGLE_LOGIN, null, null, null, loginForm))
        .thenReturn(googleLoginResponse);

    // the response to the initial login to Google will contain the authorization string in the body
    String authToken = "authToken";
    String googleLoginResponseBody = Const.GOOLE_LOGIN_AUTH + authToken + "\n";
    when(googleLoginResponse.getBody()).thenReturn(googleLoginResponseBody);
    when(googleLoginResponse.getStatusCode()).thenReturn(HttpStatus.SC_OK);

    when(googleUtil.getAuthTokenFromLoginResponse(googleLoginResponseBody)).thenReturn(authToken);

    // setup the query params for the login to Play
    Map<String, String> playLoginQueryParams = new HashMap<String, String>();
    playLoginQueryParams.put(QueryParamConst.HL_NAME, QueryParamConst.HL_VALUE);
    playLoginQueryParams.put(QueryParamConst.U_NAME, QueryParamConst.U_VALUE);

    // setup the request headers for the login to play
    Map<String, String> playLoginRequestHeaders = new HashMap<String, String>();
    when(googleUtil.createAuthHeaderValue(authToken)).thenReturn(authHeaderValue);
    playLoginRequestHeaders.put(HeaderName.AUTHORIZATION, authHeaderValue);

    // the response to logging into play will contain the st and sjsaid cookies
    String sjsaidValue = "sjsaidValue";
    Map<String, String> playLoginResponseCookies = new HashMap<String, String>();
    playLoginResponseCookies.put(CookieName.SJSAID, sjsaidValue);
    playLoginResponseCookies.put(CookieName.XT, xtValue);

    RestResponse playLoginResponse = mock(RestResponse.class);
    when(playLoginResponse.getCookies()).thenReturn(playLoginResponseCookies);
    when(playLoginResponse.getStatusCode()).thenReturn(HttpStatus.SC_OK);

    // mock the login to Play
    when(restClient.doPost(
            Const.USE_HTTPS,
            HostName.PLAY,
            Path.MUSIC_LOGIN,
            playLoginQueryParams,
            playLoginRequestHeaders,
            null,
            null))
        .thenReturn(playLoginResponse);

    when(playSessionFactory.create(xtValue, sjsaidValue, authToken)).thenReturn(playSession);

    LoginResponse loginResponse = mock(LoginResponse.class);
    when(loginResponseFactory.create(LoginResult.SUCCESS, playSession)).thenReturn(loginResponse);

    // do the call
    assertEquals(loginResponse, playClient.login(emailAddress, password));
  }
  @SuppressWarnings("unchecked")
  public void testGetPlayURIHappyPath() throws URISyntaxException, IOException {

    // mock request and response
    RestResponse restResponse = mock(RestResponse.class);
    when(restClient.doGet(
            eq(Const.USE_HTTPS),
            eq(HostName.PLAY),
            eq(Path.MUSIC_PLAY),
            isA(Map.class),
            isA(Map.class),
            isA(Map.class)))
        .thenReturn(restResponse);

    when(restResponse.getStatusCode()).thenReturn(HttpStatus.SC_OK);

    String playResponseJson = "playResponseJson";
    when(restResponse.getBody()).thenReturn(playResponseJson);
    StreamingUrl streamingUrl = mock(StreamingUrl.class);
    when(gsonWrapper.fromJson(playResponseJson, StreamingUrl.class)).thenReturn(streamingUrl);

    String url = "http://google.com";
    when(streamingUrl.getUrl()).thenReturn(url);

    URI uri = new URI(url);

    // do the call
    assertEquals(uri, playClient.getPlayURI(songId, playSession));
  }
  @SuppressWarnings("unchecked")
  public void testSearchHappyPath() throws IOException, URISyntaxException {
    // mock the POST and response
    RestResponse searchRestResponse = mock(RestResponse.class);

    when(restClient.doPost(
            eq(Const.USE_HTTPS),
            eq(HostName.PLAY),
            eq(Path.MUSIC_SEARCH),
            isA((Map.class)),
            isA(Map.class),
            (Map<String, String>) isNull(),
            isA(Map.class)))
        .thenReturn(searchRestResponse);

    String searchResultBody = "searchResultBody";
    when(searchRestResponse.getBody()).thenReturn(searchResultBody);
    when(searchRestResponse.getStatusCode()).thenReturn(HttpStatus.SC_OK);

    SearchResponse searchResponse = mock(SearchResponse.class);
    when(gsonWrapper.fromJson(searchResultBody, SearchResponse.class)).thenReturn(searchResponse);

    SearchResults searchResults = mock(SearchResults.class);
    when(searchResponse.getResults()).thenReturn(searchResults);

    // do the call and compare results
    assertEquals(searchResults, playClient.search(query, playSession));
  }
  public void testLoginFailsDueToOtherError() throws IOException, URISyntaxException {
    // mock interactions -- assume bad credentials
    RestResponse restResponse = mock(RestResponse.class);
    when(restResponse.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);

    when(restClient.doPost(
            Const.USE_HTTPS, HostName.GOOGLE, Path.GOOGLE_LOGIN, null, null, null, loginForm))
        .thenReturn(restResponse);

    LoginResponse loginResponse = mock(LoginResponse.class);
    when(loginResponseFactory.create(LoginResult.FAILURE, null)).thenReturn(loginResponse);

    // do the call
    assertEquals(loginResponse, playClient.login(emailAddress, password));
  }
  public void testLoginFailsDueToBadCredentials() throws IOException, URISyntaxException {
    // mock interactions -- assume bad credentials
    RestResponse googleLoginResponse = mock(RestResponse.class);
    when(googleLoginResponse.getStatusCode()).thenReturn(HttpStatus.SC_FORBIDDEN);

    when(restClient.doPost(
            Const.USE_HTTPS, HostName.GOOGLE, Path.GOOGLE_LOGIN, null, null, null, loginForm))
        .thenReturn(googleLoginResponse);

    LoginResponse loginResponse = mock(LoginResponse.class);
    when(loginResponseFactory.create(LoginResult.BAD_CREDENTIALS, null)).thenReturn(loginResponse);

    // do the call
    assertEquals(loginResponse, playClient.login(emailAddress, password));
  }
  @SuppressWarnings("unchecked")
  public void testLoadAllPlaylistsHappyPath() throws IOException, URISyntaxException {
    // mock interactions
    RestResponse restResponse = mock(RestResponse.class);
    when(restClient.doPost(
            eq(Const.USE_HTTPS),
            eq(HostName.PLAY),
            eq(Path.MUSIC_LOAD_PLAYLIST),
            isA((Map.class)),
            isA(Map.class),
            (Map<String, String>) isNull(),
            isA(Map.class)))
        .thenReturn(restResponse);

    when(restResponse.getStatusCode()).thenReturn(HttpStatus.SC_OK);

    String responseBody = "responseBody";
    when(restResponse.getBody()).thenReturn(responseBody);

    LoadAllPlaylistsResponse loadAllPlaylistsResponse = mock(LoadAllPlaylistsResponse.class);
    when(gsonWrapper.fromJson(responseBody, LoadAllPlaylistsResponse.class))
        .thenReturn(loadAllPlaylistsResponse);

    Playlist playlist = mock(Playlist.class);
    Collection<Playlist> playlists = new ArrayList<Playlist>();
    playlists.add(playlist);

    when(loadAllPlaylistsResponse.getPlaylists()).thenReturn(playlists);

    // do the call
    Collection<Playlist> resultPlaylists = playClient.loadAllPlaylists(playSession);

    // verify results
    assertNotNull(resultPlaylists);
    assertFalse(resultPlaylists.isEmpty());
  }