1 // Copyright 2020 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 "testing/gtest/include/gtest/gtest.h"
6 
7 #include "chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.h"
8 #include "chrome/test/views/chrome_views_test_base.h"
9 #include "ui/views/controls/button/label_button.h"
10 #include "ui/views/test/widget_test.h"
11 
12 namespace {
13 
14 class TestDelegate : public ui::ProfileSigninConfirmationDelegate {
15  public:
TestDelegate(int * cancels,int * continues,int * signins)16   TestDelegate(int* cancels, int* continues, int* signins)
17       : cancels_(cancels), continues_(continues), signins_(signins) {}
18   ~TestDelegate() override = default;
19 
OnCancelSignin()20   void OnCancelSignin() override { (*cancels_)++; }
OnContinueSignin()21   void OnContinueSignin() override { (*continues_)++; }
OnSigninWithNewProfile()22   void OnSigninWithNewProfile() override { (*signins_)++; }
23 
24   int* cancels_;
25   int* continues_;
26   int* signins_;
27 };
28 
29 }  // namespace
30 
31 class ProfileSigninConfirmationDialogTest : public ChromeViewsTestBase {
32  public:
BuildDialog(std::unique_ptr<ui::ProfileSigninConfirmationDelegate> delegate)33   void BuildDialog(
34       std::unique_ptr<ui::ProfileSigninConfirmationDelegate> delegate) {
35     auto dialog = std::make_unique<ProfileSigninConfirmationDialogViews>(
36         nullptr, "foo@bar.com", std::move(delegate), true);
37     weak_dialog_ = dialog.get();
38 
39     widget_ = views::DialogDelegate::CreateDialogWidget(dialog.release(),
40                                                         GetContext(), nullptr);
41     widget_->Show();
42   }
43 
PressButton(views::Button * button)44   void PressButton(views::Button* button) {
45     views::test::WidgetDestroyedWaiter destroy_waiter(widget_);
46     // Synthesize both press & release - different platforms have different
47     // notions about whether buttons activate on press or on release.
48     button->OnKeyPressed(
49         ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE));
50     button->OnKeyReleased(
51         ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SPACE, ui::EF_NONE));
52     destroy_waiter.Wait();
53   }
54 
55   ProfileSigninConfirmationDialogViews* weak_dialog_ = nullptr;
56   views::Widget* widget_ = nullptr;
57 };
58 
59 // Regression test for https://crbug.com/1054866
TEST_F(ProfileSigninConfirmationDialogTest,CloseButtonOnlyCallsDelegateOnce)60 TEST_F(ProfileSigninConfirmationDialogTest, CloseButtonOnlyCallsDelegateOnce) {
61   int cancels = 0;
62   int continues = 0;
63   int signins = 0;
64   auto delegate =
65       std::make_unique<TestDelegate>(&cancels, &continues, &signins);
66   BuildDialog(std::move(delegate));
67   widget_->Show();
68 
69   // Press the "continue signin" button.
70   views::Button* button =
71       static_cast<views::Button*>(weak_dialog_->GetExtraView());
72   PressButton(button);
73 
74   // The delegate should *not* have gotten a call back to OnCancelSignin. If the
75   // fix for https://crbug.com/1054866 regresses, either it will, or we'll have
76   // crashed above.
77   EXPECT_EQ(cancels, 0);
78   EXPECT_EQ(continues, 1);
79   EXPECT_EQ(signins, 0);
80 }
81 
82 // Regression test for https://crbug.com/1091232
TEST_F(ProfileSigninConfirmationDialogTest,CancelButtonOnlyCallsDelegateOnce)83 TEST_F(ProfileSigninConfirmationDialogTest, CancelButtonOnlyCallsDelegateOnce) {
84   int cancels = 0;
85   int continues = 0;
86   int signins = 0;
87   auto delegate =
88       std::make_unique<TestDelegate>(&cancels, &continues, &signins);
89   BuildDialog(std::move(delegate));
90   widget_->Show();
91 
92   // Press the "Cancel" button.
93   views::Button* button = weak_dialog_->GetCancelButton();
94   PressButton(button);
95 
96   EXPECT_EQ(cancels, 1);
97   EXPECT_EQ(continues, 0);
98   EXPECT_EQ(signins, 0);
99 }
100 
101 // Regression test for https://crbug.com/1091232
TEST_F(ProfileSigninConfirmationDialogTest,NewProfileButtonOnlyCallsDelegateOnce)102 TEST_F(ProfileSigninConfirmationDialogTest,
103        NewProfileButtonOnlyCallsDelegateOnce) {
104   int cancels = 0;
105   int continues = 0;
106   int signins = 0;
107   auto delegate =
108       std::make_unique<TestDelegate>(&cancels, &continues, &signins);
109   BuildDialog(std::move(delegate));
110   widget_->Show();
111 
112   // Press the "Signin with new profile" button.
113   views::Button* button = weak_dialog_->GetOkButton();
114   PressButton(button);
115 
116   EXPECT_EQ(cancels, 0);
117   EXPECT_EQ(continues, 0);
118   EXPECT_EQ(signins, 1);
119 }
120