1 /* 2 * Copyright (C) 2020 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.systemui.qs; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.any; 22 import static org.mockito.Mockito.anyInt; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.verifyZeroInteractions; 26 import static org.mockito.Mockito.when; 27 28 import android.content.ClipData; 29 import android.content.ClipboardManager; 30 import android.testing.TestableLooper; 31 import android.view.View; 32 import android.widget.TextView; 33 34 import androidx.test.ext.junit.runners.AndroidJUnit4; 35 import androidx.test.filters.SmallTest; 36 37 import com.android.systemui.plugins.ActivityStarter; 38 import com.android.systemui.plugins.FalsingManager; 39 import com.android.systemui.res.R; 40 import com.android.systemui.retail.data.repository.FakeRetailModeRepository; 41 import com.android.systemui.retail.domain.interactor.RetailModeInteractorImpl; 42 import com.android.systemui.settings.UserTracker; 43 import com.android.systemui.utils.leaks.LeakCheckedTest; 44 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.mockito.ArgumentCaptor; 49 import org.mockito.Mock; 50 import org.mockito.MockitoAnnotations; 51 52 @RunWith(AndroidJUnit4.class) 53 @TestableLooper.RunWithLooper 54 @SmallTest 55 public class QSFooterViewControllerTest extends LeakCheckedTest { 56 57 @Mock 58 private QSFooterView mView; 59 @Mock 60 private UserTracker mUserTracker; 61 @Mock 62 private QSPanelController mQSPanelController; 63 @Mock 64 private ClipboardManager mClipboardManager; 65 @Mock 66 private TextView mBuildText; 67 @Mock 68 private FalsingManager mFalsingManager; 69 @Mock 70 private ActivityStarter mActivityStarter; 71 72 private FakeRetailModeRepository mRetailModeRepository; 73 74 private QSFooterViewController mController; 75 private View mEditButton; 76 77 @Before setup()78 public void setup() throws Exception { 79 MockitoAnnotations.initMocks(this); 80 81 mRetailModeRepository = new FakeRetailModeRepository(); 82 mRetailModeRepository.setRetailMode(false); 83 84 mEditButton = new View(mContext); 85 86 injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); 87 88 mContext.addMockSystemService(ClipboardManager.class, mClipboardManager); 89 90 when(mView.getContext()).thenReturn(mContext); 91 when(mView.getResources()).thenReturn(mContext.getResources()); 92 when(mUserTracker.getUserContext()).thenReturn(mContext); 93 94 when(mView.isAttachedToWindow()).thenReturn(true); 95 when(mView.findViewById(R.id.build)).thenReturn(mBuildText); 96 when(mView.findViewById(android.R.id.edit)).thenReturn(mEditButton); 97 98 mController = new QSFooterViewController(mView, mUserTracker, mFalsingManager, 99 mActivityStarter, mQSPanelController, 100 new RetailModeInteractorImpl(mRetailModeRepository)); 101 102 mController.init(); 103 } 104 105 @Test testBuildTextCopy()106 public void testBuildTextCopy() { 107 String text = "TEST"; 108 ArgumentCaptor<View.OnLongClickListener> onLongClickCaptor = 109 ArgumentCaptor.forClass(View.OnLongClickListener.class); 110 111 verify(mBuildText).setOnLongClickListener(onLongClickCaptor.capture()); 112 113 when(mBuildText.getText()).thenReturn(text); 114 onLongClickCaptor.getValue().onLongClick(mBuildText); 115 116 ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class); 117 verify(mClipboardManager).setPrimaryClip(captor.capture()); 118 assertThat(captor.getValue().getItemAt(0).getText()).isEqualTo(text); 119 } 120 121 @Test testEditButton_falseTap()122 public void testEditButton_falseTap() { 123 when(mFalsingManager.isFalseTap(anyInt())).thenReturn(true); 124 125 mEditButton.performClick(); 126 127 verify(mQSPanelController, never()).showEdit(any()); 128 verifyZeroInteractions(mActivityStarter); 129 } 130 131 @Test testEditButton_realTap()132 public void testEditButton_realTap() { 133 when(mFalsingManager.isFalseTap(anyInt())).thenReturn(false); 134 135 mEditButton.performClick(); 136 137 ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); 138 139 verify(mActivityStarter).postQSRunnableDismissingKeyguard(captor.capture()); 140 captor.getValue().run(); 141 verify(mQSPanelController).showEdit(mEditButton); 142 } 143 144 @Test testEditButton_notRetailMode_visible()145 public void testEditButton_notRetailMode_visible() { 146 mRetailModeRepository.setRetailMode(false); 147 148 mController.setVisibility(View.VISIBLE); 149 assertThat(mEditButton.getVisibility()).isEqualTo(View.VISIBLE); 150 } 151 152 @Test testEditButton_retailMode_notVisible()153 public void testEditButton_retailMode_notVisible() { 154 mRetailModeRepository.setRetailMode(true); 155 156 mController.setVisibility(View.VISIBLE); 157 assertThat(mEditButton.getVisibility()).isEqualTo(View.GONE); 158 } 159 } 160