/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.example.github.api; import com.android.example.github.util.LiveDataCallAdapterFactory; import com.android.example.github.vo.Contributor; import com.android.example.github.vo.Repo; import com.android.example.github.vo.User; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import android.arch.core.executor.testing.InstantTaskExecutorRule; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.BufferedSource; import okio.Okio; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import static com.android.example.github.util.LiveDataTestUtil.getValue; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.core.IsNull.notNullValue; import static org.junit.Assert.assertThat; @RunWith(JUnit4.class) public class GithubServiceTest { @Rule public InstantTaskExecutorRule instantExecutorRule = new InstantTaskExecutorRule(); private GithubService service; private MockWebServer mockWebServer; @Before public void createService() throws IOException { mockWebServer = new MockWebServer(); service = new Retrofit.Builder() .baseUrl(mockWebServer.url("/")) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(new LiveDataCallAdapterFactory()) .build() .create(GithubService.class); } @After public void stopService() throws IOException { mockWebServer.shutdown(); } @Test public void getUser() throws IOException, InterruptedException { enqueueResponse("user-yigit.json"); User yigit = getValue(service.getUser("yigit")).body; RecordedRequest request = mockWebServer.takeRequest(); assertThat(request.getPath(), is("/users/yigit")); assertThat(yigit, notNullValue()); assertThat(yigit.avatarUrl, is("https://avatars3.githubusercontent.com/u/89202?v=3")); assertThat(yigit.company, is("Google")); assertThat(yigit.blog, is("birbit.com")); } @Test public void getRepos() throws IOException, InterruptedException { enqueueResponse("repos-yigit.json"); List<Repo> repos = getValue(service.getRepos("yigit")).body; RecordedRequest request = mockWebServer.takeRequest(); assertThat(request.getPath(), is("/users/yigit/repos")); assertThat(repos.size(), is(2)); Repo repo = repos.get(0); assertThat(repo.fullName, is("yigit/AckMate")); Repo.Owner owner = repo.owner; assertThat(owner, notNullValue()); assertThat(owner.login, is("yigit")); assertThat(owner.url, is("https://api.github.com/users/yigit")); Repo repo2 = repos.get(1); assertThat(repo2.fullName, is("yigit/android-architecture")); } @Test public void getContributors() throws IOException, InterruptedException { enqueueResponse("contributors.json"); List<Contributor> contributors = getValue( service.getContributors("foo", "bar")).body; assertThat(contributors.size(), is(3)); Contributor yigit = contributors.get(0); assertThat(yigit.getLogin(), is("yigit")); assertThat(yigit.getAvatarUrl(), is("https://avatars3.githubusercontent.com/u/89202?v=3")); assertThat(yigit.getContributions(), is(291)); assertThat(contributors.get(1).getLogin(), is("guavabot")); assertThat(contributors.get(2).getLogin(), is("coltin")); } @Test public void search() throws IOException, InterruptedException { String header = "<https://api.github.com/search/repositories?q=foo&page=2>; rel=\"next\"," + " <https://api.github.com/search/repositories?q=foo&page=34>; rel=\"last\""; Map<String, String> headers = new HashMap<>(); headers.put("link", header); enqueueResponse("search.json", headers); ApiResponse<RepoSearchResponse> response = getValue( service.searchRepos("foo")); assertThat(response, notNullValue()); assertThat(response.body.getTotal(), is(41)); assertThat(response.body.getItems().size(), is(30)); assertThat(response.links.get("next"), is("https://api.github.com/search/repositories?q=foo&page=2")); assertThat(response.getNextPage(), is(2)); } private void enqueueResponse(String fileName) throws IOException { enqueueResponse(fileName, Collections.emptyMap()); } private void enqueueResponse(String fileName, Map<String, String> headers) throws IOException { InputStream inputStream = getClass().getClassLoader() .getResourceAsStream("api-response/" + fileName); BufferedSource source = Okio.buffer(Okio.source(inputStream)); MockResponse mockResponse = new MockResponse(); for (Map.Entry<String, String> header : headers.entrySet()) { mockResponse.addHeader(header.getKey(), header.getValue()); } mockWebServer.enqueue(mockResponse .setBody(source.readString(StandardCharsets.UTF_8))); } }