package org.atlasapi.persistence.output; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Set; import com.google.common.collect.ImmutableList; import com.metabroadcast.applications.client.model.internal.Application; import com.metabroadcast.applications.client.model.internal.ApplicationConfiguration; import org.atlasapi.application.v3.DefaultApplication; import org.atlasapi.media.entity.Brand; import org.atlasapi.media.entity.ChildRef; import org.atlasapi.media.entity.Encoding; import org.atlasapi.media.entity.Episode; import org.atlasapi.media.entity.Location; import org.atlasapi.media.entity.LookupRef; import org.atlasapi.media.entity.Policy; import org.atlasapi.media.entity.Publisher; import org.atlasapi.media.entity.Version; import org.atlasapi.persistence.audit.NoLoggingPersistenceAuditLog; import org.atlasapi.persistence.audit.PerHourAndDayMongoPersistenceAuditLog; import org.atlasapi.persistence.audit.PersistenceAuditLog; import org.atlasapi.persistence.content.ContentWriter; import org.atlasapi.persistence.content.mongo.MongoContentWriter; import org.atlasapi.persistence.lookup.entry.LookupEntry; import org.atlasapi.persistence.lookup.mongo.MongoLookupEntryStore; import org.atlasapi.persistence.player.PlayerResolver; import org.atlasapi.persistence.service.ServiceResolver; import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.metabroadcast.common.persistence.MongoTestHelper; import com.metabroadcast.common.persistence.mongo.DatabasedMongo; import com.metabroadcast.common.time.DateTimeZones; import com.metabroadcast.common.time.TimeMachine; import com.mongodb.ReadPreference; @RunWith( MockitoJUnitRunner.class ) public class MongoAvailableItemsResolverTest { private static final ServiceResolver serviceResolver = mock(ServiceResolver.class); private static final PlayerResolver playerResolver = mock(PlayerResolver.class); private final DatabasedMongo mongo = MongoTestHelper.anEmptyTestDatabase(); private final TimeMachine clock = new TimeMachine(); private final MongoLookupEntryStore lookupStore = new MongoLookupEntryStore(mongo.collection("lookup"), new NoLoggingPersistenceAuditLog(), ReadPreference.primary()); private final MongoAvailableItemsResolver resolver = new MongoAvailableItemsResolver(mongo, lookupStore, clock); private final PersistenceAuditLog persistenceAuditLog = new PerHourAndDayMongoPersistenceAuditLog(mongo); private final ContentWriter writer = new MongoContentWriter(mongo, lookupStore, persistenceAuditLog, playerResolver, serviceResolver, clock); private final Brand primary = new Brand("primary", "primary", Publisher.BBC); private final Brand equivalent = new Brand("equivalent", "equivalent", Publisher.PA); private final Episode p1 = episode("p1", primary, location("p1l1", dateTime(0), dateTime(10))); private final Episode p2 = episode("p2", primary); private final Episode e1 = episode("e1", equivalent, location("e1l1", dateTime(0), dateTime(10))); private final Episode e2 = episode("e2", equivalent, location("e2l2", null, null)); // Availability start/end of null implies always available private Application application = mock(Application.class); private ApplicationConfiguration configWithoutPA; private ApplicationConfiguration configWithPA; @Before public void setUp() { writer.createOrUpdate(primary); writer.createOrUpdate(equivalent); writer.createOrUpdate(p1); writer.createOrUpdate(p2); writer.createOrUpdate(e1); writer.createOrUpdate(e2); writeEquivalences(p1, e1); writeEquivalences(p2, e2); primary.setEquivalentTo(ImmutableSet.of(LookupRef.from(equivalent))); p2.setEquivalentTo(ImmutableSet.of(LookupRef.from(p1))); configWithoutPA = ApplicationConfiguration.builder() .withPrecedence(ImmutableList.of()) .withEnabledWriteSources(ImmutableList.of()) .build(); configWithPA = ApplicationConfiguration.builder() .withPrecedence(ImmutableList.of(Publisher.PA)) .withEnabledWriteSources(ImmutableList.of()) .build(); } @Test public void testResolvesChildrenOfEquivalentBrandsAsTheItemsOfThePrimaryBrand() { clock.jumpTo(dateTime(5)); when(application.getConfiguration()).thenReturn(configWithoutPA); Set<ChildRef> childRefs = ImmutableSet.copyOf(resolver.availableItemsFor(primary, application)); ChildRef childRef = Iterables.getOnlyElement(childRefs); assertEquals(p1.getCanonicalUri(), childRef.getUri()); when(application.getConfiguration()).thenReturn(configWithPA); childRefs = ImmutableSet.copyOf(resolver.availableItemsFor(primary, application)); assertThat(childRefs.size(), is(2)); assertThat(Iterables.transform(childRefs, ChildRef.TO_URI), hasItems(p1.getCanonicalUri(), p2.getCanonicalUri())); } private void writeEquivalences(Episode a, Episode b) { LookupEntry aEntry = LookupEntry.lookupEntryFrom(a) .copyWithDirectEquivalents(ImmutableSet.of(LookupRef.from(b))) .copyWithEquivalents(ImmutableSet.of(LookupRef.from(b))); LookupEntry bEntry = LookupEntry.lookupEntryFrom(b) .copyWithDirectEquivalents(ImmutableSet.of(LookupRef.from(a))) .copyWithEquivalents(ImmutableSet.of(LookupRef.from(a))); lookupStore.store(aEntry); lookupStore.store(bEntry); } private Episode episode(String uri, Brand container, Location... locations) { Episode episode = new Episode(); episode.setCanonicalUri(uri); episode.setContainer(container); episode.setPublisher(container.getPublisher()); Version version = new Version(); Encoding encoding = new Encoding(); encoding.setAvailableAt(ImmutableSet.copyOf(locations)); version.setManifestedAs(ImmutableSet.of(encoding)); episode.setVersions(ImmutableSet.of(version)); return episode; } private Location location(String uri, DateTime start, DateTime end) { Location location = new Location(); location.setUri(uri); Policy policy = new Policy(); policy.setAvailabilityStart(start); policy.setAvailabilityEnd(end); location.setPolicy(policy); return location; } private DateTime dateTime(int millis) { return new DateTime(millis,DateTimeZones.UTC); } }