Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get Available Markets #98

Merged
merged 3 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ Please describe the tests that you ran to verify your changes. Provide instructi
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream modules
- [ ] Any dependent changes have been merged and published in downstream modules
54 changes: 54 additions & 0 deletions src/main/java/spotify/api/impl/MarketApiRetrofit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package spotify.api.impl;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Call;
import retrofit2.Response;
import spotify.api.enums.HttpStatusCode;
import spotify.api.interfaces.MarketApi;
import spotify.exceptions.HttpRequestFailedException;
import spotify.factories.RetrofitHttpServiceFactory;
import spotify.models.markets.MarketFull;
import spotify.retrofit.services.MarketService;
import spotify.utils.LoggingUtil;
import spotify.utils.ResponseChecker;


public class MarketApiRetrofit implements MarketApi {
private final Logger logger = LoggerFactory.getLogger(MarketApiRetrofit.class);
private final String accessToken;
private final MarketService marketService;

public MarketApiRetrofit(final String accessToken) {
this(accessToken, RetrofitHttpServiceFactory.getMarketService());
}

public MarketApiRetrofit(final String accessToken, final MarketService marketService) {
this.accessToken = accessToken;
this.marketService = marketService;
}

@Override
public MarketFull getMarkets(){
logger.trace("Constructing HTTP call to fetch markets.");
Call<MarketFull> httpCall = marketService.getMarkets("Bearer " + this.accessToken);

try {
logger.info("Executing HTTP call to fetch markets.");
logger.debug("Fetching markets....");
LoggingUtil.logHttpCall(logger, httpCall);
Response<MarketFull> response = httpCall.execute();

ResponseChecker.throwIfRequestHasNotBeenFulfilledCorrectly(response, HttpStatusCode.OK);

logger.info("Markets fetched successfully.");
return response.body();

} catch (IOException ex) {
logger.error("HTTP request to fetch requested markets has failed.");
throw new HttpRequestFailedException(ex.getMessage());
}
}
}
8 changes: 8 additions & 0 deletions src/main/java/spotify/api/interfaces/MarketApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package spotify.api.interfaces;

import spotify.models.markets.MarketFull;

public interface MarketApi {
MarketFull getMarkets();

}
9 changes: 8 additions & 1 deletion src/main/java/spotify/api/spotify/SpotifyApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import spotify.models.episodes.EpisodeFullCollection;
import spotify.models.episodes.EpisodeSimplified;
import spotify.models.generic.Image;
import spotify.models.markets.MarketFull;
import spotify.models.paging.CursorBasedPaging;
import spotify.models.paging.Paging;
import spotify.models.players.CurrentlyPlayingObject;
Expand Down Expand Up @@ -62,6 +63,7 @@ public class SpotifyApi {
private PersonalizationApi personalizationApi;
private PlayerApi playerApi;
private SearchApi searchApi;
private MarketApi marketApi;

public SpotifyApi(final String accessToken) {
this.setup(accessToken);
Expand All @@ -72,7 +74,6 @@ public void setApis(TrackApi trackApi, AlbumApi albumApi) {
this.albumApi = albumApi;
}


public TrackFull getTrack(String trackId, Map<String, String> options) {
logger.info("Requesting a track with id {}.", trackId);
return trackApi.getTrack(trackId, options);
Expand Down Expand Up @@ -103,6 +104,11 @@ public AlbumFull getAlbum(String albumId, Map<String, String> options) {
return albumApi.getAlbum(albumId, options);
}

public MarketFull getMarket() {
logger.info("Requesting all available markets.");
return marketApi.getMarkets();
}

public AlbumFullCollection getAlbums(List<String> listOfAlbumIds, Map<String, String> options) {
logger.info("Requesting multiple albums.");
return albumApi.getAlbums(listOfAlbumIds, options);
Expand Down Expand Up @@ -460,5 +466,6 @@ private void setup(final String accessToken) {
this.personalizationApi = new PersonalizationApiRetrofit(accessToken);
this.playerApi = new PlayerApiRetrofit(accessToken);
this.searchApi = new SearchApiRetrofit(accessToken);
this.marketApi = new MarketApiRetrofit(accessToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,8 @@ private static <T> T getRetrofitHttpService(final Class<T> serviceClassToBeCreat

return httpClient.create(serviceClassToBeCreatedFor);
}

public static MarketService getMarketService() {
return getRetrofitHttpService(MarketService.class, API_BASE_URL_HTTPS_WITH_VERSION);
}
}
11 changes: 11 additions & 0 deletions src/main/java/spotify/models/markets/MarketFull.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package spotify.models.markets;

import java.util.List;

public class MarketFull {
private List<String> markets;

public List<String> getMarkets() {
return markets;
}
}
11 changes: 11 additions & 0 deletions src/main/java/spotify/retrofit/services/MarketService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package spotify.retrofit.services;

import retrofit2.Call;
import retrofit2.http.*;
import spotify.models.markets.MarketFull;

public interface MarketService {
@GET("markets")
Call<MarketFull> getMarkets(@Header("Authorization") String accessToken);

}
84 changes: 84 additions & 0 deletions src/test/java/spotify/api/impl/MarketApiRetrofitTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package spotify.api.impl;

import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.ResponseBody;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import retrofit2.Call;
import retrofit2.Response;
import spotify.exceptions.HttpRequestFailedException;
import spotify.exceptions.SpotifyActionFailedException;
import spotify.models.markets.MarketFull;
import spotify.retrofit.services.MarketService;

import java.io.IOException;

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class MarketApiRetrofitTest extends AbstractApiRetrofitTest {
private MarketApiRetrofit sut;
@Mock
private MarketService mockedMarketService;
@Mock
private Call<MarketFull> mockedMarketFullCall;

@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);

sut = new MarketApiRetrofit(fakeAccessToken, mockedMarketService);

when(mockedMarketService.getMarkets(anyString())).thenReturn(mockedMarketFullCall);

when(mockedMarketFullCall.request()).thenReturn(new Request.Builder().url(fakeUrl).build());
}

@Test
void getMarketsUsesCorrectValuesToCreatHttpCall() throws IOException {
when(mockedMarketFullCall.execute()).thenReturn(Response.success(new MarketFull()));

sut.getMarkets();
verify(mockedMarketService).getMarkets(fakeAccessTokenWithBearer);
}

@Test
void getMarketsExecutesHttpCall() throws IOException {
when(mockedMarketFullCall.execute()).thenReturn(Response.success(new MarketFull()));

sut.getMarkets();
verify(mockedMarketFullCall).execute();
}

@Test
void getMarketsThrowsSpotifyActionFailedExceptionWhenError() throws IOException {
when(mockedMarketFullCall.execute())
.thenReturn(
Response.error(
400,
ResponseBody.create(MediaType.get("application/json"), getJson("error.json"))
)
);

Assertions.assertThrows(SpotifyActionFailedException.class, () -> sut.getMarkets());
}

@Test
void getMarketsThrowsHttpRequestFailedWhenHttpFails() throws IOException {
when(mockedMarketFullCall.execute()).thenThrow(IOException.class);

Assertions.assertThrows(HttpRequestFailedException.class, () -> sut.getMarkets());
}

@Test
void getMarketsReturnsMarketFullWhenSuccessful() throws IOException {
when(mockedMarketFullCall.execute()).thenReturn(Response.success(new MarketFull()));

Assertions.assertNotNull(sut.getMarkets());
}
}
Loading