diff --git a/Podfile.lock b/Podfile.lock index 29f42644..f6fb1255 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -27,7 +27,7 @@ PODS: - OHHTTPStubs/Swift (6.1.0): - OHHTTPStubs/Default - UIDeviceIdentifier (1.1.4) - - WordPressShared (1.7.0): + - WordPressShared (1.7.2): - CocoaLumberjack (~> 3.4) - FormatterKit/TimeIntervalFormatter (= 1.8.2) - wpxmlrpc (0.8.4) @@ -63,7 +63,7 @@ SPEC CHECKSUMS: OCMock: 43565190abc78977ad44a61c0d20d7f0784d35ab OHHTTPStubs: 1e21c7d2c084b8153fc53d48400d8919d2d432d0 UIDeviceIdentifier: 8f8a24b257a4d978c8d40ad1e7355b944ffbfa8c - WordPressShared: cfbda56868419842dd7a106a4e807069a0c17aa9 + WordPressShared: 63d57a4a07ad9f9a1ee5e8a7162e48fbb5192014 wpxmlrpc: 6ba55c773cfa27083ae4a2173e69b19f46da98e2 PODFILE CHECKSUM: 34d4f957f37c097c360d2863370ce2e5e06511cc diff --git a/WordPressKit.podspec b/WordPressKit.podspec index e43f028b..c2c6df01 100644 --- a/WordPressKit.podspec +++ b/WordPressKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "WordPressKit" - s.version = "3.1.0" + s.version = "3.2.0-beta.1" 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 77b7a2db..f5febe68 100644 --- a/WordPressKit.xcodeproj/project.pbxproj +++ b/WordPressKit.xcodeproj/project.pbxproj @@ -421,11 +421,25 @@ 93F50A441F227CFB00B5BEBA /* UsersServiceRemoteXMLRPCTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93F50A431F227CFB00B5BEBA /* UsersServiceRemoteXMLRPCTests.swift */; }; 93F50A471F227F3600B5BEBA /* xmlrpc-response-getprofile.xml in Resources */ = {isa = PBXBuildFile; fileRef = 93F50A451F227F3600B5BEBA /* xmlrpc-response-getprofile.xml */; }; 93F50A481F227F3600B5BEBA /* xmlrpc-response-valid-but-unexpected-dictionary.xml in Resources */ = {isa = PBXBuildFile; fileRef = 93F50A461F227F3600B5BEBA /* xmlrpc-response-valid-but-unexpected-dictionary.xml */; }; + 9A88174C223C01E400A3AB20 /* blog-service-jetpack-remote-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 9AD75C7A223BEF7A00AED6F4 /* blog-service-jetpack-remote-success.json */; }; + 9A88174D223C01E400A3AB20 /* blog-service-jetpack-remote-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A881738223BFC8E00A3AB20 /* blog-service-jetpack-remote-failure.json */; }; + 9A88174E223C01E400A3AB20 /* blog-service-jetpack-remote-error-unknown.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A88173A223BFE5100A3AB20 /* blog-service-jetpack-remote-error-unknown.json */; }; + 9A88174F223C01E400A3AB20 /* blog-service-jetpack-remote-error-forbidden.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A88173C223BFF0400A3AB20 /* blog-service-jetpack-remote-error-forbidden.json */; }; + 9A881750223C01E400A3AB20 /* blog-service-jetpack-remote-error-install-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A88173E223C012900A3AB20 /* blog-service-jetpack-remote-error-install-failure.json */; }; + 9A881751223C01E400A3AB20 /* blog-service-jetpack-remote-error-install-response.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A88173F223C014200A3AB20 /* blog-service-jetpack-remote-error-install-response.json */; }; + 9A881752223C01E400A3AB20 /* blog-service-jetpack-remote-error-login-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A881740223C015C00A3AB20 /* blog-service-jetpack-remote-error-login-failure.json */; }; + 9A881753223C01E400A3AB20 /* blog-service-jetpack-remote-error-site-is-jetpack.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A881742223C017100A3AB20 /* blog-service-jetpack-remote-error-site-is-jetpack.json */; }; + 9A881754223C01E400A3AB20 /* blog-service-jetpack-remote-error-activation-install.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A881741223C017100A3AB20 /* blog-service-jetpack-remote-error-activation-install.json */; }; + 9A881755223C01E400A3AB20 /* blog-service-jetpack-remote-error-activation-response.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A881743223C017200A3AB20 /* blog-service-jetpack-remote-error-activation-response.json */; }; + 9A881756223C01E400A3AB20 /* blog-service-jetpack-remote-error-activation-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = 9A881744223C017200A3AB20 /* blog-service-jetpack-remote-error-activation-failure.json */; }; 9AB6D647218705E90008F274 /* RemoteDiff.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6D646218705E90008F274 /* RemoteDiff.swift */; }; 9AB6D64A218727D60008F274 /* PostServiceRemoteRESTRevisionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6D649218727D60008F274 /* PostServiceRemoteRESTRevisionsTest.swift */; }; 9AB6D64B21872A0D0008F274 /* post-revisions-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 9AB6D648218722BB0008F274 /* post-revisions-success.json */; }; 9AB6D64E218731AB0008F274 /* post-revisions-mapping-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 9AB6D64D218731380008F274 /* post-revisions-mapping-success.json */; }; 9AB6D64F218731AB0008F274 /* post-revisions-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = 9AB6D64C218730130008F274 /* post-revisions-failure.json */; }; + 9ABE13EB223F8DA3006A8806 /* blog-service-jetpack-remote-error-invalid-credentials.json in Resources */ = {isa = PBXBuildFile; fileRef = 9ABE13EA223F8D62006A8806 /* blog-service-jetpack-remote-error-invalid-credentials.json */; }; + 9AD75C77223943C600AED6F4 /* BlogServiceRemoteREST+Jetpack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AD75C76223943C600AED6F4 /* BlogServiceRemoteREST+Jetpack.swift */; }; + 9AD75C79223BEC5D00AED6F4 /* BlogServiceRemoteRESTTests+Jetpack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AD75C78223BEC5D00AED6F4 /* BlogServiceRemoteRESTTests+Jetpack.swift */; }; 9AEAA774215E774A00876E62 /* site-quick-start-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 9AEAA772215E71C000876E62 /* site-quick-start-success.json */; }; 9AEAA775215E774A00876E62 /* site-quick-start-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = 9AEAA773215E723200876E62 /* site-quick-start-failure.json */; }; 9AF4F2FC218331DC00570E4B /* PostServiceRemoteREST+Revisions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF4F2FB218331DC00570E4B /* PostServiceRemoteREST+Revisions.swift */; }; @@ -922,11 +936,25 @@ 93F50A431F227CFB00B5BEBA /* UsersServiceRemoteXMLRPCTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UsersServiceRemoteXMLRPCTests.swift; sourceTree = ""; }; 93F50A451F227F3600B5BEBA /* xmlrpc-response-getprofile.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "xmlrpc-response-getprofile.xml"; sourceTree = ""; }; 93F50A461F227F3600B5BEBA /* xmlrpc-response-valid-but-unexpected-dictionary.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "xmlrpc-response-valid-but-unexpected-dictionary.xml"; sourceTree = ""; }; + 9A881738223BFC8E00A3AB20 /* blog-service-jetpack-remote-failure.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-failure.json"; sourceTree = ""; }; + 9A88173A223BFE5100A3AB20 /* blog-service-jetpack-remote-error-unknown.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-unknown.json"; sourceTree = ""; }; + 9A88173C223BFF0400A3AB20 /* blog-service-jetpack-remote-error-forbidden.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-forbidden.json"; sourceTree = ""; }; + 9A88173E223C012900A3AB20 /* blog-service-jetpack-remote-error-install-failure.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-install-failure.json"; sourceTree = ""; }; + 9A88173F223C014200A3AB20 /* blog-service-jetpack-remote-error-install-response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-install-response.json"; sourceTree = ""; }; + 9A881740223C015C00A3AB20 /* blog-service-jetpack-remote-error-login-failure.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-login-failure.json"; sourceTree = ""; }; + 9A881741223C017100A3AB20 /* blog-service-jetpack-remote-error-activation-install.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-activation-install.json"; sourceTree = ""; }; + 9A881742223C017100A3AB20 /* blog-service-jetpack-remote-error-site-is-jetpack.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-site-is-jetpack.json"; sourceTree = ""; }; + 9A881743223C017200A3AB20 /* blog-service-jetpack-remote-error-activation-response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-activation-response.json"; sourceTree = ""; }; + 9A881744223C017200A3AB20 /* blog-service-jetpack-remote-error-activation-failure.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-activation-failure.json"; sourceTree = ""; }; 9AB6D646218705E90008F274 /* RemoteDiff.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteDiff.swift; sourceTree = ""; }; 9AB6D648218722BB0008F274 /* post-revisions-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "post-revisions-success.json"; sourceTree = ""; }; 9AB6D649218727D60008F274 /* PostServiceRemoteRESTRevisionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostServiceRemoteRESTRevisionsTest.swift; sourceTree = ""; }; 9AB6D64C218730130008F274 /* post-revisions-failure.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "post-revisions-failure.json"; sourceTree = ""; }; 9AB6D64D218731380008F274 /* post-revisions-mapping-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "post-revisions-mapping-success.json"; sourceTree = ""; }; + 9ABE13EA223F8D62006A8806 /* blog-service-jetpack-remote-error-invalid-credentials.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-error-invalid-credentials.json"; sourceTree = ""; }; + 9AD75C76223943C600AED6F4 /* BlogServiceRemoteREST+Jetpack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BlogServiceRemoteREST+Jetpack.swift"; sourceTree = ""; }; + 9AD75C78223BEC5D00AED6F4 /* BlogServiceRemoteRESTTests+Jetpack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BlogServiceRemoteRESTTests+Jetpack.swift"; sourceTree = ""; }; + 9AD75C7A223BEF7A00AED6F4 /* blog-service-jetpack-remote-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blog-service-jetpack-remote-success.json"; sourceTree = ""; }; 9AEAA772215E71C000876E62 /* site-quick-start-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "site-quick-start-success.json"; sourceTree = ""; }; 9AEAA773215E723200876E62 /* site-quick-start-failure.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "site-quick-start-failure.json"; sourceTree = ""; }; 9AF4F2FB218331DC00570E4B /* PostServiceRemoteREST+Revisions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PostServiceRemoteREST+Revisions.swift"; sourceTree = ""; }; @@ -1138,6 +1166,7 @@ isa = PBXGroup; children = ( 74B5F0DD1EF82A9600B411E7 /* BlogServiceRemoteRESTTests.m */, + 9AD75C78223BEC5D00AED6F4 /* BlogServiceRemoteRESTTests+Jetpack.swift */, ); name = Blog; sourceTree = ""; @@ -1361,6 +1390,7 @@ 74B5F0D31EF8299B00B411E7 /* BlogServiceRemoteREST.h */, 74B5F0D41EF8299B00B411E7 /* BlogServiceRemoteREST.m */, 74B5F0D51EF8299B00B411E7 /* BlogServiceRemoteXMLRPC.h */, + 9AD75C76223943C600AED6F4 /* BlogServiceRemoteREST+Jetpack.swift */, 74B5F0D61EF8299B00B411E7 /* BlogServiceRemoteXMLRPC.m */, 74BA04ED1F06DC0A00ED5CD8 /* CommentServiceRemote.h */, 74BA04EE1F06DC0A00ED5CD8 /* CommentServiceRemoteREST.h */, @@ -1594,6 +1624,18 @@ 93BD27461EE73442002BB00B /* auth-send-login-email-success.json */, 40F88F5F1F85723400AE3FAF /* auth-send-verification-email-already-verified-failure.json */, 40F88F611F85799A00AE3FAF /* auth-send-verification-email-success.json */, + 9AD75C7A223BEF7A00AED6F4 /* blog-service-jetpack-remote-success.json */, + 9A881738223BFC8E00A3AB20 /* blog-service-jetpack-remote-failure.json */, + 9ABE13EA223F8D62006A8806 /* blog-service-jetpack-remote-error-invalid-credentials.json */, + 9A88173A223BFE5100A3AB20 /* blog-service-jetpack-remote-error-unknown.json */, + 9A88173C223BFF0400A3AB20 /* blog-service-jetpack-remote-error-forbidden.json */, + 9A88173E223C012900A3AB20 /* blog-service-jetpack-remote-error-install-failure.json */, + 9A88173F223C014200A3AB20 /* blog-service-jetpack-remote-error-install-response.json */, + 9A881740223C015C00A3AB20 /* blog-service-jetpack-remote-error-login-failure.json */, + 9A881742223C017100A3AB20 /* blog-service-jetpack-remote-error-site-is-jetpack.json */, + 9A881741223C017100A3AB20 /* blog-service-jetpack-remote-error-activation-install.json */, + 9A881743223C017200A3AB20 /* blog-service-jetpack-remote-error-activation-response.json */, + 9A881744223C017200A3AB20 /* blog-service-jetpack-remote-error-activation-failure.json */, 436D564B211CCCB900CEAA33 /* domain-contact-information-response-success.json */, 74585B931F0D53B800E7E667 /* domain-service-all-domain-types.json */, 74585B9E1F0D6E7500E7E667 /* domain-service-bad-json.json */, @@ -2025,6 +2067,7 @@ 74D67F331F15C3740010C5ED /* site-users-delete-auth-failure.json in Resources */, 40819785221F74B200A298E4 /* stats-post-details.json in Resources */, 436D563A2118DE3B00CEAA33 /* supported-countries-success.json in Resources */, + 9A881756223C01E400A3AB20 /* blog-service-jetpack-remote-error-activation-failure.json in Resources */, 740B23E71F17FB4200067A2A /* xmlrpc-metaweblog-newpost-success.xml in Resources */, 74FC6F411F191C1D00112505 /* notifications-last-seen.json in Resources */, 74C473BD1EF329CA009918F2 /* site-export-auth-failure.json in Resources */, @@ -2035,7 +2078,10 @@ E14694031F344F71004052C8 /* site-plugins-error.json in Resources */, 829BA4311FACF187003ADEEA /* activity-rewind-status-success.json in Resources */, 93BD27571EE73442002BB00B /* auth-send-login-email-no-user-failure.json in Resources */, + 9A88174C223C01E400A3AB20 /* blog-service-jetpack-remote-success.json in Resources */, 93AC8ED71ED32FD000900F5A /* stats-v1.1-top-posts-day-large.json in Resources */, + 9A881755223C01E400A3AB20 /* blog-service-jetpack-remote-error-activation-response.json in Resources */, + 9A88174D223C01E400A3AB20 /* blog-service-jetpack-remote-failure.json in Resources */, 93AC8EC71ED32FD000900F5A /* stats-v1.1-clicks-day.json in Resources */, 7403A2FB1EF06FEB00DED7DC /* me-settings-change-invalid-input-failure.json in Resources */, 93AC8EC91ED32FD000900F5A /* stats-v1.1-comments-day.json in Resources */, @@ -2053,6 +2099,7 @@ E6C1E8491EF21FC100D139D9 /* is-passwordless-account-no-account-found.json in Resources */, 93AC8ED91ED32FD000900F5A /* stats-v1.1-video-plays-day-no-data.json in Resources */, 7403A2F81EF06FEB00DED7DC /* me-settings-change-display-name-success.json in Resources */, + 9A881751223C01E400A3AB20 /* blog-service-jetpack-remote-error-install-response.json in Resources */, FFE247B420C891E6002DF3A2 /* WordPressComOAuthSuccess.json in Resources */, 404057D4221C5FC40060250C /* stats-countries-data.json in Resources */, 74D67F1F1F15C3240010C5ED /* people-send-invitation-success.json in Resources */, @@ -2071,6 +2118,7 @@ 7403A2FD1EF06FEB00DED7DC /* me-settings-change-primary-site-success.json in Resources */, 93AC8ED41ED32FD000900F5A /* stats-v1.1-summary.json in Resources */, 74C473B71EF3229B009918F2 /* site-delete-unexpected-json-failure.json in Resources */, + 9A88174E223C01E400A3AB20 /* blog-service-jetpack-remote-error-unknown.json in Resources */, 40819771221DFDB700A298E4 /* stats-posts-data.json in Resources */, 93AC8ECD1ED32FD000900F5A /* stats-v1.1-insights.json in Resources */, 740B23EE1F17FB7E00067A2A /* xmlrpc-malformed-request-xml-error.xml in Resources */, @@ -2090,12 +2138,14 @@ 74D67F181F15C2D70010C5ED /* site-users-update-role-unknown-site-failure.json in Resources */, 404057D8221C986A0060250C /* stats-clicks-data.json in Resources */, 436D56532121F60500CEAA33 /* supported-states-empty.json in Resources */, + 9ABE13EB223F8DA3006A8806 /* blog-service-jetpack-remote-error-invalid-credentials.json in Resources */, 93AC8ED31ED32FD000900F5A /* stats-v1.1-streak.json in Resources */, 7403A2F91EF06FEB00DED7DC /* me-settings-change-email-success.json in Resources */, 439A44DC2107CE3C00795ED7 /* site-plans-v3-empty-failure.json in Resources */, 9AB6D64F218731AB0008F274 /* post-revisions-failure.json in Resources */, 93F50A3C1F226C0100B5BEBA /* WordPressComRestApiFailThrottled.json in Resources */, 740B23ED1F17FB7E00067A2A /* xmlrpc-bad-username-password-error.xml in Resources */, + 9A881754223C01E400A3AB20 /* blog-service-jetpack-remote-error-activation-install.json in Resources */, 93BD275B1EE73442002BB00B /* is-available-username-failure.json in Resources */, FFE247B320C891E6002DF3A2 /* WordPressComOAuthNeeds2FAFail.json in Resources */, E13EE1491F332B8500C15787 /* site-plugins-success.json in Resources */, @@ -2125,6 +2175,7 @@ 74C473BF1EF32B64009918F2 /* site-export-bad-json-failure.json in Resources */, 40819775221E497D00A298E4 /* stats-published-posts.json in Resources */, 74D67F151F15C2D70010C5ED /* site-roles-success.json in Resources */, + 9A881753223C01E400A3AB20 /* blog-service-jetpack-remote-error-site-is-jetpack.json in Resources */, D8DB404221EF22B500B8238E /* site-segments-multiple.json in Resources */, 740B23E11F17FB4200067A2A /* xmlrpc-metaweblog-editpost-bad-xml-failure.xml in Resources */, 404057CB221B80BC0060250C /* stats-top-authors.json in Resources */, @@ -2136,6 +2187,7 @@ 93BD27611EE73442002BB00B /* me-sites-empty-success.json in Resources */, 40E4698D2017D2E30030DB5F /* plugin-directory-new.json in Resources */, 4081977C221F153B00A298E4 /* stats-visits-day.json in Resources */, + 9A881750223C01E400A3AB20 /* blog-service-jetpack-remote-error-install-failure.json in Resources */, 74FC6F431F191C1D00112505 /* notifications-load-all.json in Resources */, 74C473C11EF32C74009918F2 /* site-export-missing-status-failure.json in Resources */, 828A2400201B671F004F6859 /* activity-restore-success.json in Resources */, @@ -2181,6 +2233,7 @@ 74B335E21F06F6730053A184 /* WordPressComRestApiFailRequestInvalidToken.json in Resources */, 74C473BB1EF328D8009918F2 /* site-export-success.json in Resources */, 7403A2FE1EF06FEB00DED7DC /* me-settings-change-web-address-success.json in Resources */, + 9A88174F223C01E400A3AB20 /* blog-service-jetpack-remote-error-forbidden.json in Resources */, 93BD27621EE73442002BB00B /* me-sites-success.json in Resources */, 4081977E221F269A00A298E4 /* stats-visits-month.json in Resources */, 826016FB1F9FAF6300533B6C /* activity-log-auth-failure.json in Resources */, @@ -2201,6 +2254,7 @@ FFE247B520C891E6002DF3A2 /* WordPressComAuthenticateWithIDTokenExistingUserNeedsConnection.json in Resources */, 74D67F381F15C3740010C5ED /* site-viewers-delete-auth-failure.json in Resources */, 826016FA1F9FAF6300533B6C /* activity-log-success-1.json in Resources */, + 9A881752223C01E400A3AB20 /* blog-service-jetpack-remote-error-login-failure.json in Resources */, 93AC8EDB1ED32FD000900F5A /* stats-v1.1-visits-day-bad-date.json in Resources */, 93AC8ECB1ED32FD000900F5A /* stats-v1.1-followers-email-day.json in Resources */, 740B23E41F17FB4200067A2A /* xmlrpc-metaweblog-editpost-success.xml in Resources */, @@ -2299,6 +2353,7 @@ E1A6605F1FD694ED00BAC339 /* PluginDirectoryEntry.swift in Sources */, 7430C9CB1F192F260051B8E6 /* RemoteSourcePostAttribution.m in Sources */, 40819773221E10C900A298E4 /* StatsPublishedPostsTimeIntervalData.swift in Sources */, + 9AD75C77223943C600AED6F4 /* BlogServiceRemoteREST+Jetpack.swift in Sources */, 742362E11F1025B400BD0A7F /* RemoteMenuItem.m in Sources */, 436D56332118D7AA00CEAA33 /* TransactionsServiceRemote.swift in Sources */, 93BD27721EE737A9002BB00B /* ServiceRemoteWordPressXMLRPC.m in Sources */, @@ -2468,6 +2523,7 @@ 826017001F9FD60A00533B6C /* ActivityServiceRemoteTests.swift in Sources */, 93F50A3A1F226BB600B5BEBA /* WordPressComServiceRemoteRestTests.swift in Sources */, 93AC8EE01ED32FD000900F5A /* StatsStreakTests.m in Sources */, + 9AD75C79223BEC5D00AED6F4 /* BlogServiceRemoteRESTTests+Jetpack.swift in Sources */, E13EE14C1F332C4400C15787 /* PluginServiceRemoteTests.swift in Sources */, 736C971021E80D48007A4200 /* SiteVerticalsPromptResponseDecodingTests.swift in Sources */, 74B335D81F06F1CA0053A184 /* MockWordPressComRestApi.swift in Sources */, diff --git a/WordPressKit/BlogServiceRemoteREST+Jetpack.swift b/WordPressKit/BlogServiceRemoteREST+Jetpack.swift new file mode 100644 index 00000000..ccc011d4 --- /dev/null +++ b/WordPressKit/BlogServiceRemoteREST+Jetpack.swift @@ -0,0 +1,53 @@ +public enum JetpackInstallError: String, Error { + case invalidCredentials = "INVALID_CREDENTIALS" + case forbidden = "FORBIDDEN" + case installFailure = "INSTALL_FAILURE" + case installResponseError = "INSTALL_RESPONSE_ERROR" + case loginFailure = "LOGIN_FAILURE" + case siteIsJetpack = "SITE_IS_JETPACK" + case activationOnInstallFailure = "ACTIVATION_ON_INSTALL_FAILURE" + case activationResponseError = "ACTIVATION_RESPONSE_ERROR" + case activationFailure = "ACTIVATION_FAILURE" + case unknown + + init(error key: String) { + self = JetpackInstallError(rawValue: key) ?? .unknown + } +} + +public extension BlogServiceRemoteREST { + public func installJetpack(url: String, + username: String, + password: String, + completion: @escaping (Bool, JetpackInstallError?) -> Void) { + guard let escapedURL = url.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else { + completion(false, .unknown) + return + } + let path = String(format: "jetpack-install/%@/", escapedURL) + let requestUrl = self.path(forEndpoint: path, withVersion: ._1_0) + let parameters = ["user": username, + "password": password] + + wordPressComRestApi.POST(requestUrl, + parameters: parameters as [String : AnyObject], + success: { (response: AnyObject, httpResponse: HTTPURLResponse?) in + if let response = response as? [String: Bool], + let success = response[Constants.status] { + completion(success, nil) + } else { + completion(false, .installResponseError) + } + }) { (error: NSError, httpResponse: HTTPURLResponse?) in + if let key = error.userInfo[WordPressComRestApi.ErrorKeyErrorCode] as? String { + completion(false, JetpackInstallError(error: key)) + } else { + completion(false, .unknown) + } + } + } + + private enum Constants { + static let status = "status" + } +} diff --git a/WordPressKitTests/BlogServiceRemoteRESTTests+Jetpack.swift b/WordPressKitTests/BlogServiceRemoteRESTTests+Jetpack.swift new file mode 100644 index 00000000..6e54ac9a --- /dev/null +++ b/WordPressKitTests/BlogServiceRemoteRESTTests+Jetpack.swift @@ -0,0 +1,197 @@ +import Foundation +import XCTest +@testable import WordPressKit + +class BlogServiceRemoteRESTTests_Jetpack: RemoteTestCase, RESTTestable { + let siteId = 12345 + let url = "http://www.wordpress.com" + let encodedURL = "http%3A%2F%2Fwww.wordpress.com" + let username = "username" + let password = "qwertyuiop" + + let jetpackRemoteSuccessMockFilename = "blog-service-jetpack-remote-success.json" + let jetpackRemoteFailureMockFilename = "blog-service-jetpack-remote-failure.json" + + let jetpackRemoteErrorUnknownMockFilename = "blog-service-jetpack-remote-error-unknown.json" + let jetpackRemoteErrorInvalidCredentialsMockFilename = "blog-service-jetpack-remote-error-invalid-credentials.json" + let jetpackRemoteErrorForbiddenMockFilename = "blog-service-jetpack-remote-error-forbidden.json" + let jetpackRemoteErrorInstallFailureMockFilename = "blog-service-jetpack-remote-error-install-failure.json" + let jetpackRemoteErrorInstallResponseMockFilename = "blog-service-jetpack-remote-error-install-response.json" + let jetpackRemoteErrorLoginFailureMockFilename = "blog-service-jetpack-remote-error-login-failure.json" + let jetpackRemoteErrorSiteIsJetpackMockFilename = "blog-service-jetpack-remote-error-site-is-jetpack.json" + let jetpackRemoteErrorActivationInstallMockFilename = "blog-service-jetpack-remote-error-activation-install.json" + let jetpackRemoteErrorActivationResponseMockFilename = "blog-service-jetpack-remote-error-activation-response.json" + let jetpackRemoteErrorActivationFailureMockFilename = "blog-service-jetpack-remote-error-activation-failure.json" + + var endpoint: String { return "jetpack-install/\(encodedURL)/" } + + var remote: BlogServiceRemoteREST! + + // MARK: - Overridden Methods + + override func setUp() { + super.setUp() + + remote = BlogServiceRemoteREST(wordPressComRestApi: getRestApi(), siteID: NSNumber(value: siteId)) + } + + override func tearDown() { + super.tearDown() + + remote = nil + } + + func testJetpackRemoteInstallationSuccess() { + let expect = expectation(description: "Install Jetpack success") + + stubRemoteResponse(endpoint, filename: jetpackRemoteSuccessMockFilename, contentType: .ApplicationJSON, status: 200) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertTrue(success, "Success should be true") + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationFailure() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteFailureMockFilename, contentType: .ApplicationJSON, status: 200) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationErrorInvalidCredentials() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorInvalidCredentialsMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .invalidCredentials) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationErrorUnknown() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorUnknownMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .unknown) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationErrorForbidden() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorForbiddenMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .forbidden) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationInstallFailure() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorInstallFailureMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .installFailure) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationInstallResponse() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorInstallResponseMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .installResponseError) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationLoginFailure() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorLoginFailureMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .loginFailure) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationSiteIsJetpack() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorSiteIsJetpackMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .siteIsJetpack) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationActivationInstall() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorActivationInstallMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .activationOnInstallFailure) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationActivationResponse() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorActivationResponseMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .activationResponseError) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } + + func testJetpackRemoteInstallationActivationFailure() { + let expect = expectation(description: "Install Jetpack failure") + + stubRemoteResponse(endpoint, filename: jetpackRemoteErrorActivationFailureMockFilename, contentType: .ApplicationJSON, status: 400) + remote.installJetpack(url: url, username: username, password: password) { (success, error) in + XCTAssertFalse(success, "Success should be false") + XCTAssertEqual(error, .activationFailure) + expect.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + } +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-failure.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-failure.json new file mode 100644 index 00000000..57f9fdb3 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-failure.json @@ -0,0 +1,4 @@ +{ + "error": "ACTIVATION_FAILURE", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-install.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-install.json new file mode 100644 index 00000000..2ba90359 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-install.json @@ -0,0 +1,4 @@ +{ + "error": "ACTIVATION_ON_INSTALL_FAILURE", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-response.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-response.json new file mode 100644 index 00000000..edf33c98 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-activation-response.json @@ -0,0 +1,4 @@ +{ + "error": "ACTIVATION_RESPONSE_ERROR", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-forbidden.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-forbidden.json new file mode 100644 index 00000000..5f6c30b6 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-forbidden.json @@ -0,0 +1,4 @@ +{ + "error": "FORBIDDEN", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-install-failure.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-install-failure.json new file mode 100644 index 00000000..f8a2756b --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-install-failure.json @@ -0,0 +1,4 @@ +{ + "error": "INSTALL_FAILURE", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-install-response.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-install-response.json new file mode 100644 index 00000000..e3f5e891 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-install-response.json @@ -0,0 +1,4 @@ +{ + "error": "INSTALL_RESPONSE_ERROR", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-invalid-credentials.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-invalid-credentials.json new file mode 100644 index 00000000..d1838b1d --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-invalid-credentials.json @@ -0,0 +1,4 @@ +{ + "error": "INVALID_CREDENTIALS", + "message": "bad password" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-login-failure.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-login-failure.json new file mode 100644 index 00000000..71edc46b --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-login-failure.json @@ -0,0 +1,4 @@ +{ + "error": "LOGIN_FAILURE", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-site-is-jetpack.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-site-is-jetpack.json new file mode 100644 index 00000000..50da1965 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-site-is-jetpack.json @@ -0,0 +1,4 @@ +{ + "error": "SITE_IS_JETPACK", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-unknown.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-unknown.json new file mode 100644 index 00000000..144eafce --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-error-unknown.json @@ -0,0 +1,4 @@ +{ + "error": "UNKNOWN_ERROR", + "message": "message" +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-failure.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-failure.json new file mode 100644 index 00000000..ad0b3e49 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-failure.json @@ -0,0 +1,3 @@ +{ + "status": false +} diff --git a/WordPressKitTests/Mock Data/blog-service-jetpack-remote-success.json b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-success.json new file mode 100644 index 00000000..a5e547b4 --- /dev/null +++ b/WordPressKitTests/Mock Data/blog-service-jetpack-remote-success.json @@ -0,0 +1,3 @@ +{ + "status": true +}