| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include "base/strings/string_number_conversions.h" | 
 | #include "base/strings/utf_string_conversions.h" | 
 | #include "chrome/browser/extensions/extension_apitest.h" | 
 | #include "chrome/browser/profiles/profile.h" | 
 | #include "chrome/browser/ui/browser.h" | 
 | #include "chrome/test/base/ui_test_utils.h" | 
 | #include "components/app_modal/app_modal_dialog_queue.h" | 
 | #include "components/app_modal/javascript_app_modal_dialog.h" | 
 | #include "components/app_modal/native_app_modal_dialog.h" | 
 | #include "content/public/browser/render_frame_host.h" | 
 | #include "content/public/test/test_utils.h" | 
 | #include "extensions/browser/extension_host.h" | 
 | #include "extensions/browser/process_manager.h" | 
 | #include "extensions/common/extension.h" | 
 |  | 
 | namespace extensions { | 
 |  | 
 | namespace { | 
 |  | 
 | void GetNextDialog(app_modal::NativeAppModalDialog** native_dialog) { | 
 |   DCHECK(native_dialog); | 
 |   *native_dialog = nullptr; | 
 |   app_modal::JavaScriptAppModalDialog* dialog = | 
 |       ui_test_utils::WaitForAppModalDialog(); | 
 |   *native_dialog = dialog->native_dialog(); | 
 |   ASSERT_TRUE(*native_dialog); | 
 | } | 
 |  | 
 | void CloseDialog() { | 
 |   app_modal::NativeAppModalDialog* dialog = nullptr; | 
 |   ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog)); | 
 |   dialog->CloseAppModalDialog(); | 
 | } | 
 |  | 
 | void AcceptDialog() { | 
 |   app_modal::NativeAppModalDialog* dialog = nullptr; | 
 |   ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog)); | 
 |   dialog->AcceptAppModalDialog(); | 
 | } | 
 |  | 
 | void CancelDialog() { | 
 |   app_modal::NativeAppModalDialog* dialog = nullptr; | 
 |   ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog)); | 
 |   dialog->CancelAppModalDialog(); | 
 | } | 
 |  | 
 | void CheckAlertResult(const std::string& dialog_name, | 
 |                       size_t* call_count, | 
 |                       const base::Value* value) { | 
 |   ASSERT_TRUE(value) << dialog_name; | 
 |   ASSERT_TRUE(value->is_none()); | 
 |   ++*call_count; | 
 | } | 
 |  | 
 | void CheckConfirmResult(const std::string& dialog_name, | 
 |                         bool expected_value, | 
 |                         size_t* call_count, | 
 |                         const base::Value* value) { | 
 |   ASSERT_TRUE(value) << dialog_name; | 
 |   bool current_value; | 
 |   ASSERT_TRUE(value->GetAsBoolean(¤t_value)) << dialog_name; | 
 |   ASSERT_EQ(expected_value, current_value) << dialog_name; | 
 |   ++*call_count; | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | IN_PROC_BROWSER_TEST_F(ExtensionApiTest, AlertBasic) { | 
 |   ASSERT_TRUE(RunExtensionTest("alert")) << message_; | 
 |  | 
 |   const Extension* extension = GetSingleLoadedExtension(); | 
 |   ExtensionHost* host = ProcessManager::Get(browser()->profile()) | 
 |                             ->GetBackgroundHostForExtension(extension->id()); | 
 |   ASSERT_TRUE(host); | 
 |   host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( | 
 |       base::ASCIIToUTF16("alert('This should not crash.');")); | 
 |  | 
 |   ASSERT_NO_FATAL_FAILURE(CloseDialog()); | 
 | } | 
 |  | 
 | IN_PROC_BROWSER_TEST_F(ExtensionApiTest, AlertQueue) { | 
 |   ASSERT_TRUE(RunExtensionTest("alert")) << message_; | 
 |  | 
 |   const Extension* extension = GetSingleLoadedExtension(); | 
 |   ExtensionHost* host = ProcessManager::Get(browser()->profile()) | 
 |                             ->GetBackgroundHostForExtension(extension->id()); | 
 |   ASSERT_TRUE(host); | 
 |  | 
 |   // Creates several dialogs at the same time. | 
 |   const size_t num_dialogs = 3; | 
 |   size_t call_count = 0; | 
 |   for (size_t i = 0; i != num_dialogs; ++i) { | 
 |     const std::string dialog_name = "Dialog #" + base::NumberToString(i) + "."; | 
 |     host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( | 
 |         base::ASCIIToUTF16("alert('" + dialog_name + "');"), | 
 |         base::Bind(&CheckAlertResult, dialog_name, | 
 |                    base::Unretained(&call_count))); | 
 |   } | 
 |  | 
 |   // Closes these dialogs. | 
 |   for (size_t i = 0; i != num_dialogs; ++i) { | 
 |     ASSERT_NO_FATAL_FAILURE(AcceptDialog()); | 
 |   } | 
 |  | 
 |   // All dialogs must be closed now. | 
 |   app_modal::AppModalDialogQueue* queue = | 
 |       app_modal::AppModalDialogQueue::GetInstance(); | 
 |   ASSERT_TRUE(queue); | 
 |   EXPECT_FALSE(queue->HasActiveDialog()); | 
 |   EXPECT_EQ(0, queue->end() - queue->begin()); | 
 |   while (call_count < num_dialogs) | 
 |     ASSERT_NO_FATAL_FAILURE(content::RunAllPendingInMessageLoop()); | 
 | } | 
 |  | 
 | IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ConfirmQueue) { | 
 |   ASSERT_TRUE(RunExtensionTest("alert")) << message_; | 
 |  | 
 |   const Extension* extension = GetSingleLoadedExtension(); | 
 |   ExtensionHost* host = ProcessManager::Get(browser()->profile()) | 
 |                             ->GetBackgroundHostForExtension(extension->id()); | 
 |   ASSERT_TRUE(host); | 
 |  | 
 |   // Creates several dialogs at the same time. | 
 |   const size_t num_accepted_dialogs = 3; | 
 |   const size_t num_cancelled_dialogs = 3; | 
 |   size_t call_count = 0; | 
 |   for (size_t i = 0; i != num_accepted_dialogs; ++i) { | 
 |     const std::string dialog_name = | 
 |         "Accepted dialog #" + base::NumberToString(i) + "."; | 
 |     host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( | 
 |         base::ASCIIToUTF16("confirm('" + dialog_name + "');"), | 
 |         base::Bind(&CheckConfirmResult, dialog_name, true, | 
 |                    base::Unretained(&call_count))); | 
 |   } | 
 |   for (size_t i = 0; i != num_cancelled_dialogs; ++i) { | 
 |     const std::string dialog_name = | 
 |         "Cancelled dialog #" + base::NumberToString(i) + "."; | 
 |     host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( | 
 |         base::ASCIIToUTF16("confirm('" + dialog_name + "');"), | 
 |         base::Bind(&CheckConfirmResult, dialog_name, false, | 
 |                    base::Unretained(&call_count))); | 
 |   } | 
 |  | 
 |   // Closes these dialogs. | 
 |   for (size_t i = 0; i != num_accepted_dialogs; ++i) | 
 |     ASSERT_NO_FATAL_FAILURE(AcceptDialog()); | 
 |   for (size_t i = 0; i != num_cancelled_dialogs; ++i) | 
 |     ASSERT_NO_FATAL_FAILURE(CancelDialog()); | 
 |  | 
 |   // All dialogs must be closed now. | 
 |   app_modal::AppModalDialogQueue* queue = | 
 |       app_modal::AppModalDialogQueue::GetInstance(); | 
 |   ASSERT_TRUE(queue); | 
 |   EXPECT_FALSE(queue->HasActiveDialog()); | 
 |   EXPECT_EQ(0, queue->end() - queue->begin()); | 
 |   while (call_count < num_accepted_dialogs + num_cancelled_dialogs) | 
 |     ASSERT_NO_FATAL_FAILURE(content::RunAllPendingInMessageLoop()); | 
 | } | 
 |  | 
 | }  // namespace extensions |