Commit b908f689 authored by estade's avatar estade Committed by Commit bot

Add a regression test for the CardUnmaskPrompt.

BUG=none

Review URL: https://codereview.chromium.org/1020013003

Cr-Commit-Position: refs/heads/master@{#321634}
parent d60174a4
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#include "base/strings/string16.h" #include "base/strings/string16.h"
namespace base {
class TimeDelta;
}
namespace content { namespace content {
class WebContents; class WebContents;
} }
...@@ -32,6 +36,7 @@ class CardUnmaskPromptController { ...@@ -32,6 +36,7 @@ class CardUnmaskPromptController {
virtual bool InputCvcIsValid(const base::string16& input_text) const = 0; virtual bool InputCvcIsValid(const base::string16& input_text) const = 0;
virtual bool InputExpirationIsValid(const base::string16& month, virtual bool InputExpirationIsValid(const base::string16& month,
const base::string16& year) const = 0; const base::string16& year) const = 0;
virtual base::TimeDelta GetSuccessMessageDuration() const = 0;
}; };
} // namespace autofill } // namespace autofill
......
...@@ -36,10 +36,6 @@ CardUnmaskPromptControllerImpl::~CardUnmaskPromptControllerImpl() { ...@@ -36,10 +36,6 @@ CardUnmaskPromptControllerImpl::~CardUnmaskPromptControllerImpl() {
card_unmask_view_->ControllerGone(); card_unmask_view_->ControllerGone();
} }
CardUnmaskPromptView* CardUnmaskPromptControllerImpl::CreateAndShowView() {
return CardUnmaskPromptView::CreateAndShow(this);
}
void CardUnmaskPromptControllerImpl::ShowPrompt( void CardUnmaskPromptControllerImpl::ShowPrompt(
const CreditCard& card, const CreditCard& card,
base::WeakPtr<CardUnmaskDelegate> delegate) { base::WeakPtr<CardUnmaskDelegate> delegate) {
...@@ -261,6 +257,15 @@ bool CardUnmaskPromptControllerImpl::InputExpirationIsValid( ...@@ -261,6 +257,15 @@ bool CardUnmaskPromptControllerImpl::InputExpirationIsValid(
return month_value >= now.month; return month_value >= now.month;
} }
base::TimeDelta CardUnmaskPromptControllerImpl::GetSuccessMessageDuration()
const {
return base::TimeDelta::FromMilliseconds(500);
}
CardUnmaskPromptView* CardUnmaskPromptControllerImpl::CreateAndShowView() {
return CardUnmaskPromptView::CreateAndShow(this);
}
void CardUnmaskPromptControllerImpl::LoadRiskFingerprint() { void CardUnmaskPromptControllerImpl::LoadRiskFingerprint() {
LoadRiskData( LoadRiskData(
0, web_contents_, 0, web_contents_,
......
...@@ -43,19 +43,20 @@ class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController { ...@@ -43,19 +43,20 @@ class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController {
bool InputCvcIsValid(const base::string16& input_text) const override; bool InputCvcIsValid(const base::string16& input_text) const override;
bool InputExpirationIsValid(const base::string16& month, bool InputExpirationIsValid(const base::string16& month,
const base::string16& year) const override; const base::string16& year) const override;
base::TimeDelta GetSuccessMessageDuration() const override;
protected: protected:
// Virtual so tests can suppress it. // Virtual so tests can suppress it.
virtual CardUnmaskPromptView* CreateAndShowView(); virtual CardUnmaskPromptView* CreateAndShowView();
virtual void LoadRiskFingerprint(); virtual void LoadRiskFingerprint();
virtual void OnDidLoadRiskFingerprint(const std::string& risk_data); // Protected so tests can call it.
void OnDidLoadRiskFingerprint(const std::string& risk_data);
// Exposed for testing. // Exposed for testing.
CardUnmaskPromptView* view() { return card_unmask_view_; } CardUnmaskPromptView* view() { return card_unmask_view_; }
private: private:
bool AllowsRetry(AutofillClient::GetRealPanResult result); bool AllowsRetry(AutofillClient::GetRealPanResult result);
void LogOnCloseEvents(); void LogOnCloseEvents();
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_H_ #ifndef CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_H_
#define CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_H_ #define CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_H_
#include "base/strings/string16.h"
namespace autofill { namespace autofill {
class CardUnmaskPromptController; class CardUnmaskPromptController;
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
#include "base/guid.h" #include "base/guid.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_view_tester.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
...@@ -24,14 +26,20 @@ class TestCardUnmaskDelegate : public CardUnmaskDelegate { ...@@ -24,14 +26,20 @@ class TestCardUnmaskDelegate : public CardUnmaskDelegate {
virtual ~TestCardUnmaskDelegate() {} virtual ~TestCardUnmaskDelegate() {}
// CardUnmaskDelegate implementation. // CardUnmaskDelegate implementation.
void OnUnmaskResponse(const UnmaskResponse& response) override {} void OnUnmaskResponse(const UnmaskResponse& response) override {
response_ = response;
}
void OnUnmaskPromptClosed() override {} void OnUnmaskPromptClosed() override {}
base::WeakPtr<TestCardUnmaskDelegate> GetWeakPtr() { base::WeakPtr<TestCardUnmaskDelegate> GetWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
UnmaskResponse response() { return response_; }
private: private:
UnmaskResponse response_;
base::WeakPtrFactory<TestCardUnmaskDelegate> weak_factory_; base::WeakPtrFactory<TestCardUnmaskDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TestCardUnmaskDelegate); DISALLOW_COPY_AND_ASSIGN(TestCardUnmaskDelegate);
...@@ -47,24 +55,20 @@ class TestCardUnmaskPromptController : public CardUnmaskPromptControllerImpl { ...@@ -47,24 +55,20 @@ class TestCardUnmaskPromptController : public CardUnmaskPromptControllerImpl {
weak_factory_(this) {} weak_factory_(this) {}
// CardUnmaskPromptControllerImpl implementation. // CardUnmaskPromptControllerImpl implementation.
void OnDidLoadRiskFingerprint(const std::string& risk_data) override { base::TimeDelta GetSuccessMessageDuration() const override {
CardUnmaskPromptControllerImpl::OnDidLoadRiskFingerprint(risk_data); return base::TimeDelta::FromMilliseconds(10);
// Call Quit() from here rather than from OnUnmaskDialogClosed().
// FingerprintDataLoader starts several async tasks that take a while to
// complete. If Quit() is called before FingerprintDataLoader is all done
// then LeakTracker will detect that some resources have not been freed
// and cause the browser test to fail. This is not a real leak though -
// normally the async tasks would complete and encounter weak callbacks.
runner_->Quit();
} }
void RunMessageLoop() { runner_->Run(); } void LoadRiskFingerprint() override {
OnDidLoadRiskFingerprint(std::string("risk_data"));
}
base::WeakPtr<TestCardUnmaskPromptController> GetWeakPtr() { base::WeakPtr<TestCardUnmaskPromptController> GetWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
using CardUnmaskPromptControllerImpl::view;
private: private:
scoped_refptr<content::MessageLoopRunner> runner_; scoped_refptr<content::MessageLoopRunner> runner_;
base::WeakPtrFactory<TestCardUnmaskPromptController> weak_factory_; base::WeakPtrFactory<TestCardUnmaskPromptController> weak_factory_;
...@@ -88,10 +92,11 @@ class CardUnmaskPromptViewBrowserTest : public InProcessBrowserTest { ...@@ -88,10 +92,11 @@ class CardUnmaskPromptViewBrowserTest : public InProcessBrowserTest {
TestCardUnmaskPromptController* controller() { return controller_.get(); } TestCardUnmaskPromptController* controller() { return controller_.get(); }
TestCardUnmaskDelegate* delegate() { return delegate_.get(); } TestCardUnmaskDelegate* delegate() { return delegate_.get(); }
private: protected:
// This member must outlive the controller. // This member must outlive the controller.
scoped_refptr<content::MessageLoopRunner> runner_; scoped_refptr<content::MessageLoopRunner> runner_;
private:
scoped_ptr<TestCardUnmaskPromptController> controller_; scoped_ptr<TestCardUnmaskPromptController> controller_;
scoped_ptr<TestCardUnmaskDelegate> delegate_; scoped_ptr<TestCardUnmaskDelegate> delegate_;
...@@ -99,14 +104,34 @@ class CardUnmaskPromptViewBrowserTest : public InProcessBrowserTest { ...@@ -99,14 +104,34 @@ class CardUnmaskPromptViewBrowserTest : public InProcessBrowserTest {
}; };
IN_PROC_BROWSER_TEST_F(CardUnmaskPromptViewBrowserTest, DisplayUI) { IN_PROC_BROWSER_TEST_F(CardUnmaskPromptViewBrowserTest, DisplayUI) {
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123"); controller()->ShowPrompt(test::GetMaskedServerCard(),
test::SetCreditCardInfo(&credit_card, "Bonnie Parker", delegate()->GetWeakPtr());
"2109" /* Mastercard */, "12", "2012"); }
credit_card.SetTypeForMaskedCard(kMasterCard);
controller()->ShowPrompt(credit_card, delegate()->GetWeakPtr()); // TODO(bondd): bring up on Mac.
controller()->RunMessageLoop(); #if !defined(OS_MACOSX)
// Makes sure the user can close the dialog while the verification success
// message is showing.
IN_PROC_BROWSER_TEST_F(CardUnmaskPromptViewBrowserTest,
EarlyCloseAfterSuccess) {
controller()->ShowPrompt(test::GetMaskedServerCard(),
delegate()->GetWeakPtr());
controller()->OnUnmaskResponse(base::ASCIIToUTF16("123"),
base::ASCIIToUTF16("10"),
base::ASCIIToUTF16("19"), false);
EXPECT_EQ(base::ASCIIToUTF16("123"), delegate()->response().cvc);
controller()->OnVerificationResult(AutofillClient::SUCCESS);
// Simulate the user clicking [x] before the "Success!" message disappears.
CardUnmaskPromptViewTester::For(controller()->view())->Close();
// Wait a little while; there should be no crash.
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE, base::Bind(&content::MessageLoopRunner::Quit,
base::Unretained(runner_.get())),
2 * controller()->GetSuccessMessageDuration());
runner_->Run();
} }
#endif
} // namespace } // namespace
......
// Copyright 2015 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.
#ifndef CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_TESTER_H_
#define CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_TESTER_H_
#include "base/memory/scoped_ptr.h"
namespace content {
class WebContents;
}
namespace autofill {
class CardUnmaskPromptView;
// Functionality that helps to test an AutofillCardUnmaskPromptView.
class CardUnmaskPromptViewTester {
public:
// Gets a AutofillCardUnmaskPromptViewTester for |view|.
static scoped_ptr<CardUnmaskPromptViewTester> For(CardUnmaskPromptView* view);
virtual ~CardUnmaskPromptViewTester() {}
virtual void Close() = 0;
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_TESTER_H_
// Copyright 2015 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/autofill/card_unmask_prompt_view_tester_views.h"
#include "chrome/browser/ui/views/autofill/card_unmask_prompt_views.h"
namespace autofill {
// static
scoped_ptr<CardUnmaskPromptViewTester> CardUnmaskPromptViewTester::For(
CardUnmaskPromptView* view) {
return scoped_ptr<CardUnmaskPromptViewTester>(
new CardUnmaskPromptViewTesterViews(
static_cast<CardUnmaskPromptViews*>(view)));
}
// Class that facilitates testing.
CardUnmaskPromptViewTesterViews::CardUnmaskPromptViewTesterViews(
CardUnmaskPromptViews* view)
: view_(view) {
}
CardUnmaskPromptViewTesterViews::~CardUnmaskPromptViewTesterViews() {
}
void CardUnmaskPromptViewTesterViews::Close() {
view_->ClosePrompt();
}
} // namespace autofill
// Copyright 2015 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.
#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_TESTER_VIEWS_H_
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_TESTER_VIEWS_H_
#include "chrome/browser/ui/autofill/card_unmask_prompt_view_tester.h"
namespace autofill {
class CardUnmaskPromptViews;
// Class that facilitates testing a CardUnmaskPromptViews.
class CardUnmaskPromptViewTesterViews : public CardUnmaskPromptViewTester {
public:
explicit CardUnmaskPromptViewTesterViews(CardUnmaskPromptViews* view);
~CardUnmaskPromptViewTesterViews() override;
void Close() override;
private:
CardUnmaskPromptViews* view_;
DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViewTesterViews);
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_TESTER_VIEWS_H_
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/views/autofill/card_unmask_prompt_views.h"
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/autofill/autofill_dialog_models.h"
#include "chrome/browser/ui/autofill/autofill_dialog_types.h" #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
#include "chrome/browser/ui/views/autofill/decorated_textfield.h" #include "chrome/browser/ui/views/autofill/decorated_textfield.h"
#include "chrome/browser/ui/views/autofill/tooltip_icon.h" #include "chrome/browser/ui/views/autofill/tooltip_icon.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
...@@ -22,19 +22,14 @@ ...@@ -22,19 +22,14 @@
#include "ui/views/background.h" #include "ui/views/background.h"
#include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/combobox/combobox.h" #include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/combobox/combobox_listener.h"
#include "ui/views/controls/image_view.h" #include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h" #include "ui/views/controls/label.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_client_view.h" #include "ui/views/window/dialog_client_view.h"
#include "ui/views/window/dialog_delegate.h"
namespace autofill { namespace autofill {
namespace {
// The number of pixels of blank space on the outer horizontal edges of the // The number of pixels of blank space on the outer horizontal edges of the
// dialog. // dialog.
const int kEdgePadding = 19; const int kEdgePadding = 19;
...@@ -43,12 +38,16 @@ const int kEdgePadding = 19; ...@@ -43,12 +38,16 @@ const int kEdgePadding = 19;
SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0); SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0);
SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0); SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0);
class CardUnmaskPromptViews : public CardUnmaskPromptView, // static
views::ComboboxListener, CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow(
views::DialogDelegateView, CardUnmaskPromptController* controller) {
views::TextfieldController { CardUnmaskPromptViews* view = new CardUnmaskPromptViews(controller);
public: view->Show();
explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller) return view;
}
CardUnmaskPromptViews::CardUnmaskPromptViews(
CardUnmaskPromptController* controller)
: controller_(controller), : controller_(controller),
main_contents_(nullptr), main_contents_(nullptr),
permanent_error_label_(nullptr), permanent_error_label_(nullptr),
...@@ -59,40 +58,41 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -59,40 +58,41 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
storage_checkbox_(nullptr), storage_checkbox_(nullptr),
progress_overlay_(nullptr), progress_overlay_(nullptr),
progress_label_(nullptr), progress_label_(nullptr),
weak_ptr_factory_(this) {} weak_ptr_factory_(this) {
}
~CardUnmaskPromptViews() override { CardUnmaskPromptViews::~CardUnmaskPromptViews() {
if (controller_) if (controller_)
controller_->OnUnmaskDialogClosed(); controller_->OnUnmaskDialogClosed();
} }
void Show() { void CardUnmaskPromptViews::Show() {
constrained_window::ShowWebModalDialogViews(this, constrained_window::ShowWebModalDialogViews(this,
controller_->GetWebContents()); controller_->GetWebContents());
} }
// CardUnmaskPromptView void CardUnmaskPromptViews::ControllerGone() {
void ControllerGone() override {
controller_ = nullptr; controller_ = nullptr;
ClosePrompt(); ClosePrompt();
} }
void DisableAndWaitForVerification() override { void CardUnmaskPromptViews::DisableAndWaitForVerification() {
SetInputsEnabled(false); SetInputsEnabled(false);
progress_overlay_->SetVisible(true); progress_overlay_->SetVisible(true);
GetDialogClientView()->UpdateDialogButtons(); GetDialogClientView()->UpdateDialogButtons();
Layout(); Layout();
} }
void GotVerificationResult(const base::string16& error_message, void CardUnmaskPromptViews::GotVerificationResult(
bool allow_retry) override { const base::string16& error_message,
bool allow_retry) {
if (error_message.empty()) { if (error_message.empty()) {
progress_label_->SetText(l10n_util::GetStringUTF16( progress_label_->SetText(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_SUCCESS)); IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_SUCCESS));
base::MessageLoop::current()->PostDelayedTask( base::MessageLoop::current()->PostDelayedTask(
FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt, FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(1)); controller_->GetSuccessMessageDuration());
} else { } else {
// TODO(estade): it's somewhat jarring when the error comes back too // TODO(estade): it's somewhat jarring when the error comes back too
// quickly. // quickly.
...@@ -113,14 +113,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -113,14 +113,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
permanent_error_label_->SetVisible(true); permanent_error_label_->SetVisible(true);
SetRetriableErrorMessage(base::string16()); SetRetriableErrorMessage(base::string16());
} }
GetDialogClientView()->UpdateDialogButtons(); GetDialogClientView()->UpdateDialogButtons();
} }
Layout(); Layout();
} }
void SetRetriableErrorMessage(const base::string16& message) { void CardUnmaskPromptViews::SetRetriableErrorMessage(
const base::string16& message) {
if (message.empty()) { if (message.empty()) {
error_label_->SetMultiLine(false); error_label_->SetMultiLine(false);
error_label_->SetText(base::ASCIIToUTF16(" ")); error_label_->SetText(base::ASCIIToUTF16(" "));
...@@ -132,15 +132,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -132,15 +132,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
// Update the dialog's size. // Update the dialog's size.
if (GetWidget() && controller_->GetWebContents()) { if (GetWidget() && controller_->GetWebContents()) {
constrained_window::UpdateWebContentsModalDialogPosition( constrained_window::UpdateWebContentsModalDialogPosition(
GetWidget(), GetWidget(), web_modal::WebContentsModalDialogManager::FromWebContents(
web_modal::WebContentsModalDialogManager::FromWebContents(
controller_->GetWebContents()) controller_->GetWebContents())
->delegate() ->delegate()
->GetWebContentsModalDialogHost()); ->GetWebContentsModalDialogHost());
} }
} }
void SetInputsEnabled(bool enabled) { void CardUnmaskPromptViews::SetInputsEnabled(bool enabled) {
cvc_input_->SetEnabled(enabled); cvc_input_->SetEnabled(enabled);
storage_checkbox_->SetEnabled(enabled); storage_checkbox_->SetEnabled(enabled);
...@@ -148,15 +147,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -148,15 +147,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
month_input_->SetEnabled(enabled); month_input_->SetEnabled(enabled);
if (year_input_) if (year_input_)
year_input_->SetEnabled(enabled); year_input_->SetEnabled(enabled);
} }
// views::DialogDelegateView views::View* CardUnmaskPromptViews::GetContentsView() {
View* GetContentsView() override {
InitIfNecessary(); InitIfNecessary();
return this; return this;
} }
views::View* CreateFootnoteView() override { views::View* CardUnmaskPromptViews::CreateFootnoteView() {
// Local storage checkbox and (?) tooltip. // Local storage checkbox and (?) tooltip.
views::View* storage_row = new views::View(); views::View* storage_row = new views::View();
views::BoxLayout* storage_row_layout = new views::BoxLayout( views::BoxLayout* storage_row_layout = new views::BoxLayout(
...@@ -177,61 +175,68 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -177,61 +175,68 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_TOOLTIP))); IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_TOOLTIP)));
return storage_row; return storage_row;
} }
// views::View gfx::Size CardUnmaskPromptViews::GetPreferredSize() const {
gfx::Size GetPreferredSize() const override {
// Must hardcode a width so the label knows where to wrap. TODO(estade): // Must hardcode a width so the label knows where to wrap. TODO(estade):
// This can lead to a weird looking dialog if we end up getting allocated // This can lead to a weird looking dialog if we end up getting allocated
// more width than we ask for, e.g. if the title is super long. // more width than we ask for, e.g. if the title is super long.
const int kWidth = 375; const int kWidth = 375;
return gfx::Size(kWidth, GetHeightForWidth(kWidth)); return gfx::Size(kWidth, GetHeightForWidth(kWidth));
} }
void Layout() override { void CardUnmaskPromptViews::Layout() {
for (int i = 0; i < child_count(); ++i) { for (int i = 0; i < child_count(); ++i) {
child_at(i)->SetBoundsRect(GetContentsBounds()); child_at(i)->SetBoundsRect(GetContentsBounds());
} }
} }
int GetHeightForWidth(int width) const override { int CardUnmaskPromptViews::GetHeightForWidth(int width) const {
if (!has_children()) if (!has_children())
return 0; return 0;
const gfx::Insets insets = GetInsets(); const gfx::Insets insets = GetInsets();
return main_contents_->GetHeightForWidth(width - insets.width()) + return main_contents_->GetHeightForWidth(width - insets.width()) +
insets.height(); insets.height();
} }
void OnNativeThemeChanged(const ui::NativeTheme* theme) override { void CardUnmaskPromptViews::OnNativeThemeChanged(const ui::NativeTheme* theme) {
SkColor bg_color = SkColor bg_color =
theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground); theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground);
bg_color = SkColorSetA(bg_color, 0xDD); bg_color = SkColorSetA(bg_color, 0xDD);
progress_overlay_->set_background( progress_overlay_->set_background(
views::Background::CreateSolidBackground(bg_color)); views::Background::CreateSolidBackground(bg_color));
} }
ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; } ui::ModalType CardUnmaskPromptViews::GetModalType() const {
return ui::MODAL_TYPE_CHILD;
}
base::string16 GetWindowTitle() const override { base::string16 CardUnmaskPromptViews::GetWindowTitle() const {
return controller_->GetWindowTitle(); return controller_->GetWindowTitle();
} }
void DeleteDelegate() override { delete this; } void CardUnmaskPromptViews::DeleteDelegate() {
delete this;
}
int GetDialogButtons() const override { int CardUnmaskPromptViews::GetDialogButtons() const {
return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
} }
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override { base::string16 CardUnmaskPromptViews::GetDialogButtonLabel(
ui::DialogButton button) const {
if (button == ui::DIALOG_BUTTON_OK) if (button == ui::DIALOG_BUTTON_OK)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_UNMASK_CONFIRM_BUTTON); return l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_UNMASK_CONFIRM_BUTTON);
return DialogDelegateView::GetDialogButtonLabel(button); return DialogDelegateView::GetDialogButtonLabel(button);
} }
bool ShouldDefaultButtonBeBlue() const override { return true; } bool CardUnmaskPromptViews::ShouldDefaultButtonBeBlue() const {
return true;
}
bool IsDialogButtonEnabled(ui::DialogButton button) const override { bool CardUnmaskPromptViews::IsDialogButtonEnabled(
ui::DialogButton button) const {
if (button == ui::DIALOG_BUTTON_CANCEL) if (button == ui::DIALOG_BUTTON_CANCEL)
return true; return true;
...@@ -240,40 +245,40 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -240,40 +245,40 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
return cvc_input_->enabled() && return cvc_input_->enabled() &&
controller_->InputCvcIsValid(cvc_input_->text()) && controller_->InputCvcIsValid(cvc_input_->text()) &&
ExpirationDateIsValid(); ExpirationDateIsValid();
} }
views::View* GetInitiallyFocusedView() override { return cvc_input_; } views::View* CardUnmaskPromptViews::GetInitiallyFocusedView() {
return cvc_input_;
}
bool Cancel() override { bool CardUnmaskPromptViews::Cancel() {
return true; return true;
} }
bool Accept() override { bool CardUnmaskPromptViews::Accept() {
if (!controller_) if (!controller_)
return true; return true;
controller_->OnUnmaskResponse( controller_->OnUnmaskResponse(
cvc_input_->text(), cvc_input_->text(),
month_input_ month_input_ ? month_input_->GetTextForRow(month_input_->selected_index())
? month_input_->GetTextForRow(month_input_->selected_index())
: base::string16(), : base::string16(),
year_input_ ? year_input_->GetTextForRow(year_input_->selected_index()) year_input_ ? year_input_->GetTextForRow(year_input_->selected_index())
: base::string16(), : base::string16(),
storage_checkbox_ ? storage_checkbox_->checked() : false); storage_checkbox_ ? storage_checkbox_->checked() : false);
return false; return false;
} }
// views::TextfieldController void CardUnmaskPromptViews::ContentsChanged(
void ContentsChanged(views::Textfield* sender, views::Textfield* sender,
const base::string16& new_contents) override { const base::string16& new_contents) {
if (controller_->InputCvcIsValid(new_contents)) if (controller_->InputCvcIsValid(new_contents))
cvc_input_->SetInvalid(false); cvc_input_->SetInvalid(false);
GetDialogClientView()->UpdateDialogButtons(); GetDialogClientView()->UpdateDialogButtons();
} }
// views::ComboboxListener void CardUnmaskPromptViews::OnPerformAction(views::Combobox* combobox) {
void OnPerformAction(views::Combobox* combobox) override {
if (ExpirationDateIsValid()) { if (ExpirationDateIsValid()) {
if (month_input_->invalid()) { if (month_input_->invalid()) {
month_input_->SetInvalid(false); month_input_->SetInvalid(false);
...@@ -293,10 +298,9 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -293,10 +298,9 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
} }
GetDialogClientView()->UpdateDialogButtons(); GetDialogClientView()->UpdateDialogButtons();
} }
private: void CardUnmaskPromptViews::InitIfNecessary() {
void InitIfNecessary() {
if (has_children()) if (has_children())
return; return;
...@@ -345,14 +349,12 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -345,14 +349,12 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
year_input_ = new views::Combobox(&year_combobox_model_); year_input_ = new views::Combobox(&year_combobox_model_);
year_input_->set_listener(this); year_input_->set_listener(this);
input_row->AddChildView(year_input_); input_row->AddChildView(year_input_);
input_row->AddChildView(new views::Label(base::ASCIIToUTF16(" "))); input_row->AddChildView(new views::Label(base::ASCIIToUTF16(" ")));
} }
cvc_input_ = new DecoratedTextfield( cvc_input_ = new DecoratedTextfield(
base::string16(), base::string16(),
l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), this);
this);
cvc_input_->set_default_width_in_chars(8); cvc_input_->set_default_width_in_chars(8);
input_row->AddChildView(cvc_input_); input_row->AddChildView(cvc_input_);
...@@ -383,56 +385,19 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -383,56 +385,19 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
progress_label_ = new views::Label(l10n_util::GetStringUTF16( progress_label_ = new views::Label(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_IN_PROGRESS)); IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_IN_PROGRESS));
progress_overlay_->AddChildView(progress_label_); progress_overlay_->AddChildView(progress_label_);
} }
void ClosePrompt() { GetWidget()->Close(); }
bool ExpirationDateIsValid() const { bool CardUnmaskPromptViews::ExpirationDateIsValid() const {
if (!controller_->ShouldRequestExpirationDate()) if (!controller_->ShouldRequestExpirationDate())
return true; return true;
return controller_->InputExpirationIsValid( return controller_->InputExpirationIsValid(
month_input_->GetTextForRow(month_input_->selected_index()), month_input_->GetTextForRow(month_input_->selected_index()),
year_input_->GetTextForRow(year_input_->selected_index())); year_input_->GetTextForRow(year_input_->selected_index()));
} }
CardUnmaskPromptController* controller_;
views::View* main_contents_;
// The error label for permanent errors (where the user can't retry).
views::Label* permanent_error_label_;
DecoratedTextfield* cvc_input_;
// These will be null when expiration date is not required.
views::Combobox* month_input_;
views::Combobox* year_input_;
MonthComboboxModel month_combobox_model_;
YearComboboxModel year_combobox_model_;
// The error label for most errors, which lives beneath the inputs.
views::Label* error_label_;
views::Checkbox* storage_checkbox_;
views::View* progress_overlay_;
views::Label* progress_label_;
base::WeakPtrFactory<CardUnmaskPromptViews> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews);
};
} // namespace
// static void CardUnmaskPromptViews::ClosePrompt() {
CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow( GetWidget()->Close();
CardUnmaskPromptController* controller) {
CardUnmaskPromptViews* view = new CardUnmaskPromptViews(controller);
view->Show();
return view;
} }
} // namespace autofill } // namespace autofill
// Copyright 2015 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.
#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_CARD_UNMASK_PROMPT_VIEWS_H_
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_CARD_UNMASK_PROMPT_VIEWS_H_
#include "chrome/browser/ui/autofill/autofill_dialog_models.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
#include "ui/views/controls/combobox/combobox_listener.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/window/dialog_delegate.h"
namespace views {
class Label;
class Checkbox;
}
namespace autofill {
class DecoratedTextfield;
class CardUnmaskPromptViews : public CardUnmaskPromptView,
views::ComboboxListener,
views::DialogDelegateView,
views::TextfieldController {
public:
explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller);
~CardUnmaskPromptViews() override;
void Show();
// CardUnmaskPromptView
void ControllerGone() override;
void DisableAndWaitForVerification() override;
void GotVerificationResult(const base::string16& error_message,
bool allow_retry) override;
// views::DialogDelegateView
View* GetContentsView() override;
views::View* CreateFootnoteView() override;
// views::View
gfx::Size GetPreferredSize() const override;
void Layout() override;
int GetHeightForWidth(int width) const override;
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
ui::ModalType GetModalType() const override;
base::string16 GetWindowTitle() const override;
void DeleteDelegate() override;
int GetDialogButtons() const override;
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
bool ShouldDefaultButtonBeBlue() const override;
bool IsDialogButtonEnabled(ui::DialogButton button) const override;
views::View* GetInitiallyFocusedView() override;
bool Cancel() override;
bool Accept() override;
// views::TextfieldController
void ContentsChanged(views::Textfield* sender,
const base::string16& new_contents) override;
// views::ComboboxListener
void OnPerformAction(views::Combobox* combobox) override;
private:
friend class CardUnmaskPromptViewTesterViews;
void InitIfNecessary();
void SetRetriableErrorMessage(const base::string16& message);
bool ExpirationDateIsValid() const;
void SetInputsEnabled(bool enabled);
void ClosePrompt();
CardUnmaskPromptController* controller_;
views::View* main_contents_;
// The error label for permanent errors (where the user can't retry).
views::Label* permanent_error_label_;
DecoratedTextfield* cvc_input_;
// These will be null when expiration date is not required.
views::Combobox* month_input_;
views::Combobox* year_input_;
MonthComboboxModel month_combobox_model_;
YearComboboxModel year_combobox_model_;
// The error label for most errors, which lives beneath the inputs.
views::Label* error_label_;
views::Checkbox* storage_checkbox_;
views::View* progress_overlay_;
views::Label* progress_label_;
base::WeakPtrFactory<CardUnmaskPromptViews> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews);
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_CARD_UNMASK_PROMPT_VIEWS_H_
...@@ -1941,6 +1941,7 @@ ...@@ -1941,6 +1941,7 @@
'browser/ui/views/autofill/autofill_popup_view_views.cc', 'browser/ui/views/autofill/autofill_popup_view_views.cc',
'browser/ui/views/autofill/autofill_popup_view_views.h', 'browser/ui/views/autofill/autofill_popup_view_views.h',
'browser/ui/views/autofill/card_unmask_prompt_views.cc', 'browser/ui/views/autofill/card_unmask_prompt_views.cc',
'browser/ui/views/autofill/card_unmask_prompt_views.h',
'browser/ui/views/autofill/decorated_textfield.cc', 'browser/ui/views/autofill/decorated_textfield.cc',
'browser/ui/views/autofill/decorated_textfield.h', 'browser/ui/views/autofill/decorated_textfield.h',
'browser/ui/views/autofill/expanding_textfield.cc', 'browser/ui/views/autofill/expanding_textfield.cc',
......
...@@ -429,6 +429,8 @@ ...@@ -429,6 +429,8 @@
'browser/ui/ash/volume_controller_browsertest_chromeos.cc', 'browser/ui/ash/volume_controller_browsertest_chromeos.cc',
'browser/ui/autofill/autofill_dialog_controller_browsertest.cc', 'browser/ui/autofill/autofill_dialog_controller_browsertest.cc',
'browser/ui/autofill/autofill_dialog_view_tester.h', 'browser/ui/autofill/autofill_dialog_view_tester.h',
'browser/ui/autofill/card_unmask_prompt_view_browsertest.cc',
'browser/ui/autofill/card_unmask_view_tester.h',
'browser/ui/autofill/mock_address_validator.cc', 'browser/ui/autofill/mock_address_validator.cc',
'browser/ui/autofill/mock_address_validator.h', 'browser/ui/autofill/mock_address_validator.h',
'browser/ui/autofill/password_generation_popup_view_browsertest.cc', 'browser/ui/autofill/password_generation_popup_view_browsertest.cc',
...@@ -596,6 +598,8 @@ ...@@ -596,6 +598,8 @@
'browser/ui/views/autofill/autofill_dialog_view_tester_views.cc', 'browser/ui/views/autofill/autofill_dialog_view_tester_views.cc',
'browser/ui/views/autofill/autofill_dialog_view_tester_views.h', 'browser/ui/views/autofill/autofill_dialog_view_tester_views.h',
'browser/ui/views/autofill/autofill_popup_base_view_browsertest.cc', 'browser/ui/views/autofill/autofill_popup_base_view_browsertest.cc',
'browser/ui/views/autofill/card_unmask_prompt_view_tester_views.cc',
'browser/ui/views/autofill/card_unmask_prompt_view_tester_views.h',
'browser/ui/views/autofill/password_generation_popup_view_tester_views.cc', 'browser/ui/views/autofill/password_generation_popup_view_tester_views.cc',
'browser/ui/views/autofill/password_generation_popup_view_tester_views.h', 'browser/ui/views/autofill/password_generation_popup_view_tester_views.h',
'browser/ui/views/collected_cookies_views_browsertest.cc', 'browser/ui/views/collected_cookies_views_browsertest.cc',
...@@ -2270,8 +2274,6 @@ ...@@ -2270,8 +2274,6 @@
'browser/media_galleries/fileapi/iphoto_data_provider_browsertest.cc', 'browser/media_galleries/fileapi/iphoto_data_provider_browsertest.cc',
'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm', 'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm',
'browser/spellchecker/spellcheck_message_filter_mac_browsertest.cc', 'browser/spellchecker/spellcheck_message_filter_mac_browsertest.cc',
# TODO(bondd): Make this test work on other platforms.
'browser/ui/autofill/card_unmask_prompt_view_browsertest.cc',
], ],
'sources!': [ 'sources!': [
# TODO(groby): This test depends on hunspell and we cannot run it on # TODO(groby): This test depends on hunspell and we cannot run it on
......
...@@ -209,6 +209,14 @@ CreditCard GetVerifiedCreditCard2() { ...@@ -209,6 +209,14 @@ CreditCard GetVerifiedCreditCard2() {
return credit_card; return credit_card;
} }
CreditCard GetMaskedServerCard() {
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
test::SetCreditCardInfo(&credit_card, "Bonnie Parker",
"2109" /* Mastercard */, "12", "2012");
credit_card.SetTypeForMaskedCard(kMasterCard);
return credit_card;
}
void SetProfileInfo(AutofillProfile* profile, void SetProfileInfo(AutofillProfile* profile,
const char* first_name, const char* middle_name, const char* first_name, const char* middle_name,
const char* last_name, const char* email, const char* company, const char* last_name, const char* email, const char* company,
......
...@@ -69,6 +69,9 @@ CreditCard GetVerifiedCreditCard(); ...@@ -69,6 +69,9 @@ CreditCard GetVerifiedCreditCard();
// Returns a verified credit card full of dummy info, different to the above. // Returns a verified credit card full of dummy info, different to the above.
CreditCard GetVerifiedCreditCard2(); CreditCard GetVerifiedCreditCard2();
// Returns a masked server card full of dummy info.
CreditCard GetMaskedServerCard();
// A unit testing utility that is common to a number of the Autofill unit // A unit testing utility that is common to a number of the Autofill unit
// tests. |SetProfileInfo| provides a quick way to populate a profile with // tests. |SetProfileInfo| provides a quick way to populate a profile with
// c-strings. // c-strings.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment