diff options
author | dconnelly <dconnelly@chromium.org> | 2014-08-26 07:12:29 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-26 14:13:54 +0000 |
commit | a07419281ba5b9ce15059a2b64b75a57fa64fbae (patch) | |
tree | a5dd227ccd9ad63443205c8f90158d08738be9c6 | |
parent | 6531de858f7c917d471fdb8c65fd2c4dc3715491 (diff) | |
download | chromium_src-a07419281ba5b9ce15059a2b64b75a57fa64fbae.zip chromium_src-a07419281ba5b9ce15059a2b64b75a57fa64fbae.tar.gz chromium_src-a07419281ba5b9ce15059a2b64b75a57fa64fbae.tar.bz2 |
Add ManagePasswordsBubbleNeverSaveViewController and unit tests.
BUG=328847
Review URL: https://codereview.chromium.org/450643003
Cr-Commit-Position: refs/heads/master@{#291902}
8 files changed, 293 insertions, 1 deletions
diff --git a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.h b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.h index ebf667f..8ad14db 100644 --- a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.h +++ b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.h @@ -10,6 +10,7 @@ #include "base/mac/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/base_bubble_controller.h" #import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_content_view_controller.h" +#import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h" #import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_pending_view_controller.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" @@ -18,6 +19,7 @@ // accordingly. @interface ManagePasswordsBubbleController : BaseBubbleController<ManagePasswordsBubbleContentViewDelegate, + ManagePasswordsBubbleNeverSaveViewDelegate, ManagePasswordsBubblePendingViewDelegate> { @private ManagePasswordsBubbleModel* model_; diff --git a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.mm b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.mm index 6b368d8..ac2b825 100644 --- a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.mm @@ -101,10 +101,18 @@ #pragma mark ManagePasswordsBubblePendingViewDelegate - (void)passwordShouldNeverBeSavedOnSiteWithExistingPasswords { - // TODO(dconnelly): Set the NeverSaveViewController once it's implemented. + currentController_.reset([[ManagePasswordsBubbleNeverSaveViewController alloc] + initWithModel:model_ + delegate:self]); [self performLayout]; } +#pragma mark ManagePasswordsBubbleNeverSaveViewDelegate + +- (void)neverSavePasswordCancelled { + [self updateState]; +} + @end @implementation ManagePasswordsBubbleController (Testing) diff --git a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller_unittest.mm index 456fc30..fa24fb8 100644 --- a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller_unittest.mm @@ -70,4 +70,23 @@ TEST_F(ManagePasswordsBubbleControllerTest, ManageStateShouldHaveManageView) { [[controller() currentController] class]); } +TEST_F(ManagePasswordsBubbleControllerTest, + ChoosingNeverSaveShouldHaveNeverSaveView) { + EXPECT_NE([ManagePasswordsBubbleNeverSaveViewController class], + [[controller() currentController] class]); + [controller() passwordShouldNeverBeSavedOnSiteWithExistingPasswords]; + EXPECT_EQ([ManagePasswordsBubbleNeverSaveViewController class], + [[controller() currentController] class]); +} + +TEST_F(ManagePasswordsBubbleControllerTest, + CancellingNeverSaveShouldHavePendingView) { + [controller() passwordShouldNeverBeSavedOnSiteWithExistingPasswords]; + EXPECT_NE([ManagePasswordsBubblePendingViewController class], + [[controller() currentController] class]); + [controller() neverSavePasswordCancelled]; + EXPECT_EQ([ManagePasswordsBubblePendingViewController class], + [[controller() currentController] class]); +} + } // namespace diff --git a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h new file mode 100644 index 0000000..ec942ccf --- /dev/null +++ b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h @@ -0,0 +1,43 @@ +// Copyright 2014 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_COCOA_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_NEVER_SAVE_VIEW_CONTROLLER_H_ +#define CHROME_BROWSER_UI_COCOA_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_NEVER_SAVE_VIEW_CONTROLLER_H_ + +#import <Cocoa/Cocoa.h> + +#include "base/mac/scoped_nsobject.h" +#import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_content_view_controller.h" + +class ManagePasswordsBubbleModel; + +// Handles user interaction with the password never save confirmation bubble. +@protocol ManagePasswordsBubbleNeverSaveViewDelegate< + ManagePasswordsBubbleContentViewDelegate> + +// The user chose not to never save passwords on this site. +- (void)neverSavePasswordCancelled; + +@end + +// Manages the view that confirms that the user never wants to save passwords +// on this site. +@interface ManagePasswordsBubbleNeverSaveViewController + : ManagePasswordsBubbleContentViewController { + @private + ManagePasswordsBubbleModel* model_; // weak + id<ManagePasswordsBubbleNeverSaveViewDelegate> delegate_; // weak + base::scoped_nsobject<NSButton> confirmButton_; + base::scoped_nsobject<NSButton> undoButton_; +} +- (id)initWithModel:(ManagePasswordsBubbleModel*)model + delegate:(id<ManagePasswordsBubbleNeverSaveViewDelegate>)delegate; +@end + +@interface ManagePasswordsBubbleNeverSaveViewController (Testing) +@property(readonly) NSButton* confirmButton; +@property(readonly) NSButton* undoButton; +@end + +#endif // CHROME_BROWSER_UI_COCOA_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_NEVER_SAVE_VIEW_CONTROLLER_H_ diff --git a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.mm b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.mm new file mode 100644 index 0000000..d4a6e53 --- /dev/null +++ b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.mm @@ -0,0 +1,127 @@ +// Copyright 2014 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. + +#import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h" + +#include "base/strings/sys_string_conversions.h" +#include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" +#include "grit/generated_resources.h" +#import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h" +#include "ui/base/l10n/l10n_util.h" + +using namespace password_manager::mac::ui; + +@interface ManagePasswordsBubbleNeverSaveViewController () +- (void)onConfirmClicked:(id)sender; +- (void)onUndoClicked:(id)sender; +@end + +@implementation ManagePasswordsBubbleNeverSaveViewController + +- (id)initWithModel:(ManagePasswordsBubbleModel*)model + delegate:(id<ManagePasswordsBubbleNeverSaveViewDelegate>)delegate { + if ((self = [super initWithNibName:nil bundle:nil])) { + model_ = model; + delegate_ = delegate; + } + return self; +} + +- (void)onConfirmClicked:(id)sender { + model_->OnNeverForThisSiteClicked(); + [delegate_ viewShouldDismiss]; +} + +- (void)onUndoClicked:(id)sender { + [delegate_ neverSavePasswordCancelled]; +} + +- (void)loadView { + self.view = [[[NSView alloc] initWithFrame:NSZeroRect] autorelease]; + + // ----------------------------------- + // | Title | + // | | + // | Confirmation! | + // | | + // | [Undo] [Confirm] | + // ----------------------------------- + + // Create the elements and add them to the view. + + // Title. + NSTextField* titleLabel = [self + addTitleLabel:l10n_util::GetNSString( + IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_TITLE)]; + + // Blacklist confirmation. + NSTextField* confirmationLabel = [self + addLabel:l10n_util::GetNSString( + IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_TEXT)]; + + // Undo button. + undoButton_.reset([[self addButton:l10n_util::GetNSString(IDS_CANCEL) + target:self + action:@selector(onUndoClicked:)] retain]); + + // Confirm button. + confirmButton_.reset( + [[self addButton:l10n_util::GetNSString( + IDS_MANAGE_PASSWORDS_BLACKLIST_CONFIRMATION_BUTTON) + target:self + action:@selector(onConfirmClicked:)] retain]); + + // Compute the bubble width using the title and confirmation labels. + // The explanation label can wrap to multiple lines. + const CGFloat minContentWidth = kDesiredBubbleWidth - 2 * kFramePadding; + const CGFloat contentWidth = + std::max(NSWidth([titleLabel frame]), minContentWidth); + NSSize confirmationSize = [confirmationLabel frame].size; + confirmationSize.width = contentWidth; + [confirmationLabel setFrameSize:confirmationSize]; + [GTMUILocalizerAndLayoutTweaker + sizeToFitFixedWidthTextField:confirmationLabel]; + const CGFloat width = kFramePadding + contentWidth + kFramePadding; + + // Layout the elements, starting at the bottom and moving up. + + // Buttons go on the bottom row and are right-aligned. + // Start with [Confirm]. + CGFloat curX = width - kFramePadding - NSWidth([confirmButton_ frame]); + CGFloat curY = kFramePadding; + [confirmButton_ setFrameOrigin:NSMakePoint(curX, curY)]; + + // [Undo] goes to the left of [Confirm]. + curX = NSMinX([confirmButton_ frame]) - + kRelatedControlHorizontalPadding - + NSWidth([undoButton_ frame]); + [undoButton_ setFrameOrigin:NSMakePoint(curX, curY)]; + + // Confirmation label goes on the next row and is shifted right. + curX = kFramePadding; + curY = NSMaxY([undoButton_ frame]) + kUnrelatedControlVerticalPadding; + [confirmationLabel setFrameOrigin:NSMakePoint(curX, curY)]; + + // Title goes at the top after some padding. + curY = NSMaxY([confirmationLabel frame]) + kUnrelatedControlVerticalPadding; + [titleLabel setFrameOrigin:NSMakePoint(curX, curY)]; + + // Update the bubble size. + const CGFloat height = NSMaxY([titleLabel frame]) + kFramePadding; + [self.view setFrame:NSMakeRect(0, 0, width, height)]; +} + +@end + +@implementation ManagePasswordsBubbleNeverSaveViewController (Testing) + +- (NSButton*)undoButton { + return undoButton_.get(); +} + +- (NSButton*)confirmButton { + return confirmButton_.get(); +} + +@end diff --git a/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller_unittest.mm new file mode 100644 index 0000000..06bc101 --- /dev/null +++ b/chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller_unittest.mm @@ -0,0 +1,90 @@ +// Copyright 2014 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. + +#import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h" + +#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" +#import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h" +#include "chrome/browser/ui/cocoa/passwords/manage_passwords_controller_test.h" +#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h" +#include "components/password_manager/core/common/password_manager_ui.h" + +// Helper delegate for testing the never save view of the password management +// bubble. +@interface ManagePasswordsBubbleNeverSaveViewTestDelegate + : NSObject<ManagePasswordsBubbleNeverSaveViewDelegate> { + BOOL dismissed_; + BOOL cancelledNeverSave_; +} +@property(readonly) BOOL dismissed; +@property(readonly) BOOL cancelledNeverSave; +@end + +@implementation ManagePasswordsBubbleNeverSaveViewTestDelegate + +@synthesize dismissed = dismissed_; +@synthesize cancelledNeverSave = cancelledNeverSave_; + +- (void)viewShouldDismiss { + dismissed_ = YES; +} + +- (void)neverSavePasswordCancelled { + cancelledNeverSave_ = YES; +} + +@end + +namespace { + +// Tests for the never save view of the password management bubble. +class ManagePasswordsBubbleNeverSaveViewControllerTest + : public ManagePasswordsControllerTest { + public: + ManagePasswordsBubbleNeverSaveViewControllerTest() : controller_(nil) {} + + virtual void SetUp() OVERRIDE { + ManagePasswordsControllerTest::SetUp(); + delegate_.reset( + [[ManagePasswordsBubbleNeverSaveViewTestDelegate alloc] init]); + ui_controller()->SetState(password_manager::ui::PENDING_PASSWORD_STATE); + } + + ManagePasswordsBubbleNeverSaveViewTestDelegate* delegate() { + return delegate_.get(); + } + + ManagePasswordsBubbleNeverSaveViewController* controller() { + if (!controller_) { + controller_.reset([[ManagePasswordsBubbleNeverSaveViewController alloc] + initWithModel:model() + delegate:delegate()]); + [controller_ loadView]; + } + return controller_.get(); + } + + private: + base::scoped_nsobject<ManagePasswordsBubbleNeverSaveViewController> + controller_; + base::scoped_nsobject<ManagePasswordsBubbleNeverSaveViewTestDelegate> + delegate_; +}; + +TEST_F(ManagePasswordsBubbleNeverSaveViewControllerTest, + ShouldNotifyDelegateWhenUndoClicked) { + NSButton* undoButton = controller().undoButton; + [undoButton performClick:nil]; + EXPECT_TRUE(delegate().cancelledNeverSave); +} + +TEST_F(ManagePasswordsBubbleNeverSaveViewControllerTest, + ShouldDismissAndNeverSaveWhenConfirmClicked) { + NSButton* confirmButton = controller().confirmButton; + [confirmButton performClick:nil]; + EXPECT_TRUE(delegate().dismissed); + EXPECT_TRUE(ui_controller()->never_saved_password()); +} + +} // namespace diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 3fc1922..cde70a5 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -639,6 +639,8 @@ 'browser/ui/cocoa/passwords/manage_passwords_bubble_controller.mm', 'browser/ui/cocoa/passwords/manage_passwords_bubble_manage_view_controller.h', 'browser/ui/cocoa/passwords/manage_passwords_bubble_manage_view_controller.mm', + 'browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.h', + 'browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller.mm', 'browser/ui/cocoa/passwords/manage_passwords_bubble_pending_view_controller.h', 'browser/ui/cocoa/passwords/manage_passwords_bubble_pending_view_controller.mm', 'browser/ui/cocoa/pdf_password_dialog.mm', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 7f19908..025b578 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1627,6 +1627,7 @@ 'browser/ui/cocoa/passwords/manage_passwords_bubble_confirmation_view_controller_unittest.mm', 'browser/ui/cocoa/passwords/manage_passwords_bubble_controller_unittest.mm', 'browser/ui/cocoa/passwords/manage_passwords_bubble_manage_view_controller_unittest.mm', + 'browser/ui/cocoa/passwords/manage_passwords_bubble_never_save_view_controller_unittest.mm', 'browser/ui/cocoa/passwords/manage_passwords_bubble_pending_view_controller_unittest.mm', 'browser/ui/cocoa/passwords/manage_passwords_controller_test.h', 'browser/ui/cocoa/passwords/manage_passwords_controller_test.mm', |