Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2012 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/bind.h"
      6 #include "base/files/file_path.h"
      7 #include "chrome/browser/download/download_danger_prompt.h"
      8 #include "chrome/browser/profiles/profile.h"
      9 #include "chrome/browser/ui/browser.h"
     10 #include "chrome/browser/ui/browser_commands.h"
     11 #include "chrome/browser/ui/browser_tabstrip.h"
     12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     13 #include "chrome/test/base/in_process_browser_test.h"
     14 #include "chrome/test/base/ui_test_utils.h"
     15 #include "content/public/test/mock_download_item.h"
     16 #include "testing/gmock/include/gmock/gmock.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 #include "url/gurl.h"
     19 
     20 using ::testing::_;
     21 using ::testing::ByRef;
     22 using ::testing::Eq;
     23 using ::testing::Return;
     24 using ::testing::ReturnRef;
     25 using ::testing::SaveArg;
     26 
     27 class DownloadDangerPromptTest : public InProcessBrowserTest {
     28  public:
     29   DownloadDangerPromptTest()
     30     : prompt_(NULL),
     31       expected_action_(DownloadDangerPrompt::CANCEL),
     32       did_receive_callback_(false) {
     33   }
     34 
     35   virtual ~DownloadDangerPromptTest() {
     36   }
     37 
     38   // Opens a new tab and waits for navigations to finish. If there are pending
     39   // navigations, the constrained prompt might be dismissed when the navigation
     40   // completes.
     41   void OpenNewTab() {
     42     ui_test_utils::NavigateToURLWithDisposition(
     43         browser(), GURL("about:blank"),
     44         NEW_FOREGROUND_TAB,
     45         ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
     46         ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
     47   }
     48 
     49   void SetUpExpectations(DownloadDangerPrompt::Action expected_action) {
     50     did_receive_callback_ = false;
     51     expected_action_ = expected_action;
     52     SetUpDownloadItemExpectations();
     53     CreatePrompt();
     54   }
     55 
     56   void VerifyExpectations() {
     57     content::RunAllPendingInMessageLoop();
     58     // At the end of each test, we expect no more activity from the prompt. The
     59     // prompt shouldn't exist anymore either.
     60     EXPECT_TRUE(did_receive_callback_);
     61     EXPECT_FALSE(prompt_);
     62     testing::Mock::VerifyAndClearExpectations(&download_);
     63   }
     64 
     65   void SimulatePromptAction(DownloadDangerPrompt::Action action) {
     66     prompt_->InvokeActionForTesting(action);
     67   }
     68 
     69   content::MockDownloadItem& download() { return download_; }
     70 
     71   DownloadDangerPrompt* prompt() { return prompt_; }
     72 
     73  private:
     74   void SetUpDownloadItemExpectations() {
     75     EXPECT_CALL(download_, GetFileNameToReportUser()).WillRepeatedly(Return(
     76         base::FilePath(FILE_PATH_LITERAL("evil.exe"))));
     77     EXPECT_CALL(download_, GetDangerType())
     78         .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL));
     79   }
     80 
     81   void CreatePrompt() {
     82     prompt_ = DownloadDangerPrompt::Create(
     83         &download_,
     84         browser()->tab_strip_model()->GetActiveWebContents(),
     85         false,
     86         base::Bind(&DownloadDangerPromptTest::PromptCallback, this));
     87     content::RunAllPendingInMessageLoop();
     88   }
     89 
     90   void PromptCallback(DownloadDangerPrompt::Action action) {
     91     EXPECT_FALSE(did_receive_callback_);
     92     EXPECT_EQ(expected_action_, action);
     93     did_receive_callback_ = true;
     94     prompt_ = NULL;
     95   }
     96 
     97   content::MockDownloadItem download_;
     98   DownloadDangerPrompt* prompt_;
     99   DownloadDangerPrompt::Action expected_action_;
    100   bool did_receive_callback_;
    101 
    102   DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptTest);
    103 };
    104 
    105 IN_PROC_BROWSER_TEST_F(DownloadDangerPromptTest, TestAll) {
    106   // ExperienceSampling: Set default actions for DownloadItem methods we need.
    107   ON_CALL(download(), GetURL()).WillByDefault(ReturnRef(GURL::EmptyGURL()));
    108   ON_CALL(download(), GetReferrerUrl())
    109       .WillByDefault(ReturnRef(GURL::EmptyGURL()));
    110   ON_CALL(download(), GetBrowserContext())
    111       .WillByDefault(Return(browser()->profile()));
    112 
    113   OpenNewTab();
    114 
    115   // Clicking the Accept button should invoke the ACCEPT action.
    116   SetUpExpectations(DownloadDangerPrompt::ACCEPT);
    117   SimulatePromptAction(DownloadDangerPrompt::ACCEPT);
    118   VerifyExpectations();
    119 
    120   // Clicking the Cancel button should invoke the CANCEL action.
    121   SetUpExpectations(DownloadDangerPrompt::CANCEL);
    122   SimulatePromptAction(DownloadDangerPrompt::CANCEL);
    123   VerifyExpectations();
    124 
    125   // If the download is no longer dangerous (because it was accepted), the
    126   // dialog should DISMISS itself.
    127   SetUpExpectations(DownloadDangerPrompt::DISMISS);
    128   EXPECT_CALL(download(), IsDangerous()).WillOnce(Return(false));
    129   download().NotifyObserversDownloadUpdated();
    130   VerifyExpectations();
    131 
    132   // If the download is in a terminal state then the dialog should DISMISS
    133   // itself.
    134   SetUpExpectations(DownloadDangerPrompt::DISMISS);
    135   EXPECT_CALL(download(), IsDangerous()).WillOnce(Return(true));
    136   EXPECT_CALL(download(), IsDone()).WillOnce(Return(true));
    137   download().NotifyObserversDownloadUpdated();
    138   VerifyExpectations();
    139 
    140   // If the download is dangerous and is not in a terminal state, don't dismiss
    141   // the dialog.
    142   SetUpExpectations(DownloadDangerPrompt::ACCEPT);
    143   EXPECT_CALL(download(), IsDangerous()).WillOnce(Return(true));
    144   EXPECT_CALL(download(), IsDone()).WillOnce(Return(false));
    145   download().NotifyObserversDownloadUpdated();
    146   SimulatePromptAction(DownloadDangerPrompt::ACCEPT);
    147   VerifyExpectations();
    148 
    149   // If the containing tab is closed, the dialog should DISMISS itself.
    150   OpenNewTab();
    151   SetUpExpectations(DownloadDangerPrompt::DISMISS);
    152   chrome::CloseTab(browser());
    153   VerifyExpectations();
    154 }
    155