Skip to content

Commit c4bd00d

Browse files
authored
Merge pull request #19360 from ipalm0423/issue/19075/fix-cached-notifications-appear-when-logout
Fix cached notifications appear when logout
2 parents d00920b + 02e66b6 commit c4bd00d

File tree

6 files changed

+154
-27
lines changed

6 files changed

+154
-27
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
21.0
22
-----
3-
3+
* [*] Fixed an issue where the cached notifications are retained after logging out of WordPress.com account [#19360]
44

55
20.9
66
-----

WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController+JetpackPrompt.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
extension NotificationsViewController {
22

3+
var blogForJetpackPrompt: Blog? {
4+
return Blog.lastUsed(in: managedObjectContext())
5+
}
6+
37
func promptForJetpackCredentials() {
4-
guard let blog = Blog.lastUsed(in: managedObjectContext()) else {
8+
guard let blog = blogForJetpackPrompt else {
59
return
610
}
711

@@ -14,9 +18,16 @@ extension NotificationsViewController {
1418
controller.promptType = .notifications
1519
addChild(controller)
1620
tableView.addSubview(withFadeAnimation: controller.view)
17-
controller.view.frame = CGRect(origin: .zero, size: view.frame.size)
21+
controller.view.translatesAutoresizingMaskIntoConstraints = false
22+
NSLayoutConstraint.activate([
23+
controller.view.topAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.topAnchor),
24+
controller.view.leadingAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.leadingAnchor),
25+
controller.view.trailingAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.trailingAnchor),
26+
controller.view.bottomAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.bottomAnchor)
27+
])
1828
configureControllerCompletion(controller, withBlog: blog)
1929
jetpackLoginViewController = controller
30+
controller.didMove(toParent: self)
2031
}
2132
}
2233

WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController.swift

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class NotificationsViewController: UIViewController, UIViewControllerRestoration
5656

5757
/// Indicates whether the view is required to reload results on viewWillAppear, or not
5858
///
59-
fileprivate var needsReloadResults = false
59+
var needsReloadResults = false
6060

6161
/// Cached values used for returning the estimated row heights of autosizing cells.
6262
///
@@ -137,6 +137,16 @@ class NotificationsViewController: UIViewController, UIViewControllerRestoration
137137
/// Used by JPScrollViewDelegate to send scroll position
138138
internal let scrollViewTranslationPublisher = PassthroughSubject<Bool, Never>()
139139

140+
/// The last time when user seen notifications
141+
var lastSeenTime: String? {
142+
get {
143+
return userDefaults.string(forKey: Settings.lastSeenTime)
144+
}
145+
set {
146+
userDefaults.set(newValue, forKey: Settings.lastSeenTime)
147+
}
148+
}
149+
140150
// MARK: - View Lifecycle
141151

142152
required init?(coder aDecoder: NSCoder) {
@@ -200,11 +210,10 @@ class NotificationsViewController: UIViewController, UIViewControllerRestoration
200210
reloadTableViewPreservingSelection()
201211
}
202212

203-
if !AccountHelper.isDotcomAvailable() {
213+
if shouldDisplayJetpackPrompt {
204214
promptForJetpackCredentials()
205215
} else {
206-
jetpackLoginViewController?.view.removeFromSuperview()
207-
jetpackLoginViewController?.removeFromParent()
216+
jetpackLoginViewController?.remove()
208217
}
209218

210219
showNoResultsViewIfNeeded()
@@ -686,14 +695,14 @@ private extension NotificationsViewController {
686695
}
687696

688697
@objc func defaultAccountDidChange(_ note: Foundation.Notification) {
689-
guard isViewLoaded == true && view.window != nil else {
690-
return
691-
}
692-
693-
needsReloadResults = true
694698
resetNotifications()
695699
resetLastSeenTime()
696700
resetApplicationBadge()
701+
guard isViewLoaded == true && view.window != nil else {
702+
needsReloadResults = true
703+
return
704+
}
705+
reloadResultsController()
697706
syncNewNotifications()
698707
}
699708

@@ -1558,7 +1567,11 @@ private extension NotificationsViewController {
15581567
return
15591568
}
15601569

1561-
let columnWidth: WPSplitViewControllerPrimaryColumnWidth = (shouldDisplayFullscreenNoResultsView || shouldDisplayJetpackPrompt) ? .full : .default
1570+
// Ref: https://github.com/wordpress-mobile/WordPress-iOS/issues/14547
1571+
// Don't attempt to resize the columns for full width.
1572+
let columnWidth: WPSplitViewControllerPrimaryColumnWidth = .default
1573+
// The above line should be replace with the following line when the full width issue is resolved.
1574+
// let columnWidth: WPSplitViewControllerPrimaryColumnWidth = (shouldDisplayFullscreenNoResultsView || shouldDisplayJetpackPrompt) ? .full : .default
15621575

15631576
if splitViewController.wpPrimaryColumnWidth != columnWidth {
15641577
splitViewController.wpPrimaryColumnWidth = columnWidth
@@ -1592,7 +1605,7 @@ private extension NotificationsViewController {
15921605
}
15931606

15941607
var shouldDisplayJetpackPrompt: Bool {
1595-
return AccountHelper.isDotcomAvailable() == false
1608+
return AccountHelper.isDotcomAvailable() == false && blogForJetpackPrompt != nil
15961609
}
15971610

15981611
var shouldDisplaySettingsButton: Bool {
@@ -1758,7 +1771,6 @@ private extension NotificationsViewController {
17581771
selectedNotification = nil
17591772
mainContext.deleteAllObjects(ofType: Notification.self)
17601773
try mainContext.save()
1761-
tableView.reloadData()
17621774
} catch {
17631775
DDLogError("Error while trying to nuke Notifications Collection: [\(error)]")
17641776
}
@@ -1851,15 +1863,6 @@ private extension NotificationsViewController {
18511863
return UserPersistentStoreFactory.instance()
18521864
}
18531865

1854-
var lastSeenTime: String? {
1855-
get {
1856-
return userDefaults.string(forKey: Settings.lastSeenTime)
1857-
}
1858-
set {
1859-
userDefaults.set(newValue, forKey: Settings.lastSeenTime)
1860-
}
1861-
}
1862-
18631866
var filter: Filter {
18641867
get {
18651868
let selectedIndex = filterTabBar?.selectedIndex ?? Filter.none.rawValue
@@ -2079,3 +2082,11 @@ extension NotificationsViewController: JPScrollViewDelegate {
20792082
processJetpackBannerVisibility(scrollView)
20802083
}
20812084
}
2085+
2086+
// MARK: - StoryboardLoadable
2087+
2088+
extension NotificationsViewController: StoryboardLoadable {
2089+
static var defaultStoryboardName: String {
2090+
return "Notifications"
2091+
}
2092+
}

WordPress/Classes/ViewRelated/Notifications/Notifications.storyboard

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="aRr-Yu-ntD">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="aRr-Yu-ntD">
33
<device id="retina4_7" orientation="portrait" appearance="light"/>
44
<dependencies>
55
<deployment identifier="iOS"/>
6-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
77
<capability name="System colors in document resources" minToolsVersion="11.0"/>
88
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
99
</dependencies>
1010
<scenes>
1111
<!--Notifications View Controller-->
1212
<scene sceneID="30e-Wx-jwX">
1313
<objects>
14-
<viewController extendedLayoutIncludesOpaqueBars="YES" id="aRr-Yu-ntD" customClass="NotificationsViewController" customModule="WordPress" customModuleProvider="target" sceneMemberID="viewController">
14+
<viewController storyboardIdentifier="NotificationsViewController" extendedLayoutIncludesOpaqueBars="YES" id="aRr-Yu-ntD" customClass="NotificationsViewController" customModule="WordPress" customModuleProvider="target" sceneMemberID="viewController">
1515
<layoutGuides>
1616
<viewControllerLayoutGuide type="top" id="6eI-Lt-Q4C"/>
1717
<viewControllerLayoutGuide type="bottom" id="X8S-C3-Z2w"/>

WordPress/WordPress.xcodeproj/project.pbxproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,6 +2123,7 @@
21232123
AB2211F425ED6E7A00BF72FC /* CommentServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB2211F325ED6E7A00BF72FC /* CommentServiceTests.swift */; };
21242124
AB758D9E25EFDF9C00961C0B /* LikesListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB758D9D25EFDF9C00961C0B /* LikesListController.swift */; };
21252125
ACACE3AE28D729FA000992F9 /* NoResultsViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACACE3AD28D729FA000992F9 /* NoResultsViewControllerTests.swift */; };
2126+
AC68C9CA28E5DF14009030A9 /* NotificationsViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC68C9C928E5DF14009030A9 /* NotificationsViewControllerTests.swift */; };
21262127
ACBAB5FE0E121C7300F38795 /* PostSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ACBAB5FD0E121C7300F38795 /* PostSettingsViewController.m */; };
21272128
ADF544C2195A0F620092213D /* CustomHighlightButton.m in Sources */ = {isa = PBXBuildFile; fileRef = ADF544C1195A0F620092213D /* CustomHighlightButton.m */; };
21282129
AE2F3125270B6DA000B2A9C2 /* Scanner+QuotedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE2F3124270B6DA000B2A9C2 /* Scanner+QuotedText.swift */; };
@@ -7034,6 +7035,7 @@
70347035
AB390AA9C94F16E78184E9D1 /* Pods_WordPressScreenshotGeneration.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WordPressScreenshotGeneration.framework; sourceTree = BUILT_PRODUCTS_DIR; };
70357036
AB758D9D25EFDF9C00961C0B /* LikesListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LikesListController.swift; sourceTree = "<group>"; };
70367037
ACACE3AD28D729FA000992F9 /* NoResultsViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoResultsViewControllerTests.swift; sourceTree = "<group>"; };
7038+
AC68C9C928E5DF14009030A9 /* NotificationsViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsViewControllerTests.swift; sourceTree = "<group>"; };
70377039
ACBAB5FC0E121C7300F38795 /* PostSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostSettingsViewController.h; sourceTree = "<group>"; usesTabs = 0; };
70387040
ACBAB5FD0E121C7300F38795 /* PostSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostSettingsViewController.m; sourceTree = "<group>"; usesTabs = 0; };
70397041
ADE06D6829F9044164BBA5AB /* Pods-WordPressIntents.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressIntents.release.xcconfig"; path = "../Pods/Target Support Files/Pods-WordPressIntents/Pods-WordPressIntents.release.xcconfig"; sourceTree = "<group>"; };
@@ -13325,6 +13327,22 @@
1332513327
path = Controllers;
1332613328
sourceTree = "<group>";
1332713329
};
13330+
AC68C9C728E5DEB1009030A9 /* Notification */ = {
13331+
isa = PBXGroup;
13332+
children = (
13333+
AC68C9C828E5DEE0009030A9 /* Controllers */,
13334+
);
13335+
path = Notification;
13336+
sourceTree = "<group>";
13337+
};
13338+
AC68C9C828E5DEE0009030A9 /* Controllers */ = {
13339+
isa = PBXGroup;
13340+
children = (
13341+
AC68C9C928E5DF14009030A9 /* NotificationsViewControllerTests.swift */,
13342+
);
13343+
path = Controllers;
13344+
sourceTree = "<group>";
13345+
};
1332813346
B0088A8F283D68B1008C9676 /* Stats Revamp v2 */ = {
1332913347
isa = PBXGroup;
1333013348
children = (
@@ -14078,6 +14096,7 @@
1407814096
BE20F5E11B2F738E0020694C /* ViewRelated */ = {
1407914097
isa = PBXGroup;
1408014098
children = (
14099+
AC68C9C728E5DEB1009030A9 /* Notification */,
1408114100
C3C2F84428AC8B9E00937E45 /* Jetpack */,
1408214101
F44FB6C92878957E0001E3CE /* Mention */,
1408314102
8B69F0E2255C2BC0006B1CEF /* Activity */,
@@ -20794,6 +20813,7 @@
2079420813
9A9D34FF2360A4E200BC95A3 /* StatsPeriodAsyncOperationTests.swift in Sources */,
2079520814
8BE9AB8827B6B5A300708E45 /* BlogDashboardPersistenceTests.swift in Sources */,
2079620815
B5EFB1C91B333C5A007608A3 /* NotificationSettingsServiceTests.swift in Sources */,
20816+
AC68C9CA28E5DF14009030A9 /* NotificationsViewControllerTests.swift in Sources */,
2079720817
F44FB6CD287897F90001E3CE /* SuggestionsTableViewMockDelegate.swift in Sources */,
2079820818
179501CD27A01D4100882787 /* PublicizeAuthorizationURLComponentsTests.swift in Sources */,
2079920819
4089C51422371EE30031CE78 /* TodayStatsTests.swift in Sources */,
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import XCTest
2+
@testable import WordPress
3+
4+
final class NotificationsViewControllerTests: XCTestCase {
5+
6+
private var controller: NotificationsViewController!
7+
private var contextManager: ContextManagerMock!
8+
private var utility: NotificationUtility!
9+
10+
override func setUpWithError() throws {
11+
contextManager = ContextManagerMock()
12+
contextManager.useAsSharedInstance(untilTestFinished: self)
13+
utility = NotificationUtility(coreDataStack: contextManager)
14+
controller = NotificationsViewController.loadFromStoryboard()
15+
}
16+
17+
override func tearDownWithError() throws {
18+
controller = nil
19+
contextManager = nil
20+
utility = nil
21+
}
22+
23+
func testResetNotificationsWhenAccountChange() throws {
24+
// Give
25+
_ = try utility.loadBadgeNotification()
26+
27+
// When
28+
postAccountChangeNotification()
29+
30+
// Then
31+
XCTAssertEqual(notificationCount, 0)
32+
}
33+
34+
func testResetLastSeenTimeWhenAccountChange() throws {
35+
// Give
36+
controller.lastSeenTime = "testTime"
37+
38+
// When
39+
postAccountChangeNotification()
40+
41+
// Then
42+
XCTAssertEqual(controller.lastSeenTime, nil)
43+
}
44+
45+
func testResetApplicationBadgeWhenAccountChange() throws {
46+
// Give
47+
let newUnreadCount = 1
48+
UIApplication.shared.applicationIconBadgeNumber = 0
49+
ZendeskUtils.unreadNotificationsCount = newUnreadCount
50+
51+
// When
52+
postAccountChangeNotification()
53+
54+
// Then
55+
XCTAssertEqual(UIApplication.shared.applicationIconBadgeNumber, newUnreadCount)
56+
}
57+
58+
func testNeedsReloadResultsWhenAccountChange() throws {
59+
// Give
60+
controller.needsReloadResults = false
61+
62+
// When
63+
postAccountChangeNotification()
64+
65+
// Then
66+
XCTAssertEqual(controller.needsReloadResults, true)
67+
}
68+
69+
}
70+
71+
private extension NotificationsViewControllerTests {
72+
73+
enum Constants {
74+
static let entityName = "Notification"
75+
}
76+
77+
var notificationCount: Int? {
78+
let request = NSFetchRequest<NSFetchRequestResult>(entityName: Constants.entityName)
79+
return try? contextManager.mainContext.count(for: request)
80+
}
81+
82+
func postAccountChangeNotification() {
83+
NotificationCenter.default.post(name: .WPAccountDefaultWordPressComAccountChanged, object: nil)
84+
}
85+
}

0 commit comments

Comments
 (0)