diff --git a/WordPressKit.podspec b/WordPressKit.podspec index f687e0e5..e33589ac 100644 --- a/WordPressKit.podspec +++ b/WordPressKit.podspec @@ -2,7 +2,7 @@ Pod::Spec.new do |s| s.name = 'WordPressKit' - s.version = '4.47.0-beta.5' + s.version = '4.47.0-beta.6' s.summary = 'WordPressKit offers a clean and simple WordPress.com and WordPress.org API.' s.description = <<-DESC diff --git a/WordPressKit.xcodeproj/project.pbxproj b/WordPressKit.xcodeproj/project.pbxproj index a89f2da0..1035e485 100644 --- a/WordPressKit.xcodeproj/project.pbxproj +++ b/WordPressKit.xcodeproj/project.pbxproj @@ -451,6 +451,8 @@ 984E34F422EF9465005C3F92 /* stats-file-downloads.json in Resources */ = {isa = PBXBuildFile; fileRef = 984E34F322EF9464005C3F92 /* stats-file-downloads.json */; }; 9856BE962630B5C200C12FEB /* RemoteUser+Likes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9856BE952630B5C200C12FEB /* RemoteUser+Likes.swift */; }; 98DC787522BAEBF200267279 /* StatsAllAnnualInsight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98DC787422BAEBF100267279 /* StatsAllAnnualInsight.swift */; }; + 98E1A60B27AB604600C61A7F /* site-comment-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 98E1A60A27AB604600C61A7F /* site-comment-success.json */; }; + 98E1A60D27AB621200C61A7F /* xmlrpc-site-comment-success.xml in Resources */ = {isa = PBXBuildFile; fileRef = 98E1A60C27AB621200C61A7F /* xmlrpc-site-comment-success.xml */; }; 98EA910526BC96B8004098A1 /* xmlrpc-site-comments-success.xml in Resources */ = {isa = PBXBuildFile; fileRef = 98EA910426BC96B8004098A1 /* xmlrpc-site-comments-success.xml */; }; 98F884D426BC6445009ADF57 /* CommentServiceRemoteRESTTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F884D326BC6445009ADF57 /* CommentServiceRemoteRESTTests.swift */; }; 98F884D626BC6909009ADF57 /* site-comments-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 98F884D526BC6909009ADF57 /* site-comments-success.json */; }; @@ -1095,6 +1097,8 @@ 984E34F322EF9464005C3F92 /* stats-file-downloads.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "stats-file-downloads.json"; sourceTree = ""; }; 9856BE952630B5C200C12FEB /* RemoteUser+Likes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RemoteUser+Likes.swift"; sourceTree = ""; }; 98DC787422BAEBF100267279 /* StatsAllAnnualInsight.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatsAllAnnualInsight.swift; sourceTree = ""; }; + 98E1A60A27AB604600C61A7F /* site-comment-success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "site-comment-success.json"; sourceTree = ""; }; + 98E1A60C27AB621200C61A7F /* xmlrpc-site-comment-success.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "xmlrpc-site-comment-success.xml"; sourceTree = ""; }; 98EA910426BC96B8004098A1 /* xmlrpc-site-comments-success.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "xmlrpc-site-comments-success.xml"; sourceTree = ""; }; 98F884D326BC6445009ADF57 /* CommentServiceRemoteRESTTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentServiceRemoteRESTTests.swift; sourceTree = ""; }; 98F884D526BC6909009ADF57 /* site-comments-success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "site-comments-success.json"; sourceTree = ""; }; @@ -2123,6 +2127,7 @@ 74C473C61EF334D4009918F2 /* site-active-purchases-none-active-success.json */, 74C473C41EF33242009918F2 /* site-active-purchases-two-active-success.json */, 98F884D526BC6909009ADF57 /* site-comments-success.json */, + 98E1A60A27AB604600C61A7F /* site-comment-success.json */, 731BA83921DECE93000FDFCD /* site-creation-success.json */, 74C473B21EF3204B009918F2 /* site-delete-auth-failure.json */, 74C473B41EF320CC009918F2 /* site-delete-bad-json-failure.json */, @@ -2227,6 +2232,7 @@ 93F50A451F227F3600B5BEBA /* xmlrpc-response-getprofile.xml */, 93F50A461F227F3600B5BEBA /* xmlrpc-response-valid-but-unexpected-dictionary.xml */, 98EA910426BC96B8004098A1 /* xmlrpc-site-comments-success.xml */, + 98E1A60C27AB621200C61A7F /* xmlrpc-site-comment-success.xml */, 740B23DE1F17FB4200067A2A /* xmlrpc-wp-getpost-bad-xml-failure.xml */, 740B23DF1F17FB4200067A2A /* xmlrpc-wp-getpost-invalid-id-failure.xml */, 740B23E01F17FB4200067A2A /* xmlrpc-wp-getpost-success.xml */, @@ -2706,8 +2712,10 @@ 404057DC221C9FD80060250C /* stats-referrer-data.json in Resources */, FA87FE0924EB3FEF003FBEE3 /* reader-post-comments-subscription-status-success.json in Resources */, E6B0461325E5B6F500DF6F4F /* sites-invites-links-disable.json in Resources */, + 98E1A60D27AB621200C61A7F /* xmlrpc-site-comment-success.xml in Resources */, 74C473C71EF334D4009918F2 /* site-active-purchases-none-active-success.json in Resources */, FA87FE0D24EB4450003FBEE3 /* reader-post-comments-unsubscribe-success.json in Resources */, + 98E1A60B27AB604600C61A7F /* site-comment-success.json in Resources */, 829BA4321FACF187003ADEEA /* activity-rewind-status-restore-finished.json in Resources */, F3FF8A29279C991B00E5C90F /* site-email-followers-get-success-more-pages.json in Resources */, 74D67F181F15C2D70010C5ED /* site-users-update-role-unknown-site-failure.json in Resources */, diff --git a/WordPressKit/CommentServiceRemote.h b/WordPressKit/CommentServiceRemote.h index 3eb17bf7..1621c57a 100644 --- a/WordPressKit/CommentServiceRemote.h +++ b/WordPressKit/CommentServiceRemote.h @@ -31,6 +31,14 @@ typedef enum { success:(void (^)(NSArray *posts))success failure:(void (^)(NSError *error))failure; + +/** + Loads the specified comment associated with a blog + */ +- (void)getCommentWithID:(NSNumber *)commentID + success:(void (^)(RemoteComment *comment))success + failure:(void (^)(NSError * error))failure; + /** Publishes a new comment */ diff --git a/WordPressKit/CommentServiceRemoteREST.m b/WordPressKit/CommentServiceRemoteREST.m index 157aba86..6a34e1ba 100644 --- a/WordPressKit/CommentServiceRemoteREST.m +++ b/WordPressKit/CommentServiceRemoteREST.m @@ -76,6 +76,28 @@ - (NSString *)parameterForCommentStatus:(NSNumber *)status } } +- (void)getCommentWithID:(NSNumber *)commentID + success:(void (^)(RemoteComment *comment))success + failure:(void (^)(NSError * error))failure +{ + NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@", self.siteID, commentID]; + NSString *requestUrl = [self pathForEndpoint:path + withVersion:ServiceRemoteWordPressComRESTApiVersion_1_1]; + + [self.wordPressComRestApi GET:requestUrl + parameters:nil + success:^(id responseObject, NSHTTPURLResponse *httpResponse) { + RemoteComment *comment = [self remoteCommentFromJSONDictionary:responseObject]; + if (success) { + success(comment); + } + } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { + if (failure) { + failure(error); + } + }]; +} + - (void)createComment:(RemoteComment *)comment success:(void (^)(RemoteComment *comment))success failure:(void (^)(NSError *))failure diff --git a/WordPressKitTests/CommentServiceRemoteRESTTests.swift b/WordPressKitTests/CommentServiceRemoteRESTTests.swift index 6de8cb67..cc1df856 100644 --- a/WordPressKitTests/CommentServiceRemoteRESTTests.swift +++ b/WordPressKitTests/CommentServiceRemoteRESTTests.swift @@ -5,13 +5,19 @@ import XCTest final class CommentServiceRemoteRESTTests: RemoteTestCase, RESTTestable { private let fetchCommentsSuccessFilename = "site-comments-success.json" + private let fetchCommentSuccessFilename = "site-comment-success.json" private let siteId = 0 + private let commentId = 1 private var remote: CommentServiceRemoteREST! private var siteCommentsEndpoint: String { return "sites/\(siteId)/comments" } + private var siteCommentEndpoint: String { + return "sites/\(siteId)/comments/\(commentId)" + } + override func setUp() { super.setUp() remote = CommentServiceRemoteREST(wordPressComRestApi: getRestApi(), siteID: NSNumber(value: siteId)) @@ -64,4 +70,44 @@ final class CommentServiceRemoteRESTTests: RemoteTestCase, RESTTestable { waitForExpectations(timeout: timeout, handler: nil) } + + func testGetSingleCommentSucceeds() { + let expect = expectation(description: "Fetching a single site comment should succeed") + + stubRemoteResponse(siteCommentEndpoint, + filename: fetchCommentSuccessFilename, + contentType: .ApplicationJSON) + + remote.getCommentWithID(NSNumber(value: commentId), + success: { comment in + + guard let comment = comment else { + XCTFail("Failed to retrieve mock site comment") + return + } + + XCTAssertEqual(comment.authorID, NSNumber(value: 12345)) + XCTAssertEqual(comment.author, "Comment Author") + XCTAssertEqual(comment.authorEmail, "author@email.com") + XCTAssertEqual(comment.authorUrl, "author URL") + XCTAssertEqual(comment.authorIP, "000.0.00.000") + XCTAssertEqual(comment.date, NSDate(wordPressComJSONString: "2021-08-04T07:58:49+00:00") as Date) + XCTAssertEqual(comment.link, "comment URL") + XCTAssertEqual(comment.parentID, nil) + XCTAssertEqual(comment.postID, NSNumber(value: 1)) + XCTAssertEqual(comment.postTitle, "Post title") + XCTAssertEqual(comment.status, "approve") + XCTAssertEqual(comment.type, "comment") + XCTAssertEqual(comment.isLiked, false) + XCTAssertEqual(comment.likeCount, NSNumber(value: 0)) + XCTAssertEqual(comment.canModerate, true) + XCTAssertEqual(comment.content, "I am comment content") + XCTAssertEqual(comment.rawContent, "I am comment raw content") + expect.fulfill() + }, failure: { _ in + XCTFail("This callback shouldn't get called") + }) + + waitForExpectations(timeout: timeout, handler: nil) + } } diff --git a/WordPressKitTests/CommentServiceRemoteXMLRPCTests.swift b/WordPressKitTests/CommentServiceRemoteXMLRPCTests.swift index b0d40c68..749e49bf 100644 --- a/WordPressKitTests/CommentServiceRemoteXMLRPCTests.swift +++ b/WordPressKitTests/CommentServiceRemoteXMLRPCTests.swift @@ -6,6 +6,7 @@ import wpxmlrpc class CommentServiceRemoteXMLRPCTests: RemoteTestCase, XMLRPCTestable { private var remote: Any? private let getSiteCommentsSuccessMockFilename = "xmlrpc-site-comments-success.xml" + private let getSiteCommentSuccessMockFilename = "xmlrpc-site-comment-success.xml" override func setUp() { super.setUp() @@ -59,4 +60,41 @@ class CommentServiceRemoteXMLRPCTests: RemoteTestCase, XMLRPCTestable { } } + func testGetSingleCommentSucceeds() { + let expect = expectation(description: "Fetching a single site comment should succeed") + + stubRemoteResponse(XMLRPCTestableConstants.xmlRpcUrl, + filename: getSiteCommentSuccessMockFilename, + contentType: .XML) + + if let remoteInstance = remote as? CommentServiceRemote { + + remoteInstance.getCommentWithID(NSNumber(value: 1), + success: { comment in + + guard let comment = comment else { + XCTFail("Failed to retrieve mock site comment") + return + } + + XCTAssertEqual(comment.author, "Comment Author") + XCTAssertEqual(comment.authorEmail, "author@email.com") + XCTAssertEqual(comment.authorUrl, "author URL") + XCTAssertEqual(comment.authorIP, "000.0.00.000") + XCTAssertEqual(comment.link, "comment URL") + XCTAssertEqual(comment.parentID, NSNumber(value: 1)) + XCTAssertEqual(comment.postID, NSNumber(value: 2)) + XCTAssertEqual(comment.postTitle, "Post title") + XCTAssertEqual(comment.status, "approve") + XCTAssertEqual(comment.type, "comment") + XCTAssertEqual(comment.content, "I am comment content") + XCTAssertEqual(comment.rawContent, nil) + expect.fulfill() + }, failure: { _ in + XCTFail("This callback shouldn't get called") + }) + + waitForExpectations(timeout: timeout, handler: nil) + } + } } diff --git a/WordPressKitTests/Mock Data/site-comment-success.json b/WordPressKitTests/Mock Data/site-comment-success.json new file mode 100644 index 00000000..91edad8a --- /dev/null +++ b/WordPressKitTests/Mock Data/site-comment-success.json @@ -0,0 +1,38 @@ +{ + "ID": 1, + "post": { + "ID": 1, + "title": "Post title", + "type": "post", + "link": "post URL" + }, + "author": { + "ID": 12345, + "login": "", + "email": "author@email.com", + "name": "Comment Author", + "first_name": "", + "last_name": "", + "nice_name": "", + "URL": "author URL", + "avatar_URL": "avatar URL", + "profile_URL": "profile URL", + "ip_address": "000.0.00.000" + }, + "date": "2021-08-04T07:58:49+00:00", + "URL": "comment URL", + "short_URL": "short URL", + "content": "I am comment content", + "raw_content": "I am comment raw content", + "status": "approved", + "parent": false, + "type": "comment", + "like_count": 0, + "i_like": false, + "meta": { + "links": { + } + }, + "can_moderate": true, + "i_replied": false +} diff --git a/WordPressKitTests/Mock Data/xmlrpc-site-comment-success.xml b/WordPressKitTests/Mock Data/xmlrpc-site-comment-success.xml new file mode 100644 index 00000000..366c0f39 --- /dev/null +++ b/WordPressKitTests/Mock Data/xmlrpc-site-comment-success.xml @@ -0,0 +1,25 @@ + + + + + + + date_created_gmt20210804T21:01:08 + user_id1 + comment_id1 + parent1 + statusapprove + contentI am comment content + linkcomment URL + post_id2 + post_titlePost title + authorComment Author + author_urlauthor URL + author_emailauthor@email.com + author_ip000.0.00.000 + typecomment + + + + +