blob: 85e278eb36786a22701114b2ff1e046a0bbd9bb2 [file] [log] [blame]
// Copyright 2013 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 "chrome/browser/ui/views/sync/one_click_signin_dialog_view.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "chrome/browser/ui/sync/one_click_signin_links_delegate.h"
#include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "components/constrained_window/constrained_window_views.h"
#include "ui/events/event_utils.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
#include "ui/views/window/dialog_client_view.h"
class OneClickSigninDialogViewTest : public ChromeViewsTestBase,
public views::WidgetObserver {
public:
OneClickSigninDialogViewTest() {}
void SetUp() override {
ChromeViewsTestBase::SetUp();
SetConstrainedWindowViewsClient(CreateChromeConstrainedWindowViewsClient());
// Create a widget to host the anchor view.
anchor_widget_ = new views::Widget;
views::Widget::InitParams widget_params =
CreateParams(views::Widget::InitParams::TYPE_WINDOW);
anchor_widget_->Init(widget_params);
anchor_widget_->Show();
}
void TearDown() override {
OneClickSigninDialogView::Hide();
anchor_widget_->Close();
anchor_widget_ = NULL;
ChromeViewsTestBase::TearDown();
}
protected:
OneClickSigninDialogView* ShowOneClickSigninDialog() {
OneClickSigninDialogView::ShowDialog(
base::string16(),
std::make_unique<TestOneClickSigninLinksDelegate>(this),
anchor_widget_->GetNativeWindow(),
base::Bind(&OneClickSigninDialogViewTest::OnStartSync,
base::Unretained(this)));
OneClickSigninDialogView* view =
OneClickSigninDialogView::view_for_testing();
EXPECT_TRUE(view != NULL);
return view;
}
void OnStartSync(OneClickSigninSyncStarter::StartSyncMode mode) {
on_start_sync_called_ = true;
mode_ = mode;
}
// Waits for the OneClickSigninDialogView to close, by observing its Widget,
// then running a RunLoop, which OnWidgetDestroyed will quit. It's not
// sufficient to wait for the message loop to go idle, as the dialog has a
// closing animation which may still be running at that point. Instead, wait
// for its widget to be destroyed.
void WaitForClose() {
views::Widget* widget =
OneClickSigninDialogView::view_for_testing()->GetWidget();
widget->AddObserver(this);
base::RunLoop run_loop;
run_loop_ = &run_loop;
// Block until OnWidgetDestroyed() is fired.
run_loop.Run();
// The Widget has been destroyed, so there's no need to remove this as an
// observer.
}
// views::WidgetObserver method:
void OnWidgetDestroyed(views::Widget* widget) override { run_loop_->Quit(); }
bool on_start_sync_called_ = false;
OneClickSigninSyncStarter::StartSyncMode mode_ =
OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST;
int learn_more_click_count_ = 0;
int advanced_click_count_ = 0;
private:
friend class TestOneClickSigninLinksDelegate;
class TestOneClickSigninLinksDelegate : public OneClickSigninLinksDelegate {
public:
// |test| is not owned by this object.
explicit TestOneClickSigninLinksDelegate(OneClickSigninDialogViewTest* test)
: test_(test) {}
// OneClickSigninLinksDelegate:
void OnLearnMoreLinkClicked(bool is_dialog) override {
++test_->learn_more_click_count_;
}
void OnAdvancedLinkClicked() override { ++test_->advanced_click_count_; }
private:
OneClickSigninDialogViewTest* test_;
DISALLOW_COPY_AND_ASSIGN(TestOneClickSigninLinksDelegate);
};
// Widget to host the anchor view of the dialog. Destroys itself when closed.
views::Widget* anchor_widget_ = nullptr;
base::RunLoop* run_loop_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(OneClickSigninDialogViewTest);
};
TEST_F(OneClickSigninDialogViewTest, ShowDialog) {
ShowOneClickSigninDialog();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(OneClickSigninDialogView::IsShowing());
}
TEST_F(OneClickSigninDialogViewTest, HideDialog) {
ShowOneClickSigninDialog();
OneClickSigninDialogView::Hide();
WaitForClose();
EXPECT_FALSE(OneClickSigninDialogView::IsShowing());
EXPECT_TRUE(on_start_sync_called_);
EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC, mode_);
}
TEST_F(OneClickSigninDialogViewTest, OkButton) {
OneClickSigninDialogView* view = ShowOneClickSigninDialog();
view->GetDialogClientView()->ResetViewShownTimeStampForTesting();
gfx::Point center(10, 10);
const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, center, center,
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON);
view->GetDialogClientView()->ok_button()->OnMousePressed(event);
view->GetDialogClientView()->ok_button()->OnMouseReleased(event);
WaitForClose();
EXPECT_FALSE(OneClickSigninDialogView::IsShowing());
EXPECT_TRUE(on_start_sync_called_);
EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, mode_);
}
TEST_F(OneClickSigninDialogViewTest, UndoButton) {
OneClickSigninDialogView* view = ShowOneClickSigninDialog();
view->GetDialogClientView()->ResetViewShownTimeStampForTesting();
gfx::Point center(10, 10);
const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, center, center,
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON);
view->GetDialogClientView()->cancel_button()->OnMousePressed(event);
view->GetDialogClientView()->cancel_button()->OnMouseReleased(event);
WaitForClose();
EXPECT_FALSE(OneClickSigninDialogView::IsShowing());
EXPECT_TRUE(on_start_sync_called_);
EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC, mode_);
}
TEST_F(OneClickSigninDialogViewTest, AdvancedLink) {
OneClickSigninDialogView* view = ShowOneClickSigninDialog();
// Simulate pressing a link in the dialog.
views::LinkListener* listener = view;
listener->LinkClicked(view->advanced_link_, 0);
WaitForClose();
EXPECT_TRUE(on_start_sync_called_);
EXPECT_EQ(OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST, mode_);
EXPECT_FALSE(OneClickSigninDialogView::IsShowing());
EXPECT_EQ(0, advanced_click_count_);
}
TEST_F(OneClickSigninDialogViewTest, LearnMoreLink) {
OneClickSigninDialogView* view = ShowOneClickSigninDialog();
views::LinkListener* listener = view;
listener->LinkClicked(view->learn_more_link_, 0);
// View should still be showing and the OnLearnMoreLinkClicked method
// of the delegate should have been called with |is_dialog| == true.
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(OneClickSigninDialogView::IsShowing());
EXPECT_EQ(1, learn_more_click_count_);
}
TEST_F(OneClickSigninDialogViewTest, PressEnterKey) {
OneClickSigninDialogView* one_click_view = ShowOneClickSigninDialog();
ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0);
one_click_view->GetWidget()->OnKeyEvent(&event);
WaitForClose();
EXPECT_FALSE(OneClickSigninDialogView::IsShowing());
EXPECT_TRUE(on_start_sync_called_);
EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, mode_);
}
TEST_F(OneClickSigninDialogViewTest, PressEscapeKey) {
OneClickSigninDialogView* one_click_view = ShowOneClickSigninDialog();
ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, 0);
one_click_view->GetWidget()->OnKeyEvent(&event);
WaitForClose();
EXPECT_FALSE(OneClickSigninDialogView::IsShowing());
EXPECT_TRUE(on_start_sync_called_);
EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC, mode_);
}