1 /*
2  * Copyright (C) 2021 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 
17 package com.android.settings.accessibility;
18 
19 import static android.content.Context.MODE_PRIVATE;
20 
21 import static com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController.KEY_CUSTOM_DELAY_VALUE;
22 import static com.android.settings.accessibility.ToggleAutoclickPreferenceController.KEY_DELAY_MODE;
23 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.Mockito.doReturn;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.verify;
31 import static org.robolectric.Shadows.shadowOf;
32 
33 import android.content.Context;
34 import android.content.SharedPreferences;
35 import android.provider.Settings;
36 import android.widget.ImageView;
37 import android.widget.SeekBar;
38 import android.widget.TextView;
39 
40 import androidx.lifecycle.LifecycleObserver;
41 import androidx.preference.PreferenceScreen;
42 import androidx.test.core.app.ApplicationProvider;
43 
44 import com.android.settings.R;
45 import com.android.settingslib.core.lifecycle.Lifecycle;
46 import com.android.settingslib.widget.LayoutPreference;
47 
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 import org.robolectric.RobolectricTestRunner;
54 
55 /** Tests for {@link ToggleAutoclickCustomSeekbarController}. */
56 @RunWith(RobolectricTestRunner.class)
57 public class ToggleAutoclickCustomSeekbarControllerTest {
58 
59     @Mock
60     private PreferenceScreen mScreen;
61 
62     @Mock
63     private LayoutPreference mLayoutPreference;
64 
65     @Mock
66     private Lifecycle mLifecycle;
67 
68     private SharedPreferences mSharedPreferences;
69     private TextView mDelayLabel;
70     private ImageView mShorter;
71     private ImageView mLonger;
72     private SeekBar mSeekBar;
73     private ToggleAutoclickCustomSeekbarController mController;
74     private Context mContext;
75 
76     @Before
setUp()77     public void setUp() {
78         MockitoAnnotations.initMocks(this);
79 
80         final String mPrefKey = "prefKey";
81         mContext = ApplicationProvider.getApplicationContext();
82         mSharedPreferences = mContext.getSharedPreferences(mContext.getPackageName(), MODE_PRIVATE);
83         mDelayLabel = new TextView(mContext);
84         mShorter = new ImageView(mContext);
85         mLonger = new ImageView(mContext);
86         mSeekBar = new SeekBar(mContext);
87         mController =
88                 new ToggleAutoclickCustomSeekbarController(mContext, mLifecycle, mPrefKey);
89 
90         doReturn(mLayoutPreference).when(mScreen).findPreference(mPrefKey);
91         doReturn(mSeekBar).when(mLayoutPreference).findViewById(R.id.autoclick_delay);
92         doReturn(mDelayLabel).when(mLayoutPreference).findViewById(R.id.current_label);
93         doReturn(mShorter).when(mLayoutPreference).findViewById(R.id.shorter);
94         doReturn(mLonger).when(mLayoutPreference).findViewById(R.id.longer);
95     }
96 
97     @Test
getAvailabilityStatus_available()98     public void getAvailabilityStatus_available() {
99         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
100     }
101 
102     @Test
constructor_hasLifecycle_addObserver()103     public void constructor_hasLifecycle_addObserver() {
104         verify(mLifecycle).addObserver(any(LifecycleObserver.class));
105     }
106 
107     @Test
displayPreference_initSeekBar()108     public void displayPreference_initSeekBar() {
109         mSharedPreferences.edit().putInt(KEY_CUSTOM_DELAY_VALUE, 700).apply();
110 
111         mController.onResume();
112         mController.displayPreference(mScreen);
113         mController.onPause();
114         final SeekBar.OnSeekBarChangeListener mListener =
115                 shadowOf(mSeekBar).getOnSeekBarChangeListener();
116 
117         assertThat(mSeekBar.getMax()).isEqualTo(8);
118         assertThat(mSeekBar.getProgress()).isEqualTo(5);
119         assertThat(mListener).isNotNull();
120     }
121 
122     @Test
displayPreference_initDelayLabel()123     public void displayPreference_initDelayLabel() {
124         mSharedPreferences.edit().putInt(KEY_CUSTOM_DELAY_VALUE, 700).apply();
125 
126         mController.onResume();
127         mController.displayPreference(mScreen);
128         mController.onPause();
129 
130         assertThat(mDelayLabel.getText()).isEqualTo("0.7 seconds");
131     }
132 
133     @Test
onSharedPreferenceChanged_delayMode_updateCustomDelayValue()134     public void onSharedPreferenceChanged_delayMode_updateCustomDelayValue() {
135         mSharedPreferences.edit().putInt(KEY_CUSTOM_DELAY_VALUE, 700).apply();
136 
137         mController.displayPreference(mScreen);
138         mController.onSharedPreferenceChanged(mSharedPreferences, KEY_DELAY_MODE);
139         final int actualDelayValue =
140                 Settings.Secure.getInt(mContext.getContentResolver(),
141                         Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, /* def= */ 0);
142         final int actualCustomDelayValue =
143                 mSharedPreferences.getInt(KEY_CUSTOM_DELAY_VALUE, /* defValue= */ 0);
144 
145         assertThat(mDelayLabel.getText()).isEqualTo("0.7 seconds");
146         assertThat(mSeekBar.getProgress()).isEqualTo(5);
147         assertThat(actualDelayValue).isEqualTo(700);
148         assertThat(actualCustomDelayValue).isEqualTo(700);
149     }
150 
151     @Test
onSeekBarProgressChanged_updateCustomDelayValue()152     public void onSeekBarProgressChanged_updateCustomDelayValue() {
153         mSharedPreferences.edit().putInt(KEY_CUSTOM_DELAY_VALUE, 700).apply();
154 
155         mController.displayPreference(mScreen);
156         mController.mSeekBarChangeListener.onProgressChanged(mock(SeekBar.class),
157                 /* value= */ 8,
158                 true);
159         final int actualDelayValue =
160                 Settings.Secure.getInt(mContext.getContentResolver(),
161                         Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, /* def= */ 0);
162         final int actualCustomDelayValue =
163                 mSharedPreferences.getInt(KEY_CUSTOM_DELAY_VALUE, /* defValue= */ 0);
164 
165         assertThat(mDelayLabel.getText()).isEqualTo("1 second");
166         assertThat(mSeekBar.getProgress()).isEqualTo(8);
167         assertThat(actualDelayValue).isEqualTo(1000);
168         assertThat(actualCustomDelayValue).isEqualTo(1000);
169     }
170 
171     @Test
onShorterClicked_updateCustomDelayValue()172     public void onShorterClicked_updateCustomDelayValue() {
173         mSharedPreferences.edit().putInt(KEY_CUSTOM_DELAY_VALUE, 700).apply();
174 
175         mController.displayPreference(mScreen);
176         mShorter.callOnClick();
177         final int actualDelayValue =
178                 Settings.Secure.getInt(mContext.getContentResolver(),
179                 Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, /* def= */ 0);
180         final int actualCustomDelayValue =
181                 mSharedPreferences.getInt(KEY_CUSTOM_DELAY_VALUE, /* defValue= */ 0);
182 
183         assertThat(mSeekBar.getProgress()).isEqualTo(4);
184         assertThat(mDelayLabel.getText()).isEqualTo("0.6 seconds");
185         assertThat(actualDelayValue).isEqualTo(600);
186         assertThat(actualCustomDelayValue).isEqualTo(600);
187     }
188 
189     @Test
onLongerClicked_updateCustomDelayValue()190     public void onLongerClicked_updateCustomDelayValue() {
191         mSharedPreferences.edit().putInt(KEY_CUSTOM_DELAY_VALUE, 700).apply();
192 
193         mController.displayPreference(mScreen);
194         mLonger.callOnClick();
195         final int actualDelayValue =
196                 Settings.Secure.getInt(mContext.getContentResolver(),
197                         Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, /* def= */ 0);
198         final int actualCustomDelayValue =
199                 mSharedPreferences.getInt(KEY_CUSTOM_DELAY_VALUE, /* defValue= */ 0);
200 
201         assertThat(mSeekBar.getProgress()).isEqualTo(6);
202         assertThat(mDelayLabel.getText()).isEqualTo("0.8 seconds");
203         assertThat(actualDelayValue).isEqualTo(800);
204         assertThat(actualCustomDelayValue).isEqualTo(800);
205     }
206 }
207