Home | History | Annotate | Download | only in download
      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/files/file_path.h"
      6 #include "base/memory/ref_counted.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/memory/weak_ptr.h"
      9 #include "chrome/browser/download/download_ui_controller.h"
     10 #include "content/public/test/mock_download_item.h"
     11 #include "content/public/test/mock_download_manager.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using content::MockDownloadItem;
     16 using content::MockDownloadManager;
     17 using testing::AnyNumber;
     18 using testing::Assign;
     19 using testing::Return;
     20 using testing::ReturnRefOfCopy;
     21 using testing::SaveArg;
     22 using testing::_;
     23 
     24 namespace {
     25 
     26 // A DownloadUIController::Delegate that stores the DownloadItem* for the last
     27 // download that was sent to the UI.
     28 class TestDelegate : public DownloadUIController::Delegate {
     29  public:
     30   explicit TestDelegate(base::WeakPtr<content::DownloadItem*> receiver);
     31   virtual ~TestDelegate() {}
     32 
     33  private:
     34   virtual void NotifyDownloadStarting(content::DownloadItem* item) OVERRIDE;
     35 
     36   base::WeakPtr<content::DownloadItem*> receiver_;
     37 };
     38 
     39 TestDelegate::TestDelegate(base::WeakPtr<content::DownloadItem*> receiver)
     40     : receiver_(receiver) {
     41 }
     42 
     43 void TestDelegate::NotifyDownloadStarting(content::DownloadItem* item) {
     44   if (receiver_.get())
     45     *receiver_ = item;
     46 }
     47 
     48 class DownloadUIControllerTest : public testing::Test {
     49  public:
     50   DownloadUIControllerTest();
     51 
     52  protected:
     53   // testing::Test
     54   virtual void SetUp() OVERRIDE;
     55 
     56   // Returns a MockDownloadItem that has AddObserver and RemoveObserver
     57   // expectations set up to store the observer in |item_observer_|.
     58   scoped_ptr<MockDownloadItem> GetMockDownload();
     59 
     60   // Returns a TestDelegate. Invoking NotifyDownloadStarting on the returned
     61   // delegate results in the DownloadItem* being stored in |received_item_|.
     62   scoped_ptr<DownloadUIController::Delegate> GetTestDelegate();
     63 
     64   MockDownloadManager* manager() { return manager_.get(); }
     65   content::DownloadManager::Observer* manager_observer() {
     66     return manager_observer_;
     67   }
     68   content::DownloadItem::Observer* item_observer() { return item_observer_; }
     69   content::DownloadItem* received_item() { return received_item_; }
     70 
     71  private:
     72   scoped_ptr<MockDownloadManager> manager_;
     73   content::DownloadManager::Observer* manager_observer_;
     74   content::DownloadItem::Observer* item_observer_;
     75   content::DownloadItem* received_item_;
     76 
     77   base::WeakPtrFactory<content::DownloadItem*> receiver_factory_;
     78 };
     79 
     80 DownloadUIControllerTest::DownloadUIControllerTest()
     81     : manager_observer_(NULL),
     82       item_observer_(NULL),
     83       received_item_(NULL),
     84       receiver_factory_(&received_item_) {
     85 }
     86 
     87 void DownloadUIControllerTest::SetUp() {
     88   manager_.reset(new testing::StrictMock<MockDownloadManager>());
     89   EXPECT_CALL(*manager_, AddObserver(_))
     90       .WillOnce(SaveArg<0>(&manager_observer_));
     91   EXPECT_CALL(*manager_, RemoveObserver(_))
     92       .WillOnce(Assign(&manager_observer_,
     93                        static_cast<content::DownloadManager::Observer*>(NULL)));
     94   EXPECT_CALL(*manager_, GetAllDownloads(_));
     95 }
     96 
     97 scoped_ptr<MockDownloadItem> DownloadUIControllerTest::GetMockDownload() {
     98   scoped_ptr<MockDownloadItem> item(
     99       new testing::StrictMock<MockDownloadItem>());
    100   EXPECT_CALL(*item, AddObserver(_))
    101       .WillOnce(SaveArg<0>(&item_observer_));
    102   EXPECT_CALL(*item, RemoveObserver(_))
    103       .WillOnce(Assign(&item_observer_,
    104                        static_cast<content::DownloadItem::Observer*>(NULL)));
    105   return item.Pass();
    106 }
    107 
    108 scoped_ptr<DownloadUIController::Delegate>
    109 DownloadUIControllerTest::GetTestDelegate() {
    110   scoped_ptr<DownloadUIController::Delegate> delegate(
    111       new TestDelegate(receiver_factory_.GetWeakPtr()));
    112   return delegate.Pass();
    113 }
    114 
    115 // Normal downloads that are constructed in the IN_PROGRESS state should be
    116 // presented to the UI when GetTargetFilePath() returns a non-empty path.
    117 // I.e. once the download target has been determined.
    118 TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyBasic) {
    119   scoped_ptr<MockDownloadItem> item = GetMockDownload();
    120   DownloadUIController controller(manager(), GetTestDelegate());
    121   EXPECT_CALL(*item, GetTargetFilePath())
    122       .WillOnce(ReturnRefOfCopy(base::FilePath()));
    123   EXPECT_CALL(*item, GetState())
    124       .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS));
    125 
    126   ASSERT_TRUE(manager_observer());
    127   manager_observer()->OnDownloadCreated(manager(), item.get());
    128 
    129   // The destination for the download hasn't been determined yet. It should not
    130   // be displayed.
    131   EXPECT_FALSE(received_item());
    132   ASSERT_TRUE(item_observer());
    133 
    134   // Once the destination has been determined, then it should be displayed.
    135   EXPECT_CALL(*item, GetTargetFilePath())
    136       .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
    137   item_observer()->OnDownloadUpdated(item.get());
    138 
    139   EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item());
    140 }
    141 
    142 // Downloads that have a target path on creation and are in the IN_PROGRESS
    143 // state should be displayed in the UI immediately without requiring an
    144 // additional OnDownloadUpdated() notification.
    145 TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyReadyOnCreate) {
    146   scoped_ptr<MockDownloadItem> item = GetMockDownload();
    147   DownloadUIController controller(manager(), GetTestDelegate());
    148   EXPECT_CALL(*item, GetTargetFilePath())
    149       .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
    150   EXPECT_CALL(*item, GetState())
    151       .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS));
    152 
    153   ASSERT_TRUE(manager_observer());
    154   manager_observer()->OnDownloadCreated(manager(), item.get());
    155   EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item());
    156 }
    157 
    158 // History downloads (downloads that are not in IN_PROGRESS on create) should
    159 // not be displayed on the shelf.
    160 TEST_F(DownloadUIControllerTest, DownloadUIController_NoNotifyHistory) {
    161   scoped_ptr<MockDownloadItem> item = GetMockDownload();
    162   DownloadUIController controller(manager(), GetTestDelegate());
    163   EXPECT_CALL(*item, GetState())
    164       .WillRepeatedly(Return(content::DownloadItem::COMPLETE));
    165 
    166   ASSERT_TRUE(manager_observer());
    167   manager_observer()->OnDownloadCreated(manager(), item.get());
    168   EXPECT_FALSE(received_item());
    169 
    170   item_observer()->OnDownloadUpdated(item.get());
    171   EXPECT_FALSE(received_item());
    172 }
    173 
    174 } // namespace
    175