Home | History | Annotate | Download | only in views
      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 "chrome/browser/ui/views/select_file_dialog_extension.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 #include "ui/shell_dialogs/selected_file_info.h"
     10 
     11 namespace {
     12 
     13 const SelectFileDialogExtension::RoutingID kDefaultRoutingID =
     14     SelectFileDialogExtension::RoutingID();
     15 
     16 }  // namespace
     17 
     18 // Must be a class so it can be a friend of SelectFileDialogExtension.
     19 class SelectFileDialogExtensionTest : public testing::Test {
     20  public:
     21   SelectFileDialogExtensionTest() {}
     22   virtual ~SelectFileDialogExtensionTest() {}
     23 
     24   static SelectFileDialogExtension* CreateDialog(
     25       ui::SelectFileDialog::Listener* listener) {
     26     SelectFileDialogExtension* dialog = new SelectFileDialogExtension(listener,
     27                                                                       NULL);
     28     // Simulate the dialog opening.
     29     EXPECT_FALSE(SelectFileDialogExtension::PendingExists(kDefaultRoutingID));
     30     dialog->AddPending(kDefaultRoutingID);
     31     EXPECT_TRUE(SelectFileDialogExtension::PendingExists(kDefaultRoutingID));
     32     return dialog;
     33   }
     34 
     35  private:
     36   DISALLOW_COPY_AND_ASSIGN(SelectFileDialogExtensionTest);
     37 };
     38 
     39 // Test listener for a SelectFileDialog.
     40 class TestListener : public ui::SelectFileDialog::Listener {
     41  public:
     42   TestListener() : selected_(false), file_index_(-1) {}
     43   virtual ~TestListener() {}
     44 
     45   bool selected() const { return selected_; }
     46   int file_index() const { return file_index_; }
     47 
     48   // ui::SelectFileDialog::Listener implementation
     49   virtual void FileSelected(const base::FilePath& path,
     50                             int index,
     51                             void* params) OVERRIDE {
     52     selected_ = true;
     53     file_index_ = index;
     54   }
     55 
     56  private:
     57   bool selected_;
     58   int file_index_;
     59 
     60   DISALLOW_COPY_AND_ASSIGN(TestListener);
     61 };
     62 
     63 // Client of a SelectFileDialog that deletes itself whenever the dialog
     64 // is closed. This is a common pattern in UI code.
     65 class SelfDeletingClient : public ui::SelectFileDialog::Listener {
     66  public:
     67   SelfDeletingClient() {
     68     dialog_ = SelectFileDialogExtensionTest::CreateDialog(this);
     69   }
     70 
     71   virtual ~SelfDeletingClient() {
     72     if (dialog_.get())
     73       dialog_->ListenerDestroyed();
     74   }
     75 
     76   SelectFileDialogExtension* dialog() const { return dialog_.get(); }
     77 
     78   // ui::SelectFileDialog::Listener implementation
     79   virtual void FileSelected(const base::FilePath& path,
     80                             int index,
     81                             void* params) OVERRIDE {
     82     delete this;
     83   }
     84 
     85  private:
     86   scoped_refptr<SelectFileDialogExtension> dialog_;
     87 };
     88 
     89 TEST_F(SelectFileDialogExtensionTest, FileSelected) {
     90   const int kFileIndex = 5;
     91   scoped_ptr<TestListener> listener(new TestListener);
     92   scoped_refptr<SelectFileDialogExtension> dialog =
     93       CreateDialog(listener.get());
     94   // Simulate selecting a file.
     95   ui::SelectedFileInfo info;
     96   SelectFileDialogExtension::OnFileSelected(kDefaultRoutingID, info,
     97                                             kFileIndex);
     98   // Simulate closing the dialog so the listener gets invoked.
     99   dialog->ExtensionDialogClosing(NULL);
    100   EXPECT_TRUE(listener->selected());
    101   EXPECT_EQ(kFileIndex, listener->file_index());
    102 }
    103 
    104 TEST_F(SelectFileDialogExtensionTest, FileSelectionCanceled) {
    105   scoped_ptr<TestListener> listener(new TestListener);
    106   scoped_refptr<SelectFileDialogExtension> dialog =
    107       CreateDialog(listener.get());
    108   // Simulate cancelling the dialog.
    109   SelectFileDialogExtension::OnFileSelectionCanceled(kDefaultRoutingID);
    110   // Simulate closing the dialog so the listener gets invoked.
    111   dialog->ExtensionDialogClosing(NULL);
    112   EXPECT_FALSE(listener->selected());
    113   EXPECT_EQ(-1, listener->file_index());
    114 }
    115 
    116 TEST_F(SelectFileDialogExtensionTest, SelfDeleting) {
    117   SelfDeletingClient* client = new SelfDeletingClient();
    118   // Ensure we don't crash or trip an Address Sanitizer warning about
    119   // use-after-free.
    120   ui::SelectedFileInfo file_info;
    121   SelectFileDialogExtension::OnFileSelected(kDefaultRoutingID, file_info, 0);
    122   // Simulate closing the dialog so the listener gets invoked.
    123   client->dialog()->ExtensionDialogClosing(NULL);
    124 }
    125