1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tv.data;
17 
18 import static android.media.tv.TvContract.Programs.Genres.COMEDY;
19 import static android.media.tv.TvContract.Programs.Genres.FAMILY_KIDS;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 import static com.google.common.truth.Truth.assertWithMessage;
23 
24 import android.media.tv.TvContentRating;
25 import android.media.tv.TvContract.Programs.Genres;
26 import android.os.Parcel;
27 
28 import com.android.tv.data.api.Program;
29 import com.android.tv.data.api.Program.CriticScore;
30 import com.android.tv.testing.TvRobolectricTestRunner;
31 import com.android.tv.testing.constants.ConfigConstants;
32 
33 import com.google.common.collect.ImmutableList;
34 
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.robolectric.RuntimeEnvironment;
38 import org.robolectric.annotation.Config;
39 
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.List;
43 
44 /** Tests for {@link ProgramImpl}. */
45 @RunWith(TvRobolectricTestRunner.class)
46 @Config(sdk = ConfigConstants.SDK)
47 public class ProgramTest {
48     private static final int NOT_FOUND_GENRE = 987;
49 
50     private static final int FAMILY_GENRE_ID = GenreItems.getId(FAMILY_KIDS);
51 
52     private static final int COMEDY_GENRE_ID = GenreItems.getId(COMEDY);
53 
54     @Test
testBuild()55     public void testBuild() {
56         Program program = new ProgramImpl.Builder().build();
57         assertWithMessage("isValid").that(program.isValid()).isFalse();
58     }
59 
60     @Test
testNoGenres()61     public void testNoGenres() {
62         Program program = new ProgramImpl.Builder().setCanonicalGenres("").build();
63         assertNullCanonicalGenres(program);
64         assertHasGenre(program, NOT_FOUND_GENRE, false);
65         assertHasGenre(program, FAMILY_GENRE_ID, false);
66         assertHasGenre(program, COMEDY_GENRE_ID, false);
67         assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
68     }
69 
70     @Test
testFamilyGenre()71     public void testFamilyGenre() {
72         Program program = new ProgramImpl.Builder().setCanonicalGenres(FAMILY_KIDS).build();
73         assertCanonicalGenres(program, FAMILY_KIDS);
74         assertHasGenre(program, NOT_FOUND_GENRE, false);
75         assertHasGenre(program, FAMILY_GENRE_ID, true);
76         assertHasGenre(program, COMEDY_GENRE_ID, false);
77         assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
78     }
79 
80     @Test
testFamilyComedyGenre()81     public void testFamilyComedyGenre() {
82         Program program =
83                 new ProgramImpl.Builder().setCanonicalGenres(FAMILY_KIDS + ", " + COMEDY).build();
84         assertCanonicalGenres(program, FAMILY_KIDS, COMEDY);
85         assertHasGenre(program, NOT_FOUND_GENRE, false);
86         assertHasGenre(program, FAMILY_GENRE_ID, true);
87         assertHasGenre(program, COMEDY_GENRE_ID, true);
88         assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
89     }
90 
91     @Test
testOtherGenre()92     public void testOtherGenre() {
93         Program program = new ProgramImpl.Builder().setCanonicalGenres("other").build();
94         assertCanonicalGenres(program);
95         assertHasGenre(program, NOT_FOUND_GENRE, false);
96         assertHasGenre(program, FAMILY_GENRE_ID, false);
97         assertHasGenre(program, COMEDY_GENRE_ID, false);
98         assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
99     }
100 
101     @Test
testParcelable()102     public void testParcelable() {
103         List<CriticScore> criticScores = new ArrayList<>();
104         criticScores.add(new CriticScore("1", "2", "3"));
105         criticScores.add(new CriticScore("4", "5", "6"));
106         ImmutableList<TvContentRating> ratings =
107                 ImmutableList.of(
108                         TvContentRating.unflattenFromString("1/2/3"),
109                         TvContentRating.unflattenFromString("4/5/6"));
110         ProgramImpl p =
111                 new ProgramImpl.Builder()
112                         .setId(1)
113                         .setPackageName("2")
114                         .setChannelId(3)
115                         .setTitle("4")
116                         .setSeriesId("5")
117                         .setEpisodeTitle("6")
118                         .setSeasonNumber("7")
119                         .setSeasonTitle("8")
120                         .setEpisodeNumber("9")
121                         .setStartTimeUtcMillis(10)
122                         .setEndTimeUtcMillis(11)
123                         .setDescription("12")
124                         .setLongDescription("12-long")
125                         .setVideoWidth(13)
126                         .setVideoHeight(14)
127                         .setCriticScores(criticScores)
128                         .setPosterArtUri("15")
129                         .setThumbnailUri("16")
130                         .setCanonicalGenres(Genres.encode(Genres.SPORTS, Genres.SHOPPING))
131                         .setContentRatings(ratings)
132                         .setRecordingProhibited(true)
133                         .build();
134         Parcel p1 = Parcel.obtain();
135         Parcel p2 = Parcel.obtain();
136         try {
137             p.writeToParcel(p1, 0);
138             byte[] bytes = p1.marshall();
139             p2.unmarshall(bytes, 0, bytes.length);
140             p2.setDataPosition(0);
141             ProgramImpl r2 = ProgramImpl.fromParcel(p2);
142             assertThat(r2).isEqualTo(p);
143         } finally {
144             p1.recycle();
145             p2.recycle();
146         }
147     }
148 
149     @Test
testParcelableWithCriticScore()150     public void testParcelableWithCriticScore() {
151         ProgramImpl program =
152                 new ProgramImpl.Builder()
153                         .setTitle("MyTitle")
154                         .addCriticScore(
155                                 new CriticScore(
156                                         "default source", "5/10", "http://testurl/testimage.jpg"))
157                         .build();
158         Parcel parcel = Parcel.obtain();
159         program.writeToParcel(parcel, 0);
160         parcel.setDataPosition(0);
161         Program programFromParcel = ProgramImpl.CREATOR.createFromParcel(parcel);
162 
163         assertThat(programFromParcel.getCriticScores()).isNotNull();
164         assertThat(programFromParcel.getCriticScores().get(0).source).isEqualTo("default source");
165         assertThat(programFromParcel.getCriticScores().get(0).score).isEqualTo("5/10");
166         assertThat(programFromParcel.getCriticScores().get(0).logoUrl)
167                 .isEqualTo("http://testurl/testimage.jpg");
168     }
169 
170     @Test
getEpisodeContentDescription_blank()171     public void getEpisodeContentDescription_blank() {
172         Program program = new ProgramImpl.Builder().build();
173         assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application)).isNull();
174     }
175 
176     @Test
getEpisodeContentDescription_seasonEpisodeAndTitle()177     public void getEpisodeContentDescription_seasonEpisodeAndTitle() {
178         Program program =
179                 new ProgramImpl.Builder()
180                         .setSeasonNumber("1")
181                         .setEpisodeNumber("2")
182                         .setEpisodeTitle("The second one")
183                         .build();
184         assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
185                 .isEqualTo("Season 1 Episode 2 The second one");
186     }
187 
188     @Test
getEpisodeContentDescription_EpisodeAndTitle()189     public void getEpisodeContentDescription_EpisodeAndTitle() {
190         Program program =
191                 new ProgramImpl.Builder()
192                         .setEpisodeNumber("2")
193                         .setEpisodeTitle("The second one")
194                         .build();
195         assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
196                 .isEqualTo("Episode 2 The second one");
197     }
198 
199     @Test
getEpisodeContentDescription_seasonEpisode()200     public void getEpisodeContentDescription_seasonEpisode() {
201         Program program =
202                 new ProgramImpl.Builder().setSeasonNumber("1").setEpisodeNumber("2").build();
203         assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
204                 .isEqualTo("Season 1 Episode 2 ");
205     }
206 
207     @Test
getEpisodeContentDescription_EpisodeTitle()208     public void getEpisodeContentDescription_EpisodeTitle() {
209         Program program = new ProgramImpl.Builder().setEpisodeTitle("The second one").build();
210         assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
211                 .isEqualTo("The second one");
212     }
213 
214     @Test
getEpisodeDisplayTitle_blank()215     public void getEpisodeDisplayTitle_blank() {
216         Program program = new ProgramImpl.Builder().build();
217         assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application)).isNull();
218     }
219 
220     @Test
getEpisodeDisplayTitle_seasonEpisodeAndTitle()221     public void getEpisodeDisplayTitle_seasonEpisodeAndTitle() {
222         Program program =
223                 new ProgramImpl.Builder()
224                         .setSeasonNumber("1")
225                         .setEpisodeNumber("2")
226                         .setEpisodeTitle("The second one")
227                         .build();
228         assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
229                 .isEqualTo("S1: Ep. 2 The second one");
230     }
231 
232     @Test
getEpisodeDisplayTitle_EpisodeTitle()233     public void getEpisodeDisplayTitle_EpisodeTitle() {
234         Program program =
235                 new ProgramImpl.Builder()
236                         .setEpisodeNumber("2")
237                         .setEpisodeTitle("The second one")
238                         .build();
239         assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
240                 .isEqualTo("Ep. 2 The second one");
241     }
242 
243     @Test
getEpisodeDisplayTitle_seasonEpisode()244     public void getEpisodeDisplayTitle_seasonEpisode() {
245         Program program =
246                 new ProgramImpl.Builder().setSeasonNumber("1").setEpisodeNumber("2").build();
247         assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
248                 .isEqualTo("S1: Ep. 2 ");
249     }
250 
251     @Test
getEpisodeDisplayTitle_episode()252     public void getEpisodeDisplayTitle_episode() {
253         Program program = new ProgramImpl.Builder().setEpisodeTitle("The second one").build();
254         assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
255                 .isEqualTo("The second one");
256     }
257 
assertNullCanonicalGenres(Program program)258     private static void assertNullCanonicalGenres(Program program) {
259         String[] actual = program.getCanonicalGenres();
260         assertWithMessage("Expected null canonical genres but was " + Arrays.toString(actual))
261                 .that(actual)
262                 .isNull();
263     }
264 
assertCanonicalGenres(Program program, String... expected)265     private static void assertCanonicalGenres(Program program, String... expected) {
266         assertWithMessage("canonical genres")
267                 .that(Arrays.asList(program.getCanonicalGenres()))
268                 .isEqualTo(Arrays.asList(expected));
269     }
270 
assertHasGenre(Program program, int genreId, boolean expected)271     private static void assertHasGenre(Program program, int genreId, boolean expected) {
272         assertWithMessage("hasGenre(" + genreId + ")")
273                 .that(program.hasGenre(genreId))
274                 .isEqualTo(expected);
275     }
276 }
277