private ExtendedOnDemandProgramType onDemandFor(Item item) {
   ItemOnDemandHierarchy hierarchy = hierarchyFrom(item);
   String onDemandImi =
       idGenerator.generateOnDemandImi(
           hierarchy.item(), hierarchy.version(), hierarchy.encoding(), hierarchy.location());
   return (ExtendedOnDemandProgramType) generator.generate(hierarchy, onDemandImi);
 }
  @Test
  public void testNitroSpecificFields() {
    Film film = createNitroFilm(false);
    ItemOnDemandHierarchy hierarchy = hierarchyFrom(film);
    String versionCrid = idGenerator.generateVersionCrid(hierarchy.item(), hierarchy.version());
    String onDemandImi =
        idGenerator.generateOnDemandImi(
            hierarchy.item(), hierarchy.version(), hierarchy.encoding(), hierarchy.location());

    ExtendedOnDemandProgramType onDemand =
        (ExtendedOnDemandProgramType) generator.generate(hierarchy, onDemandImi);

    assertEquals("http://nitro.bbc.co.uk/services/youview", onDemand.getServiceIDRef());
    assertEquals(versionCrid, onDemand.getProgram().getCrid());
    assertEquals(onDemandImi, onDemand.getInstanceMetadataId());

    InstanceDescriptionType instanceDesc = onDemand.getInstanceDescription();

    AVAttributesType avAttributes = instanceDesc.getAVAttributes();
    List<AudioAttributesType> audioAttributes = avAttributes.getAudioAttributes();
    AudioAttributesType audioAttribute = Iterables.getOnlyElement(audioAttributes);
    AudioLanguageType audioLanguage = audioAttribute.getAudioLanguage();

    assertEquals("urn:tva:metadata:cs:AudioPurposeCS:2007:1", audioLanguage.getPurpose());
    assertEquals(true, audioLanguage.isSupplemental());
    assertEquals("dubbed", audioLanguage.getType());
  }
  @Test
  public void testNonPublisherSpecificFields() {
    ItemOnDemandHierarchy onDemandHierarchy = hierarchyFrom(createNitroFilm(true));

    ExtendedOnDemandProgramType onDemand =
        (ExtendedOnDemandProgramType) generator.generate(onDemandHierarchy, ON_DEMAND_IMI);

    assertEquals("P0DT1H30M0.000S", onDemand.getPublishedDuration().toString());
    assertEquals("2012-07-03T00:00:00Z", onDemand.getStartOfAvailability().toString());
    assertEquals("2013-07-17T00:00:00Z", onDemand.getEndOfAvailability().toString());
    assertTrue(onDemand.getFree().isValue());

    InstanceDescriptionType instanceDesc = onDemand.getInstanceDescription();

    CaptionLanguageType captionLanguage =
        Iterables.getOnlyElement(instanceDesc.getCaptionLanguage());

    assertTrue(captionLanguage.isClosed());
    assertEquals(captionLanguage.getValue(), "en");

    List<SignLanguageType> signLanguages = instanceDesc.getSignLanguage();
    SignLanguageType signLanguageType = Iterables.getOnlyElement(signLanguages);
    assertEquals("bfi", signLanguageType.getValue());

    AVAttributesType avAttributes = instanceDesc.getAVAttributes();
    AudioAttributesType audioAttrs = Iterables.getOnlyElement(avAttributes.getAudioAttributes());

    assertEquals("urn:mpeg:mpeg7:cs:AudioPresentationCS:2001:3", audioAttrs.getMixType().getHref());

    VideoAttributesType videoAttrs = avAttributes.getVideoAttributes();

    assertEquals(Integer.valueOf(1280), videoAttrs.getHorizontalSize());
    assertEquals(Integer.valueOf(720), videoAttrs.getVerticalSize());
    assertEquals("16:9", Iterables.getOnlyElement(videoAttrs.getAspectRatio()).getValue());

    assertEquals(BigInteger.valueOf(VIDEO_BITRATE), avAttributes.getBitRate().getValue());
    assertTrue(avAttributes.getBitRate().isVariable());

    UniqueIDType otherId = Iterables.getOnlyElement(instanceDesc.getOtherIdentifier());
    assertEquals("b020tm1g", otherId.getValue());
    assertEquals("epid.bbc.co.uk", otherId.getAuthority());
  }
  @Test
  public void testIfNoActualAvailabilityThenContentNotMarkedAsAvailable() {
    ItemOnDemandHierarchy onDemandHierarchy = hierarchyFrom(createNitroFilm(false));

    onDemandHierarchy.location().getPolicy().setActualAvailabilityStart(null);

    ExtendedOnDemandProgramType onDemand =
        (ExtendedOnDemandProgramType) generator.generate(onDemandHierarchy, ON_DEMAND_IMI);

    InstanceDescriptionType instanceDesc = onDemand.getInstanceDescription();
    Set<String> hrefs =
        ImmutableSet.copyOf(Iterables.transform(instanceDesc.getGenre(), GENRE_TO_HREF));

    assertTrue(
        "No 'media available' genre should be added if no actual availability has been identified",
        hrefs.isEmpty());

    assertEquals("2012-07-03T00:00:00Z", onDemand.getStartOfAvailability().toString());
    assertEquals("2013-07-17T00:00:00Z", onDemand.getEndOfAvailability().toString());
  }
  @Test
  public void testIfActualAvailabilityPresentThenContentMarkedAsAvailable() {
    ItemOnDemandHierarchy onDemandHierarchy = hierarchyFrom(createNitroFilm(false));

    ExtendedOnDemandProgramType onDemand =
        (ExtendedOnDemandProgramType) generator.generate(onDemandHierarchy, ON_DEMAND_IMI);

    InstanceDescriptionType instanceDesc = onDemand.getInstanceDescription();
    Set<String> hrefs =
        ImmutableSet.copyOf(Iterables.transform(instanceDesc.getGenre(), GENRE_TO_HREF));
    Set<String> types =
        ImmutableSet.copyOf(Iterables.transform(instanceDesc.getGenre(), GENRE_TO_TYPE));

    assertEquals(
        "http://refdata.youview.com/mpeg7cs/YouViewMediaAvailabilityCS/2010-09-29#media_available",
        getOnlyElement(hrefs));
    assertEquals("other", getOnlyElement(types));

    assertEquals("2012-07-03T00:00:00Z", onDemand.getStartOfAvailability().toString());
    assertEquals("2013-07-17T00:00:00Z", onDemand.getEndOfAvailability().toString());
  }