package org.atlasapi.media.channel;
import java.util.List;
import java.util.Map;
import java.util.stream.StreamSupport;
import org.atlasapi.media.entity.Alias;
import org.atlasapi.media.entity.Identified;
import org.atlasapi.media.entity.MediaType;
import org.atlasapi.media.entity.Publisher;
import com.metabroadcast.common.base.Maybe;
import com.metabroadcast.common.persistence.MongoTestHelper;
import com.metabroadcast.common.persistence.mongo.DatabasedMongo;
import com.metabroadcast.common.stream.MoreCollectors;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import org.joda.time.DateTime;
import org.junit.BeforeClass;
import org.junit.Test;
import static junit.framework.TestCase.assertFalse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class MongoChannelStoreRetrievalTest {
private static final DatabasedMongo mongo = MongoTestHelper.anEmptyTestDatabase();
private static final ChannelGroupStore channelGroupStore = new MongoChannelGroupStore(mongo);
private static final MongoChannelStore store = new MongoChannelStore(
mongo, channelGroupStore, channelGroupStore
);
private static Long channelId1;
private static Long channelId2;
private static Long channelId3;
private static Long channelId4;
private static Long channelId5;
private static Long channelWithAliasId;
private static Channel channelWithAlias;
private static DateTime dateTime;
@BeforeClass
public static void setUp() throws InterruptedException {
dateTime = DateTime.now();
channelId1 = store.createOrUpdate(
channel(1, "uri1", "key1", "sport", dateTime, "test/1", "test/2")
).getId();
channelId2 = store.createOrUpdate(
channel(2, "uri2", "key2", "not-sport", null, "asdf/1")
).getId();
channelId3 = store.createOrUpdate(
channel(3, "uri3", "key3", "flim", null, "test/3", "asdf/2")
).getId();
channelId4 = store.createOrUpdate(
channel(4, "uri4", "key4", "old episode", dateTime.minusDays(1), "test")
).getId();
channelId5 = store.createOrUpdate(
channel(5, "uri5", "key5", "episode", dateTime.plusDays(1), "test")
).getId();
channelWithAlias = channel(
6,
"uri6",
"key6",
"episode",
dateTime.plusDays(1),
"testAlias"
);
channelWithAliasId = store.createOrUpdate(channelWithAlias).getId();
Thread.sleep(2000);
}
private static Channel channel(
long id,
String uri,
String key,
String genre,
DateTime advertisedFrom,
String... aliasUrls
) {
Channel channel = new Channel();
channel.setCanonicalUri(uri);
channel.setAliasUrls(ImmutableSet.copyOf(aliasUrls));
channel.setSource(Publisher.BBC);
channel.setMediaType(MediaType.VIDEO);
channel.setKey(key);
channel.setAvailableFrom(ImmutableSet.of());
channel.setGenres(ImmutableSet.of(genre));
channel.setAdvertiseFrom(advertisedFrom);
return channel;
}
@Test
public void testRetrievesAChannel() {
Maybe<Channel> channel = store.fromId(channelId1);
assertTrue(channel.hasValue());
assertThat(channel.requireValue().getCanonicalUri(), is(equalTo("uri1")));
assertThat(
channel.requireValue().getAdvertiseFrom().getMillis(),
is(equalTo(dateTime.getMillis()))
);
}
@Test
public void testRetrievesSomeChannels() {
List<Long> ids = Lists.newArrayList(channelId1, channelId3);
Iterable<Channel> channels = store.forIds(ids);
assertThat(Iterables.size(channels), is(2));
Map<String, Channel> channelMap = Maps.uniqueIndex(channels, Identified.TO_URI);
assertThat(channelMap.get("uri1").getId(), is(channelId1));
assertThat(channelMap.get("uri2"), is(nullValue()));
assertThat(channelMap.get("uri3").getId(), is(channelId3));
}
@Test
public void testRetrievesAllChannels() {
Iterable<Channel> channels = store.all();
assertThat(Iterables.size(channels), is(6));
Map<String, Channel> channelMap = Maps.uniqueIndex(channels, Identified.TO_URI);
assertThat(channelMap.get("uri1").getId(), is(channelId1));
assertThat(channelMap.get("uri2").getId(), is(channelId2));
assertThat(channelMap.get("uri3").getId(), is(channelId3));
}
@Test
public void testRetrievesAllChannelsInOrder() {
Iterable<Channel> channels = store.all();
List<Long> channelIds = ImmutableList.copyOf(
StreamSupport.stream(channels.spliterator(), false)
.map(Identified::getId)
.collect(MoreCollectors.toImmutableList())
);
List<Long> expectedIds = Ordering.natural().immutableSortedCopy(
Lists.newArrayList(
channelId1,
channelId2,
channelId3,
channelId4,
channelId5,
channelWithAliasId
)
);
assertEquals(expectedIds, channelIds);
}
@Test
public void testRetrievesChannelsByAliasPrefix() {
String prefix = "test/";
Map<String, Channel> aliases = store.forAliases(prefix);
assertThat(aliases.size(), is(3));
assertThat(aliases.get(prefix + 1).getId(), is(channelId1));
assertThat(aliases.get(prefix + 2).getId(), is(channelId1));
assertThat(aliases.get(prefix + 3).getId(), is(channelId3));
}
@Test
public void testRetrievesChannelsByAlias() {
Maybe<Channel> channel = store.forAlias("test/1");
assertThat(channel.requireValue().getId(), is(channelId1));
}
@Test
public void testRetrievesChannelByURI() {
assertThat(store.fromUri("uri1").requireValue().getId(), is(channelId1));
}
@Test
public void testRetrievesChannelByKey() {
assertThat(store.fromKey("key1").requireValue().getId(), is(channelId1));
}
@Test
public void testRetrievesChannelByGenre() {
ChannelQuery query = ChannelQuery.builder().withGenres(ImmutableSet.of("sport")).build();
Channel retrieved = Iterables.getOnlyElement(store.allChannels(query));
assertThat(retrieved.getId(), is(channelId1));
}
@Test
public void testRetrievesOldEpisodes() {
ChannelQuery query = ChannelQuery.builder()
.withAdvertisedOn(dateTime.minusHours(1))
.build();
Iterable<Channel> channels = store.allChannels(query);
assertThat(Iterables.size(channels), is(1));
}
@Test
public void testDoesNotRetrieveEpisodesThatAreNotAdvertisedYet() {
ChannelQuery query = ChannelQuery.builder().withAdvertisedOn(dateTime.minusDays(2)).build();
Iterable<Channel> retrieved = store.allChannels(query);
assertTrue(Iterables.isEmpty(retrieved));
}
@Test
public void testRetrievesChannelByPublisher() {
ChannelQuery query = ChannelQuery.builder().withPublisher(Publisher.BBC).build();
Iterable<Channel> channels = store.allChannels(query);
assertFalse(Iterables.isEmpty(channels));
Iterable<Channel> filtered = StreamSupport.stream(channels.spliterator(), false)
.filter(channel -> !channel.getSource().equals(Publisher.BBC))
.collect(MoreCollectors.toImmutableList());
assertTrue(Iterables.isEmpty(filtered));
}
@Test
public void testRetrievesChannelByUri() {
ChannelQuery query = ChannelQuery.builder().withUri("uri1").build();
Iterable<Channel> channels = store.allChannels(query);
assertFalse(Iterables.isEmpty(channels));
assertTrue(Iterables.getOnlyElement(channels).getUri().equals("uri1"));
}
@Test
public void testRetrievesChannelByAlias() {
Alias alias = new Alias("dragons", "everywhere");
channelWithAlias.setAliases(ImmutableList.of(alias));
store.createOrUpdate(channelWithAlias);
ChannelQuery query = ChannelQuery.builder()
.withAliasNamespace("dragons")
.withAliasValue("everywhere")
.build();
Iterable<Channel> channels = store.forKeyPairAlias(query);
assertFalse(Iterables.isEmpty(channels));
assertTrue(Iterables.getOnlyElement(channels).getAliases().contains(alias));
}
}