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,396 +38,366 @@ const int kEdgePadding = 19; ...@@ -43,396 +38,366 @@ 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;
: controller_(controller), }
main_contents_(nullptr),
permanent_error_label_(nullptr),
cvc_input_(nullptr),
month_input_(nullptr),
year_input_(nullptr),
error_label_(nullptr),
storage_checkbox_(nullptr),
progress_overlay_(nullptr),
progress_label_(nullptr),
weak_ptr_factory_(this) {}
~CardUnmaskPromptViews() override {
if (controller_)
controller_->OnUnmaskDialogClosed();
}
void Show() { CardUnmaskPromptViews::CardUnmaskPromptViews(
constrained_window::ShowWebModalDialogViews(this, CardUnmaskPromptController* controller)
controller_->GetWebContents()); : controller_(controller),
} main_contents_(nullptr),
permanent_error_label_(nullptr),
cvc_input_(nullptr),
month_input_(nullptr),
year_input_(nullptr),
error_label_(nullptr),
storage_checkbox_(nullptr),
progress_overlay_(nullptr),
progress_label_(nullptr),
weak_ptr_factory_(this) {
}
// CardUnmaskPromptView CardUnmaskPromptViews::~CardUnmaskPromptViews() {
void ControllerGone() override { if (controller_)
controller_ = nullptr; controller_->OnUnmaskDialogClosed();
ClosePrompt(); }
}
void DisableAndWaitForVerification() override { void CardUnmaskPromptViews::Show() {
SetInputsEnabled(false); constrained_window::ShowWebModalDialogViews(this,
progress_overlay_->SetVisible(true); controller_->GetWebContents());
GetDialogClientView()->UpdateDialogButtons(); }
Layout();
}
void GotVerificationResult(const base::string16& error_message, void CardUnmaskPromptViews::ControllerGone() {
bool allow_retry) override { controller_ = nullptr;
if (error_message.empty()) { ClosePrompt();
progress_label_->SetText(l10n_util::GetStringUTF16( }
IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_SUCCESS));
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt,
weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(1));
} else {
// TODO(estade): it's somewhat jarring when the error comes back too
// quickly.
progress_overlay_->SetVisible(false);
if (allow_retry) {
SetInputsEnabled(true);
// If there is more than one input showing, don't mark anything as
// invalid since we don't know the location of the problem.
if (!controller_->ShouldRequestExpirationDate())
cvc_input_->SetInvalid(true);
// TODO(estade): When do we hide |error_label_|?
SetRetriableErrorMessage(error_message);
} else {
permanent_error_label_->SetText(error_message);
permanent_error_label_->SetVisible(true);
SetRetriableErrorMessage(base::string16());
}
GetDialogClientView()->UpdateDialogButtons();
}
Layout(); void CardUnmaskPromptViews::DisableAndWaitForVerification() {
} SetInputsEnabled(false);
progress_overlay_->SetVisible(true);
GetDialogClientView()->UpdateDialogButtons();
Layout();
}
void SetRetriableErrorMessage(const base::string16& message) { void CardUnmaskPromptViews::GotVerificationResult(
if (message.empty()) { const base::string16& error_message,
error_label_->SetMultiLine(false); bool allow_retry) {
error_label_->SetText(base::ASCIIToUTF16(" ")); if (error_message.empty()) {
} else { progress_label_->SetText(l10n_util::GetStringUTF16(
error_label_->SetMultiLine(true); IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_SUCCESS));
error_label_->SetText(message); base::MessageLoop::current()->PostDelayedTask(
} FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt,
weak_ptr_factory_.GetWeakPtr()),
controller_->GetSuccessMessageDuration());
} else {
// TODO(estade): it's somewhat jarring when the error comes back too
// quickly.
progress_overlay_->SetVisible(false);
// Update the dialog's size. if (allow_retry) {
if (GetWidget() && controller_->GetWebContents()) { SetInputsEnabled(true);
constrained_window::UpdateWebContentsModalDialogPosition(
GetWidget(),
web_modal::WebContentsModalDialogManager::FromWebContents(
controller_->GetWebContents())
->delegate()
->GetWebContentsModalDialogHost());
}
}
void SetInputsEnabled(bool enabled) { // If there is more than one input showing, don't mark anything as
cvc_input_->SetEnabled(enabled); // invalid since we don't know the location of the problem.
storage_checkbox_->SetEnabled(enabled); if (!controller_->ShouldRequestExpirationDate())
cvc_input_->SetInvalid(true);
if (month_input_) // TODO(estade): When do we hide |error_label_|?
month_input_->SetEnabled(enabled); SetRetriableErrorMessage(error_message);
if (year_input_) } else {
year_input_->SetEnabled(enabled); permanent_error_label_->SetText(error_message);
permanent_error_label_->SetVisible(true);
SetRetriableErrorMessage(base::string16());
}
GetDialogClientView()->UpdateDialogButtons();
} }
// views::DialogDelegateView Layout();
View* GetContentsView() override { }
InitIfNecessary();
return this;
}
views::View* CreateFootnoteView() override { void CardUnmaskPromptViews::SetRetriableErrorMessage(
// Local storage checkbox and (?) tooltip. const base::string16& message) {
views::View* storage_row = new views::View(); if (message.empty()) {
views::BoxLayout* storage_row_layout = new views::BoxLayout( error_label_->SetMultiLine(false);
views::BoxLayout::kHorizontal, kEdgePadding, kEdgePadding, 0); error_label_->SetText(base::ASCIIToUTF16(" "));
storage_row->SetLayoutManager(storage_row_layout); } else {
storage_row->SetBorder( error_label_->SetMultiLine(true);
views::Border::CreateSolidSidedBorder(1, 0, 0, 0, kSubtleBorderColor)); error_label_->SetText(message);
storage_row->set_background(
views::Background::CreateSolidBackground(kShadingColor));
storage_checkbox_ = new views::Checkbox(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX));
storage_checkbox_->SetChecked(controller_->GetStoreLocallyStartState());
storage_row->AddChildView(storage_checkbox_);
storage_row_layout->SetFlexForView(storage_checkbox_, 1);
storage_row->AddChildView(new TooltipIcon(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_TOOLTIP)));
return storage_row;
} }
// views::View // Update the dialog's size.
gfx::Size GetPreferredSize() const override { if (GetWidget() && controller_->GetWebContents()) {
// Must hardcode a width so the label knows where to wrap. TODO(estade): constrained_window::UpdateWebContentsModalDialogPosition(
// This can lead to a weird looking dialog if we end up getting allocated GetWidget(), web_modal::WebContentsModalDialogManager::FromWebContents(
// more width than we ask for, e.g. if the title is super long. controller_->GetWebContents())
const int kWidth = 375; ->delegate()
return gfx::Size(kWidth, GetHeightForWidth(kWidth)); ->GetWebContentsModalDialogHost());
} }
}
void Layout() override { void CardUnmaskPromptViews::SetInputsEnabled(bool enabled) {
for (int i = 0; i < child_count(); ++i) { cvc_input_->SetEnabled(enabled);
child_at(i)->SetBoundsRect(GetContentsBounds()); storage_checkbox_->SetEnabled(enabled);
}
}
int GetHeightForWidth(int width) const override { if (month_input_)
if (!has_children()) month_input_->SetEnabled(enabled);
return 0; if (year_input_)
const gfx::Insets insets = GetInsets(); year_input_->SetEnabled(enabled);
return main_contents_->GetHeightForWidth(width - insets.width()) + }
insets.height();
}
void OnNativeThemeChanged(const ui::NativeTheme* theme) override { views::View* CardUnmaskPromptViews::GetContentsView() {
SkColor bg_color = InitIfNecessary();
theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground); return this;
bg_color = SkColorSetA(bg_color, 0xDD); }
progress_overlay_->set_background(
views::Background::CreateSolidBackground(bg_color));
}
ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; } views::View* CardUnmaskPromptViews::CreateFootnoteView() {
// Local storage checkbox and (?) tooltip.
views::View* storage_row = new views::View();
views::BoxLayout* storage_row_layout = new views::BoxLayout(
views::BoxLayout::kHorizontal, kEdgePadding, kEdgePadding, 0);
storage_row->SetLayoutManager(storage_row_layout);
storage_row->SetBorder(
views::Border::CreateSolidSidedBorder(1, 0, 0, 0, kSubtleBorderColor));
storage_row->set_background(
views::Background::CreateSolidBackground(kShadingColor));
storage_checkbox_ = new views::Checkbox(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX));
storage_checkbox_->SetChecked(controller_->GetStoreLocallyStartState());
storage_row->AddChildView(storage_checkbox_);
storage_row_layout->SetFlexForView(storage_checkbox_, 1);
storage_row->AddChildView(new TooltipIcon(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_TOOLTIP)));
return storage_row;
}
base::string16 GetWindowTitle() const override { gfx::Size CardUnmaskPromptViews::GetPreferredSize() const {
return controller_->GetWindowTitle(); // 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
// more width than we ask for, e.g. if the title is super long.
const int kWidth = 375;
return gfx::Size(kWidth, GetHeightForWidth(kWidth));
}
void CardUnmaskPromptViews::Layout() {
for (int i = 0; i < child_count(); ++i) {
child_at(i)->SetBoundsRect(GetContentsBounds());
} }
}
void DeleteDelegate() override { delete this; } int CardUnmaskPromptViews::GetHeightForWidth(int width) const {
if (!has_children())
return 0;
const gfx::Insets insets = GetInsets();
return main_contents_->GetHeightForWidth(width - insets.width()) +
insets.height();
}
int GetDialogButtons() const override { void CardUnmaskPromptViews::OnNativeThemeChanged(const ui::NativeTheme* theme) {
return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; SkColor bg_color =
} theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground);
bg_color = SkColorSetA(bg_color, 0xDD);
progress_overlay_->set_background(
views::Background::CreateSolidBackground(bg_color));
}
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override { ui::ModalType CardUnmaskPromptViews::GetModalType() const {
if (button == ui::DIALOG_BUTTON_OK) return ui::MODAL_TYPE_CHILD;
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_UNMASK_CONFIRM_BUTTON); }
return DialogDelegateView::GetDialogButtonLabel(button); base::string16 CardUnmaskPromptViews::GetWindowTitle() const {
} return controller_->GetWindowTitle();
}
bool ShouldDefaultButtonBeBlue() const override { return true; } void CardUnmaskPromptViews::DeleteDelegate() {
delete this;
}
bool IsDialogButtonEnabled(ui::DialogButton button) const override { int CardUnmaskPromptViews::GetDialogButtons() const {
if (button == ui::DIALOG_BUTTON_CANCEL) return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
return true; }
DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); base::string16 CardUnmaskPromptViews::GetDialogButtonLabel(
ui::DialogButton button) const {
if (button == ui::DIALOG_BUTTON_OK)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_UNMASK_CONFIRM_BUTTON);
return cvc_input_->enabled() && return DialogDelegateView::GetDialogButtonLabel(button);
controller_->InputCvcIsValid(cvc_input_->text()) && }
ExpirationDateIsValid();
}
views::View* GetInitiallyFocusedView() override { return cvc_input_; } bool CardUnmaskPromptViews::ShouldDefaultButtonBeBlue() const {
return true;
}
bool Cancel() override { bool CardUnmaskPromptViews::IsDialogButtonEnabled(
ui::DialogButton button) const {
if (button == ui::DIALOG_BUTTON_CANCEL)
return true; return true;
}
bool Accept() override { DCHECK_EQ(ui::DIALOG_BUTTON_OK, button);
if (!controller_)
return true;
controller_->OnUnmaskResponse(
cvc_input_->text(),
month_input_
? month_input_->GetTextForRow(month_input_->selected_index())
: base::string16(),
year_input_ ? year_input_->GetTextForRow(year_input_->selected_index())
: base::string16(),
storage_checkbox_ ? storage_checkbox_->checked() : false);
return false;
}
// views::TextfieldController return cvc_input_->enabled() &&
void ContentsChanged(views::Textfield* sender, controller_->InputCvcIsValid(cvc_input_->text()) &&
const base::string16& new_contents) override { ExpirationDateIsValid();
if (controller_->InputCvcIsValid(new_contents)) }
cvc_input_->SetInvalid(false);
GetDialogClientView()->UpdateDialogButtons(); views::View* CardUnmaskPromptViews::GetInitiallyFocusedView() {
} return cvc_input_;
}
// views::ComboboxListener bool CardUnmaskPromptViews::Cancel() {
void OnPerformAction(views::Combobox* combobox) override { return true;
if (ExpirationDateIsValid()) { }
if (month_input_->invalid()) {
month_input_->SetInvalid(false);
year_input_->SetInvalid(false);
error_label_->SetMultiLine(false);
SetRetriableErrorMessage(base::string16());
}
} else if (month_input_->selected_index() !=
month_combobox_model_.GetDefaultIndex() &&
year_input_->selected_index() !=
year_combobox_model_.GetDefaultIndex()) {
month_input_->SetInvalid(true);
year_input_->SetInvalid(true);
error_label_->SetMultiLine(true);
SetRetriableErrorMessage(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_INVALID_EXPIRATION_DATE));
}
GetDialogClientView()->UpdateDialogButtons(); bool CardUnmaskPromptViews::Accept() {
} if (!controller_)
return true;
private: controller_->OnUnmaskResponse(
void InitIfNecessary() { cvc_input_->text(),
if (has_children()) month_input_ ? month_input_->GetTextForRow(month_input_->selected_index())
return; : base::string16(),
year_input_ ? year_input_->GetTextForRow(year_input_->selected_index())
main_contents_ = new views::View(); : base::string16(),
main_contents_->SetLayoutManager( storage_checkbox_ ? storage_checkbox_->checked() : false);
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 10)); return false;
AddChildView(main_contents_); }
permanent_error_label_ = new views::Label();
permanent_error_label_->set_background(
views::Background::CreateSolidBackground(
SkColorSetRGB(0xdb, 0x44, 0x37)));
permanent_error_label_->SetBorder(
views::Border::CreateEmptyBorder(10, kEdgePadding, 10, kEdgePadding));
permanent_error_label_->SetEnabledColor(SK_ColorWHITE);
permanent_error_label_->SetAutoColorReadabilityEnabled(false);
permanent_error_label_->SetVisible(false);
permanent_error_label_->SetMultiLine(true);
permanent_error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
main_contents_->AddChildView(permanent_error_label_);
views::View* controls_container = new views::View();
controls_container->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, kEdgePadding, 0, 0));
main_contents_->AddChildView(controls_container);
views::Label* instructions =
new views::Label(controller_->GetInstructionsMessage());
instructions->SetMultiLine(true);
instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT);
instructions->SetBorder(views::Border::CreateEmptyBorder(0, 0, 15, 0));
controls_container->AddChildView(instructions);
views::View* input_row = new views::View();
input_row->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5));
controls_container->AddChildView(input_row);
if (controller_->ShouldRequestExpirationDate()) {
month_input_ = new views::Combobox(&month_combobox_model_);
month_input_->set_listener(this);
input_row->AddChildView(month_input_);
input_row->AddChildView(new views::Label(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_EXPIRATION_DATE_SEPARATOR)));
year_input_ = new views::Combobox(&year_combobox_model_);
year_input_->set_listener(this);
input_row->AddChildView(year_input_);
input_row->AddChildView(new views::Label(base::ASCIIToUTF16(" ")));
}
cvc_input_ = new DecoratedTextfield( void CardUnmaskPromptViews::ContentsChanged(
base::string16(), views::Textfield* sender,
l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), const base::string16& new_contents) {
this); if (controller_->InputCvcIsValid(new_contents))
cvc_input_->set_default_width_in_chars(8); cvc_input_->SetInvalid(false);
input_row->AddChildView(cvc_input_);
views::ImageView* cvc_image = new views::ImageView();
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid()));
input_row->AddChildView(cvc_image);
// Reserve vertical space for the error label, assuming it's one line.
error_label_ = new views::Label(base::ASCIIToUTF16(" "));
error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
error_label_->SetEnabledColor(kWarningColor);
error_label_->SetBorder(views::Border::CreateEmptyBorder(3, 0, 5, 0));
controls_container->AddChildView(error_label_);
progress_overlay_ = new views::View();
views::BoxLayout* progress_layout =
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
progress_layout->set_main_axis_alignment(
views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
progress_layout->set_cross_axis_alignment(
views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
progress_overlay_->SetLayoutManager(progress_layout);
progress_overlay_->SetVisible(false); GetDialogClientView()->UpdateDialogButtons();
AddChildView(progress_overlay_); }
progress_label_ = new views::Label(l10n_util::GetStringUTF16( void CardUnmaskPromptViews::OnPerformAction(views::Combobox* combobox) {
IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_IN_PROGRESS)); if (ExpirationDateIsValid()) {
progress_overlay_->AddChildView(progress_label_); if (month_input_->invalid()) {
month_input_->SetInvalid(false);
year_input_->SetInvalid(false);
error_label_->SetMultiLine(false);
SetRetriableErrorMessage(base::string16());
}
} else if (month_input_->selected_index() !=
month_combobox_model_.GetDefaultIndex() &&
year_input_->selected_index() !=
year_combobox_model_.GetDefaultIndex()) {
month_input_->SetInvalid(true);
year_input_->SetInvalid(true);
error_label_->SetMultiLine(true);
SetRetriableErrorMessage(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_INVALID_EXPIRATION_DATE));
} }
void ClosePrompt() { GetWidget()->Close(); } GetDialogClientView()->UpdateDialogButtons();
}
bool ExpirationDateIsValid() const {
if (!controller_->ShouldRequestExpirationDate())
return true;
return controller_->InputExpirationIsValid( void CardUnmaskPromptViews::InitIfNecessary() {
month_input_->GetTextForRow(month_input_->selected_index()), if (has_children())
year_input_->GetTextForRow(year_input_->selected_index())); return;
main_contents_ = new views::View();
main_contents_->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 10));
AddChildView(main_contents_);
permanent_error_label_ = new views::Label();
permanent_error_label_->set_background(
views::Background::CreateSolidBackground(
SkColorSetRGB(0xdb, 0x44, 0x37)));
permanent_error_label_->SetBorder(
views::Border::CreateEmptyBorder(10, kEdgePadding, 10, kEdgePadding));
permanent_error_label_->SetEnabledColor(SK_ColorWHITE);
permanent_error_label_->SetAutoColorReadabilityEnabled(false);
permanent_error_label_->SetVisible(false);
permanent_error_label_->SetMultiLine(true);
permanent_error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
main_contents_->AddChildView(permanent_error_label_);
views::View* controls_container = new views::View();
controls_container->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, kEdgePadding, 0, 0));
main_contents_->AddChildView(controls_container);
views::Label* instructions =
new views::Label(controller_->GetInstructionsMessage());
instructions->SetMultiLine(true);
instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT);
instructions->SetBorder(views::Border::CreateEmptyBorder(0, 0, 15, 0));
controls_container->AddChildView(instructions);
views::View* input_row = new views::View();
input_row->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5));
controls_container->AddChildView(input_row);
if (controller_->ShouldRequestExpirationDate()) {
month_input_ = new views::Combobox(&month_combobox_model_);
month_input_->set_listener(this);
input_row->AddChildView(month_input_);
input_row->AddChildView(new views::Label(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_EXPIRATION_DATE_SEPARATOR)));
year_input_ = new views::Combobox(&year_combobox_model_);
year_input_->set_listener(this);
input_row->AddChildView(year_input_);
input_row->AddChildView(new views::Label(base::ASCIIToUTF16(" ")));
} }
CardUnmaskPromptController* controller_; cvc_input_ = new DecoratedTextfield(
base::string16(),
views::View* main_contents_; l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), this);
cvc_input_->set_default_width_in_chars(8);
// The error label for permanent errors (where the user can't retry). input_row->AddChildView(cvc_input_);
views::Label* permanent_error_label_;
views::ImageView* cvc_image = new views::ImageView();
DecoratedTextfield* cvc_input_; ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid()));
// These will be null when expiration date is not required. input_row->AddChildView(cvc_image);
views::Combobox* month_input_;
views::Combobox* year_input_; // Reserve vertical space for the error label, assuming it's one line.
error_label_ = new views::Label(base::ASCIIToUTF16(" "));
MonthComboboxModel month_combobox_model_; error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
YearComboboxModel year_combobox_model_; error_label_->SetEnabledColor(kWarningColor);
error_label_->SetBorder(views::Border::CreateEmptyBorder(3, 0, 5, 0));
// The error label for most errors, which lives beneath the inputs. controls_container->AddChildView(error_label_);
views::Label* error_label_;
progress_overlay_ = new views::View();
views::Checkbox* storage_checkbox_; views::BoxLayout* progress_layout =
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
views::View* progress_overlay_; progress_layout->set_main_axis_alignment(
views::Label* progress_label_; views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
progress_layout->set_cross_axis_alignment(
base::WeakPtrFactory<CardUnmaskPromptViews> weak_ptr_factory_; views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
progress_overlay_->SetLayoutManager(progress_layout);
progress_overlay_->SetVisible(false);
AddChildView(progress_overlay_);
progress_label_ = new views::Label(l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_VERIFICATION_IN_PROGRESS));
progress_overlay_->AddChildView(progress_label_);
}
DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews); bool CardUnmaskPromptViews::ExpirationDateIsValid() const {
}; if (!controller_->ShouldRequestExpirationDate())
return true;
} // namespace return controller_->InputExpirationIsValid(
month_input_->GetTextForRow(month_input_->selected_index()),
year_input_->GetTextForRow(year_input_->selected_index()));
}
// 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