diff --git a/WordPress/Classes/System/WordPress-Bridging-Header.h b/WordPress/Classes/System/WordPress-Bridging-Header.h index 7702d473312a..7e1a6e6b7770 100644 --- a/WordPress/Classes/System/WordPress-Bridging-Header.h +++ b/WordPress/Classes/System/WordPress-Bridging-Header.h @@ -54,7 +54,6 @@ #import "SettingsSelectionViewController.h" #import "SettingsMultiTextViewController.h" #import "SettingsTextViewController.h" -#import "SettingsViewController.h" #import "SourcePostAttribution.h" #import "SuggestionsTableView.h" #import "SupportViewController.h" diff --git a/WordPress/Classes/ViewRelated/AccountSettingsViewController.swift b/WordPress/Classes/ViewRelated/AccountSettingsViewController.swift new file mode 100644 index 000000000000..e985c6a73707 --- /dev/null +++ b/WordPress/Classes/ViewRelated/AccountSettingsViewController.swift @@ -0,0 +1,121 @@ +import Foundation +import UIKit +import RxSwift +import WordPressComAnalytics + +func AccountSettingsViewController(account account: WPAccount) -> ImmuTableViewController { + let service = AccountSettingsService(userID: account.userID.integerValue, api: account.restApi) + return AccountSettingsViewController(service: service) +} + +func AccountSettingsViewController(service service: AccountSettingsService) -> ImmuTableViewController { + let controller = AccountSettingsController(service: service) + let viewController = ImmuTableViewController(controller: controller) + assert(viewController.controller?.presenter != nil, "ImmuTableViewController should have set the presenter for AccountSettingsController") + return viewController +} + +private struct AccountSettingsController: SettingsController { + weak var presenter: ImmuTablePresenter? = nil + + let title = NSLocalizedString("Account Settings", comment: "Account Settings Title"); + + var immuTableRows: [ImmuTableRow.Type] { + return [ + TextRow.self, + EditableTextRow.self, + MediaSizeRow.self, + SwitchRow.self] + } + + // MARK: - Initialization + + let service: AccountSettingsService + + init(service: AccountSettingsService) { + self.service = service + } + + // MARK: - Model mapping + + func mapViewModel(settings: AccountSettings?) -> ImmuTable { + precondition(presenter != nil, "presenter must be set before using") + guard let presenter = presenter else { + // This shouldn't happen. If there's no presenter we can't push the + // editText controllers. + return ImmuTable.Empty + } + let username = TextRow( + title: NSLocalizedString("Username", comment: "Account Settings Username label"), + value: settings?.username ?? "") + + let email = TextRow( + title: NSLocalizedString("Email", comment: "Account Settings Email label"), + value: settings?.email ?? "") + + let webAddress = EditableTextRow( + title: NSLocalizedString("Web Address", comment: "Account Settings Web Address label"), + value: settings?.webAddress ?? "", + action: presenter.push(editWebAddress()) + ) + + let uploadSize = MediaSizeRow( + title: NSLocalizedString("Max Image Upload Size", comment: "Title for the image size settings option."), + value: Int(MediaService.maxImageSizeSetting().width), + onChange: mediaSizeChanged()) + + let visualEditor = SwitchRow( + title: NSLocalizedString("Visual Editor", comment: "Option to enable the visual editor"), + value: WPPostViewController.isNewEditorEnabled(), + onChange: visualEditorChanged() + ) + + return ImmuTable(sections: [ + ImmuTableSection( + rows: [ + username, + email, + webAddress + ]), + ImmuTableSection( + headerText: NSLocalizedString("Media", comment: "Title label for the media settings section in the app settings"), + rows: [ + uploadSize + ], + footerText: nil), + ImmuTableSection( + headerText: NSLocalizedString("Editor", comment: "Title label for the editor settings section in the app settings"), + rows: [ + visualEditor + ], + footerText: nil) + ]) + } + + // MARK: - Actions + + func editWebAddress() -> ImmuTableRowControllerGenerator { + return editText(AccountSettingsChange.WebAddress, hint: NSLocalizedString("Shown publicly when you comment on blogs.", comment: "Help text when editing web address")) + } + + func mediaSizeChanged() -> Int -> Void { + return { + value in + let size = CGSize(width: value, height: value) + MediaService.setMaxImageSizeSetting(size) + } + } + + func visualEditorChanged() -> Bool -> Void { + return { + enabled in + if enabled { + WPAnalytics.track(.EditorToggledOn) + } else { + WPAnalytics.track(.EditorToggledOff) + } + WPPostViewController.setNewEditorEnabled(enabled) + } + } +} + diff --git a/WordPress/Classes/ViewRelated/Me/MyProfileViewController.swift b/WordPress/Classes/ViewRelated/Me/MyProfileViewController.swift index 0dcfd7adad7d..1ffac915badb 100644 --- a/WordPress/Classes/ViewRelated/Me/MyProfileViewController.swift +++ b/WordPress/Classes/ViewRelated/Me/MyProfileViewController.swift @@ -17,7 +17,7 @@ func MyProfileViewController(service service: AccountSettingsService) -> ImmuTab /// MyProfileController requires the `presenter` to be set before using. /// To avoid problems, it's marked private and should only be initialized using the /// `MyProfileViewController` factory functions. -private struct MyProfileController: ImmuTableController { +private struct MyProfileController: SettingsController { // MARK: - ImmuTableController weak var presenter: ImmuTablePresenter? = nil @@ -28,26 +28,6 @@ private struct MyProfileController: ImmuTableController { return [EditableTextRow.self] } - var immuTable: Observable { - precondition(presenter != nil, "presenter must be set before using") - return service.settings.map(mapViewModel) - } - - var errorMessage: Observable { - precondition(presenter != nil, "presenter must be set before using") - guard let presenter = presenter else { - // This shouldn't happen, but if it does, disabling the error feels - // safer than having it running when the VC is not visible. - return Observable.just(nil) - } - return service.refresh - .pausable(presenter.visible) - // replace errors with .Failed status - .catchErrorJustReturn(.Failed) - // convert status to string - .map({ $0.errorMessage }) - } - // MARK: - Initialization let service: AccountSettingsService @@ -95,34 +75,4 @@ private struct MyProfileController: ImmuTableController { ]) } - // MARK: - Actions - - func editText(changeType: (AccountSettingsChangeWithString), hint: String? = nil) -> ImmuTableRowControllerGenerator { - return { row in - let row = row as! EditableTextRow - return self.controllerForEditableText(row, changeType: changeType, hint: hint) - } - } - - func controllerForEditableText(row: EditableTextRow, changeType: (AccountSettingsChangeWithString), hint: String? = nil, isPassword: Bool = false) -> SettingsTextViewController { - let title = row.title - let value = row.value - - let controller = SettingsTextViewController( - text: value, - placeholder: "\(title)...", - hint: hint, - isPassword: isPassword) - - controller.title = title - controller.onValueChanged = { - value in - - let change = changeType(value) - self.service.saveChange(change) - DDLogSwift.logDebug("\(title) changed: \(value)") - } - - return controller - } } diff --git a/WordPress/Classes/ViewRelated/MeViewController.swift b/WordPress/Classes/ViewRelated/MeViewController.swift index 6ffae8eb9671..afb4745d92a1 100644 --- a/WordPress/Classes/ViewRelated/MeViewController.swift +++ b/WordPress/Classes/ViewRelated/MeViewController.swift @@ -194,8 +194,14 @@ class MeViewController: UITableViewController, UIViewControllerRestoration { func pushAccountSettings() -> ImmuTableAction { return { [unowned self] row in + guard let account = self.defaultAccount() else { + let error = "Tried to push Account Settings without a default account. This shouldn't happen" + assertionFailure(error) + DDLogSwift.logError(error) + return + } WPAppAnalytics.track(.OpenedAccountSettings) - let controller = SettingsViewController() + let controller = AccountSettingsViewController(account: account) self.navigationController?.pushViewController(controller, animated: true) } } diff --git a/WordPress/Classes/ViewRelated/Settings/SettingsViewController.h b/WordPress/Classes/ViewRelated/Settings/SettingsViewController.h deleted file mode 100644 index 9c846d774d55..000000000000 --- a/WordPress/Classes/ViewRelated/Settings/SettingsViewController.h +++ /dev/null @@ -1,3 +0,0 @@ -@interface SettingsViewController : UITableViewController - -@end diff --git a/WordPress/Classes/ViewRelated/Settings/SettingsViewController.m b/WordPress/Classes/ViewRelated/Settings/SettingsViewController.m deleted file mode 100644 index 777e497cce65..000000000000 --- a/WordPress/Classes/ViewRelated/Settings/SettingsViewController.m +++ /dev/null @@ -1,286 +0,0 @@ -/* - - Settings contents: - - - Image Resize - - Visual Editor - - Shake to Feedback (Internal Beta only) - - */ - -#import "SettingsViewController.h" -#import "WordPressComApi.h" -#import "SupportViewController.h" -#import "WPAccount.h" -#import "WPPostViewController.h" -#import "WPTableViewSectionHeaderFooterView.h" -#import "SupportViewController.h" -#import "ContextManager.h" -#import "ContextManager.h" -#import "AccountService.h" -#import "Constants.h" -#import "Mediaservice.h" -#import "WPLookbackPresenter.h" -#import "WordPress-Swift.h" -#import - -#ifdef LOOKBACK_ENABLED -#import -#endif - -typedef enum { - SettingsSectionMedia = 0, - SettingsSectionEditor, - SettingsSectionInternalBeta, - SettingsSectionCount -} SettingsSection; - -static NSString * const WPSettingsRestorationID = @"WPSettingsRestorationID"; -static NSString * const SwitchTableViewCellIdentifier = @"SwitchTableViewCell"; -static NSString * const MediaSizeSliderCellIdentifier = @"MediaSizeSliderCell"; - -static CGFloat const SettingsRowHeight = 44.0; - -static NSInteger const MediaSizeSliderStep = 50; - -@interface SettingsViewController () - -@property (nonatomic, assign) BOOL showInternalBetaSection; - -@end - -@implementation SettingsViewController - -+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder -{ - return [[self alloc] init]; -} - -- (instancetype)init -{ - self = [super initWithStyle:UITableViewStyleGrouped]; - if (self) { - self.restorationIdentifier = WPSettingsRestorationID; - self.restorationClass = [self class]; - } - return self; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -#pragma mark - View lifecycle - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.title = NSLocalizedString(@"Settings", @"App Settings"); - -#ifdef LOOKBACK_ENABLED - self.showInternalBetaSection = YES; -#else - self.showInternalBetaSection = NO; -#endif - - [self.tableView registerNib:[UINib nibWithNibName:@"MediaSizeSliderCell" bundle:nil] forCellReuseIdentifier:MediaSizeSliderCellIdentifier]; - [self.tableView registerClass:[SwitchTableViewCell class] forCellReuseIdentifier:SwitchTableViewCellIdentifier]; - - [WPStyleGuide resetReadableMarginsForTableView:self.tableView]; - [WPStyleGuide configureColorsForView:self.view andTableView:self.tableView]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - [self.navigationController setNavigationBarHidden:NO animated:animated]; - [self.tableView reloadData]; -} - - -#pragma mark - Cell Actions - -- (void)handleImageSizeChanged:(NSInteger)value -{ - [MediaService setMaxImageSizeSetting:CGSizeMake(value, value)]; -} - -- (void)handleEditorChanged:(BOOL)value -{ - if (value) { - [WPAnalytics track:WPAnalyticsStatEditorToggledOn]; - } else { - [WPAnalytics track:WPAnalyticsStatEditorToggledOff]; - } - [WPPostViewController setNewEditorEnabled:value]; -} - -- (void)handleShakeToPullUpFeedbackChanged:(BOOL)value -{ -#ifdef LOOKBACK_ENABLED - [[NSUserDefaults standardUserDefaults] setBool:value forKey:WPLookbackPresenterShakeToPullUpFeedbackKey]; - [Lookback lookback].shakeToRecord = value; -#endif -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return [self.tableView isEditing] ? 1 : SettingsSectionCount; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - switch (section) { - case SettingsSectionMedia: - return 1; - - case SettingsSectionEditor: { - if (![WPPostViewController isNewEditorAvailable]) { - return 0; - } else { - return 1; - } - } - - case SettingsSectionInternalBeta: - if (self.showInternalBetaSection) { - return 1; - } - else { - return 0; - } - default: - return 0; - - } -} - -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section -{ - if (section == SettingsSectionEditor && ![WPPostViewController isNewEditorAvailable]) { - return nil; - } - - WPTableViewSectionHeaderFooterView *header = [[WPTableViewSectionHeaderFooterView alloc] initWithReuseIdentifier:nil style:WPTableViewSectionStyleHeader]; - header.title = [self titleForHeaderInSection:section]; - return header; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section -{ - if (section == SettingsSectionEditor && ![WPPostViewController isNewEditorAvailable]) { - return 1; - } - - NSString *title = [self titleForHeaderInSection:section]; - return [WPTableViewSectionHeaderFooterView heightForHeader:title width:CGRectGetWidth(self.view.bounds)]; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section -{ - static const CGFloat kDefaultFooterHeight = 16.0f; - - if (section == SettingsSectionEditor && ![WPPostViewController isNewEditorAvailable]) { - return 1; - } else { - return kDefaultFooterHeight; - } -} - -- (NSString *)titleForHeaderInSection:(NSInteger)section -{ - if (section == SettingsSectionMedia) { - return NSLocalizedString(@"Media", @"Title label for the media settings section in the app settings"); - - } else if (section == SettingsSectionEditor) { - return NSLocalizedString(@"Editor", @"Title label for the editor settings section in the app settings"); - - } else if (section == SettingsSectionInternalBeta) { - if (self.showInternalBetaSection) { - return NSLocalizedString(@"Internal Beta", @""); - } else { - return @""; - } - } - - return nil; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (indexPath.section == SettingsSectionMedia) { - return [MediaSizeSliderCell height]; - } - return SettingsRowHeight; -} - -- (UITableViewCell *)cellForMediaSizeInTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath { - MediaSizeSliderCell *cell = [tableView dequeueReusableCellWithIdentifier:MediaSizeSliderCellIdentifier forIndexPath:indexPath]; - cell.title = NSLocalizedString(@"Max Image Upload Size", @"Title for the image size settings option."); - cell.minValue = MediaMinImageSizeDimension; - cell.maxValue = MediaMaxImageSizeDimension; - cell.step = MediaSizeSliderStep; - cell.value = [MediaService maxImageSizeSetting].width; - - __weak SettingsViewController *weakSelf = self; - cell.onChange = ^(NSInteger value) { - [weakSelf handleImageSizeChanged:value]; - }; - - return cell; -} - -- (UITableViewCell *)cellForVisualEditorInTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SwitchTableViewCellIdentifier forIndexPath:indexPath]; - cell.name = NSLocalizedString(@"Visual Editor", @"Option to enable the visual editor"); - cell.on = [WPPostViewController isNewEditorEnabled]; - - __weak SettingsViewController *weakSelf = self; - cell.onChange = ^(BOOL value) { - [weakSelf handleEditorChanged:value]; - }; - - return cell; -} - -- (UITableViewCell *)cellForFeedbackInTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath { -#ifndef LOOKBACK_ENABLED - NSAssert(NO, @"Should never execute this when Lookback is disabled."); -#endif - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SwitchTableViewCellIdentifier forIndexPath:indexPath]; - cell.name = NSLocalizedString(@"Shake for Feedback", @"Option to allow the user to shake the device to pull up the feedback mechanism"); - cell.on = [[NSUserDefaults standardUserDefaults] boolForKey:WPLookbackPresenterShakeToPullUpFeedbackKey]; - - __weak SettingsViewController *weakSelf = self; - cell.onChange = ^(BOOL value) { - [weakSelf handleShakeToPullUpFeedbackChanged:value]; - }; - return cell; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell *cell = nil; - switch (indexPath.section) { - case SettingsSectionMedia: - cell = [self cellForMediaSizeInTableView:tableView indexPath:indexPath]; - break; - case SettingsSectionEditor: - cell = [self cellForVisualEditorInTableView:tableView indexPath:indexPath]; - break; - case SettingsSectionInternalBeta: - cell = [self cellForFeedbackInTableView:tableView indexPath:indexPath]; - break; - } - NSAssert(cell != nil, @"We should have a cell by now"); - - [WPStyleGuide configureTableViewCell:cell]; - - return cell; -} - -@end diff --git a/WordPress/Classes/ViewRelated/SettingsCommon.swift b/WordPress/Classes/ViewRelated/SettingsCommon.swift new file mode 100644 index 000000000000..4b2d7769a99e --- /dev/null +++ b/WordPress/Classes/ViewRelated/SettingsCommon.swift @@ -0,0 +1,70 @@ +import RxSwift + +protocol SettingsController: ImmuTableController { + var service: AccountSettingsService { get } + var presenter: ImmuTablePresenter? { get } + func mapViewModel(settings: AccountSettings?) -> ImmuTable +} + +// MARK: - Shared implementation +extension SettingsController { + var immutableRows: [ImmuTableRow.Type] { + return [ + TextRow.self, + EditableTextRow.self, + MediaSizeRow.self, + SwitchRow.self] + } + + var immuTable: Observable { + precondition(presenter != nil, "presenter must be set before using") + return service.settings.map(mapViewModel) + } + + var errorMessage: Observable { + precondition(presenter != nil, "presenter must be set before using") + guard let presenter = presenter else { + // This shouldn't happen, but if it does, disabling the error feels + // safer than having it running when the VC is not visible. + return Observable.just(nil) + } + return service.refresh + .pausable(presenter.visible) + // replace errors with .Failed status + .catchErrorJustReturn(.Failed) + // convert status to string + .map({ $0.errorMessage }) + } +} + +// MARK: - Actions +extension SettingsController { + func editText(changeType: (AccountSettingsChangeWithString), hint: String? = nil) -> ImmuTableRowControllerGenerator { + return { row in + let row = row as! EditableTextRow + return self.controllerForEditableText(row, changeType: changeType, hint: hint) + } + } + + func controllerForEditableText(row: EditableTextRow, changeType: (AccountSettingsChangeWithString), hint: String? = nil, isPassword: Bool = false) -> SettingsTextViewController { + let title = row.title + let value = row.value + + let controller = SettingsTextViewController( + text: value, + placeholder: "\(title)...", + hint: hint, + isPassword: isPassword) + + controller.title = title + controller.onValueChanged = { + value in + + let change = changeType(value) + self.service.saveChange(change) + DDLogSwift.logDebug("\(title) changed: \(value)") + } + + return controller + } +} \ No newline at end of file diff --git a/WordPress/Classes/ViewRelated/Stats/StatsViewController.m b/WordPress/Classes/ViewRelated/Stats/StatsViewController.m index f0b8d46966db..ca1122f372cd 100644 --- a/WordPress/Classes/ViewRelated/Stats/StatsViewController.m +++ b/WordPress/Classes/ViewRelated/Stats/StatsViewController.m @@ -5,7 +5,6 @@ #import "WPAccount.h" #import "ContextManager.h" #import "BlogService.h" -#import "SettingsViewController.h" #import "SFHFKeychainUtils.h" #import "TodayExtensionService.h" #import diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index e2080a9129ea..f3bfbc70746b 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -488,6 +488,8 @@ E149D65019349E69006A843D /* MediaServiceRemoteREST.m in Sources */ = {isa = PBXBuildFile; fileRef = E149D64B19349E69006A843D /* MediaServiceRemoteREST.m */; }; E149D65119349E69006A843D /* MediaServiceRemoteXMLRPC.m in Sources */ = {isa = PBXBuildFile; fileRef = E149D64D19349E69006A843D /* MediaServiceRemoteXMLRPC.m */; }; E14B13C31C4E7675009DD68F /* Reachability+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14B13C21C4E7675009DD68F /* Reachability+Rx.swift */; }; + E14B40FD1C58B806005046F6 /* AccountSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14B40FC1C58B806005046F6 /* AccountSettingsViewController.swift */; }; + E14B40FF1C58B93F005046F6 /* SettingsCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14B40FE1C58B93F005046F6 /* SettingsCommon.swift */; }; E1556CF2193F6FE900FC52EA /* CommentService.m in Sources */ = {isa = PBXBuildFile; fileRef = E1556CF1193F6FE900FC52EA /* CommentService.m */; }; E15618FD16DB8677006532C4 /* UIKitTestHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E15618FC16DB8677006532C4 /* UIKitTestHelper.m */; }; E15618FF16DBA983006532C4 /* xmlrpc-response-newpost.xml in Resources */ = {isa = PBXBuildFile; fileRef = E15618FE16DBA983006532C4 /* xmlrpc-response-newpost.xml */; }; @@ -538,7 +540,6 @@ E1A6DBE219DC7D140071AC1E /* PostServiceRemoteXMLRPC.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A6DBE019DC7D140071AC1E /* PostServiceRemoteXMLRPC.m */; }; E1A6DBE519DC7D230071AC1E /* PostService.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A6DBE419DC7D230071AC1E /* PostService.m */; }; E1A8CACB1C22FF7C0038689E /* MeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A8CACA1C22FF7C0038689E /* MeViewController.swift */; }; - E1AB07AD1578D34300D6AD64 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1AB07AC1578D34300D6AD64 /* SettingsViewController.m */; }; E1AC282D18282423004D394C /* SFHFKeychainUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 292CECFF1027259000BD407D /* SFHFKeychainUtils.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; E1B23B081BFB3B370006559B /* MyProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1B23B071BFB3B370006559B /* MyProfileViewController.swift */; }; E1B289DB19F7AF7000DB0707 /* RemoteBlog.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B289DA19F7AF7000DB0707 /* RemoteBlog.m */; }; @@ -1477,7 +1478,6 @@ E100C6BA1741472F00AE48D8 /* WordPress-11-12.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = "WordPress-11-12.xcmappingmodel"; sourceTree = ""; }; E105E9CD1726955600C0D9E7 /* WPAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WPAccount.h; sourceTree = ""; }; E105E9CE1726955600C0D9E7 /* WPAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WPAccount.m; sourceTree = ""; }; - E10675C7183F82E900E5CE5C /* SettingsViewControllerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewControllerTest.m; sourceTree = ""; }; E10675C9183FA78E00E5CE5C /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; E10B3651158F2D3F00419A93 /* QuartzCore.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; E10B3653158F2D4500419A93 /* UIKit.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -1551,6 +1551,8 @@ E149D64C19349E69006A843D /* MediaServiceRemoteXMLRPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaServiceRemoteXMLRPC.h; sourceTree = ""; }; E149D64D19349E69006A843D /* MediaServiceRemoteXMLRPC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MediaServiceRemoteXMLRPC.m; sourceTree = ""; }; E14B13C21C4E7675009DD68F /* Reachability+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Reachability+Rx.swift"; sourceTree = ""; }; + E14B40FC1C58B806005046F6 /* AccountSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountSettingsViewController.swift; sourceTree = ""; }; + E14B40FE1C58B93F005046F6 /* SettingsCommon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsCommon.swift; sourceTree = ""; }; E14D65C717E09663007E3EA4 /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; }; E150520B16CAC5C400D3DDDC /* BlogJetpackTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlogJetpackTest.m; sourceTree = ""; }; E150520D16CAC75A00D3DDDC /* CoreDataTestHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreDataTestHelper.h; sourceTree = ""; }; @@ -1624,8 +1626,6 @@ E1A6DBE319DC7D230071AC1E /* PostService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostService.h; sourceTree = ""; }; E1A6DBE419DC7D230071AC1E /* PostService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PostService.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; E1A8CACA1C22FF7C0038689E /* MeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeViewController.swift; sourceTree = ""; }; - E1AB07AB1578D34300D6AD64 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = ""; }; - E1AB07AC1578D34300D6AD64 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = SettingsViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; E1B23B071BFB3B370006559B /* MyProfileViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MyProfileViewController.swift; path = Me/MyProfileViewController.swift; sourceTree = ""; }; E1B289D919F7AF7000DB0707 /* RemoteBlog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RemoteBlog.h; path = "Remote Objects/RemoteBlog.h"; sourceTree = ""; }; E1B289DA19F7AF7000DB0707 /* RemoteBlog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RemoteBlog.m; path = "Remote Objects/RemoteBlog.m"; sourceTree = ""; }; @@ -2209,10 +2209,12 @@ children = ( FFC6ADD21B56F295002F3C84 /* AboutViewController.swift */, FFC6ADD31B56F295002F3C84 /* AboutViewController.xib */, + E14B40FC1C58B806005046F6 /* AccountSettingsViewController.swift */, E1A8CACA1C22FF7C0038689E /* MeViewController.swift */, 315FC2C31A2CB29300E7CDA2 /* MeHeaderView.h */, 315FC2C41A2CB29300E7CDA2 /* MeHeaderView.m */, E1B23B071BFB3B370006559B /* MyProfileViewController.swift */, + E14B40FE1C58B93F005046F6 /* SettingsCommon.swift */, ); name = Me; sourceTree = ""; @@ -2422,8 +2424,6 @@ 93069F581762410B000C966D /* ActivityLogDetailViewController.m */, 93069F54176237A4000C966D /* ActivityLogViewController.h */, 93069F55176237A4000C966D /* ActivityLogViewController.m */, - E1AB07AB1578D34300D6AD64 /* SettingsViewController.h */, - E1AB07AC1578D34300D6AD64 /* SettingsViewController.m */, 93027BB61758332300483FFD /* SupportViewController.h */, 93027BB71758332300483FFD /* SupportViewController.m */, ); @@ -3243,7 +3243,6 @@ B5AEEC801ACAD0A5008BF2A4 /* ViewControllers */ = { isa = PBXGroup; children = ( - E10675C7183F82E900E5CE5C /* SettingsViewControllerTest.m */, E1B2FF581C637AE200F6BDEA /* PlanListViewControllerTest.swift */, ); name = ViewControllers; @@ -4721,6 +4720,7 @@ E6E27D621C6144DB0063F821 /* SharingButton.swift in Sources */, E6374DC01C444D8B00F24720 /* PublicizeConnection.swift in Sources */, 5D17F0BE1A1D4C5F0087CCB8 /* PrivateSiteURLProtocol.m in Sources */, + E14B40FF1C58B93F005046F6 /* SettingsCommon.swift in Sources */, 937D9A0F19F83812007B9D5F /* WordPress-22-23.xcmappingmodel in Sources */, 5D1D04761B7A50B100CDE646 /* ReaderStreamViewController.swift in Sources */, B587798619B799EB00E57C5A /* Notification+Interface.swift in Sources */, @@ -4752,7 +4752,6 @@ B55853F31962337500FAF6C3 /* NSScanner+Helpers.m in Sources */, B5EFB1C21B31B98E007608A3 /* NotificationsService.swift in Sources */, 5903AE1B19B60A98009D5354 /* WPButtonForNavigationBar.m in Sources */, - E1AB07AD1578D34300D6AD64 /* SettingsViewController.m in Sources */, E13EB7A5157D230000885780 /* WordPressComApi.m in Sources */, 5D5D0027187DA9D30027CEF6 /* PostCategoriesViewController.m in Sources */, E1E4CE0B1773C59B00430844 /* WPAvatarSource.m in Sources */, @@ -4763,6 +4762,7 @@ E1A8CACB1C22FF7C0038689E /* MeViewController.swift in Sources */, 5D3E334E15EEBB6B005FC6F2 /* ReachabilityUtils.m in Sources */, B54106901B6FE38400C880D0 /* WPWebViewController+Auth.swift in Sources */, + E14B40FD1C58B806005046F6 /* AccountSettingsViewController.swift in Sources */, 08CC677F1C49B65A00153AD7 /* Menu.m in Sources */, BE13B3E71B2B58D800A4211D /* BlogListViewController.m in Sources */, B532D4E9199D4357006E4DF6 /* NoteBlockCommentTableViewCell.swift in Sources */, diff --git a/WordPress/WordPressTest/SettingsViewControllerTest.m b/WordPress/WordPressTest/SettingsViewControllerTest.m deleted file mode 100644 index 50bec47b734d..000000000000 --- a/WordPress/WordPressTest/SettingsViewControllerTest.m +++ /dev/null @@ -1,203 +0,0 @@ -#import -#import "WPAccount.h" -#import "Blog.h" -#import "PushNotificationsManagerTestHelper.h" -#import "SettingsViewController.h" -#import "ContextManager.h" -#import "AccountService.h" -#import "BlogService.h" -#import "TestContextManager.h" - - - -@interface SettingsViewControllerTest : XCTestCase - -@property (nonatomic, strong) TestContextManager *testContextManager; - -@end - -@implementation SettingsViewControllerTest - -- (void)setUp -{ - [super setUp]; - self.testContextManager = [[TestContextManager alloc] init]; - - NSManagedObjectContext *context = [self.testContextManager mainContext]; - AccountService *accountService = [[AccountService alloc] initWithManagedObjectContext:context]; - WPAccount *defaultAccount = [accountService defaultWordPressComAccount]; - - if (defaultAccount) { - [accountService removeDefaultWordPressComAccount]; - } -} - -- (void)tearDown -{ - [super tearDown]; - self.testContextManager = nil; -} - -- (void)testWpcomSection -{ - NSManagedObjectContext *context = [self.testContextManager mainContext]; - AccountService *accountService = [[AccountService alloc] initWithManagedObjectContext:context]; - BlogService *blogService = [[BlogService alloc] initWithManagedObjectContext:context]; - WPAccount *defaultAccount = [accountService defaultWordPressComAccount]; - - XCTAssertNil(defaultAccount, @"There should be no default account"); - - [PushNotificationsManagerTestHelper removeDummyDeviceToken]; - SettingsViewController *controller = [self settingsViewController]; - [self present:controller]; - - UITableView *table = controller.tableView; - UITableViewCell *cell = [self tableView:table cellForRow:0]; - - /* - Signed out - - - Sign In - */ - XCTAssertEqual(1, [table numberOfRowsInSection:0]); - XCTAssertEqualObjects(@"Sign In", cell.accessibilityIdentifier); - - - // Sign In - XCTestExpectation *saveExpectation = [self expectationWithDescription:@"Context save expectation"]; - self.testContextManager.testExpectation = saveExpectation; - - WPAccount *account = [accountService createOrUpdateWordPressComAccountWithUsername:@"jacksparrow" password:@"piratesobrave" authToken:@"token"]; - - [self waitForExpectationsWithTimeout:2.0 handler:nil]; - - /* - Signed In, Notifications disabled, 1 blog - - - Username jacksparrow - - Sign Out - */ - XCTAssertEqual(2, [table numberOfRowsInSection:0]); - cell = [self tableView:table cellForRow:0]; - XCTAssertEqualObjects(@"Username", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:1]; - XCTAssertEqualObjects(@"Sign Out", cell.accessibilityIdentifier); - - [PushNotificationsManagerTestHelper setDummyDeviceToken]; - [table reloadData]; - - /* - Signed In, Notifications enabled, 0 blogs - - - Username jacksparrow - - Manage Notifications - - Sign Out - */ - XCTAssertEqual(3, [table numberOfRowsInSection:0]); - cell = [self tableView:table cellForRow:0]; - XCTAssertEqualObjects(@"Username", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:1]; - XCTAssertEqualObjects(@"Manage Notifications", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:2]; - XCTAssertEqualObjects(@"Sign Out", cell.accessibilityIdentifier); - - saveExpectation = [self expectationWithDescription:@"Context save expectation"]; - self.testContextManager.testExpectation = saveExpectation; - - NSString *xmlrpc = @"http://blog1.com/xmlrpc.php"; - NSString *url = @"blog1.com"; - Blog *blog = [blogService findBlogWithXmlrpc:xmlrpc inAccount:account]; - if (!blog) { - blog = [blogService createBlogWithAccount:account]; - blog.xmlrpc = xmlrpc; - blog.url = url; - } - [[ContextManager sharedInstance] saveContext:account.managedObjectContext]; - [self waitForExpectationsWithTimeout:2.0 handler:nil]; - - [table reloadData]; - - /* - Signed In, Notifications enabled, 1 blogs - - - Username jacksparrow - - Manage Notifications - - Sign Out - */ - XCTAssertEqual(3, [table numberOfRowsInSection:0]); - cell = [self tableView:table cellForRow:0]; - XCTAssertEqualObjects(@"Username", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:1]; - XCTAssertEqualObjects(@"Manage Notifications", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:2]; - XCTAssertEqualObjects(@"Sign Out", cell.accessibilityIdentifier); - - saveExpectation = [self expectationWithDescription:@"Context save expectation"]; - self.testContextManager.testExpectation = saveExpectation; - - xmlrpc = @"http://blog2.com/xmlrpc.php"; - url = @"blog2.com"; - blog = [blogService findBlogWithXmlrpc:xmlrpc inAccount:account]; - if (!blog) { - blog = [blogService createBlogWithAccount:account]; - blog.xmlrpc = xmlrpc; - blog.url = url; - } - [[ContextManager sharedInstance] saveContext:account.managedObjectContext]; - [self waitForExpectationsWithTimeout:2.0 handler:^(NSError *error) { - NSLog(@"Error: %@", error); - }]; - - [table reloadData]; - - /* - Signed In, Notifications enabled, 2 blogs - - - Username jacksparrow - - Manage Notifications - - Sign Out - */ - XCTAssertEqual(3, [table numberOfRowsInSection:0]); - cell = [self tableView:table cellForRow:0]; - XCTAssertEqualObjects(@"Username", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:1]; - XCTAssertEqualObjects(@"Manage Notifications", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:2]; - XCTAssertEqualObjects(@"Sign Out", cell.accessibilityIdentifier); - - [PushNotificationsManagerTestHelper removeDummyDeviceToken]; - [table reloadData]; - - /* - Signed In, Notifications disabled, 2 blogs - - - Username jacksparrow - - Sign Out - */ - XCTAssertEqual(2, [table numberOfRowsInSection:0]); - cell = [self tableView:table cellForRow:0]; - XCTAssertEqualObjects(@"Username", cell.accessibilityIdentifier); - cell = [self tableView:table cellForRow:1]; - XCTAssertEqualObjects(@"Sign Out", cell.accessibilityIdentifier); -} - -- (SettingsViewController *)settingsViewController { - SettingsViewController *controller = [SettingsViewController new]; - // Force view load - [controller view]; - return controller; -} - -- (void)present:(UIViewController *)controller { - [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:controller animated:NO completion:nil]; -} - -- (void)dismiss:(UIViewController *)controller { - [[[[[UIApplication sharedApplication] delegate] window] rootViewController] dismissViewControllerAnimated:NO completion:nil]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRow:(NSInteger)row { - return [tableView.dataSource tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]]; -} - -@end