Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def wordpress_ui
end

def wordpress_kit
pod 'WordPressKit', '~> 13.1'
# pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', commit: ''
# pod 'WordPressKit', '~> 13.1'
pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', commit: '7c01ab3f347d16c083239ce9f2945636e7fd4611'
# pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', branch: ''
# pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', tag: ''
# pod 'WordPressKit', path: '../WordPressKit-iOS'
Expand Down
13 changes: 9 additions & 4 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ DEPENDENCIES:
- SwiftLint (~> 0.50)
- WordPress-Editor-iOS (~> 1.19.9)
- WordPressAuthenticator (>= 9.0.1, ~> 9.0)
- WordPressKit (~> 13.1)
- WordPressKit (from `https://github.com/wordpress-mobile/WordPressKit-iOS.git`, commit `7c01ab3f347d16c083239ce9f2945636e7fd4611`)
- WordPressShared (~> 2.3)
- WordPressUI (~> 1.15)
- ZendeskSupportSDK (= 5.3.0)
Expand All @@ -129,7 +129,6 @@ DEPENDENCIES:
SPEC REPOS:
https://github.com/wordpress-mobile/cocoapods-specs.git:
- WordPressAuthenticator
- WordPressKit
- WordPressShared
trunk:
- Alamofire
Expand Down Expand Up @@ -176,11 +175,17 @@ EXTERNAL SOURCES:
:tag: 0.2.0
Gutenberg:
:podspec: https://cdn.a8c-ci.services/gutenberg-mobile/Gutenberg-v1.112.0.podspec
WordPressKit:
:commit: 7c01ab3f347d16c083239ce9f2945636e7fd4611
:git: https://github.com/wordpress-mobile/WordPressKit-iOS.git

CHECKOUT OPTIONS:
FSInteractiveMap:
:git: https://github.com/wordpress-mobile/FSInteractiveMap.git
:tag: 0.2.0
WordPressKit:
:commit: 7c01ab3f347d16c083239ce9f2945636e7fd4611
:git: https://github.com/wordpress-mobile/WordPressKit-iOS.git

SPEC CHECKSUMS:
Alamofire: ae5c501addb7afdbb13687d7f2f722c78734c2d3
Expand Down Expand Up @@ -213,7 +218,7 @@ SPEC CHECKSUMS:
WordPress-Aztec-iOS: fbebd569c61baa252b3f5058c0a2a9a6ada686bb
WordPress-Editor-iOS: bda9f7f942212589b890329a0cb22547311749ef
WordPressAuthenticator: 0891ba77c788044d32fe67a4d0435fdd598cecbd
WordPressKit: 7189845e0325fc6022a02638b572e1de8c1d7cc6
WordPressKit: c1ba7b4f531693a0914f676423808fdffd820d81
WordPressShared: cad7777b283d3ce2752f283df587342a581cd49b
WordPressUI: a491454affda3b0fb812812e637dc5e8f8f6bd06
wpxmlrpc: 68db063041e85d186db21f674adf08d9c70627fd
Expand All @@ -226,6 +231,6 @@ SPEC CHECKSUMS:
ZendeskSupportSDK: 3a8e508ab1d9dd22dc038df6c694466414e037ba
ZIPFoundation: d170fa8e270b2a32bef9dcdcabff5b8f1a5deced

PODFILE CHECKSUM: c5e45de40d73e6b9d86e8abf4d65a7c53bcd7079
PODFILE CHECKSUM: df05b91f0efd79fc4cf7269403f857144c3a73e6

COCOAPODS: 1.14.2
2 changes: 1 addition & 1 deletion RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
24.4
-----

* [**] [internal] Refactored .org REST API calls. [#22612]

24.3
-----
Expand Down
3 changes: 2 additions & 1 deletion WordPress/Classes/Models/Blog.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ typedef NS_ENUM(NSInteger, SiteVisibility) {
@interface Blog : NSManagedObject

@property (nonatomic, strong, readwrite, nullable) NSNumber *blogID __deprecated_msg("Use dotComID instead");
/// WordPress.com site ID stored as signed 32-bit integer.
@property (nonatomic, strong, readwrite, nullable) NSNumber *dotComID;
@property (nonatomic, strong, readwrite, nullable) NSString *xmlrpc;
@property (nonatomic, strong, readwrite, nullable) NSString *apiKey;
Expand Down Expand Up @@ -208,7 +209,7 @@ typedef NS_ENUM(NSInteger, SiteVisibility) {
@property (nonatomic, weak, readonly, nullable) NSArray *sortedConnections;
@property (nonatomic, readonly, nullable) NSArray<Role *> *sortedRoles;
@property (nonatomic, strong, readonly, nullable) WordPressOrgXMLRPCApi *xmlrpcApi;
@property (nonatomic, strong, readonly, nullable) WordPressOrgRestApi *wordPressOrgRestApi;
@property (nonatomic, strong, readonly, nullable) WordPressOrgRestApi *selfHostedSiteRestApi;
@property (nonatomic, weak, readonly, nullable) NSString *version;
@property (nonatomic, strong, readonly, nullable) NSString *authToken;
@property (nonatomic, strong, readonly, nullable) NSSet *allowedFileTypes;
Expand Down
18 changes: 9 additions & 9 deletions WordPress/Classes/Models/Blog.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
@interface Blog ()

@property (nonatomic, strong, readwrite) WordPressOrgXMLRPCApi *xmlrpcApi;
@property (nonatomic, strong, readwrite) WordPressOrgRestApi *wordPressOrgRestApi;
@property (nonatomic, strong, readwrite) WordPressOrgRestApi *selfHostedSiteRestApi;

@end

Expand Down Expand Up @@ -99,7 +99,7 @@ @implementation Blog
@synthesize videoPressEnabled;
@synthesize isSyncingMedia;
@synthesize xmlrpcApi = _xmlrpcApi;
@synthesize wordPressOrgRestApi = _wordPressOrgRestApi;
@synthesize selfHostedSiteRestApi = _selfHostedSiteRestApi;

#pragma mark - NSManagedObject subclass methods

Expand All @@ -113,7 +113,7 @@ - (void)prepareForDeletion
}

[_xmlrpcApi invalidateAndCancelTasks];
[_wordPressOrgRestApi invalidateAndCancelTasks];
[_selfHostedSiteRestApi invalidateAndCancelTasks];
}

- (void)didTurnIntoFault
Expand All @@ -122,7 +122,7 @@ - (void)didTurnIntoFault

// Clean up instance variables
self.xmlrpcApi = nil;
self.wordPressOrgRestApi = nil;
self.selfHostedSiteRestApi = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

Expand Down Expand Up @@ -701,7 +701,7 @@ - (BOOL)supportsPluginManagement
// Reference: https://make.wordpress.org/core/2020/07/16/new-and-modified-rest-api-endpoints-in-wordpress-5-5/
if(!supports && !self.account){
supports = !self.isHostedAtWPcom
&& self.wordPressOrgRestApi
&& self.selfHostedSiteRestApi
&& [self hasRequiredWordPressVersion:@"5.5"];
}

Expand Down Expand Up @@ -886,12 +886,12 @@ - (WordPressOrgXMLRPCApi *)xmlrpcApi
return _xmlrpcApi;
}

- (WordPressOrgRestApi *)wordPressOrgRestApi
- (WordPressOrgRestApi *)selfHostedSiteRestApi
{
if (_wordPressOrgRestApi == nil) {
_wordPressOrgRestApi = [[WordPressOrgRestApi alloc] initWithBlog:self];
if (_selfHostedSiteRestApi == nil) {
_selfHostedSiteRestApi = self.account == nil ? [[WordPressOrgRestApi alloc] initWithBlog:self] : nil;
}
return _wordPressOrgRestApi;
return _selfHostedSiteRestApi;
}

- (WordPressComRestApi *)wordPressComRestApi
Expand Down
62 changes: 27 additions & 35 deletions WordPress/Classes/Networking/WordPressOrgRestApi+WordPress.swift
Original file line number Diff line number Diff line change
@@ -1,33 +1,6 @@
import Foundation
import WordPressKit

private func makeAuthenticator(blog: Blog) -> Authenticator? {
return blog.account != nil
? makeTokenAuthenticator(blog: blog)
: makeCookieNonceAuthenticator(blog: blog)
}

private func makeTokenAuthenticator(blog: Blog) -> Authenticator? {
guard let token = blog.authToken else {
DDLogError("Failed to initialize a .com API client with blog: \(blog)")
return nil
}
return TokenAuthenticator(token: token)
}

private func makeCookieNonceAuthenticator(blog: Blog) -> Authenticator? {
guard let loginURL = try? blog.loginUrl().asURL(),
let adminURL = try? blog.adminUrl(withPath: "").asURL(),
let username = blog.username,
let password = blog.password,
let version = blog.version as String? else {
DDLogError("Failed to initialize a .org API client with blog: \(blog)")
return nil
}

return CookieNonceAuthenticator(username: username, password: password, loginURL: loginURL, adminURL: adminURL, version: version)
}

private func apiBase(blog: Blog) -> URL? {
guard blog.account == nil else {
assertionFailure(".com support has not been implemented yet")
Expand All @@ -37,15 +10,34 @@ private func apiBase(blog: Blog) -> URL? {
}

extension WordPressOrgRestApi {
@objc public convenience init?(blog: Blog) {
guard let apiBase = apiBase(blog: blog),
let authenticator = makeAuthenticator(blog: blog) else {
@objc
convenience init?(blog: Blog) {
if let dotComID = blog.dotComID?.uint64Value,
let token = blog.account?.authToken,
token.count > 0 {
self.init(
dotComSiteID: dotComID,
bearerToken: token,
userAgent: WPUserAgent.wordPress(),
apiURL: AppEnvironment.current.wordPressComApiBase
)
} else if let apiBase = apiBase(blog: blog),
let loginURL = try? blog.loginUrl().asURL(),
let adminURL = try? blog.adminUrl(withPath: "").asURL(),
let username = blog.username,
let password = blog.password {
self.init(
selfHostedSiteWPJSONURL: apiBase,
credential: .init(
loginURL: loginURL,
username: username,
password: password,
adminURL: adminURL
),
userAgent: WPUserAgent.wordPress()
)
} else {
return nil
}
self.init(
apiBase: apiBase,
authenticator: authenticator,
userAgent: WPUserAgent.wordPress()
)
}
}
15 changes: 4 additions & 11 deletions WordPress/Classes/Services/BlockEditorSettingsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,15 @@ class BlockEditorSettingsService {
}

convenience init?(blog: Blog, coreDataStack: CoreDataStackSwift) {
let remoteAPI: WordPressRestApi
if blog.isAccessibleThroughWPCom(),
blog.dotComID?.intValue != nil,
let restAPI = blog.wordPressComRestApi() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mokagio @tiagomar I think I have found the root cause of the testAddGalleryBlock failure: .org REST API calls stopped using API-Mocks in this PR. We used to use a WordPressComRestApi instance, which can be mocked by UI tests API-Mocks. But the new WordPressOrgRestApi doesn't support that. I'll just need to add that support back by allowing passing a custom "api base URL", which can be set to mock server url during UI tests.

Here are some details about the issue.

As @tiagomar has pointed out, the "html content" is different: one use images block and the other use a gallery block. This variable here dictates which block to use. It's part of a protocol defined in Gutenberg Mobile. One place, which appears to be the only place in UI tests, that makes Gutenberg Mobile calls this variable is successfully fetching and updating editor settings, which sends a .org REST API call. As I mentioned before, this PR breaks API mocks for .org REST API calls, which results in a fetching editor settings failure, which ultimately leads the editor produces a different html content.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the new WordPressOrgRestApi doesn't support that. I'll just need to add that support back by allowing passing a custom "api base URL", which can be set to mock server url during UI tests.

I think being able to customize the base URL is good design regardless, even if 99% of the usages will be with the default one configured in the library.

remoteAPI = restAPI
} else if let orgAPI = blog.wordPressOrgRestApi {
remoteAPI = orgAPI
} else {
guard let remoteAPI = WordPressOrgRestApi(blog: blog) else {
// This is should only happen if there is a problem with the blog itsself.
return nil
}

self.init(blog: blog, remoteAPI: remoteAPI, coreDataStack: coreDataStack)
}

init(blog: Blog, remoteAPI: WordPressRestApi, coreDataStack: CoreDataStackSwift) {
init(blog: Blog, remoteAPI: WordPressOrgRestApi, coreDataStack: CoreDataStackSwift) {
assert(blog.objectID.persistentStore != nil, "The blog instance should be saved first")
self.blog = blog
self.coreDataStack = coreDataStack
Expand Down Expand Up @@ -65,7 +58,7 @@ class BlockEditorSettingsService {
// MARK: Editor `theme_supports` support
private extension BlockEditorSettingsService {
func fetchTheme(_ completion: @escaping BlockEditorSettingsServiceCompletion) {
remote.fetchTheme(forSiteID: blog.dotComID?.intValue) { [weak self] (response) in
remote.fetchTheme { [weak self] (response) in
guard let `self` = self else { return }
switch response {
case .success(let editorTheme):
Expand Down Expand Up @@ -127,7 +120,7 @@ private extension BlockEditorSettingsService {
// MARK: Editor Global Styles support
private extension BlockEditorSettingsService {
func fetchBlockEditorSettings(_ completion: @escaping BlockEditorSettingsServiceCompletion) {
remote.fetchBlockEditorSettings(forSiteID: blog.dotComID?.intValue) { [weak self] (response) in
remote.fetchBlockEditorSettings { [weak self] (response) in
guard let `self` = self else { return }
switch response {
case .success(let remoteSettings):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,20 +323,17 @@ private extension BloggingPromptsService {
return params
}()

api.GET(path, parameters: requestParameter as [String: AnyObject]) { result, _ in
switch result {
case .success(let responseObject):
do {
let data = try JSONSerialization.data(withJSONObject: responseObject, options: [])
let remotePrompts = try Self.jsonDecoder.decode([BloggingPromptRemoteObject].self, from: data)
completion(.success(remotePrompts))
} catch {
completion(.failure(error))
}
case .failure(let error):
api.GET(path, parameters: requestParameter as [String: AnyObject], success: { (responseObject, _) in
do {
let data = try JSONSerialization.data(withJSONObject: responseObject, options: [])
let remotePrompts = try Self.jsonDecoder.decode([BloggingPromptRemoteObject].self, from: data)
completion(.success(remotePrompts))
} catch {
completion(.failure(error))
}
}
}, failure: { (error, _) in
completion(.failure(error))
})
}

/// Loads local prompts based on the given parameters.
Expand Down
32 changes: 15 additions & 17 deletions WordPress/Classes/Stores/PluginStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -690,18 +690,16 @@ private extension PluginStore {
}

func fetchPluginDirectoryEntry(slug: String) {
let remote = PluginDirectoryServiceRemote()
state.fetchingDirectoryEntry[slug] = true
remote.getPluginInformation(
slug: slug,
completion: { [actionDispatcher] (result) in
switch result {
case .success(let entry):
actionDispatcher.dispatch(PluginAction.receivePluginDirectoryEntry(slug: slug, entry: entry))
case .failure(let error):
actionDispatcher.dispatch(PluginAction.receivePluginDirectoryEntryFailed(slug: slug, error: error))
}
})
Task { @MainActor [actionDispatcher] in
let remote = PluginDirectoryServiceRemote()
do {
let entry = try await remote.getPluginInformation(slug: slug)
actionDispatcher.dispatch(PluginAction.receivePluginDirectoryEntry(slug: slug, entry: entry))
} catch {
actionDispatcher.dispatch(PluginAction.receivePluginDirectoryEntryFailed(slug: slug, error: error))
}
}
}

func receivePluginDirectoryEntry(slug: String, entry: PluginDirectoryEntry) {
Expand Down Expand Up @@ -747,12 +745,12 @@ private extension PluginStore {
func fetchPluginDirectoryFeed(feed: PluginDirectoryFeedType) {
state.fetchingDirectoryFeed[feed.slug] = true

let remote = PluginDirectoryServiceRemote()
remote.getPluginFeed(feed) { [actionDispatcher] result in
switch result {
case .success(let response):
Task { @MainActor [actionDispatcher] in
let remote = PluginDirectoryServiceRemote()
do {
let response = try await remote.getPluginFeed(feed)
actionDispatcher.dispatch(PluginAction.receivePluginDirectoryFeed(feed: feed, response: response))
case .failure(let error):
} catch {
actionDispatcher.dispatch(PluginAction.receivePluginDirectoryFeedFailed(feed: feed, error: error))
}
}
Expand Down Expand Up @@ -803,7 +801,7 @@ private extension PluginStore {
}

private func selfHostedRemoteClient(site: JetpackSiteRef) -> PluginManagementClient? {
guard let remote = BlogService.blog(with: site)?.wordPressOrgRestApi else {
guard let remote = BlogService.blog(with: site)?.selfHostedSiteRestApi else {
return nil
}

Expand Down
Loading