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 import static org.junit.Assert.assertTrue; 21 22 import android.net.Uri; 23 import android.provider.DocumentsContract.Document; 24 import android.provider.DocumentsContract.Root; 25 import android.support.test.filters.SmallTest; 26 import android.support.test.runner.AndroidJUnit4; 27 import android.test.AndroidTestCase; 28 29 import com.android.documentsui.R; 30 import com.android.documentsui.base.DocumentInfo; 31 import com.android.documentsui.base.RootInfo; 32 import com.android.documentsui.base.State; 33 import com.android.documentsui.dirlist.TestContext; 34 import com.android.documentsui.dirlist.TestData; 35 import com.android.documentsui.selection.SelectionManager; 36 import com.android.documentsui.testing.SelectionManagers; 37 import com.android.documentsui.testing.TestDirectoryDetails; 38 import com.android.documentsui.testing.TestEnv; 39 import com.android.documentsui.testing.TestFeatures; 40 import com.android.documentsui.testing.TestMenu; 41 import com.android.documentsui.testing.TestMenuInflater; 42 import com.android.documentsui.testing.TestMenuItem; 43 import com.android.documentsui.testing.TestScopedPreferences; 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 private TestMenuItem rename; 57 private TestMenuItem selectAll; 58 private TestMenuItem moveTo; 59 private TestMenuItem copyTo; 60 private TestMenuItem compress; 61 private TestMenuItem extractTo; 62 private TestMenuItem share; 63 private TestMenuItem delete; 64 private TestMenuItem createDir; 65 private TestMenuItem settings; 66 private TestMenuItem newWindow; 67 private TestMenuItem open; 68 private TestMenuItem openWith; 69 private TestMenuItem openInNewWindow; 70 private TestMenuItem cut; 71 private TestMenuItem copy; 72 private TestMenuItem paste; 73 private TestMenuItem pasteInto; 74 private TestMenuItem advanced; 75 private TestMenuItem eject; 76 private TestMenuItem view; 77 private TestMenuItem debug; 78 79 private TestFeatures features; 80 private TestSelectionDetails selectionDetails; 81 private TestDirectoryDetails dirDetails; 82 private TestSearchViewManager testSearchManager; 83 private TestScopedPreferences preferences; 84 private RootInfo testRootInfo; 85 private DocumentInfo testDocInfo; 86 private State state = new State(); 87 private MenuManager mgr; 88 private TestActivity activity = TestActivity.create(TestEnv.create()); 89 private SelectionManager selectionManager; 90 91 @Before 92 public void setUp() { 93 testMenu = TestMenu.create(); 94 rename = testMenu.findItem(R.id.menu_rename); 95 selectAll = testMenu.findItem(R.id.menu_select_all); 96 moveTo = testMenu.findItem(R.id.menu_move_to); 97 copyTo = testMenu.findItem(R.id.menu_copy_to); 98 compress = testMenu.findItem(R.id.menu_compress); 99 extractTo = testMenu.findItem(R.id.menu_extract_to); 100 share = testMenu.findItem(R.id.menu_share); 101 delete = testMenu.findItem(R.id.menu_delete); 102 createDir = testMenu.findItem(R.id.menu_create_dir); 103 settings = testMenu.findItem(R.id.menu_settings); 104 newWindow = testMenu.findItem(R.id.menu_new_window); 105 open = testMenu.findItem(R.id.menu_open); 106 openWith = testMenu.findItem(R.id.menu_open_with); 107 openInNewWindow = testMenu.findItem(R.id.menu_open_in_new_window); 108 cut = testMenu.findItem(R.id.menu_cut_to_clipboard); 109 copy = testMenu.findItem(R.id.menu_copy_to_clipboard); 110 paste = testMenu.findItem(R.id.menu_paste_from_clipboard); 111 pasteInto = testMenu.findItem(R.id.menu_paste_into_folder); 112 advanced = testMenu.findItem(R.id.menu_advanced); 113 eject = testMenu.findItem(R.id.menu_eject_root); 114 view = testMenu.findItem(R.id.menu_view_in_owner); 115 debug = testMenu.findItem(R.id.menu_debug); 116 117 features = new TestFeatures(); 118 119 // These items by default are visible 120 testMenu.findItem(R.id.menu_select_all).setVisible(true); 121 testMenu.findItem(R.id.menu_list).setVisible(true); 122 123 selectionDetails = new TestSelectionDetails(); 124 dirDetails = new TestDirectoryDetails(); 125 testSearchManager = new TestSearchViewManager(); 126 preferences = new TestScopedPreferences(); 127 selectionManager = SelectionManagers.createTestInstance(TestData.create(1)); 128 selectionManager.toggleSelection("0"); 129 130 mgr = new MenuManager( 131 features, 132 testSearchManager, 133 state, 134 dirDetails, 135 activity, 136 selectionManager, 137 this::getApplicationNameFromAuthority, 138 this::getUriFromModelId); 139 140 testRootInfo = new RootInfo(); 141 testDocInfo = new DocumentInfo(); 142 } 143 144 private Uri getUriFromModelId(String id) { 145 return Uri.EMPTY; 146 } 147 private String getApplicationNameFromAuthority(String authority) { 148 return "TestApp"; 149 } 150 151 @Test 152 public void testActionMenu() { 153 selectionDetails.canDelete = true; 154 selectionDetails.canRename = true; 155 dirDetails.canCreateDoc = true; 156 157 mgr.updateActionMenu(testMenu, selectionDetails); 158 159 rename.assertEnabled(); 160 delete.assertVisible(); 161 share.assertVisible(); 162 copyTo.assertEnabled(); 163 compress.assertEnabled(); 164 extractTo.assertInvisible(); 165 moveTo.assertEnabled(); 166 view.assertInvisible(); 167 } 168 169 @Test 170 public void testActionMenu_ContainsPartial() { 171 selectionDetails.containPartial = true; 172 dirDetails.canCreateDoc = true; 173 mgr.updateActionMenu(testMenu, selectionDetails); 174 175 rename.assertDisabled(); 176 share.assertInvisible(); 177 copyTo.assertDisabled(); 178 compress.assertDisabled(); 179 extractTo.assertDisabled(); 180 moveTo.assertDisabled(); 181 view.assertInvisible(); 182 } 183 184 @Test 185 public void testActionMenu_CreateArchives_ReflectsFeatureState() { 186 features.archiveCreation = false; 187 dirDetails.canCreateDoc = true; 188 mgr.updateActionMenu(testMenu, selectionDetails); 189 190 compress.assertInvisible(); 191 compress.assertDisabled(); 192 } 193 194 @Test 195 public void testActionMenu_CreateArchive() { 196 dirDetails.canCreateDoc = true; 197 mgr.updateActionMenu(testMenu, selectionDetails); 198 199 compress.assertEnabled(); 200 } 201 202 @Test 203 public void testActionMenu_NoCreateArchive() { 204 dirDetails.canCreateDoc = false; 205 mgr.updateActionMenu(testMenu, selectionDetails); 206 207 compress.assertDisabled(); 208 } 209 210 @Test 211 public void testActionMenu_cantRename() { 212 selectionDetails.canRename = false; 213 mgr.updateActionMenu(testMenu, selectionDetails); 214 215 rename.assertDisabled(); 216 } 217 218 @Test 219 public void testActionMenu_cantDelete() { 220 selectionDetails.canDelete = false; 221 mgr.updateActionMenu(testMenu, selectionDetails); 222 223 delete.assertInvisible(); 224 // We shouldn't be able to move files if we can't delete them 225 moveTo.assertDisabled(); 226 } 227 228 @Test 229 public void testActionsMenu_canViewInOwner() { 230 selectionDetails.canViewInOwner = true; 231 mgr.updateActionMenu(testMenu, selectionDetails); 232 233 view.assertVisible(); 234 } 235 236 @Test 237 public void testActionMenu_changeToCanDelete() { 238 selectionDetails.canDelete = false; 239 mgr.updateActionMenu(testMenu, selectionDetails); 240 241 selectionDetails.canDelete = true; 242 mgr.updateActionMenu(testMenu, selectionDetails); 243 244 delete.assertVisible(); 245 delete.assertEnabled(); 246 moveTo.assertVisible(); 247 moveTo.assertEnabled(); 248 } 249 250 @Test 251 public void testActionMenu_ContainsDirectory() { 252 selectionDetails.containDirectories = true; 253 mgr.updateActionMenu(testMenu, selectionDetails); 254 255 // We can't share directories 256 share.assertInvisible(); 257 } 258 259 @Test 260 public void testActionMenu_RemovesDirectory() { 261 selectionDetails.containDirectories = true; 262 mgr.updateActionMenu(testMenu, selectionDetails); 263 264 selectionDetails.containDirectories = false; 265 mgr.updateActionMenu(testMenu, selectionDetails); 266 267 share.assertVisible(); 268 share.assertEnabled(); 269 } 270 271 @Test 272 public void testActionMenu_CantExtract() { 273 selectionDetails.canExtract = false; 274 mgr.updateActionMenu(testMenu, selectionDetails); 275 276 extractTo.assertInvisible(); 277 } 278 279 @Test 280 public void testActionMenu_CanExtract_hidesCopyToAndCompressAndShare() { 281 features.archiveCreation = true; 282 selectionDetails.canExtract = true; 283 dirDetails.canCreateDoc = true; 284 mgr.updateActionMenu(testMenu, selectionDetails); 285 286 extractTo.assertEnabled(); 287 copyTo.assertDisabled(); 288 compress.assertDisabled(); 289 } 290 291 @Test 292 public void testActionMenu_CanOpenWith() { 293 selectionDetails.canOpenWith = true; 294 mgr.updateActionMenu(testMenu, selectionDetails); 295 296 openWith.assertVisible(); 297 openWith.assertEnabled(); 298 } 299 300 @Test 301 public void testActionMenu_NoOpenWith() { 302 selectionDetails.canOpenWith = false; 303 mgr.updateActionMenu(testMenu, selectionDetails); 304 305 openWith.assertVisible(); 306 openWith.assertDisabled(); 307 } 308 309 @Test 310 public void testOptionMenu() { 311 mgr.updateOptionMenu(testMenu); 312 313 advanced.assertInvisible(); 314 advanced.assertTitle(R.string.menu_advanced_show); 315 createDir.assertDisabled(); 316 debug.assertInvisible(); 317 assertTrue(testSearchManager.updateMenuCalled()); 318 } 319 320 @Test 321 public void testOptionMenu_ShowAdvanced() { 322 state.showAdvanced = true; 323 state.showDeviceStorageOption = true; 324 mgr.updateOptionMenu(testMenu); 325 326 advanced.assertVisible(); 327 advanced.assertTitle(R.string.menu_advanced_hide); 328 } 329 330 @Test 331 public void testOptionMenu_CanCreateDirectory() { 332 dirDetails.canCreateDirectory = true; 333 mgr.updateOptionMenu(testMenu); 334 335 createDir.assertEnabled(); 336 } 337 338 @Test 339 public void testOptionMenu_HasRootSettings() { 340 dirDetails.hasRootSettings = true; 341 mgr.updateOptionMenu(testMenu); 342 343 settings.assertVisible(); 344 } 345 346 @Test 347 public void testInflateContextMenu_Files() { 348 TestMenuInflater inflater = new TestMenuInflater(); 349 350 selectionDetails.containFiles = true; 351 selectionDetails.containDirectories = false; 352 mgr.inflateContextMenuForDocs(testMenu, inflater, selectionDetails); 353 354 assertEquals(R.menu.file_context_menu, inflater.lastInflatedMenuId); 355 } 356 357 @Test 358 public void testInflateContextMenu_Dirs() { 359 TestMenuInflater inflater = new TestMenuInflater(); 360 361 selectionDetails.containFiles = false; 362 selectionDetails.containDirectories = true; 363 mgr.inflateContextMenuForDocs(testMenu, inflater, selectionDetails); 364 365 assertEquals(R.menu.dir_context_menu, inflater.lastInflatedMenuId); 366 } 367 368 @Test 369 public void testInflateContextMenu_Mixed() { 370 TestMenuInflater inflater = new TestMenuInflater(); 371 372 selectionDetails.containFiles = true; 373 selectionDetails.containDirectories = true; 374 mgr.inflateContextMenuForDocs(testMenu, inflater, selectionDetails); 375 376 assertEquals(R.menu.mixed_context_menu, inflater.lastInflatedMenuId); 377 } 378 379 @Test 380 public void testContextMenu_EmptyArea() { 381 mgr.updateContextMenuForContainer(testMenu); 382 383 selectAll.assertVisible(); 384 selectAll.assertEnabled(); 385 paste.assertVisible(); 386 paste.assertDisabled(); 387 createDir.assertVisible(); 388 createDir.assertDisabled(); 389 } 390 391 @Test 392 public void testContextMenu_EmptyArea_NoItemToPaste() { 393 dirDetails.hasItemsToPaste = false; 394 dirDetails.canCreateDoc = true; 395 396 mgr.updateContextMenuForContainer(testMenu); 397 398 selectAll.assertVisible(); 399 selectAll.assertEnabled(); 400 paste.assertVisible(); 401 paste.assertDisabled(); 402 createDir.assertVisible(); 403 createDir.assertDisabled(); 404 } 405 406 @Test 407 public void testContextMenu_EmptyArea_CantCreateDoc() { 408 dirDetails.hasItemsToPaste = true; 409 dirDetails.canCreateDoc = false; 410 411 mgr.updateContextMenuForContainer(testMenu); 412 413 selectAll.assertVisible(); 414 selectAll.assertEnabled(); 415 paste.assertVisible(); 416 paste.assertDisabled(); 417 createDir.assertVisible(); 418 createDir.assertDisabled(); 419 } 420 421 @Test 422 public void testContextMenu_EmptyArea_CanPaste() { 423 dirDetails.hasItemsToPaste = true; 424 dirDetails.canCreateDoc = true; 425 426 mgr.updateContextMenuForContainer(testMenu); 427 428 selectAll.assertVisible(); 429 selectAll.assertEnabled(); 430 paste.assertVisible(); 431 paste.assertEnabled(); 432 createDir.assertVisible(); 433 createDir.assertDisabled(); 434 } 435 436 @Test 437 public void testContextMenu_EmptyArea_CanCreateDirectory() { 438 dirDetails.canCreateDirectory = true; 439 440 mgr.updateContextMenuForContainer(testMenu); 441 442 selectAll.assertVisible(); 443 selectAll.assertEnabled(); 444 paste.assertVisible(); 445 paste.assertDisabled(); 446 createDir.assertVisible(); 447 createDir.assertEnabled(); 448 } 449 450 @Test 451 public void testContextMenu_OnFile() { 452 selectionDetails.size = 1; 453 mgr.updateContextMenuForFiles(testMenu, selectionDetails); 454 open.assertVisible(); 455 open.assertEnabled(); 456 cut.assertVisible(); 457 copy.assertVisible(); 458 rename.assertVisible(); 459 createDir.assertVisible(); 460 delete.assertVisible(); 461 } 462 463 @Test 464 public void testContextMenu_OnFile_CanOpenWith() { 465 selectionDetails.canOpenWith = true; 466 mgr.updateContextMenuForFiles(testMenu, selectionDetails); 467 openWith.assertVisible(); 468 openWith.assertEnabled(); 469 } 470 471 @Test 472 public void testContextMenu_OnFile_NoOpenWith() { 473 selectionDetails.canOpenWith = false; 474 mgr.updateContextMenuForFiles(testMenu, selectionDetails); 475 openWith.assertVisible(); 476 openWith.assertDisabled(); 477 } 478 479 @Test 480 public void testContextMenu_OnMultipleFiles() { 481 selectionDetails.size = 3; 482 mgr.updateContextMenuForFiles(testMenu, selectionDetails); 483 open.assertVisible(); 484 open.assertDisabled(); 485 } 486 487 @Test 488 public void testContextMenu_OnWritableDirectory() { 489 selectionDetails.size = 1; 490 selectionDetails.canPasteInto = true; 491 dirDetails.hasItemsToPaste = true; 492 mgr.updateContextMenuForDirs(testMenu, selectionDetails); 493 openInNewWindow.assertVisible(); 494 openInNewWindow.assertEnabled(); 495 cut.assertVisible(); 496 copy.assertVisible(); 497 pasteInto.assertVisible(); 498 pasteInto.assertEnabled(); 499 rename.assertVisible(); 500 delete.assertVisible(); 501 } 502 503 @Test 504 public void testContextMenu_OnNonWritableDirectory() { 505 selectionDetails.size = 1; 506 selectionDetails.canPasteInto = false; 507 mgr.updateContextMenuForDirs(testMenu, selectionDetails); 508 openInNewWindow.assertVisible(); 509 openInNewWindow.assertEnabled(); 510 cut.assertVisible(); 511 copy.assertVisible(); 512 pasteInto.assertVisible(); 513 pasteInto.assertDisabled(); 514 rename.assertVisible(); 515 delete.assertVisible(); 516 } 517 518 @Test 519 public void testContextMenu_OnWritableDirectory_NothingToPaste() { 520 selectionDetails.canPasteInto = true; 521 selectionDetails.size = 1; 522 dirDetails.hasItemsToPaste = false; 523 mgr.updateContextMenuForDirs(testMenu, selectionDetails); 524 pasteInto.assertVisible(); 525 pasteInto.assertDisabled(); 526 } 527 528 @Test 529 public void testContextMenu_OnMultipleDirectories() { 530 selectionDetails.size = 3; 531 mgr.updateContextMenuForDirs(testMenu, selectionDetails); 532 openInNewWindow.assertVisible(); 533 openInNewWindow.assertDisabled(); 534 } 535 536 @Test 537 public void testContextMenu_OnMixedDocs() { 538 selectionDetails.containDirectories = true; 539 selectionDetails.containFiles = true; 540 selectionDetails.size = 2; 541 selectionDetails.canDelete = true; 542 mgr.updateContextMenu(testMenu, selectionDetails); 543 cut.assertVisible(); 544 cut.assertEnabled(); 545 copy.assertVisible(); 546 copy.assertEnabled(); 547 delete.assertVisible(); 548 delete.assertEnabled(); 549 } 550 551 @Test 552 public void testContextMenu_OnMixedDocs_hasPartialFile() { 553 selectionDetails.containDirectories = true; 554 selectionDetails.containFiles = true; 555 selectionDetails.size = 2; 556 selectionDetails.containPartial = true; 557 selectionDetails.canDelete = true; 558 mgr.updateContextMenu(testMenu, selectionDetails); 559 cut.assertVisible(); 560 cut.assertDisabled(); 561 copy.assertVisible(); 562 copy.assertDisabled(); 563 delete.assertVisible(); 564 delete.assertEnabled(); 565 } 566 567 @Test 568 public void testContextMenu_OnMixedDocs_hasUndeletableFile() { 569 selectionDetails.containDirectories = true; 570 selectionDetails.containFiles = true; 571 selectionDetails.size = 2; 572 selectionDetails.canDelete = false; 573 mgr.updateContextMenu(testMenu, selectionDetails); 574 cut.assertVisible(); 575 cut.assertDisabled(); 576 copy.assertVisible(); 577 copy.assertEnabled(); 578 delete.assertVisible(); 579 delete.assertDisabled(); 580 } 581 582 @Test 583 public void testRootContextMenu() { 584 testRootInfo.flags = Root.FLAG_SUPPORTS_CREATE; 585 586 mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo); 587 588 eject.assertInvisible(); 589 590 openInNewWindow.assertVisible(); 591 openInNewWindow.assertEnabled(); 592 593 pasteInto.assertVisible(); 594 pasteInto.assertDisabled(); 595 596 settings.assertVisible(); 597 settings.assertDisabled(); 598 } 599 600 @Test 601 public void testRootContextMenu_HasRootSettings() { 602 testRootInfo.flags = Root.FLAG_HAS_SETTINGS; 603 mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo); 604 605 settings.assertEnabled(); 606 } 607 608 @Test 609 public void testRootContextMenu_NonWritableRoot() { 610 dirDetails.hasItemsToPaste = true; 611 mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo); 612 613 pasteInto.assertVisible(); 614 pasteInto.assertDisabled(); 615 } 616 617 @Test 618 public void testRootContextMenu_NothingToPaste() { 619 testRootInfo.flags = Root.FLAG_SUPPORTS_CREATE; 620 testDocInfo.flags = Document.FLAG_DIR_SUPPORTS_CREATE; 621 dirDetails.hasItemsToPaste = false; 622 mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo); 623 624 pasteInto.assertVisible(); 625 pasteInto.assertDisabled(); 626 } 627 628 @Test 629 public void testRootContextMenu_PasteIntoWritableRoot() { 630 testRootInfo.flags = Root.FLAG_SUPPORTS_CREATE; 631 testDocInfo.flags = Document.FLAG_DIR_SUPPORTS_CREATE; 632 dirDetails.hasItemsToPaste = true; 633 mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo); 634 635 pasteInto.assertVisible(); 636 pasteInto.assertEnabled(); 637 } 638 639 @Test 640 public void testRootContextMenu_Eject() { 641 testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT; 642 mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo); 643 644 eject.assertEnabled(); 645 } 646 647 @Test 648 public void testRootContextMenu_EjectInProcess() { 649 testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT; 650 testRootInfo.ejecting = true; 651 mgr.updateRootContextMenu(testMenu, testRootInfo, testDocInfo); 652 653 eject.assertDisabled(); 654 } 655 } 656