Home | History | Annotate | Download | only in app_list
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/path_service.h"
      6 #include "base/run_loop.h"
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "chrome/browser/extensions/extension_browsertest.h"
      9 #include "chrome/browser/profiles/profile.h"
     10 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
     11 #include "chrome/browser/ui/app_list/app_list_service.h"
     12 #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h"
     13 #include "chrome/browser/ui/browser.h"
     14 #include "chrome/browser/ui/browser_finder.h"
     15 #include "chrome/browser/ui/host_desktop.h"
     16 #include "chrome/common/chrome_paths.h"
     17 #include "chrome/test/base/in_process_browser_test.h"
     18 #include "ui/app_list/app_list_model.h"
     19 #include "ui/app_list/search_box_model.h"
     20 #include "ui/app_list/search_result.h"
     21 #include "ui/app_list/search_result_observer.h"
     22 #include "ui/base/models/list_model_observer.h"
     23 
     24 // Browser Test for AppListController that runs on all platforms supporting
     25 // app_list.
     26 typedef InProcessBrowserTest AppListControllerBrowserTest;
     27 
     28 // Test the CreateNewWindow function of the controller delegate.
     29 IN_PROC_BROWSER_TEST_F(AppListControllerBrowserTest, CreateNewWindow) {
     30   const chrome::HostDesktopType desktop = chrome::GetActiveDesktop();
     31   AppListService* service = test::GetAppListService();
     32   AppListControllerDelegate* controller(service->GetControllerDelegate());
     33   ASSERT_TRUE(controller);
     34 
     35   EXPECT_EQ(1U, chrome::GetBrowserCount(browser()->profile(), desktop));
     36   EXPECT_EQ(0U, chrome::GetBrowserCount(
     37       browser()->profile()->GetOffTheRecordProfile(), desktop));
     38 
     39   controller->CreateNewWindow(browser()->profile(), false);
     40   EXPECT_EQ(2U, chrome::GetBrowserCount(browser()->profile(), desktop));
     41 
     42   controller->CreateNewWindow(browser()->profile(), true);
     43   EXPECT_EQ(1U, chrome::GetBrowserCount(
     44       browser()->profile()->GetOffTheRecordProfile(), desktop));
     45 }
     46 
     47 // Browser Test for AppListController that observes search result changes.
     48 class AppListControllerSearchResultsBrowserTest
     49     : public ExtensionBrowserTest,
     50       public app_list::SearchResultObserver,
     51       public ui::ListModelObserver {
     52  public:
     53   AppListControllerSearchResultsBrowserTest()
     54       : observed_result_(NULL),
     55         item_uninstall_count_(0),
     56         observed_results_list_(NULL) {}
     57 
     58   void WatchResultsLookingForItem(
     59       app_list::AppListModel::SearchResults* search_results,
     60       const std::string& extension_name) {
     61     EXPECT_FALSE(observed_results_list_);
     62     observed_results_list_ = search_results;
     63     observed_results_list_->AddObserver(this);
     64     item_to_observe_ = base::ASCIIToUTF16(extension_name);
     65   }
     66 
     67   void StopWatchingResults() {
     68     EXPECT_TRUE(observed_results_list_);
     69     observed_results_list_->RemoveObserver(this);
     70   }
     71 
     72  protected:
     73   void AttemptToLocateItem() {
     74     if (observed_result_) {
     75       observed_result_->RemoveObserver(this);
     76       observed_result_ = NULL;
     77     }
     78 
     79     for (size_t i = 0; i < observed_results_list_->item_count(); ++i) {
     80       if (observed_results_list_->GetItemAt(i)->title() != item_to_observe_)
     81         continue;
     82 
     83       // Ensure there is at most one.
     84       EXPECT_FALSE(observed_result_);
     85       observed_result_ = observed_results_list_->GetItemAt(i);
     86     }
     87 
     88     if (observed_result_)
     89       observed_result_->AddObserver(this);
     90   }
     91 
     92   // Overridden from SearchResultObserver:
     93   virtual void OnIconChanged() OVERRIDE {}
     94   virtual void OnActionsChanged() OVERRIDE {}
     95   virtual void OnIsInstallingChanged() OVERRIDE {}
     96   virtual void OnPercentDownloadedChanged() OVERRIDE {}
     97   virtual void OnItemInstalled() OVERRIDE {}
     98   virtual void OnItemUninstalled() OVERRIDE {
     99     ++item_uninstall_count_;
    100     EXPECT_TRUE(observed_result_);
    101   }
    102 
    103   // Overridden from ui::ListModelObserver:
    104   virtual void ListItemsAdded(size_t start, size_t count) OVERRIDE {
    105     AttemptToLocateItem();
    106   }
    107   virtual void ListItemsRemoved(size_t start, size_t count) OVERRIDE {
    108     AttemptToLocateItem();
    109   }
    110   virtual void ListItemMoved(size_t index, size_t target_index) OVERRIDE {}
    111   virtual void ListItemsChanged(size_t start, size_t count) OVERRIDE {}
    112 
    113   app_list::SearchResult* observed_result_;
    114   int item_uninstall_count_;
    115 
    116  private:
    117   base::string16 item_to_observe_;
    118   app_list::AppListModel::SearchResults* observed_results_list_;
    119 
    120   DISALLOW_COPY_AND_ASSIGN(AppListControllerSearchResultsBrowserTest);
    121 };
    122 
    123 
    124 // Flaky on Mac. https://crbug.com/415264
    125 #if defined(OS_MACOSX)
    126 #define MAYBE_UninstallSearchResult DISABLED_UninstallSearchResult
    127 #else
    128 #define MAYBE_UninstallSearchResult UninstallSearchResult
    129 #endif
    130 // Test showing search results, and uninstalling one of them while displayed.
    131 IN_PROC_BROWSER_TEST_F(AppListControllerSearchResultsBrowserTest,
    132                        MAYBE_UninstallSearchResult) {
    133   base::FilePath test_extension_path;
    134   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_extension_path));
    135   test_extension_path = test_extension_path.AppendASCII("extensions")
    136       .AppendASCII("platform_apps")
    137       .AppendASCII("minimal");
    138   const extensions::Extension* extension =
    139       InstallExtension(test_extension_path,
    140                        1 /* expected_change: new install */);
    141   ASSERT_TRUE(extension);
    142 
    143   AppListService* service = test::GetAppListService();
    144   ASSERT_TRUE(service);
    145   service->ShowForProfile(browser()->profile());
    146 
    147   app_list::AppListModel* model = test::GetAppListModel(service);
    148   ASSERT_TRUE(model);
    149   WatchResultsLookingForItem(model->results(), extension->name());
    150 
    151   // Ensure a search finds the extension.
    152   EXPECT_FALSE(observed_result_);
    153   model->search_box()->SetText(base::ASCIIToUTF16("minimal"));
    154   EXPECT_TRUE(observed_result_);
    155 
    156   // Ensure the UI is updated. This is via PostTask in views.
    157   base::RunLoop().RunUntilIdle();
    158 
    159   // Now uninstall and ensure this browser test observes it.
    160   EXPECT_EQ(0, item_uninstall_count_);
    161   UninstallExtension(extension->id());
    162   EXPECT_EQ(1, item_uninstall_count_);
    163 
    164   // Results should not be immediately refreshed. When they are, the item should
    165   // be removed from the model.
    166   EXPECT_TRUE(observed_result_);
    167   base::RunLoop().RunUntilIdle();
    168   EXPECT_FALSE(observed_result_);
    169   StopWatchingResults();
    170   service->DismissAppList();
    171 }
    172