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