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 
17 package com.android.documentsui.files;
18 
19 import static junit.framework.Assert.assertEquals;
20 
21 import static org.junit.Assert.assertTrue;
22 
23 import android.net.Uri;
24 import android.provider.DocumentsContract.Document;
25 import android.provider.DocumentsContract.Root;
26 
27 import androidx.recyclerview.selection.SelectionTracker;
28 import androidx.test.filters.SmallTest;
29 import androidx.test.runner.AndroidJUnit4;
30 
31 import com.android.documentsui.R;
32 import com.android.documentsui.SelectionHelpers;
33 import com.android.documentsui.base.DocumentInfo;
34 import com.android.documentsui.base.RootInfo;
35 import com.android.documentsui.base.State;
36 import com.android.documentsui.base.UserId;
37 import com.android.documentsui.dirlist.TestData;
38 import com.android.documentsui.testing.TestDirectoryDetails;
39 import com.android.documentsui.testing.TestEnv;
40 import com.android.documentsui.testing.TestFeatures;
41 import com.android.documentsui.testing.TestMenu;
42 import com.android.documentsui.testing.TestMenuInflater;
43 import com.android.documentsui.testing.TestMenuItem;
44 import com.android.documentsui.testing.TestSearchViewManager;
45 import com.android.documentsui.testing.TestSelectionDetails;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 
51 @RunWith(AndroidJUnit4.class)
52 @SmallTest
53 public final class MenuManagerTest {
54 
55     private TestMenu testMenu;
56 
57     /* Directory Context Menu items */
58     private TestMenuItem dirShare;
59     private TestMenuItem dirOpen;
60     private TestMenuItem dirOpenWith;
61     private TestMenuItem dirCutToClipboard;
62     private TestMenuItem dirCopyToClipboard;
63     private TestMenuItem dirPasteFromClipboard;
64     private TestMenuItem dirCreateDir;
65     private TestMenuItem dirSelectAll;
66     private TestMenuItem mDirDeselectAll;
67     private TestMenuItem dirRename;
68     private TestMenuItem dirDelete;
69     private TestMenuItem dirViewInOwner;
70     private TestMenuItem dirPasteIntoFolder;
71     private TestMenuItem dirInspect;
72     private TestMenuItem dirOpenInNewWindow;
73 
74     /* Root List Context Menu items */
75     private TestMenuItem rootEjectRoot;
76     private TestMenuItem rootOpenInNewWindow;
77     private TestMenuItem rootPasteIntoFolder;
78     private TestMenuItem rootSettings;
79 
80     /* Action Mode menu items */
81     private TestMenuItem actionModeOpen;
82     private TestMenuItem actionModeOpenWith;
83     private TestMenuItem actionModeShare;
84     private TestMenuItem actionModeDelete;
85     private TestMenuItem actionModeSelectAll;
86     private TestMenuItem mActionModeDeselectAll;
87     private TestMenuItem actionModeCopyTo;
88     private TestMenuItem actionModeExtractTo;
89     private TestMenuItem actionModeMoveTo;
90     private TestMenuItem actionModeCompress;
91     private TestMenuItem actionModeRename;
92     private TestMenuItem actionModeViewInOwner;
93     private TestMenuItem actionModeInspector;
94     private TestMenuItem actionModeSort;
95 
96     /* Option Menu items */
97     private TestMenuItem optionSearch;
98     private TestMenuItem optionDebug;
99     private TestMenuItem optionNewWindow;
100     private TestMenuItem optionCreateDir;
101     private TestMenuItem optionSelectAll;
102     private TestMenuItem optionSettings;
103     private TestMenuItem optionInspector;
104     private TestMenuItem optionSort;
105     private TestMenuItem mOptionLauncher;
106     private TestMenuItem mOptionShowHiddenFiles;
107 
108     /* Sub Option Menu items */
109     private TestMenuItem subOptionGrid;
110     private TestMenuItem subOptionList;
111 
112     private TestFeatures features;
113     private TestSelectionDetails selectionDetails;
114     private TestDirectoryDetails dirDetails;
115     private TestSearchViewManager testSearchManager;
116     private RootInfo testRootInfo;
117     private DocumentInfo testDocInfo;
118     private State state = new State();
119     private MenuManager mgr;
120     private TestActivity activity = TestActivity.create(TestEnv.create());
121     private SelectionTracker<String> selectionManager;
122 
123     private int mFilesCount;
124 
125     @Before
setUp()126     public void setUp() {
127         testMenu = TestMenu.create();
128 
129         // The context menu on anything in DirectoryList (including no selection).
130         dirShare = testMenu.findItem(R.id.dir_menu_share);
131         dirOpen = testMenu.findItem(R.id.dir_menu_open);
132         dirOpenWith = testMenu.findItem(R.id.dir_menu_open_with);
133         dirCutToClipboard = testMenu.findItem(R.id.dir_menu_cut_to_clipboard);
134         dirCopyToClipboard = testMenu.findItem(R.id.dir_menu_copy_to_clipboard);
135         dirPasteFromClipboard = testMenu.findItem(R.id.dir_menu_paste_from_clipboard);
136         dirCreateDir = testMenu.findItem(R.id.dir_menu_create_dir);
137         dirSelectAll = testMenu.findItem(R.id.dir_menu_select_all);
138         mDirDeselectAll = testMenu.findItem(R.id.dir_menu_deselect_all);
139         dirRename = testMenu.findItem(R.id.dir_menu_rename);
140         dirDelete = testMenu.findItem(R.id.dir_menu_delete);
141         dirViewInOwner = testMenu.findItem(R.id.dir_menu_view_in_owner);
142         dirPasteIntoFolder = testMenu.findItem(R.id.dir_menu_paste_into_folder);
143         dirInspect = testMenu.findItem(R.id.dir_menu_inspect);
144         dirOpenInNewWindow = testMenu.findItem(R.id.dir_menu_open_in_new_window);
145 
146         rootEjectRoot = testMenu.findItem(R.id.root_menu_eject_root);
147         rootOpenInNewWindow = testMenu.findItem(R.id.root_menu_open_in_new_window);
148         rootPasteIntoFolder = testMenu.findItem(R.id.root_menu_paste_into_folder);
149         rootSettings = testMenu.findItem(R.id.root_menu_settings);
150 
151         // Menu actions (including overflow) when action mode *is* active.
152         actionModeOpenWith = testMenu.findItem(R.id.action_menu_open_with);
153         actionModeShare = testMenu.findItem(R.id.action_menu_share);
154         actionModeDelete = testMenu.findItem(R.id.action_menu_delete);
155         actionModeSelectAll = testMenu.findItem(R.id.action_menu_select_all);
156         mActionModeDeselectAll = testMenu.findItem(R.id.action_menu_deselect_all);
157         actionModeCopyTo = testMenu.findItem(R.id.action_menu_copy_to);
158         actionModeExtractTo = testMenu.findItem(R.id.action_menu_extract_to);
159         actionModeMoveTo = testMenu.findItem(R.id.action_menu_move_to);
160         actionModeCompress = testMenu.findItem(R.id.action_menu_compress);
161         actionModeRename = testMenu.findItem(R.id.action_menu_rename);
162         actionModeInspector = testMenu.findItem(R.id.action_menu_inspect);
163         actionModeViewInOwner = testMenu.findItem(R.id.action_menu_view_in_owner);
164         actionModeSort = testMenu.findItem(R.id.action_menu_sort);
165 
166         // Menu actions (including overflow) when action mode is not active.
167         optionSearch = testMenu.findItem(R.id.option_menu_search);
168         optionDebug = testMenu.findItem(R.id.option_menu_debug);
169         optionNewWindow = testMenu.findItem(R.id.option_menu_new_window);
170         optionCreateDir = testMenu.findItem(R.id.option_menu_create_dir);
171         optionSelectAll = testMenu.findItem(R.id.option_menu_select_all);
172         optionSettings = testMenu.findItem(R.id.option_menu_settings);
173         optionInspector = testMenu.findItem(R.id.option_menu_inspect);
174         optionSort = testMenu.findItem(R.id.option_menu_sort);
175         mOptionLauncher = testMenu.findItem(R.id.option_menu_launcher);
176         mOptionShowHiddenFiles = testMenu.findItem(R.id.option_menu_show_hidden_files);
177 
178         // Menu actions on root title row.
179         subOptionGrid = testMenu.findItem(R.id.sub_menu_grid);
180         subOptionList = testMenu.findItem(R.id.sub_menu_list);
181 
182         features = new TestFeatures();
183 
184         // These items by default are visible
185         testMenu.findItem(R.id.dir_menu_select_all).setVisible(true);
186         testMenu.findItem(R.id.option_menu_select_all).setVisible(true);
187         testMenu.findItem(R.id.sub_menu_list).setVisible(true);
188 
189         selectionDetails = new TestSelectionDetails();
190         dirDetails = new TestDirectoryDetails();
191         testSearchManager = new TestSearchViewManager();
192         selectionManager = SelectionHelpers.createTestInstance(TestData.create(1));
193         selectionManager.select("0");
194 
195         selectionDetails.size = 1;
196         mFilesCount = 10;
197 
198         mgr = new MenuManager(
199                 features,
200                 testSearchManager,
201                 state,
202                 dirDetails,
203                 activity,
204                 selectionManager,
205                 this::getApplicationNameFromAuthority,
206                 this::getUriFromModelId,
207                 this::getFilesCount);
208 
209         testRootInfo = new RootInfo();
210         testDocInfo = new DocumentInfo();
211         state.stack.push(testDocInfo);
212     }
213 
getUriFromModelId(String id)214     private Uri getUriFromModelId(String id) {
215         return Uri.EMPTY;
216     }
217 
getApplicationNameFromAuthority(UserId userId, String authority)218     private String getApplicationNameFromAuthority(UserId userId, String authority) {
219         return "TestApp";
220     }
221 
getFilesCount()222     private int getFilesCount() {
223         return mFilesCount;
224     }
225 
226     @Test
testActionMenu()227     public void testActionMenu() {
228         selectionDetails.canDelete = true;
229         selectionDetails.canRename = true;
230         dirDetails.canCreateDoc = true;
231 
232         mgr.updateActionMenu(testMenu, selectionDetails);
233 
234         actionModeRename.assertEnabledAndVisible();
235         actionModeDelete.assertEnabledAndVisible();
236         actionModeShare.assertEnabledAndVisible();
237         actionModeCopyTo.assertEnabledAndVisible();
238         actionModeCompress.assertEnabledAndVisible();
239         actionModeExtractTo.assertDisabledAndInvisible();
240         actionModeMoveTo.assertEnabledAndVisible();
241         actionModeViewInOwner.assertDisabledAndInvisible();
242         actionModeSort.assertEnabledAndVisible();
243         actionModeSelectAll.assertEnabledAndVisible();
244         mActionModeDeselectAll.assertDisabledAndInvisible();
245     }
246 
247     @Test
testActionMenu_ContainsPartial()248     public void testActionMenu_ContainsPartial() {
249         selectionDetails.containPartial = true;
250         dirDetails.canCreateDoc = true;
251         mgr.updateActionMenu(testMenu, selectionDetails);
252 
253         actionModeRename.assertDisabledAndInvisible();
254         actionModeShare.assertDisabledAndInvisible();
255         actionModeCopyTo.assertDisabledAndInvisible();
256         actionModeCompress.assertDisabledAndInvisible();
257         actionModeExtractTo.assertDisabledAndInvisible();
258         actionModeMoveTo.assertDisabledAndInvisible();
259         actionModeViewInOwner.assertDisabledAndInvisible();
260     }
261 
262     @Test
testActionMenu_CreateArchives_ReflectsFeatureState()263     public void testActionMenu_CreateArchives_ReflectsFeatureState() {
264         features.archiveCreation = false;
265         dirDetails.canCreateDoc = true;
266         mgr.updateActionMenu(testMenu, selectionDetails);
267 
268         actionModeCompress.assertDisabledAndInvisible();
269     }
270 
271     @Test
testActionMenu_CreateArchive()272     public void testActionMenu_CreateArchive() {
273         dirDetails.canCreateDoc = true;
274         mgr.updateActionMenu(testMenu, selectionDetails);
275 
276         actionModeCompress.assertEnabledAndVisible();
277     }
278 
279     @Test
testActionMenu_NoCreateArchive()280     public void testActionMenu_NoCreateArchive() {
281         dirDetails.canCreateDoc = false;
282         mgr.updateActionMenu(testMenu, selectionDetails);
283 
284         actionModeCompress.assertDisabledAndInvisible();
285     }
286 
287     @Test
testActionMenu_cantRename()288     public void testActionMenu_cantRename() {
289         selectionDetails.canRename = false;
290         mgr.updateActionMenu(testMenu, selectionDetails);
291 
292         actionModeRename.assertDisabledAndInvisible();
293     }
294 
295     @Test
testActionMenu_cantDelete()296     public void testActionMenu_cantDelete() {
297         selectionDetails.canDelete = false;
298         mgr.updateActionMenu(testMenu, selectionDetails);
299 
300         actionModeDelete.assertDisabledAndInvisible();
301         // We shouldn't be able to move files if we can't delete them
302         actionModeMoveTo.assertDisabledAndInvisible();
303     }
304 
305     @Test
testActionsMenu_canViewInOwner()306     public void testActionsMenu_canViewInOwner() {
307         activity.resources.strings.put(R.string.menu_view_in_owner, "Insert name here! %s");
308         selectionDetails.canViewInOwner = true;
309         mgr.updateActionMenu(testMenu, selectionDetails);
310 
311         actionModeViewInOwner.assertEnabledAndVisible();
312     }
313 
314     @Test
testActionsMenu_cantViewInOwner_noSelection()315     public void testActionsMenu_cantViewInOwner_noSelection() {
316         // Simulate empty selection
317         selectionManager = SelectionHelpers.createTestInstance();
318         mgr = new MenuManager(
319                 features,
320                 testSearchManager,
321                 state,
322                 dirDetails,
323                 activity,
324                 selectionManager,
325                 this::getApplicationNameFromAuthority,
326                 this::getUriFromModelId,
327                 this::getFilesCount);
328 
329         selectionDetails.canViewInOwner = true;
330         mgr.updateActionMenu(testMenu, selectionDetails);
331 
332         actionModeViewInOwner.assertDisabledAndInvisible();
333     }
334 
335     @Test
testActionMenu_changeToCanDelete()336     public void testActionMenu_changeToCanDelete() {
337         selectionDetails.canDelete = false;
338         mgr.updateActionMenu(testMenu, selectionDetails);
339 
340         selectionDetails.canDelete = true;
341         mgr.updateActionMenu(testMenu, selectionDetails);
342 
343         actionModeDelete.assertEnabledAndVisible();
344         actionModeMoveTo.assertEnabledAndVisible();
345     }
346 
347     @Test
testActionMenu_ContainsDirectory()348     public void testActionMenu_ContainsDirectory() {
349         selectionDetails.containDirectories = true;
350         mgr.updateActionMenu(testMenu, selectionDetails);
351 
352         // We can't share directories
353         actionModeShare.assertDisabledAndInvisible();
354     }
355 
356     @Test
testActionMenu_RemovesDirectory()357     public void testActionMenu_RemovesDirectory() {
358         selectionDetails.containDirectories = true;
359         mgr.updateActionMenu(testMenu, selectionDetails);
360 
361         selectionDetails.containDirectories = false;
362         mgr.updateActionMenu(testMenu, selectionDetails);
363 
364         actionModeShare.assertEnabledAndVisible();
365     }
366 
367     @Test
testActionMenu_CantExtract()368     public void testActionMenu_CantExtract() {
369         selectionDetails.canExtract = false;
370         mgr.updateActionMenu(testMenu, selectionDetails);
371 
372         actionModeExtractTo.assertDisabledAndInvisible();
373     }
374 
375     @Test
testActionMenu_CanExtract_hidesCopyToAndCompressAndShare()376     public void testActionMenu_CanExtract_hidesCopyToAndCompressAndShare() {
377         features.archiveCreation = true;
378         selectionDetails.canExtract = true;
379         dirDetails.canCreateDoc = true;
380         mgr.updateActionMenu(testMenu, selectionDetails);
381 
382         actionModeExtractTo.assertEnabledAndVisible();
383         actionModeCopyTo.assertDisabledAndInvisible();
384         actionModeCompress.assertDisabledAndInvisible();
385     }
386 
387     @Test
testActionMenu_CanOpenWith()388     public void testActionMenu_CanOpenWith() {
389         selectionDetails.canOpenWith = true;
390         mgr.updateActionMenu(testMenu, selectionDetails);
391 
392         actionModeOpenWith.assertEnabledAndVisible();
393     }
394 
395     @Test
testActionMenu_NoOpenWith()396     public void testActionMenu_NoOpenWith() {
397         selectionDetails.canOpenWith = false;
398         mgr.updateActionMenu(testMenu, selectionDetails);
399 
400         actionModeOpenWith.assertDisabledAndInvisible();
401     }
402 
403     @Test
testActionMenu_Inspector_EnabledForSingleSelection()404     public void testActionMenu_Inspector_EnabledForSingleSelection() {
405         features.inspector = true;
406         selectionDetails.size = 1;
407         mgr.updateActionMenu(testMenu, selectionDetails);
408 
409         actionModeInspector.assertEnabledAndVisible();
410     }
411 
412     @Test
testActionMenu_Inspector_DisabledForMultiSelection()413     public void testActionMenu_Inspector_DisabledForMultiSelection() {
414         features.inspector = true;
415         selectionDetails.size = 2;
416         mgr.updateActionMenu(testMenu, selectionDetails);
417 
418         actionModeInspector.assertDisabledAndInvisible();
419     }
420 
421     @Test
testActionMenu_CanDeselectAll()422     public void testActionMenu_CanDeselectAll() {
423         selectionDetails.size = 1;
424         mFilesCount = 1;
425 
426         mgr.updateActionMenu(testMenu, selectionDetails);
427 
428         actionModeSelectAll.assertDisabledAndInvisible();
429         mActionModeDeselectAll.assertEnabledAndVisible();
430     }
431 
432     @Test
testOptionMenu()433     public void testOptionMenu() {
434         mgr.updateOptionMenu(testMenu);
435 
436         optionCreateDir.assertDisabledAndInvisible();
437         optionDebug.assertDisabledAndInvisible();
438         optionSort.assertEnabledAndVisible();
439         mOptionLauncher.assertDisabledAndInvisible();
440         mOptionShowHiddenFiles.assertEnabledAndVisible();
441         assertTrue(testSearchManager.updateMenuCalled());
442     }
443 
444     @Test
testOptionMenu_CanCreateDirectory()445     public void testOptionMenu_CanCreateDirectory() {
446         dirDetails.canCreateDirectory = true;
447         mgr.updateOptionMenu(testMenu);
448 
449         optionCreateDir.assertEnabledAndVisible();
450     }
451 
452     @Test
testOptionMenu_HasRootSettings()453     public void testOptionMenu_HasRootSettings() {
454         dirDetails.hasRootSettings = true;
455         mgr.updateOptionMenu(testMenu);
456 
457         optionSettings.assertEnabledAndVisible();
458     }
459 
460     @Test
testOptionMenu_Inspector_VisibleAndEnabled()461     public void testOptionMenu_Inspector_VisibleAndEnabled() {
462         features.inspector = true;
463         dirDetails.canInspectDirectory = true;
464         mgr.updateOptionMenu(testMenu);
465         optionInspector.assertEnabledAndVisible();
466     }
467 
468     @Test
testOptionMenu_Inspector_VisibleButDisabled()469     public void testOptionMenu_Inspector_VisibleButDisabled() {
470         features.inspector = true;
471         dirDetails.canInspectDirectory = false;
472         mgr.updateOptionMenu(testMenu);
473         optionInspector.assertDisabledAndInvisible();
474     }
475 
476     @Test
testInflateContextMenu_Files()477     public void testInflateContextMenu_Files() {
478         TestMenuInflater inflater = new TestMenuInflater();
479 
480         selectionDetails.containFiles = true;
481         selectionDetails.containDirectories = false;
482         mgr.inflateContextMenuForDocs(testMenu, inflater, selectionDetails);
483 
484         assertEquals(R.menu.file_context_menu, inflater.lastInflatedMenuId);
485     }
486 
487     @Test
testInflateContextMenu_Dirs()488     public void testInflateContextMenu_Dirs() {
489         TestMenuInflater inflater = new TestMenuInflater();
490 
491         selectionDetails.containFiles = false;
492         selectionDetails.containDirectories = true;
493         mgr.inflateContextMenuForDocs(testMenu, inflater, selectionDetails);
494 
495         assertEquals(R.menu.dir_context_menu, inflater.lastInflatedMenuId);
496     }
497 
498     @Test
testInflateContextMenu_Mixed()499     public void testInflateContextMenu_Mixed() {
500         TestMenuInflater inflater = new TestMenuInflater();
501 
502         selectionDetails.containFiles = true;
503         selectionDetails.containDirectories = true;
504         mgr.inflateContextMenuForDocs(testMenu, inflater, selectionDetails);
505 
506         assertEquals(R.menu.mixed_context_menu, inflater.lastInflatedMenuId);
507     }
508 
509     @Test
testContextMenu_EmptyArea()510     public void testContextMenu_EmptyArea() {
511         mgr.updateContextMenuForContainer(testMenu, selectionDetails);
512 
513         dirSelectAll.assertEnabledAndVisible();
514         mDirDeselectAll.assertDisabledAndInvisible();
515         dirPasteFromClipboard.assertDisabledAndInvisible();
516         dirCreateDir.assertDisabledAndInvisible();
517     }
518 
519     @Test
testContextMenu_EmptyArea_CanDeselectAll()520     public void testContextMenu_EmptyArea_CanDeselectAll() {
521         selectionDetails.size = 1;
522         mFilesCount = 1;
523 
524         mgr.updateContextMenuForContainer(testMenu, selectionDetails);
525 
526         dirSelectAll.assertDisabledAndInvisible();
527         mDirDeselectAll.assertEnabledAndVisible();
528     }
529 
530     @Test
testContextMenu_EmptyArea_NoItemToPaste()531     public void testContextMenu_EmptyArea_NoItemToPaste() {
532         dirDetails.hasItemsToPaste = false;
533         dirDetails.canCreateDoc = true;
534 
535         mgr.updateContextMenuForContainer(testMenu, selectionDetails);
536 
537         dirSelectAll.assertEnabledAndVisible();
538         dirPasteFromClipboard.assertDisabledAndInvisible();
539         dirCreateDir.assertDisabledAndInvisible();
540     }
541 
542     @Test
testContextMenu_EmptyArea_CantCreateDoc()543     public void testContextMenu_EmptyArea_CantCreateDoc() {
544         dirDetails.hasItemsToPaste = true;
545         dirDetails.canCreateDoc = false;
546 
547         mgr.updateContextMenuForContainer(testMenu, selectionDetails);
548 
549         dirSelectAll.assertEnabledAndVisible();
550         dirPasteFromClipboard.assertDisabledAndInvisible();
551         dirCreateDir.assertDisabledAndInvisible();
552     }
553 
554     @Test
testContextMenu_EmptyArea_CanPaste()555     public void testContextMenu_EmptyArea_CanPaste() {
556         dirDetails.hasItemsToPaste = true;
557         dirDetails.canCreateDoc = true;
558 
559         mgr.updateContextMenuForContainer(testMenu, selectionDetails);
560 
561         dirSelectAll.assertEnabledAndVisible();
562         dirPasteFromClipboard.assertEnabledAndVisible();
563         dirCreateDir.assertDisabledAndInvisible();
564     }
565 
566     @Test
testContextMenu_EmptyArea_CanCreateDirectory()567     public void testContextMenu_EmptyArea_CanCreateDirectory() {
568         dirDetails.canCreateDirectory = true;
569 
570         mgr.updateContextMenuForContainer(testMenu, selectionDetails);
571 
572         dirSelectAll.assertEnabledAndVisible();
573         dirPasteFromClipboard.assertDisabledAndInvisible();
574         dirCreateDir.assertEnabledAndVisible();
575     }
576 
577     @Test
testContextMenu_OnFile()578     public void testContextMenu_OnFile() {
579         selectionDetails.size = 1;
580         mgr.updateContextMenuForFiles(testMenu, selectionDetails);
581         dirOpen.assertDisabledAndInvisible();
582         dirCutToClipboard.assertDisabledAndInvisible();
583         dirCopyToClipboard.assertEnabledAndVisible();
584         dirRename.assertDisabledAndInvisible();
585         dirCreateDir.assertEnabledAndVisible();
586         dirDelete.assertDisabledAndInvisible();
587     }
588 
589     @Test
testContextMenu_OnFile_CanOpenWith()590     public void testContextMenu_OnFile_CanOpenWith() {
591         selectionDetails.canOpenWith = true;
592         mgr.updateContextMenuForFiles(testMenu, selectionDetails);
593         dirOpenWith.assertEnabledAndVisible();
594     }
595 
596     @Test
testContextMenu_OnFile_NoOpenWith()597     public void testContextMenu_OnFile_NoOpenWith() {
598         selectionDetails.canOpenWith = false;
599         mgr.updateContextMenuForFiles(testMenu, selectionDetails);
600         dirOpenWith.assertDisabledAndInvisible();
601     }
602 
603     @Test
testContextMenu_OnMultipleFiles()604     public void testContextMenu_OnMultipleFiles() {
605         selectionDetails.size = 3;
606         mgr.updateContextMenuForFiles(testMenu, selectionDetails);
607         dirOpen.assertDisabledAndInvisible();
608     }
609 
610     @Test
testContextMenu_OnWritableDirectory()611     public void testContextMenu_OnWritableDirectory() {
612         selectionDetails.size = 1;
613         selectionDetails.canPasteInto = true;
614         dirDetails.hasItemsToPaste = true;
615         mgr.updateContextMenuForDirs(testMenu, selectionDetails);
616         dirOpenInNewWindow.assertEnabledAndVisible();
617         dirCutToClipboard.assertDisabledAndInvisible();
618         dirCopyToClipboard.assertEnabledAndVisible();
619         dirPasteIntoFolder.assertEnabledAndVisible();
620         dirRename.assertDisabledAndInvisible();
621         dirDelete.assertDisabledAndInvisible();
622     }
623 
624     @Test
testContextMenu_OnNonWritableDirectory()625     public void testContextMenu_OnNonWritableDirectory() {
626         selectionDetails.size = 1;
627         selectionDetails.canPasteInto = false;
628         mgr.updateContextMenuForDirs(testMenu, selectionDetails);
629         dirOpenInNewWindow.assertEnabledAndVisible();
630         dirCutToClipboard.assertDisabledAndInvisible();
631         dirCopyToClipboard.assertEnabledAndVisible();
632         dirPasteIntoFolder.assertDisabledAndInvisible();
633         dirRename.assertDisabledAndInvisible();
634         dirDelete.assertDisabledAndInvisible();
635     }
636 
637     @Test
testContextMenu_CanInspectContainer()638     public void testContextMenu_CanInspectContainer() {
639         features.inspector = true;
640         dirDetails.canInspectDirectory = true;
641         mgr.updateContextMenuForContainer(testMenu, selectionDetails);
642         dirInspect.assertEnabledAndVisible();
643     }
644 
645     @Test
testContextMenu_OnWritableDirectory_NothingToPaste()646     public void testContextMenu_OnWritableDirectory_NothingToPaste() {
647         selectionDetails.canPasteInto = true;
648         selectionDetails.size = 1;
649         dirDetails.hasItemsToPaste = false;
650         mgr.updateContextMenuForDirs(testMenu, selectionDetails);
651         dirPasteIntoFolder.assertDisabledAndInvisible();
652     }
653 
654     @Test
testContextMenu_OnMultipleDirectories()655     public void testContextMenu_OnMultipleDirectories() {
656         selectionDetails.size = 3;
657         mgr.updateContextMenuForDirs(testMenu, selectionDetails);
658         dirOpenInNewWindow.assertDisabledAndInvisible();
659     }
660 
661     @Test
testContextMenu_OnMixedDocs()662     public void testContextMenu_OnMixedDocs() {
663         selectionDetails.containDirectories = true;
664         selectionDetails.containFiles = true;
665         selectionDetails.size = 2;
666         selectionDetails.canDelete = true;
667         mgr.updateContextMenu(testMenu, selectionDetails);
668         dirCutToClipboard.assertEnabledAndVisible();
669         dirCopyToClipboard.assertEnabledAndVisible();
670         dirDelete.assertEnabledAndVisible();
671     }
672 
673     @Test
testContextMenu_OnMixedDocs_hasPartialFile()674     public void testContextMenu_OnMixedDocs_hasPartialFile() {
675         selectionDetails.containDirectories = true;
676         selectionDetails.containFiles = true;
677         selectionDetails.size = 2;
678         selectionDetails.containPartial = true;
679         selectionDetails.canDelete = true;
680         mgr.updateContextMenu(testMenu, selectionDetails);
681         dirCutToClipboard.assertDisabledAndInvisible();
682         dirCopyToClipboard.assertDisabledAndInvisible();
683         dirDelete.assertEnabledAndVisible();
684     }
685 
686     @Test
testContextMenu_OnMixedDocs_hasUndeletableFile()687     public void testContextMenu_OnMixedDocs_hasUndeletableFile() {
688         selectionDetails.containDirectories = true;
689         selectionDetails.containFiles = true;
690         selectionDetails.size = 2;
691         selectionDetails.canDelete = false;
692         mgr.updateContextMenu(testMenu, selectionDetails);
693         dirCutToClipboard.assertDisabledAndInvisible();
694         dirCopyToClipboard.assertEnabledAndVisible();
695         dirDelete.assertDisabledAndInvisible();
696     }
697 
698     @Test
testContextMenu_CanInspectSingleSelection()699     public void testContextMenu_CanInspectSingleSelection() {
700         selectionDetails.size = 1;
701         mgr.updateContextMenuForFiles(testMenu, selectionDetails);
702         dirInspect.assertEnabledAndVisible();
703     }
704 
705     @Test
testRootContextMenu()706     public void testRootContextMenu() {
707         testRootInfo.flags = Root.FLAG_SUPPORTS_CREATE;
708 
709         mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo);
710 
711         rootEjectRoot.assertDisabledAndInvisible();
712         rootOpenInNewWindow.assertEnabledAndVisible();
713         rootPasteIntoFolder.assertDisabledAndInvisible();
714         rootSettings.assertDisabledAndInvisible();
715     }
716 
717     @Test
testRootContextMenu_HasRootSettings()718     public void testRootContextMenu_HasRootSettings() {
719         testRootInfo.flags = Root.FLAG_HAS_SETTINGS;
720         mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo);
721 
722         rootSettings.assertEnabledAndVisible();
723     }
724 
725     @Test
testRootContextMenu_NonWritableRoot()726     public void testRootContextMenu_NonWritableRoot() {
727         dirDetails.hasItemsToPaste = true;
728         mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo);
729 
730         rootPasteIntoFolder.assertDisabledAndInvisible();
731     }
732 
733     @Test
testRootContextMenu_NothingToPaste()734     public void testRootContextMenu_NothingToPaste() {
735         testRootInfo.flags = Root.FLAG_SUPPORTS_CREATE;
736         testDocInfo.flags = Document.FLAG_DIR_SUPPORTS_CREATE;
737         dirDetails.hasItemsToPaste = false;
738         mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo);
739 
740         rootPasteIntoFolder.assertDisabledAndInvisible();
741     }
742 
743     @Test
testRootContextMenu_PasteIntoWritableRoot()744     public void testRootContextMenu_PasteIntoWritableRoot() {
745         testRootInfo.flags = Root.FLAG_SUPPORTS_CREATE;
746         testDocInfo.flags = Document.FLAG_DIR_SUPPORTS_CREATE;
747         dirDetails.hasItemsToPaste = true;
748         mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo);
749 
750         rootPasteIntoFolder.assertEnabledAndVisible();
751     }
752 
753     @Test
testRootContextMenu_Eject()754     public void testRootContextMenu_Eject() {
755         testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT;
756         mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo);
757 
758         rootEjectRoot.assertEnabledAndVisible();
759     }
760 
761     @Test
testRootContextMenu_EjectInProcess()762     public void testRootContextMenu_EjectInProcess() {
763         testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT;
764         testRootInfo.ejecting = true;
765         mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo);
766 
767         rootEjectRoot.assertDisabledAndInvisible();
768     }
769 }
770