Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / extensions / extension_install_dialog_view_browsertest.cc
1 // Copyright 2014 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/extensions/extension_install_dialog_view.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_browsertest.h"
9 #include "chrome/browser/extensions/extension_icon_manager.h"
10 #include "chrome/browser/extensions/extension_install_prompt.h"
11 #include "chrome/browser/extensions/extension_install_prompt_experiment.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/browser/ui/webui/extensions/extension_settings_handler.h"
15 #include "chrome/common/extensions/extension_test_util.h"
16 #include "components/constrained_window/constrained_window_views.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/test/test_utils.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/permissions/permissions_data.h"
21 #include "extensions/common/test_util.h"
22 #include "ui/views/controls/scroll_view.h"
23 #include "ui/views/view.h"
24 #include "ui/views/widget/widget.h"
25
26 // A simple delegate implementation that counts the number of times
27 // |InstallUIProceed| and |InstallUIAbort| are called.
28 class MockExtensionInstallPromptDelegate
29     : public ExtensionInstallPrompt::Delegate {
30  public:
31   MockExtensionInstallPromptDelegate()
32       : proceed_count_(0),
33         abort_count_(0) {}
34
35   // ExtensionInstallPrompt::Delegate overrides.
36   void InstallUIProceed() override;
37   void InstallUIAbort(bool user_initiated) override;
38
39   int proceed_count() { return proceed_count_; }
40   int abort_count() { return abort_count_; }
41
42  protected:
43   int proceed_count_;
44   int abort_count_;
45 };
46
47 void MockExtensionInstallPromptDelegate::InstallUIProceed() {
48   ++proceed_count_;
49 }
50
51 void MockExtensionInstallPromptDelegate::InstallUIAbort(bool user_initiated) {
52   ++abort_count_;
53 }
54
55 // This lets us construct the parent for the prompt we're constructing in our
56 // tests.
57 class MockExtensionInstallPrompt : public ExtensionInstallPrompt {
58  public:
59   explicit MockExtensionInstallPrompt(content::WebContents* web_contents)
60       : ExtensionInstallPrompt(web_contents), prompt_(NULL) {}
61   ~MockExtensionInstallPrompt() override {}
62   void set_prompt(ExtensionInstallPrompt::Prompt* prompt) {
63     prompt_ = prompt;
64   }
65   ExtensionInstallPrompt::Prompt* get_prompt() {
66     return prompt_;
67   }
68
69  private:
70   ExtensionInstallPrompt::Prompt* prompt_;
71 };
72
73 class ExtensionInstallDialogViewTestBase : public ExtensionBrowserTest {
74  protected:
75   explicit ExtensionInstallDialogViewTestBase(
76       ExtensionInstallPrompt::PromptType prompt_type);
77   ~ExtensionInstallDialogViewTestBase() override {}
78
79   void SetUpOnMainThread() override;
80
81   ExtensionInstallPrompt::Prompt* prompt() { return prompt_.get(); }
82   content::WebContents* web_contents() { return web_contents_; }
83   MockExtensionInstallPromptDelegate* delegate() { return &delegate_; }
84
85   void SetPromptPermissions(std::vector<base::string16> permissions);
86   void SetPromptDetails(std::vector<base::string16> details);
87   void SetPromptRetainedFiles(std::vector<base::FilePath> files);
88
89  private:
90   const extensions::Extension* extension_;
91   MockExtensionInstallPrompt* install_prompt_;
92   scoped_refptr<ExtensionInstallPrompt::Prompt> prompt_;
93   content::WebContents* web_contents_;
94   MockExtensionInstallPromptDelegate delegate_;
95
96   DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogViewTestBase);
97 };
98
99 ExtensionInstallDialogViewTestBase::ExtensionInstallDialogViewTestBase(
100     ExtensionInstallPrompt::PromptType prompt_type)
101     : extension_(NULL),
102       install_prompt_(NULL),
103       prompt_(new ExtensionInstallPrompt::Prompt(prompt_type)),
104       web_contents_(NULL) {
105 }
106
107 void ExtensionInstallDialogViewTestBase::SetUpOnMainThread() {
108   ExtensionBrowserTest::SetUpOnMainThread();
109
110   extension_ = ExtensionBrowserTest::LoadExtension(test_data_dir_.AppendASCII(
111       "install_prompt/permissions_scrollbar_regression"));
112
113   web_contents_ = browser()->tab_strip_model()->GetWebContentsAt(0);
114
115   install_prompt_ = new MockExtensionInstallPrompt(web_contents_);
116   install_prompt_->set_prompt(prompt_.get());
117   prompt_->set_experiment(ExtensionInstallPromptExperiment::ControlGroup());
118   prompt_->set_extension(extension_);
119
120   scoped_ptr<ExtensionIconManager> icon_manager(new ExtensionIconManager());
121   const SkBitmap icon_bitmap = icon_manager->GetIcon(extension_->id());
122   gfx::Image icon = gfx::Image::CreateFrom1xBitmap(icon_bitmap);
123   prompt_->set_icon(icon);
124
125   this->SetPromptPermissions(std::vector<base::string16>());
126   this->SetPromptDetails(std::vector<base::string16>());
127   this->SetPromptRetainedFiles(std::vector<base::FilePath>());
128 }
129
130 void ExtensionInstallDialogViewTestBase::SetPromptPermissions(
131     std::vector<base::string16> permissions) {
132   prompt_->SetPermissions(permissions,
133                           ExtensionInstallPrompt::REGULAR_PERMISSIONS);
134 }
135
136 void ExtensionInstallDialogViewTestBase::SetPromptDetails(
137     std::vector<base::string16> details) {
138   prompt_->SetPermissionsDetails(details,
139                                  ExtensionInstallPrompt::REGULAR_PERMISSIONS);
140 }
141
142 void ExtensionInstallDialogViewTestBase::SetPromptRetainedFiles(
143     std::vector<base::FilePath> files) {
144   prompt_->set_retained_files(files);
145 }
146
147 class ScrollbarTest : public ExtensionInstallDialogViewTestBase {
148  protected:
149   ScrollbarTest();
150   ~ScrollbarTest() override {}
151
152   bool IsScrollbarVisible();
153
154  private:
155   DISALLOW_COPY_AND_ASSIGN(ScrollbarTest);
156 };
157
158 ScrollbarTest::ScrollbarTest()
159     : ExtensionInstallDialogViewTestBase(
160           ExtensionInstallPrompt::PERMISSIONS_PROMPT) {
161 }
162
163 bool ScrollbarTest::IsScrollbarVisible() {
164   ExtensionInstallDialogView* dialog = new ExtensionInstallDialogView(
165       profile(),
166       web_contents(),
167       delegate(),
168       prompt());
169
170   // Create the modal view around the install dialog view.
171   views::Widget* modal =
172       CreateBrowserModalDialogViews(dialog,
173                                     web_contents()->GetTopLevelNativeWindow());
174   modal->Show();
175   content::RunAllBlockingPoolTasksUntilIdle();
176
177   // Check if the vertical scrollbar is visible.
178   return dialog->scroll_view()->vertical_scroll_bar()->visible();
179 }
180
181 // Tests that a scrollbar _is_ shown for an excessively long extension
182 // install prompt.
183 IN_PROC_BROWSER_TEST_F(ScrollbarTest, LongPromptScrollbar) {
184   base::string16 permission_string(base::ASCIIToUTF16("Test"));
185   std::vector<base::string16> permissions;
186   std::vector<base::string16> details;
187   for (int i = 0; i < 20; i++) {
188     permissions.push_back(permission_string);
189     details.push_back(base::string16());
190   }
191   this->SetPromptPermissions(permissions);
192   this->SetPromptDetails(details);
193   ASSERT_TRUE(IsScrollbarVisible()) << "Scrollbar is not visible";
194 }
195
196 // Tests that a scrollbar isn't shown for this regression case.
197 // See crbug.com/385570 for details.
198 IN_PROC_BROWSER_TEST_F(ScrollbarTest, ScrollbarRegression) {
199   base::string16 permission_string(base::ASCIIToUTF16(
200       "Read and modify your data on *.facebook.com"));
201   std::vector<base::string16> permissions;
202   permissions.push_back(permission_string);
203   this->SetPromptPermissions(permissions);
204   std::vector<base::string16> details;
205   details.push_back(base::string16());
206   this->SetPromptDetails(details);
207   ASSERT_FALSE(IsScrollbarVisible()) << "Scrollbar is visible";
208 }
209
210 class ExtensionInstallDialogViewTest
211     : public ExtensionInstallDialogViewTestBase {
212  protected:
213   ExtensionInstallDialogViewTest()
214       : ExtensionInstallDialogViewTestBase(
215             ExtensionInstallPrompt::INSTALL_PROMPT) {}
216   ~ExtensionInstallDialogViewTest() override {}
217
218  private:
219   DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogViewTest);
220 };
221
222 // Verifies that the delegate is notified when the user selects to accept or
223 // cancel the install.
224 IN_PROC_BROWSER_TEST_F(ExtensionInstallDialogViewTest, NotifyDelegate) {
225   {
226     // The user confirms the install.
227     MockExtensionInstallPromptDelegate delegate;
228     scoped_ptr<ExtensionInstallDialogView> dialog(
229         new ExtensionInstallDialogView(
230             profile(), web_contents(), &delegate, prompt()));
231     views::DialogDelegateView* delegate_view = dialog.get();
232
233     delegate_view->Accept();
234     delegate_view->OnClosed();
235     dialog.reset();
236
237     EXPECT_EQ(0, delegate.abort_count());
238     EXPECT_EQ(1, delegate.proceed_count());
239   }
240
241   {
242     // The user cancels the install.
243     MockExtensionInstallPromptDelegate delegate;
244     scoped_ptr<ExtensionInstallDialogView> dialog(
245         new ExtensionInstallDialogView(
246             profile(), web_contents(), &delegate, prompt()));
247     views::DialogDelegateView* delegate_view = dialog.get();
248
249     delegate_view->Cancel();
250     delegate_view->OnClosed();
251     dialog.reset();
252
253     EXPECT_EQ(1, delegate.abort_count());
254     EXPECT_EQ(0, delegate.proceed_count());
255   }
256
257   {
258     // Corner case: Dialog is closed without the user explicitly choosing to
259     // proceed or cancel.
260     MockExtensionInstallPromptDelegate delegate;
261     scoped_ptr<ExtensionInstallDialogView> dialog(
262         new ExtensionInstallDialogView(
263             profile(), web_contents(), &delegate, prompt()));
264     dialog.reset();
265
266     EXPECT_EQ(1, delegate.abort_count());
267     EXPECT_EQ(0, delegate.proceed_count());
268   }
269 }