package de.is24.infrastructure.gridfs.http.repos;
import de.is24.infrastructure.gridfs.http.category.LocalExecutionOnly;
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.domain.RepoEntry;
import de.is24.infrastructure.gridfs.http.domain.SortOrder;
import de.is24.infrastructure.gridfs.http.gridfs.StorageService;
import de.is24.infrastructure.gridfs.http.mongo.IntegrationTestContext;
import de.is24.infrastructure.gridfs.http.web.controller.StaticRepositoryInfoControllerIT;
import org.fest.assertions.api.Assertions;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.data.mongodb.core.query.Query;
import java.util.Date;
import java.util.List;
import static de.is24.infrastructure.gridfs.http.domain.SortField.name;
import static de.is24.infrastructure.gridfs.http.domain.SortOrder.asc;
import static de.is24.infrastructure.gridfs.http.domain.SortOrder.desc;
import static de.is24.infrastructure.gridfs.http.utils.RepositoryUtils.uniqueRepoName;
import static de.is24.infrastructure.gridfs.http.utils.RepositoryUtils.uniqueRepoNameWithPrefix;
import static de.is24.infrastructure.gridfs.http.utils.RpmUtils.COMPLEX_RPM_FILE_NAME;
import static de.is24.infrastructure.gridfs.http.utils.RpmUtils.RPM_FILE;
import static de.is24.infrastructure.gridfs.http.utils.RpmUtils.SOURCE_RPM_FILE_NAME;
import static de.is24.infrastructure.gridfs.http.utils.RpmUtils.streamOf;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.startsWith;
import static org.joda.time.DateTime.now;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;
/**
* NOTE: Most finders are tested <b>implicitly</b> in {@link StaticRepositoryInfoControllerIT}.
*/
@Category(LocalExecutionOnly.class)
public class StaticRepositoryInfoProviderIT {
@ClassRule
public static IntegrationTestContext context = new IntegrationTestContext();
private StaticRepositoryInfoProvider provider;
private StorageService storageService;
@Before
public void setUp() throws Exception {
provider = new StaticRepositoryInfoProvider(context.mongoTemplate(), context.repoEntriesRepository());
storageService = context.gridFsService();
cleanExistingRepos();
}
private void cleanExistingRepos() {
final List<RepoEntry> repoEntries = context.repoEntriesRepository().findAll();
for (RepoEntry entry : repoEntries) {
storageService.deleteRepository(entry.getName());
}
context.gridFsTemplate().delete(new Query());
}
@Test
public void shouldFindReposForQueryStaticByMatchingRegex() throws Exception {
String givenReponameRegex = "r.po-[0-9]*";
String reponame = createRepoFromDaysAgoWithData(1);
List<RepoEntry> entries = findRepoByNameAndOlderDays(givenReponameRegex, 0);
assertResultContainsRepoWithGivenName(reponame, entries);
cleanUpRepositories(reponame);
}
@Test
public void shouldFindReposForQueryStaticByMatchingOlderDate() throws Exception {
String givenReponame = createRepoFromDaysAgoWithData(2);
List<RepoEntry> entries = findRepoByNameAndOlderDays(".", 1);
assertResultContainsRepoWithGivenName(givenReponame, entries);
cleanUpRepositories(givenReponame);
}
@SuppressWarnings("unchecked")
@Test
public void shouldGetEmptyAndNotEmptyRepos() throws Exception {
String givenRepoWithData = createRepoFromDaysAgoWithData(0);
String givenEmptyRepo = createEmptyRepoWithPrefix("emptyRepo");
List<FolderInfo> items = provider.getRepos(name, SortOrder.asc).getItems();
List<String> repoNames = items.stream().map(FolderInfo::getName).collect(toList());
assertThat(repoNames, hasItem(givenRepoWithData));
assertThat(repoNames, hasItem(givenEmptyRepo));
cleanUpRepositories(givenEmptyRepo, givenRepoWithData);
}
@Test
public void shouldGetSortedStaticReposByName() throws Exception {
String givenEmptyRepo1 = createEmptyRepoWithPrefix("A");
String givenEmptyRepo2 = createEmptyRepoWithPrefix("B");
String givenEmptyRepo3 = createEmptyRepoWithPrefix("C");
Container<FolderInfo> sortedStaticRepos = provider.getRepos(name, SortOrder.asc);
thenReposAreSortedByName(sortedStaticRepos, givenEmptyRepo1, givenEmptyRepo2, givenEmptyRepo3);
sortedStaticRepos = provider.getRepos(name, desc);
thenReposAreSortedByName(sortedStaticRepos, givenEmptyRepo3, givenEmptyRepo2, givenEmptyRepo1);
cleanUpRepositories(givenEmptyRepo1, givenEmptyRepo2, givenEmptyRepo3);
}
@Test
public void shouldHaveNotRootAsRepoInList() throws Exception {
Container<FolderInfo> repos = provider.getRepos(name, SortOrder.asc);
for (FolderInfo info : repos.getItems()) {
Assertions.assertThat(info.getName()).isNotNull();
}
}
@Test
public void shouldSortByFilename() throws Exception {
String repoA = createEmptyRepoWithPrefix("A");
String repoB = createEmptyRepoWithPrefix("B");
String repoC = createEmptyRepoWithPrefix("C");
context.gridFsService().storeRpm(repoA, streamOf(SOURCE_RPM_FILE_NAME));
context.gridFsService().storeRpm(repoB, streamOf(COMPLEX_RPM_FILE_NAME));
context.gridFsService().storeRpm(repoC, streamOf(RPM_FILE.getName()));
Container<FileInfo> files = provider.find(".*", name, asc);
assertThat(files.getItems().get(0).getFilename(), startsWith("is24-"));
}
private String createEmptyRepoWithPrefix(String prefix) {
String reponame = uniqueRepoNameWithPrefix(prefix);
context.repoService().createOrUpdate(reponame);
return reponame;
}
private String createRepoFromDaysAgoWithData(int days) throws Exception {
String reponame = uniqueRepoName();
context.gridFsService().storeRpm(reponame, streamOf(COMPLEX_RPM_FILE_NAME));
context.metadataService().generateYumMetadataIfNecessary(reponame);
context.mongoTemplate()
.updateFirst(
query(where("name").is(reponame)), update("lastModified", now().minusDays(days).toDate()),
RepoEntry.class);
return reponame;
}
private List<RepoEntry> findRepoByNameAndOlderDays(String givenReponameRegex, int olderdays) {
Date newerSevenDaysAgo = now().minusDays(7).toDate();
Date olderOneDayAgo = now().minusDays(olderdays).toDate();
return provider.find(givenReponameRegex, newerSevenDaysAgo, olderOneDayAgo);
}
@SuppressWarnings("unchecked")
private void thenReposAreSortedByName(Container<FolderInfo> givenStaticRepos, String expectedValue1,
String expectedValue2, String expectedValue3) {
List<String> repoNames = givenStaticRepos.getItems().stream().map(FolderInfo::getName).collect(toList());
assertThat(repoNames, hasItem(expectedValue1));
assertThat(repoNames, hasItem(expectedValue2));
assertThat(repoNames, hasItem(expectedValue3));
}
private void assertResultContainsRepoWithGivenName(String reponame, List<RepoEntry> entries) {
assertThat(entries.stream().map(RepoEntry::getName).collect(toList()), hasItem(reponame));
}
private void cleanUpRepositories(String... repoNames) {
for (String repoName : repoNames) {
storageService.deleteRepository(repoName);
}
}
}