Skip to content

Commit

Permalink
Merge pull request wordpress-mobile#21078 from wordpress-mobile/task/…
Browse files Browse the repository at this point in the history
…20974-blog-sync-sharing-limit

Jetpack Social: Add sharing limit sync on launch or blog switch
  • Loading branch information
dvdchr authored Jul 13, 2023
2 parents 4431ec7 + 00d8364 commit c1de45a
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 15 deletions.
11 changes: 11 additions & 0 deletions WordPress/Classes/Services/BlogService.m
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,17 @@ - (void)syncBlogAndAllMetadata:(Blog *)blog completionHandler:(void (^)(void))co
dispatch_group_leave(syncGroup);
}];

if ([Feature enabled:FeatureFlagJetpackSocial] && blog.dotComID != nil) {
JetpackSocialService *jetpackSocialService = [[JetpackSocialService alloc] initWithContextManager:ContextManager.sharedInstance];
dispatch_group_enter(syncGroup);
[jetpackSocialService syncSharingLimitWithDotComID:blog.dotComID success:^{
dispatch_group_leave(syncGroup);
} failure:^(NSError * _Nullable error) {
DDLogError(@"Failed syncing publicize sharing limit for blog %@: %@", blog.url, error);
dispatch_group_leave(syncGroup);
}];
}

dispatch_group_enter(syncGroup);
[remote getAllAuthorsWithSuccess:^(NSArray<RemoteUser *> *users) {
[self updateMultiAuthor:users forBlog:blogObjectID completionHandler:^{
Expand Down
42 changes: 39 additions & 3 deletions WordPress/Classes/Services/JetpackSocialService.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import WordPressKit
import CoreData

class JetpackSocialService {
@objc class JetpackSocialService: NSObject {

// MARK: Properties

Expand All @@ -16,6 +16,13 @@ class JetpackSocialService {

// MARK: Methods


/// Init method for Objective-C.
///
@objc init(contextManager: ContextManager) {
self.coreDataStack = contextManager
}

init(coreDataStack: CoreDataStackSwift = ContextManager.shared) {
self.coreDataStack = coreDataStack
}
Expand All @@ -31,10 +38,11 @@ class JetpackSocialService {
/// - blogID: The ID of the blog.
/// - completion: Closure that's called after the sync process completes.
func syncSharingLimit(for blogID: Int, completion: @escaping (Result<PublicizeInfo.SharingLimit?, Error>) -> Void) {
remote.fetchPublicizeInfo(for: blogID) { [weak self] result in
// allow `self` to be retained inside this closure so the completion block will always be executed.
remote.fetchPublicizeInfo(for: blogID) { result in
switch result {
case .success(let remotePublicizeInfo):
self?.coreDataStack.performAndSave({ context -> PublicizeInfo.SharingLimit? in
self.coreDataStack.performAndSave({ context -> PublicizeInfo.SharingLimit? in
guard let blog = try Blog.lookup(withID: blogID, in: context) else {
// unexpected to fall into this case, since the API should return an error response.
throw ServiceError.blogNotFound(id: blogID)
Expand Down Expand Up @@ -62,15 +70,43 @@ class JetpackSocialService {
}
}

/// Sync method for Objective-C.
/// Fetches the latest state of the blog's Publicize auto-sharing limits and stores them locally.
///
/// - Parameters:
/// - dotComID: The WP.com ID of the blog.
/// - success: Closure called when the sync process succeeds.
/// - failure: Closure called when the sync process fails.
@objc func syncSharingLimit(dotComID: NSNumber?,
success: (() -> Void)?,
failure: ((NSError?) -> Void)?) {
guard let blogID = dotComID?.intValue else {
failure?(ServiceError.nilBlogID as NSError)
return
}

syncSharingLimit(for: blogID, completion: { result in
switch result {
case .success:
success?()
case .failure(let error):
failure?(error as NSError)
}
})
}

// MARK: Errors

enum ServiceError: LocalizedError {
case blogNotFound(id: Int)
case nilBlogID

var errorDescription: String? {
switch self {
case .blogNotFound(let id):
return "Blog with id: \(id) was unexpectedly not found."
case .nilBlogID:
return "Blog ID is unexpectedly nil."
}
}
}
Expand Down
66 changes: 54 additions & 12 deletions WordPress/WordPressTest/JetpackSocialServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ class JetpackSocialServiceTests: CoreDataTestCase {
// non-existing PublicizeInfo + nil RemotePublicizeInfo -> nothing changes
func testSyncSharingLimitWithNilPublicizeInfo() {
stub(condition: isPath(jetpackSocialPath)) { _ in
HTTPStubsResponse(jsonObject: [String: Any](),
statusCode: 200,
headers: nil)
HTTPStubsResponse(jsonObject: [String: Any](), statusCode: 200, headers: nil)
}

let expectation = expectation(description: "syncSharingLimit should succeed")
Expand Down Expand Up @@ -110,9 +108,7 @@ class JetpackSocialServiceTests: CoreDataTestCase {
func testSyncSharingLimitWithNilPublicizeInfoGivenPreExistingData() throws {
try addPreExistingPublicizeInfo()
stub(condition: isPath(jetpackSocialPath)) { _ in
HTTPStubsResponse(jsonObject: [String: Any](),
statusCode: 200,
headers: nil)
HTTPStubsResponse(jsonObject: [String: Any](), statusCode: 200, headers: nil)
}

let expectation = expectation(description: "syncSharingLimit should succeed")
Expand All @@ -133,9 +129,7 @@ class JetpackSocialServiceTests: CoreDataTestCase {
func testSyncSharingLimitWithNewPublicizeInfoGivenInvalidBlogID() {
let invalidBlogID = 1002
stub(condition: isPath("/wpcom/v2/sites/\(invalidBlogID)/jetpack-social")) { _ in
HTTPStubsResponse(jsonObject: [String: Any](),
statusCode: 200,
headers: nil)
HTTPStubsResponse(jsonObject: [String: Any](), statusCode: 200, headers: nil)
}

let expectation = expectation(description: "syncSharingLimit should fail")
Expand All @@ -154,9 +148,7 @@ class JetpackSocialServiceTests: CoreDataTestCase {

func testSyncSharingLimitRemoteFetchFailure() {
stub(condition: isPath(jetpackSocialPath)) { _ in
HTTPStubsResponse(jsonObject: [String: Any](),
statusCode: 500,
headers: nil)
HTTPStubsResponse(jsonObject: [String: Any](), statusCode: 500, headers: nil)
}

let expectation = expectation(description: "syncSharingLimit should fail")
Expand All @@ -171,6 +163,56 @@ class JetpackSocialServiceTests: CoreDataTestCase {
wait(for: [expectation], timeout: timeout)
}

// MARK: syncSharingLimit Objective-C

func testObjcSyncSharingLimitSuccess() async {
stub(condition: isPath(jetpackSocialPath)) { _ in
HTTPStubsResponse(jsonObject: [String: Any](), statusCode: 200, headers: nil)
}

let syncSucceeded = await withCheckedContinuation { continuation in
service.syncSharingLimit(dotComID: NSNumber(value: blogID)) {
continuation.resume(returning: true)
} failure: { error in
continuation.resume(returning: false)
}
}

XCTAssertTrue(syncSucceeded)
}

func testObjcSyncSharingLimitNilIDFailure() async {
stub(condition: isPath(jetpackSocialPath)) { _ in
HTTPStubsResponse(jsonObject: [String: Any](), statusCode: 500, headers: nil)
}

let syncSucceeded = await withCheckedContinuation { continuation in
service.syncSharingLimit(dotComID: NSNumber(value: blogID)) {
continuation.resume(returning: true)
} failure: { error in
continuation.resume(returning: false)
}
}

XCTAssertFalse(syncSucceeded)
}

func testObjcSyncSharingLimitRequestFailure() async {
stub(condition: isPath(jetpackSocialPath)) { _ in
HTTPStubsResponse(jsonObject: [String: Any](), statusCode: 500, headers: nil)
}

let syncSucceeded = await withCheckedContinuation { continuation in
service.syncSharingLimit(dotComID: NSNumber(value: blogID)) {
continuation.resume(returning: true)
} failure: { error in
continuation.resume(returning: false)
}
}

XCTAssertFalse(syncSucceeded)
}

}

// MARK: - Helpers
Expand Down

0 comments on commit c1de45a

Please sign in to comment.