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.tests.ui;
18
19import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
20
21import android.support.test.filters.SmallTest;
22import android.support.test.uiautomator.BySelector;
23import android.support.test.uiautomator.UiObject2;
24import android.support.test.uiautomator.Until;
25
26import com.android.tv.R;
27import com.android.tv.testing.uihelper.ByResource;
28import com.android.tv.testing.uihelper.DialogHelper;
29
30@SmallTest
31public class ParentalControlsTest extends LiveChannelsTestCase {
32
33    private BySelector mBySettingsSidePanel;
34
35    @Override
36    protected void setUp() throws Exception {
37        super.setUp();
38        mLiveChannelsHelper.assertAppStarted();
39        mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
40                R.string.side_panel_title_settings);
41        prepareParentalControl();
42    }
43
44    @Override
45    protected void tearDown() throws Exception {
46        switchParentalControl(R.string.option_toggle_parental_controls_on);
47        super.tearDown();
48    }
49
50    public void testRatingDependentSelect() {
51        // Show ratings fragment.
52        BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
53                R.string.option_program_restrictions);
54        assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
55        mSidePanelHelper.assertNavigateToItem(R.string.option_ratings);
56        mDevice.pressDPadCenter();
57        // Block rating 6 and rating 12. Check if dependent select works well.
58        bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.option_ratings);
59        assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
60        // Test on blocking and unblocking Japanese rating.
61        int blockAge = 6;
62        int unBlockAge = 12;
63        int maxAge = 20;
64        int minAge = 4;
65        for (int age = minAge; age <= maxAge; age++) {
66            UiObject2 ratingCheckBox = mSidePanelHelper.assertNavigateToItem(String.valueOf(age))
67                    .findObject(ByResource.id(mTargetResources, R.id.check_box));
68            if (ratingCheckBox.isChecked()) {
69                mDevice.pressDPadCenter();
70            }
71        }
72        mSidePanelHelper.assertNavigateToItem(String.valueOf(blockAge));
73        mDevice.pressDPadCenter();
74        assertRatingViewIsChecked(minAge, maxAge, blockAge, true);
75        mSidePanelHelper.assertNavigateToItem(String.valueOf(unBlockAge));
76        mDevice.pressDPadCenter();
77        assertRatingViewIsChecked(minAge, maxAge, unBlockAge, false);
78        mDevice.pressBack();
79        mDevice.pressBack();
80        getInstrumentation().waitForIdleSync();
81    }
82
83    private void assertRatingViewIsChecked(int minAge, int maxAge, int selectedAge,
84            boolean expectedValue) {
85        for (int age = minAge; age <= maxAge; age++) {
86            UiObject2 ratingCheckBox = mSidePanelHelper.assertNavigateToItem(String.valueOf(age))
87                    .findObject(ByResource.id(mTargetResources, R.id.check_box));
88            if (age < selectedAge) {
89                assertTrue("The lower rating age should be unblocked", !ratingCheckBox.isChecked());
90            } else if (age > selectedAge) {
91                assertTrue("The higher rating age should be blocked", ratingCheckBox.isChecked());
92            } else {
93                assertEquals("The rating for age " + selectedAge + " isBlocked ", expectedValue,
94                        ratingCheckBox.isChecked());
95            }
96        }
97    }
98
99    /**
100     * Prepare the need for testRatingDependentSelect.
101     * 1. Turn on parental control if it's off.
102     * 2. Make sure Japan rating system is selected.
103     */
104    private void prepareParentalControl() {
105        showParentalControl();
106        switchParentalControl(R.string.option_toggle_parental_controls_off);
107        // Show all rating systems.
108        mSidePanelHelper.assertNavigateToItem(R.string.option_program_restrictions);
109        mDevice.pressDPadCenter();
110        BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
111                R.string.option_program_restrictions);
112        assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
113        mSidePanelHelper.assertNavigateToItem(R.string.option_country_rating_systems);
114        mDevice.pressDPadCenter();
115        bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.option_country_rating_systems);
116        assertWaitForCondition(mDevice,Until.hasObject(bySidePanel));
117        mSidePanelHelper.assertNavigateToItem(R.string.option_see_all_rating_systems);
118        mDevice.pressDPadCenter();
119        // Make sure Japan rating system is selected.
120        UiObject2 ratingSystemCheckBox = mSidePanelHelper.assertNavigateToItem("Japan")
121                .findObject(ByResource.id(mTargetResources, R.id.check_box));
122        if (!ratingSystemCheckBox.isChecked()) {
123            mDevice.pressDPadCenter();
124            getInstrumentation().waitForIdleSync();
125        }
126        mDevice.pressBack();
127    }
128
129    private void switchParentalControl(int oppositeStateResId) {
130        BySelector bySidePanel = mSidePanelHelper.byViewText(oppositeStateResId);
131        if (mDevice.hasObject(bySidePanel)) {
132            mSidePanelHelper.assertNavigateToItem(oppositeStateResId);
133            mDevice.pressDPadCenter();
134            getInstrumentation().waitForIdleSync();
135        }
136    }
137
138    private void showParentalControl() {
139        // Show menu and select parental controls.
140        mMenuHelper.showMenu();
141        mMenuHelper.assertPressOptionsSettings();
142        assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
143        mSidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
144        mDevice.pressDPadCenter();
145        // Enter pin code.
146        DialogHelper dialogHelper = new DialogHelper(mDevice, mTargetResources);
147        dialogHelper.assertWaitForPinDialogOpen();
148        dialogHelper.enterPinCodes();
149        dialogHelper.assertWaitForPinDialogClose();
150        BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
151                R.string.menu_parental_controls);
152        assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
153    }
154}
155