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.deviceinfo;
18 
19 import static org.mockito.Mockito.atLeastOnce;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.never;
22 import static org.mockito.Mockito.spy;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import android.content.Context;
27 import android.content.pm.PackageManager;
28 import android.os.storage.DiskInfo;
29 import android.os.storage.StorageManager;
30 import android.os.storage.VolumeInfo;
31 import android.os.storage.VolumeRecord;
32 import android.view.Menu;
33 
34 import androidx.fragment.app.Fragment;
35 import androidx.test.core.app.ApplicationProvider;
36 import androidx.test.ext.junit.runners.AndroidJUnit4;
37 
38 import com.android.settings.deviceinfo.storage.StorageEntry;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.Answers;
44 import org.mockito.Mock;
45 import org.mockito.MockitoAnnotations;
46 
47 @RunWith(AndroidJUnit4.class)
48 public class VolumeOptionMenuControllerTest {
49 
50     private static final String INTERNAL_VOLUME_ID = "1";
51     private static final String EXTERNAL_VOLUME_ID = "2";
52     private static final String DISK_ID = "3";
53     private static final String VOLUME_RECORD_FSUUID = "volume_record_fsuuid";
54 
55     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
56     private Menu mMenu;
57     @Mock private PackageManager mPackageManager;
58     @Mock private VolumeInfo mExternalVolumeInfo;
59     @Mock private VolumeInfo mInternalVolumeInfo;
60 
61     private Context mContext;
62     private VolumeOptionMenuController mController;
63 
64     @Before
setUp()65     public void setUp() {
66         MockitoAnnotations.initMocks(this);
67 
68         mContext = spy(ApplicationProvider.getApplicationContext());
69         when(mContext.getPackageManager()).thenReturn(mPackageManager);
70 
71         when(mInternalVolumeInfo.getId()).thenReturn(INTERNAL_VOLUME_ID);
72         when(mInternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
73         when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
74         when(mInternalVolumeInfo.isMountedWritable()).thenReturn(true);
75         when(mExternalVolumeInfo.getId()).thenReturn(EXTERNAL_VOLUME_ID);
76 
77         final StorageEntry selectedStorageEntry = new StorageEntry(mContext, mInternalVolumeInfo);
78         mController = new VolumeOptionMenuController(mContext, mock(Fragment.class),
79                 selectedStorageEntry);
80     }
81 
82     @Test
onPrepareOptionsMenu_unSupportedDiskInfo_formatIsVisible()83     public void onPrepareOptionsMenu_unSupportedDiskInfo_formatIsVisible() {
84         final StorageEntry unsupportedStorageEntry =
85                 new StorageEntry(new DiskInfo(DISK_ID, 0 /* flags */));
86         mController.setSelectedStorageEntry(unsupportedStorageEntry);
87 
88         mController.onPrepareOptionsMenu(mMenu);
89 
90         verify(mController.mFormat, atLeastOnce()).setVisible(true);
91         verify(mController.mRename, never()).setVisible(true);
92         verify(mController.mMount, never()).setVisible(true);
93         verify(mController.mUnmount, never()).setVisible(true);
94         verify(mController.mFormatAsPortable, never()).setVisible(true);
95         verify(mController.mFormatAsInternal, never()).setVisible(true);
96         verify(mController.mMigrate, never()).setVisible(true);
97         verify(mController.mFree, never()).setVisible(true);
98         verify(mController.mForget, never()).setVisible(true);
99     }
100 
101     @Test
onPrepareOptionsMenu_missingVolumeRecord_forgetIsVisible()102     public void onPrepareOptionsMenu_missingVolumeRecord_forgetIsVisible() {
103         final StorageEntry missingStorageEntry =
104                 new StorageEntry(new VolumeRecord(0 /* type */, VOLUME_RECORD_FSUUID));
105         mController.setSelectedStorageEntry(missingStorageEntry);
106 
107         mController.onPrepareOptionsMenu(mMenu);
108 
109         verify(mController.mForget, atLeastOnce()).setVisible(true);
110         verify(mController.mRename, never()).setVisible(true);
111         verify(mController.mMount, never()).setVisible(true);
112         verify(mController.mUnmount, never()).setVisible(true);
113         verify(mController.mFormat, never()).setVisible(true);
114         verify(mController.mFormatAsPortable, never()).setVisible(true);
115         verify(mController.mFormatAsInternal, never()).setVisible(true);
116         verify(mController.mMigrate, never()).setVisible(true);
117         verify(mController.mFree, never()).setVisible(true);
118     }
119 
120     @Test
onPrepareOptionsMenu_unmountedStorage_mountIsVisible()121     public void onPrepareOptionsMenu_unmountedStorage_mountIsVisible() {
122         when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_UNMOUNTED);
123         mController.setSelectedStorageEntry(new StorageEntry(mContext, mInternalVolumeInfo));
124 
125         mController.onPrepareOptionsMenu(mMenu);
126 
127         verify(mController.mMount, atLeastOnce()).setVisible(true);
128         verify(mController.mRename, never()).setVisible(true);
129         verify(mController.mUnmount, never()).setVisible(true);
130         verify(mController.mFormat, never()).setVisible(true);
131         verify(mController.mFormatAsPortable, never()).setVisible(true);
132         verify(mController.mFormatAsInternal, never()).setVisible(true);
133         verify(mController.mMigrate, never()).setVisible(true);
134         verify(mController.mFree, never()).setVisible(true);
135         verify(mController.mForget, never()).setVisible(true);
136     }
137 
138     @Test
onPrepareOptionsMenu_privateNotDefaultInternal_someMenusAreVisible()139     public void onPrepareOptionsMenu_privateNotDefaultInternal_someMenusAreVisible() {
140         mController.onPrepareOptionsMenu(mMenu);
141 
142         verify(mController.mRename, atLeastOnce()).setVisible(true);
143         verify(mController.mFormatAsPortable, atLeastOnce()).setVisible(true);
144         verify(mController.mMount, never()).setVisible(true);
145         verify(mController.mFormat, never()).setVisible(true);
146         verify(mController.mFormatAsInternal, never()).setVisible(true);
147         verify(mController.mFree, never()).setVisible(true);
148         verify(mController.mForget, never()).setVisible(true);
149     }
150 
151     @Test
onPrepareOptionsMenu_privateDefaultInternal_mostMenusAreNotVisible()152     public void onPrepareOptionsMenu_privateDefaultInternal_mostMenusAreNotVisible() {
153         when(mInternalVolumeInfo.getId()).thenReturn(VolumeInfo.ID_PRIVATE_INTERNAL);
154         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
155 
156         mController.onPrepareOptionsMenu(mMenu);
157 
158         verify(mController.mRename, never()).setVisible(true);
159         verify(mController.mUnmount, never()).setVisible(true);
160         verify(mController.mFormatAsPortable, never()).setVisible(true);
161         verify(mController.mMount, never()).setVisible(true);
162         verify(mController.mFormat, never()).setVisible(true);
163         verify(mController.mFormatAsInternal, never()).setVisible(true);
164         verify(mController.mFree, never()).setVisible(true);
165         verify(mController.mForget, never()).setVisible(true);
166     }
167 
168     @Test
onPrepareOptionsMenu_publicStorage_someMenusArcVisible()169     public void onPrepareOptionsMenu_publicStorage_someMenusArcVisible() {
170         when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
171         when(mExternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
172         when(mExternalVolumeInfo.getDiskId()).thenReturn(DISK_ID);
173         final DiskInfo externalDiskInfo = mock(DiskInfo.class);
174         mController.setSelectedStorageEntry(new StorageEntry(mContext, mExternalVolumeInfo));
175 
176         mController.onPrepareOptionsMenu(mMenu);
177 
178         verify(mController.mRename, atLeastOnce()).setVisible(true);
179         verify(mController.mUnmount, atLeastOnce()).setVisible(true);
180         verify(mController.mFormatAsInternal, atLeastOnce()).setVisible(true);
181         verify(mController.mFormatAsPortable, never()).setVisible(true);
182         verify(mController.mFormat, never()).setVisible(true);
183         verify(mController.mMount, never()).setVisible(true);
184         verify(mController.mFree, never()).setVisible(true);
185         verify(mController.mForget, never()).setVisible(true);
186     }
187 
188     @Test
onPrepareOptionsMenu_noExternalStorage_migrateNotVisible()189     public void onPrepareOptionsMenu_noExternalStorage_migrateNotVisible() {
190         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
191 
192         mController.onPrepareOptionsMenu(mMenu);
193 
194         verify(mController.mMigrate, atLeastOnce()).setVisible(false);
195         verify(mController.mMigrate, never()).setVisible(true);
196     }
197 
198     @Test
onPrepareOptionsMenu_externalPrimaryStorageAvailable_migrateIsVisible()199     public void onPrepareOptionsMenu_externalPrimaryStorageAvailable_migrateIsVisible() {
200         when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
201         when(mExternalVolumeInfo.isMountedWritable()).thenReturn(true);
202         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
203 
204         mController.onPrepareOptionsMenu(mMenu);
205 
206         verify(mController.mMigrate, atLeastOnce()).setVisible(true);
207     }
208 
209     @Test
onPrepareOptionsMenu_externalUnmounted_migrateIsVisible()210     public void onPrepareOptionsMenu_externalUnmounted_migrateIsVisible() {
211         when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
212         when(mExternalVolumeInfo.isMountedWritable()).thenReturn(false);
213         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
214 
215         mController.onPrepareOptionsMenu(mMenu);
216 
217         verify(mController.mMigrate, atLeastOnce()).setVisible(false);
218         verify(mController.mMigrate, never()).setVisible(true);
219     }
220 }
221