package de.is24.infrastructure.gridfs.http.web.controller; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.mongodb.BasicDBObject; import de.is24.infrastructure.gridfs.http.domain.Container; import de.is24.infrastructure.gridfs.http.domain.FileInfo; import de.is24.infrastructure.gridfs.http.domain.FolderInfo; import de.is24.infrastructure.gridfs.http.web.boot.AbstractContainerAndMongoDBStarter; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.hamcrest.CustomMatcher; import org.hamcrest.Matcher; import org.junit.Test; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import static de.is24.infrastructure.gridfs.http.utils.RepositoryUtils.getHttpClientBuilderWithoutRedirecting; import static javax.servlet.http.HttpServletResponse.SC_MOVED_PERMANENTLY; import static javax.servlet.http.HttpServletResponse.SC_OK; import static org.apache.http.util.EntityUtils.consume; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertTrue; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; public abstract class RepositoryInfoControllerIT extends AbstractContainerAndMongoDBStarter { protected String givenRepoUrl; protected String givenReponame; protected String givenRepoListUrl; protected String givenRepoUrlWithNoarch; protected String givenUnknownRepoUrl; protected String givenStaticReponame; protected String givenTagName; @Test public void shouldGetRepos() throws Exception { HttpGet get = new HttpGet(givenRepoListUrl); get.setHeader("Accept", APPLICATION_JSON_VALUE); HttpResponse response = httpClient.execute(get); Container<FolderInfo> folderInfoContainer = readJson(response, new TypeReference<Container<FolderInfo>>() { }); assertThat(response.getStatusLine().getStatusCode(), is(SC_OK)); assertThat(folderInfoContainer.getItems(), hasItem(withSizeGreaterZeroAndName(givenReponame))); } private CustomMatcher<FolderInfo> withSizeGreaterZeroAndName(final String expectedFolderInfoName) { return new CustomMatcher<FolderInfo>("FolderInfo with size greater 0") { @Override public boolean matches(Object o) { if (o instanceof FolderInfo) { FolderInfo info = (FolderInfo) o; return (info.getSize() > 0) && expectedFolderInfoName.equals(info.getName()); } return false; } }; } @SuppressWarnings("unchecked") @Test public void shouldGetSetOfFilesForGivenRepositoryAndArch() throws Exception { HttpGet get = new HttpGet(givenRepoUrlWithNoarch); get.setHeader("Accept", APPLICATION_JSON_VALUE); HttpResponse response = httpClient.execute(get); Container<FileInfo> fileInfoContainer = readJson(response, new TypeReference<Container<FileInfo>>() { }); List<FileInfo> fileInfos = fileInfoContainer.getItems(); final Matcher<FileInfo> hasGivenFilename = hasProperty("filename", is("test-artifact-1.2-1.noarch.rpm")); final Matcher<FileInfo> hasGivenReponame = hasProperty("repo", is(givenStaticReponame)); final Matcher<FileInfo> hasNoarch = hasProperty("arch", is("noarch")); assertThat(fileInfos, hasItem(allOf(hasNoarch, hasGivenFilename, hasGivenReponame))); assertThat(response.getStatusLine().getStatusCode(), is(SC_OK)); assertThat(givenRepoUrlWithNoarch, endsWith(fileInfoContainer.getPath())); } @Test public void shouldGetSetOfArchsForGivenRepository() throws IOException { HttpGet get = new HttpGet(givenRepoUrl); get.setHeader("Accept", APPLICATION_JSON_VALUE); HttpResponse response = httpClient.execute(get); Container<FolderInfo> returnedFolderInfoContainer = readJson(response, new TypeReference<Container<FolderInfo>>() { }); assertTrue(returnedFolderInfoContainer.getItems() .contains(new FolderInfo(new BasicDBObject("_id", "noarch").append("length", 1L)))); assertThat(givenRepoUrl, endsWith(returnedFolderInfoContainer.getPath())); assertThat(response.getStatusLine().getStatusCode(), is(SC_OK)); } @Test public void shouldReturn404ForUnknownRepository() throws IOException { HttpGet get = new HttpGet(givenUnknownRepoUrl); get.setHeader("Accept", APPLICATION_JSON_VALUE); HttpResponse response = httpClient.execute(get); assertThat(response.getStatusLine().getStatusCode(), is(HttpServletResponse.SC_NOT_FOUND)); } @Test public void provideRepositoryList() throws Exception { String repoListAsTextUrl = givenRepoListUrl.substring(0, givenRepoListUrl.length() - 1) + ".json"; HttpGet get = new HttpGet(repoListAsTextUrl); HttpResponse response = httpClient.execute(get); final Container<FolderInfo> folderInfoContainer = readJson(response, new TypeReference<Container<FolderInfo>>() { }); final Matcher<FolderInfo> hasGivenRepoName = hasProperty("name", is(givenReponame)); final Matcher<FolderInfo> hasGivenTagName = hasProperty("tags", hasItem(givenTagName)); assertThat(folderInfoContainer.getItems(), hasItem(hasGivenRepoName)); assertThat(response.getStatusLine().getStatusCode(), is(SC_OK)); if (!givenRepoListUrl.contains("virtual")) { assertThat(folderInfoContainer.getItems(), hasItem(hasGivenTagName)); } } @Test public void shouldRedirectWithoutTrailingSlash() throws Exception { checkRedirectWithTrailingSlash(givenRepoListUrl.substring(0, givenRepoListUrl.length() - 1)); checkRedirectWithTrailingSlash(givenRepoUrl); checkRedirectWithTrailingSlash(givenRepoUrlWithNoarch); } private void checkRedirectWithTrailingSlash(String url) throws Exception { httpClient = getHttpClientBuilderWithoutRedirecting().build(); HttpResponse response = httpClient.execute(new HttpGet(url)); consume(response.getEntity()); assertRedirectWithTrailingSlash(url, response); } private void assertRedirectWithTrailingSlash(String url, HttpResponse response) { assertThat(response.getStatusLine().getStatusCode(), is(SC_MOVED_PERMANENTLY)); Header locationHeader = response.getFirstHeader("Location"); assertThat(locationHeader, notNullValue()); assertThat(locationHeader.getValue(), is(url + "/")); } protected <T> T readJson(HttpResponse response, TypeReference<T> typeReference) throws IOException { return new ObjectMapper().readValue(response.getEntity().getContent(), typeReference); } }