1/*
2 * Copyright (C) 2016 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
17package com.android.tv.dvr.provider;
18
19import static android.support.test.InstrumentationRegistry.getContext;
20import static org.mockito.Matchers.anyInt;
21import static org.mockito.Matchers.anyObject;
22import static org.mockito.Matchers.eq;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.verify;
25import static org.mockito.Mockito.when;
26
27import android.os.Build;
28import android.support.test.filters.SdkSuppress;
29import android.support.test.filters.SmallTest;
30
31import com.android.tv.data.ChannelDataManager;
32import com.android.tv.data.Program;
33import com.android.tv.dvr.DvrDataManagerImpl;
34import com.android.tv.dvr.DvrManager;
35import com.android.tv.dvr.data.ScheduledRecording;
36import com.android.tv.dvr.data.SeriesRecording;
37import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
38
39import org.junit.Before;
40import org.junit.Test;
41import org.mockito.Mock;
42import org.mockito.MockitoAnnotations;
43
44/**
45 * Tests for {@link com.android.tv.dvr.DvrScheduleManager}
46 */
47@SmallTest
48@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
49public class DvrDbSyncTest {
50    private static final String INPUT_ID = "input_id";
51    private static final long BASE_PROGRAM_ID = 1;
52    private static final long BASE_START_TIME_MS = 0;
53    private static final long BASE_END_TIME_MS = 1;
54    private static final String BASE_SEASON_NUMBER = "2";
55    private static final String BASE_EPISODE_NUMBER = "3";
56    private static final Program BASE_PROGRAM = new Program.Builder().setId(BASE_PROGRAM_ID)
57            .setStartTimeUtcMillis(BASE_START_TIME_MS).setEndTimeUtcMillis(BASE_END_TIME_MS)
58            .build();
59    private static final Program BASE_SERIES_PROGRAM = new Program.Builder().setId(BASE_PROGRAM_ID)
60            .setStartTimeUtcMillis(BASE_START_TIME_MS).setEndTimeUtcMillis(BASE_END_TIME_MS)
61            .setSeasonNumber(BASE_SEASON_NUMBER).setEpisodeNumber(BASE_EPISODE_NUMBER).build();
62    private static final ScheduledRecording BASE_SCHEDULE =
63            ScheduledRecording.builder(INPUT_ID, BASE_PROGRAM).build();
64    private static final ScheduledRecording BASE_SERIES_SCHEDULE =
65            ScheduledRecording.builder(INPUT_ID, BASE_SERIES_PROGRAM).build();
66
67    private DvrDbSync mDbSync;
68    @Mock private DvrManager mDvrManager;
69    @Mock private DvrDataManagerImpl mDataManager;
70    @Mock private ChannelDataManager mChannelDataManager;
71    @Mock private SeriesRecordingScheduler mSeriesRecordingScheduler;
72
73    @Before
74    public void setUp() {
75        MockitoAnnotations.initMocks(this);
76        when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
77        when(mDvrManager.addSeriesRecording(anyObject(), anyObject(), anyInt()))
78                .thenReturn(SeriesRecording.builder(INPUT_ID, BASE_PROGRAM).build());
79        mDbSync = new DvrDbSync(getContext(), mDataManager, mChannelDataManager,
80                mDvrManager, mSeriesRecordingScheduler);
81    }
82
83    @Test
84    public void testHandleUpdateProgram_null() {
85        addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
86        mDbSync.handleUpdateProgram(null, BASE_PROGRAM_ID);
87        verify(mDataManager).removeScheduledRecording(BASE_SCHEDULE);
88    }
89
90    @Test
91    public void testHandleUpdateProgram_changeTimeNotStarted() {
92        addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
93        long startTimeMs = BASE_START_TIME_MS + 1;
94        long endTimeMs = BASE_END_TIME_MS + 1;
95        Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
96                .setEndTimeUtcMillis(endTimeMs).build();
97        mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
98        assertUpdateScheduleCalled(program);
99    }
100
101    @Test
102    public void testHandleUpdateProgram_changeTimeInProgressNotCalled() {
103        addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SCHEDULE)
104                .setState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS).build());
105        long startTimeMs = BASE_START_TIME_MS + 1;
106        Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
107                .build();
108        mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
109        verify(mDataManager, never()).updateScheduledRecording(anyObject());
110    }
111
112    @Test
113    public void testHandleUpdateProgram_changeSeason() {
114        addSchedule(BASE_PROGRAM_ID, BASE_SERIES_SCHEDULE);
115        String seasonNumber = BASE_SEASON_NUMBER + "1";
116        String episodeNumber = BASE_EPISODE_NUMBER + "1";
117        Program program = new Program.Builder(BASE_SERIES_PROGRAM).setSeasonNumber(seasonNumber)
118                .setEpisodeNumber(episodeNumber).build();
119        mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
120        assertUpdateScheduleCalled(program);
121    }
122
123    @Test
124    public void testHandleUpdateProgram_finished() {
125        addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SERIES_SCHEDULE)
126                .setState(ScheduledRecording.STATE_RECORDING_FINISHED).build());
127        String seasonNumber = BASE_SEASON_NUMBER + "1";
128        String episodeNumber = BASE_EPISODE_NUMBER + "1";
129        Program program = new Program.Builder(BASE_SERIES_PROGRAM).setSeasonNumber(seasonNumber)
130                .setEpisodeNumber(episodeNumber).build();
131        mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
132        verify(mDataManager, never()).updateScheduledRecording(anyObject());
133    }
134
135    private void addSchedule(long programId, ScheduledRecording schedule) {
136        when(mDataManager.getScheduledRecordingForProgramId(programId)).thenReturn(schedule);
137    }
138
139    private void assertUpdateScheduleCalled(Program program) {
140        verify(mDataManager).updateScheduledRecording(
141                eq(ScheduledRecording.builder(INPUT_ID, program).build()));
142    }
143}
144