diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index 8a20ac4f806..d3b246f456e 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -6221,7 +6221,6 @@ WordPressKit/APIInterface/include/WordPressComRESTAPIVersion.h, WordPressKit/APIInterface/include/WordPressComRESTAPIVersionedPathBuilder.h, WordPressKit/BasicBlogAPIObjc/ServiceRemoteWordPressComREST.h, - WordPressKit/Models/RemoteComment.h, WordPressKit/Models/RemotePost.h, WordPressKit/Models/RemotePostCategory.h, WordPressKit/Models/RemoteUser.h, @@ -6230,9 +6229,6 @@ WordPressKit/Services/BlogServiceRemote.h, WordPressKit/Services/BlogServiceRemoteREST.h, WordPressKit/Services/BlogServiceRemoteXMLRPC.h, - WordPressKit/Services/CommentServiceRemote.h, - WordPressKit/Services/CommentServiceRemoteREST.h, - WordPressKit/Services/CommentServiceRemoteXMLRPC.h, WordPressKit/Services/PostServiceRemote.h, WordPressKit/Services/PostServiceRemoteOptions.h, WordPressKit/Services/PostServiceRemoteREST.h, @@ -6242,7 +6238,6 @@ WordPressKit/Services/TaxonomyServiceRemote.h, WordPressKit/Services/TaxonomyServiceRemoteREST.h, WordPressKit/Services/TaxonomyServiceRemoteXMLRPC.h, - WordPressKit/Services/ThemeServiceRemote.h, WordPressKit/Services/WordPressComServiceRemote.h, "WordPressKit/Utility/NSString+MD5.h", ); diff --git a/WooCommerce/WordPressAuthenticator/WordPressAuthenticator.h b/WooCommerce/WordPressAuthenticator/WordPressAuthenticator.h index 82692749c32..f048b10106f 100644 --- a/WooCommerce/WordPressAuthenticator/WordPressAuthenticator.h +++ b/WooCommerce/WordPressAuthenticator/WordPressAuthenticator.h @@ -25,15 +25,12 @@ FOUNDATION_EXPORT const unsigned char WordPressAuthenticatorVersionString[]; #import #import #import -#import -#import #import #import #import #import #import #import -#import #import #import #import @@ -46,10 +43,8 @@ FOUNDATION_EXPORT const unsigned char WordPressAuthenticatorVersionString[]; #import #import // Used in the tests -#import #import // Used _somewhere_ which I haven't followed up yet #import #import #import -#import diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteBloggingPrompt.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteBloggingPrompt.swift deleted file mode 100644 index 8fc2be4665d..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteBloggingPrompt.swift +++ /dev/null @@ -1,58 +0,0 @@ -public struct RemoteBloggingPrompt { - public var promptID: Int - public var text: String - public var title: String - public var content: String - public var attribution: String - public var date: Date - public var answered: Bool - public var answeredUsersCount: Int - public var answeredUserAvatarURLs: [URL] -} - -// MARK: - Decodable - -extension RemoteBloggingPrompt: Decodable { - enum CodingKeys: String, CodingKey { - case id - case text - case title - case content - case attribution - case date - case answered - case answeredUsersCount = "answered_users_count" - case answeredUserAvatarURLs = "answered_users_sample" - } - - /// Used to format the fetched object's date string to a date. - private static var dateFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.locale = .init(identifier: "en_US_POSIX") - formatter.timeZone = .init(secondsFromGMT: 0) - formatter.dateFormat = "yyyy-MM-dd" - return formatter - }() - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - - self.promptID = try container.decode(Int.self, forKey: .id) - self.text = try container.decode(String.self, forKey: .text) - self.title = try container.decode(String.self, forKey: .title) - self.content = try container.decode(String.self, forKey: .content) - self.attribution = try container.decode(String.self, forKey: .attribution) - self.answered = try container.decode(Bool.self, forKey: .answered) - self.date = Self.dateFormatter.date(from: try container.decode(String.self, forKey: .date)) ?? Date() - self.answeredUsersCount = try container.decode(Int.self, forKey: .answeredUsersCount) - - let userAvatars = try container.decode([UserAvatar].self, forKey: .answeredUserAvatarURLs) - self.answeredUserAvatarURLs = userAvatars.compactMap { URL(string: $0.avatar) } - } - - /// meta structure to simplify decoding logic for user avatar objects. - /// this is intended to be private. - private struct UserAvatar: Codable { - var avatar: String - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteBloggingPromptsSettings.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteBloggingPromptsSettings.swift deleted file mode 100644 index 7bc6363100c..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteBloggingPromptsSettings.swift +++ /dev/null @@ -1,51 +0,0 @@ -public struct RemoteBloggingPromptsSettings: Codable { - public var promptCardEnabled: Bool - public var promptRemindersEnabled: Bool - public var reminderDays: ReminderDays - public var reminderTime: String - public var isPotentialBloggingSite: Bool - - public struct ReminderDays: Codable { - public var monday: Bool - public var tuesday: Bool - public var wednesday: Bool - public var thursday: Bool - public var friday: Bool - public var saturday: Bool - public var sunday: Bool - - public init(monday: Bool, tuesday: Bool, wednesday: Bool, thursday: Bool, friday: Bool, saturday: Bool, sunday: Bool) { - self.monday = monday - self.tuesday = tuesday - self.wednesday = wednesday - self.thursday = thursday - self.friday = friday - self.saturday = saturday - self.sunday = sunday - } - } - - private enum CodingKeys: String, CodingKey { - case promptCardEnabled = "prompts_card_opted_in" - case promptRemindersEnabled = "prompts_reminders_opted_in" - case reminderDays = "reminders_days" - case reminderTime = "reminders_time" - case isPotentialBloggingSite = "is_potential_blogging_site" - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(promptRemindersEnabled, forKey: .promptRemindersEnabled) - try container.encode(reminderDays, forKey: .reminderDays) - try container.encode(reminderTime, forKey: .reminderTime) - } - - public init(promptCardEnabled: Bool = false, promptRemindersEnabled: Bool, reminderDays: RemoteBloggingPromptsSettings.ReminderDays, reminderTime: String, isPotentialBloggingSite: Bool = false) { - self.promptCardEnabled = promptCardEnabled - self.promptRemindersEnabled = promptRemindersEnabled - self.reminderDays = reminderDays - self.reminderTime = reminderTime - self.isPotentialBloggingSite = isPotentialBloggingSite - } - -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteComment.h b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteComment.h deleted file mode 100644 index 82c1917c775..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteComment.h +++ /dev/null @@ -1,23 +0,0 @@ -#import - -@interface RemoteComment : NSObject -@property (nonatomic, strong) NSNumber *commentID; -@property (nonatomic, strong) NSNumber *authorID; -@property (nonatomic, strong) NSString *author; -@property (nonatomic, strong) NSString *authorEmail; -@property (nonatomic, strong) NSString *authorUrl; -@property (nonatomic, strong) NSString *authorAvatarURL; -@property (nonatomic, strong) NSString *authorIP; -@property (nonatomic, strong) NSString *content; -@property (nonatomic, strong) NSString *rawContent; -@property (nonatomic, strong) NSDate *date; -@property (nonatomic, strong) NSString *link; -@property (nonatomic, strong) NSNumber *parentID; -@property (nonatomic, strong) NSNumber *postID; -@property (nonatomic, strong) NSString *postTitle; -@property (nonatomic, strong) NSString *status; -@property (nonatomic, strong) NSString *type; -@property (nonatomic) BOOL isLiked; -@property (nonatomic, strong) NSNumber *likeCount; -@property (nonatomic) BOOL canModerate; -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteComment.m b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteComment.m deleted file mode 100644 index 7620e8ae146..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteComment.m +++ /dev/null @@ -1,5 +0,0 @@ -#import "RemoteComment.h" - -@implementation RemoteComment - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteCommentV2.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteCommentV2.swift deleted file mode 100644 index a80eaea2dbe..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteCommentV2.swift +++ /dev/null @@ -1,95 +0,0 @@ -/// Captures the JSON structure for Comments returned from API v2 endpoint. -public struct RemoteCommentV2 { - public var commentID: Int - public var postID: Int - public var parentID: Int = 0 - public var authorID: Int - public var authorName: String? - public var authorEmail: String? // only available in edit context - public var authorURL: String? - public var authorIP: String? // only available in edit context - public var authorUserAgent: String? // only available in edit context - public var authorAvatarURL: String? - public var date: Date - public var content: String - public var rawContent: String? // only available in edit context - public var link: String - public var status: String - public var type: String -} - -// MARK: - Decodable - -extension RemoteCommentV2: Decodable { - enum CodingKeys: String, CodingKey { - case id - case post - case parent - case author - case authorName = "author_name" - case authorEmail = "author_email" - case authorURL = "author_url" - case authorIP = "author_ip" - case authorUserAgent = "author_user_agent" - case date = "date_gmt" // take the gmt version, as the other `date` parameter doesn't provide timezone information. - case content - case authorAvatarURLs = "author_avatar_urls" - case link - case status - case type - } - - enum ContentCodingKeys: String, CodingKey { - case rendered - case raw - } - - enum AuthorAvatarCodingKeys: String, CodingKey { - case size96 = "96" // this is the default size for avatar URL in API v1.1. - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - - self.commentID = try container.decode(Int.self, forKey: .id) - self.postID = try container.decode(Int.self, forKey: .post) - self.parentID = try container.decode(Int.self, forKey: .parent) - self.authorID = try container.decode(Int.self, forKey: .author) - self.authorName = try container.decode(String.self, forKey: .authorName) - self.authorEmail = try container.decodeIfPresent(String.self, forKey: .authorEmail) - self.authorURL = try container.decode(String.self, forKey: .authorURL) - self.authorIP = try container.decodeIfPresent(String.self, forKey: .authorIP) - self.authorUserAgent = try container.decodeIfPresent(String.self, forKey: .authorUserAgent) - self.link = try container.decode(String.self, forKey: .link) - self.type = try container.decode(String.self, forKey: .type) - - // since `date_gmt` is already in GMT timezone, manually add the timezone string to make the rfc3339 formatter happy (or it will throw otherwise). - guard let dateString = try? container.decode(String.self, forKey: .date), - let date = NSDate.with(wordPressComJSONString: dateString + "+00:00") else { - throw DecodingError.dataCorruptedError(forKey: .date, in: container, debugDescription: "Date parsing failed") - } - self.date = date - - let contentContainer = try container.nestedContainer(keyedBy: ContentCodingKeys.self, forKey: .content) - self.rawContent = try contentContainer.decodeIfPresent(String.self, forKey: .raw) - self.content = try contentContainer.decode(String.self, forKey: .rendered) - - let remoteStatus = try container.decode(String.self, forKey: .status) - self.status = Self.status(from: remoteStatus) - - let avatarContainer = try container.nestedContainer(keyedBy: AuthorAvatarCodingKeys.self, forKey: .authorAvatarURLs) - self.authorAvatarURL = try avatarContainer.decode(String.self, forKey: .size96) - } - - /// Maintain parity with the client-side comment statuses. Refer to `CommentServiceRemoteREST:statusWithRemoteStatus`. - private static func status(from remoteStatus: String) -> String { - switch remoteStatus { - case "unapproved": - return "hold" - case "approved": - return "approve" - default: - return remoteStatus - } - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteDomain.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteDomain.swift deleted file mode 100644 index d1dd5a6e9e1..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteDomain.swift +++ /dev/null @@ -1,83 +0,0 @@ -import Foundation - -@objc public enum DomainType: Int16 { - case registered - case mapped - case siteRedirect - case transfer - case wpCom - - public var description: String { - switch self { - case .registered: - return NSLocalizedString("Registered Domain", comment: "Describes a domain that was registered with WordPress.com") - case .mapped: - return NSLocalizedString("Mapped Domain", comment: "Describes a domain that was mapped to WordPress.com, but registered elsewhere") - case .siteRedirect: - return NSLocalizedString("Site Redirect", comment: "Describes a site redirect domain") - case .wpCom: - return NSLocalizedString("Included with Site", comment: "Describes a standard *.wordpress.com site domain") - case .transfer: - return NSLocalizedString("Transferred Domain", comment: "Describes a domain that was transferred from elsewhere to wordpress.com") - } - } - - init(domainJson: [String: Any]) { - self.init( - type: domainJson["domain"] as? String, - wpComDomain: domainJson["wpcom_domain"] as? Bool, - hasRegistration: domainJson["has_registration"] as? Bool - ) - } - - init(type: String?, wpComDomain: Bool?, hasRegistration: Bool?) { - if type == "redirect" { - self = .siteRedirect - } else if type == "transfer" { - self = .transfer - } else if wpComDomain == true { - self = .wpCom - } else if hasRegistration == true { - self = .registered - } else { - self = .mapped - } - } -} - -public struct RemoteDomain { - public let domainName: String - public let isPrimaryDomain: Bool - public let domainType: DomainType - - // Renewals / Expiry - public let autoRenewing: Bool - public let autoRenewalDate: String - public let expirySoon: Bool - public let expired: Bool - public let expiryDate: String - - public init(domainName: String, - isPrimaryDomain: Bool, - domainType: DomainType, - autoRenewing: Bool? = nil, - autoRenewalDate: String? = nil, - expirySoon: Bool? = nil, - expired: Bool? = nil, - expiryDate: String? = nil) { - self.domainName = domainName - self.isPrimaryDomain = isPrimaryDomain - self.domainType = domainType - self.autoRenewing = autoRenewing ?? false - self.autoRenewalDate = autoRenewalDate ?? "" - self.expirySoon = expirySoon ?? false - self.expired = expired ?? false - self.expiryDate = expiryDate ?? "" - } -} - -extension RemoteDomain: CustomStringConvertible { - public var description: String { - return "\(domainName) (\(domainType.description))" - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteGravatarProfile.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteGravatarProfile.swift deleted file mode 100644 index f55ddb12bca..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteGravatarProfile.swift +++ /dev/null @@ -1,34 +0,0 @@ -import Foundation - -public class RemoteGravatarProfile { - public let profileID: String - public let hash: String - public let requestHash: String - public let profileUrl: String - public let preferredUsername: String - public let thumbnailUrl: String - public let name: String - public let displayName: String - public let formattedName: String - public let aboutMe: String - public let currentLocation: String - - init(dictionary: NSDictionary) { - profileID = dictionary.string(forKey: "id") ?? "" - hash = dictionary.string(forKey: "hash") ?? "" - requestHash = dictionary.string(forKey: "requestHash") ?? "" - profileUrl = dictionary.string(forKey: "profileUrl") ?? "" - preferredUsername = dictionary.string(forKey: "preferredUsername") ?? "" - thumbnailUrl = dictionary.string(forKey: "thumbnailUrl") ?? "" - name = dictionary.string(forKey: "name") ?? "" - displayName = dictionary.string(forKey: "displayName") ?? "" - - if let nameDictionary = dictionary.value(forKey: "name") as? NSDictionary { - formattedName = nameDictionary.string(forKey: "formatted") ?? "" - } else { - formattedName = "" - } - aboutMe = dictionary.string(forKey: "aboutMe") ?? "" - currentLocation = dictionary.string(forKey: "currentLocation") ?? "" - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteInviteLink.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteInviteLink.swift deleted file mode 100644 index 0f7d8a51288..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteInviteLink.swift +++ /dev/null @@ -1,26 +0,0 @@ -import Foundation - -public struct RemoteInviteLink { - public let inviteKey: String - public let role: String - public let isPending: Bool - public let inviteDate: Date - public let groupInvite: Bool - public let expiry: Int64 - public let link: String - - init(dict: [String: Any]) { - var date = Date() - if let inviteDate = dict["invite_date"] as? String, - let formattedDate = ISO8601DateFormatter().date(from: inviteDate) { - date = formattedDate - } - inviteKey = dict["invite_key"] as? String ?? "" - role = dict["role"] as? String ?? "" - isPending = dict["is_pending"] as? Bool ?? false - inviteDate = date - groupInvite = dict["is_group_invite"] as? Bool ?? false - expiry = dict["expiry"] as? Int64 ?? 0 - link = dict["link"] as? String ?? "" - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemotePageLayouts.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemotePageLayouts.swift deleted file mode 100644 index 42fcb9f9b82..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemotePageLayouts.swift +++ /dev/null @@ -1,86 +0,0 @@ -import Foundation - -public struct RemotePageLayouts: Codable { - public let layouts: [RemoteLayout] - public let categories: [RemoteLayoutCategory] - - enum CodingKeys: String, CodingKey { - case layouts - case categories - } - - public init(from decoder: Decoder) throws { - let map = try decoder.container(keyedBy: CodingKeys.self) - layouts = try map.decode([RemoteLayout].self, forKey: .layouts) - categories = try map.decode([RemoteLayoutCategory].self, forKey: .categories) - } - - public init() { - self.init(layouts: [], categories: []) - } - - public init(layouts: [RemoteLayout], categories: [RemoteLayoutCategory]) { - self.layouts = layouts - self.categories = categories - } -} - -public struct RemoteLayout: Codable { - public let slug: String - public let title: String - public let preview: String? - public let previewTablet: String? - public let previewMobile: String? - public let demoUrl: String? - public let content: String? - public let categories: [RemoteLayoutCategory] - - enum CodingKeys: String, CodingKey { - case slug - case title - case preview - case previewTablet = "preview_tablet" - case previewMobile = "preview_mobile" - case demoUrl = "demo_url" - case content - case categories - } - - public init(from decoder: Decoder) throws { - let map = try decoder.container(keyedBy: CodingKeys.self) - slug = try map.decode(String.self, forKey: .slug) - title = try map.decode(String.self, forKey: .title) - preview = try? map.decode(String.self, forKey: .preview) - previewTablet = try? map.decode(String.self, forKey: .previewTablet) - previewMobile = try? map.decode(String.self, forKey: .previewMobile) - demoUrl = try? map.decode(String.self, forKey: .demoUrl) - content = try? map.decode(String.self, forKey: .content) - categories = try map.decode([RemoteLayoutCategory].self, forKey: .categories) - } -} - -public struct RemoteLayoutCategory: Codable, Comparable { - public static func < (lhs: RemoteLayoutCategory, rhs: RemoteLayoutCategory) -> Bool { - return lhs.slug < rhs.slug - } - - public let slug: String - public let title: String - public let description: String - public let emoji: String? - - enum CodingKeys: String, CodingKey { - case slug - case title - case description - case emoji - } - - public init(from decoder: Decoder) throws { - let map = try decoder.container(keyedBy: CodingKeys.self) - slug = try map.decode(String.self, forKey: .slug) - title = try map.decode(String.self, forKey: .title) - description = try map.decode(String.self, forKey: .description) - emoji = try? map.decode(String.self, forKey: .emoji) - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteTheme.h b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteTheme.h deleted file mode 100644 index c067d9adb18..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteTheme.h +++ /dev/null @@ -1,26 +0,0 @@ -#import - -@interface RemoteTheme : NSObject - -@property (nonatomic, assign) BOOL active; -@property (nonatomic, strong) NSString *type; -@property (nonatomic, strong) NSString *author; -@property (nonatomic, strong) NSString *authorUrl; -@property (nonatomic, strong) NSString *desc; -@property (nonatomic, strong) NSString *demoUrl; -@property (nonatomic, strong) NSString *themeUrl; -@property (nonatomic, strong) NSString *downloadUrl; -@property (nonatomic, strong) NSDate *launchDate; -@property (nonatomic, strong) NSString *name; -@property (nonatomic, assign) NSInteger order; -@property (nonatomic, strong) NSNumber *popularityRank; -@property (nonatomic, strong) NSString *previewUrl; -@property (nonatomic, strong) NSString *price; -@property (nonatomic, strong) NSNumber *purchased; -@property (nonatomic, strong) NSString *screenshotUrl; -@property (nonatomic, strong) NSString *stylesheet; -@property (nonatomic, strong) NSString *themeId; -@property (nonatomic, strong) NSNumber *trendingRank; -@property (nonatomic, strong) NSString *version; - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteTheme.m b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteTheme.m deleted file mode 100644 index 5b6c2e83ef5..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/RemoteTheme.m +++ /dev/null @@ -1,5 +0,0 @@ -#import "RemoteTheme.h" - -@implementation RemoteTheme - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPCountry.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPCountry.swift deleted file mode 100644 index 5a0141941a0..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPCountry.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Foundation - -@objc public class WPCountry: NSObject, Codable { - public var code: String? - public var name: String? -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPState.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPState.swift deleted file mode 100644 index 630ad40d9d5..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPState.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Foundation - -@objc public class WPState: NSObject, Codable { - public var code: String? - public var name: String? -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPTimeZone.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPTimeZone.swift deleted file mode 100644 index 8974acef895..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Models/WPTimeZone.swift +++ /dev/null @@ -1,98 +0,0 @@ -import Foundation - -/// A model to represent known WordPress.com timezones -/// -public protocol WPTimeZone { - var label: String { get } - var value: String { get } - - var gmtOffset: Float? { get } - var timezoneString: String? { get } -} - -extension WPTimeZone { - public var timezoneString: String? { - return value - } -} - -public struct TimeZoneGroup { - public let name: String - public let timezones: [WPTimeZone] - - public init(name: String, timezones: [WPTimeZone]) { - self.name = name - self.timezones = timezones - } -} - -public struct NamedTimeZone: WPTimeZone { - public let label: String - public let value: String - - public var gmtOffset: Float? { - return nil - } -} - -public struct OffsetTimeZone: WPTimeZone { - let offset: Float - - public init(offset: Float) { - self.offset = offset - } - - public var label: String { - if offset == 0 { - return "UTC" - } else if offset > 0 { - return "UTC+\(hourOffset)\(minuteOffsetString)" - } else { - return "UTC\(hourOffset)\(minuteOffsetString)" - } - } - - public var value: String { - let offsetString = String(format: "%g", offset) - if offset == 0 { - return "UTC" - } else if offset > 0 { - return "UTC+\(offsetString)" - } else { - return "UTC\(offsetString)" - } - } - - public var gmtOffset: Float? { - return offset - } - - static func fromValue(_ value: String) -> OffsetTimeZone? { - guard let offsetString = try? value.removingPrefix(pattern: "UTC") else { - return nil - } - let offset: Float? - if offsetString.isEmpty { - offset = 0 - } else { - offset = Float(offsetString) - } - return offset.map(OffsetTimeZone.init) - } - - private var hourOffset: Int { - return Int(offset.rounded(.towardZero)) - } - - private var minuteOffset: Int { - return Int(abs(offset.truncatingRemainder(dividingBy: 1) * 60)) - } - - private var minuteOffsetString: String { - if minuteOffset != 0 { - return ":\(minuteOffset)" - } else { - return "" - } - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/BloggingPromptsServiceRemote.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/BloggingPromptsServiceRemote.swift deleted file mode 100644 index 5d092a8149c..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/BloggingPromptsServiceRemote.swift +++ /dev/null @@ -1,151 +0,0 @@ -/// Encapsulates logic to fetch blogging prompts from the remote endpoint. -/// -open class BloggingPromptsServiceRemote: ServiceRemoteWordPressComREST { - /// Used to format dates so the time information is omitted. - private static var dateFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.locale = .init(identifier: "en_US_POSIX") - formatter.dateFormat = "yyyy-MM-dd" - - return formatter - }() - - public enum RequestError: Error { - case encodingFailure - } - - /// Fetches a number of blogging prompts for the specified site. - /// Note that this method hits wpcom/v2, which means the `WordPressComRestAPI` needs to be initialized with `LocaleKeyV2`. - /// - /// - Parameters: - /// - siteID: Used to check which prompts have been answered for the site with given `siteID`. - /// - number: The number of prompts to query. When not specified, this will default to remote implementation. - /// - fromDate: When specified, this will fetch prompts from the given date. When not specified, this will default to remote implementation. - /// - completion: A closure that will be called when the fetch request completes. - open func fetchPrompts(for siteID: NSNumber, - number: Int? = nil, - fromDate: Date? = nil, - completion: @escaping (Result<[RemoteBloggingPrompt], Error>) -> Void) { - let path = path(forEndpoint: "sites/\(siteID)/blogging-prompts", withVersion: ._2_0) - let requestParameter: [String: AnyHashable] = { - var params = [String: AnyHashable]() - - if let number = number, number > 0 { - params["number"] = number - } - - if let fromDate = fromDate { - // convert to yyyy-MM-dd format, excluding the timezone information. - // the date parameter doesn't need to be timezone-accurate since prompts are grouped by date. - params["from"] = Self.dateFormatter.string(from: fromDate) - } - - return params - }() - - let decoder = JSONDecoder.apiDecoder - // our API decoder assumes that we're converting from snake case. - // revert it to default so the CodingKeys match the actual response keys. - decoder.keyDecodingStrategy = .useDefaultKeys - - Task { @MainActor in - await self.wordPressComRestApi - .perform( - .get, - URLString: path, - parameters: requestParameter as [String: AnyObject], - jsonDecoder: decoder, - type: [String: [RemoteBloggingPrompt]].self - ) - .map { $0.body.values.first ?? [] } - .mapError { error -> Error in error.asNSError() } - .execute(completion) - } - } - - /// Fetches the blogging prompts settings for a given site. - /// - /// - Parameters: - /// - siteID: The site ID for the blogging prompts settings. - /// - completion: Closure that will be called when the request completes. - open func fetchSettings(for siteID: NSNumber, completion: @escaping (Result) -> Void) { - let path = path(forEndpoint: "sites/\(siteID)/blogging-prompts/settings", withVersion: ._2_0) - Task { @MainActor in - await self.wordPressComRestApi.perform(.get, URLString: path, type: RemoteBloggingPromptsSettings.self) - .map { $0.body } - .mapError { error -> Error in error.asNSError() } - .execute(completion) - } - } - - /// Updates the blogging prompts settings to remote. - /// - /// This will return an updated settings object if at least one of the fields is successfully modified. - /// If nothing has changed, it will still be regarded as a successful operation; but nil will be returned. - /// - /// - Parameters: - /// - siteID: The site ID of the blogging prompts settings. - /// - settings: The updated settings to upload. - /// - completion: Closure that will be called when the request completes. - open func updateSettings(for siteID: NSNumber, - with settings: RemoteBloggingPromptsSettings, - completion: @escaping (Result) -> Void) { - let path = path(forEndpoint: "sites/\(siteID)/blogging-prompts/settings", withVersion: ._2_0) - var parameters = [String: AnyObject]() - do { - let data = try JSONEncoder().encode(settings) - parameters = try JSONSerialization.jsonObject(with: data) as? [String: AnyObject] ?? [:] - } catch { - completion(.failure(error)) - return - } - - // The parameter shouldn't be empty at this point. - // If by some chance it is, let's abort and return early. There could be something wrong with the parsing process. - guard !parameters.isEmpty else { - WPAuthenticatorLogError("Error encoding RemoteBloggingPromptsSettings object: \(settings)") - completion(.failure(RequestError.encodingFailure)) - return - } - - wordPressComRESTAPI.post(path, parameters: parameters) { responseObject, _ in - do { - let data = try JSONSerialization.data(withJSONObject: responseObject) - let response = try JSONDecoder().decode(UpdateBloggingPromptsSettingsResponse.self, from: data) - completion(.success(response.updated)) - } catch { - completion(.failure(error)) - } - } failure: { error, _ in - completion(.failure(error)) - } - } -} - -// MARK: - Private helpers - -private extension BloggingPromptsServiceRemote { - /// An intermediate object representing the response structure after updating the prompts settings. - /// - /// If there is at least one updated field, the remote will return the full `RemoteBloggingPromptsSettings` object in the `updated` key. - /// Otherwise, if no fields are changed, the remote will assign an empty array to the `updated` key. - struct UpdateBloggingPromptsSettingsResponse: Decodable { - let updated: RemoteBloggingPromptsSettings? - - private enum CodingKeys: String, CodingKey { - case updated - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - - // return nil when no fields are changed. - if let _ = try? container.decode(Array.self, forKey: .updated) { - self.updated = nil - return - } - - self.updated = try container.decode(RemoteBloggingPromptsSettings.self, forKey: .updated) - } - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemote.h b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemote.h deleted file mode 100644 index ebf6b45b371..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemote.h +++ /dev/null @@ -1,69 +0,0 @@ -#import -#import - - -// Used to determine which 'status' parameter to use when fetching Comments. -typedef enum { - CommentStatusFilterAll = 0, - CommentStatusFilterUnapproved, - CommentStatusFilterApproved, - CommentStatusFilterTrash, - CommentStatusFilterSpam, -} CommentStatusFilter; - - -@protocol CommentServiceRemote - -/** - Loads all of the comments associated with a blog - */ -- (void)getCommentsWithMaximumCount:(NSInteger)maximumComments - success:(void (^)(NSArray *comments))success - failure:(void (^)(NSError *error))failure; - - - -/** - Loads all of the comments associated with a blog - */ -- (void)getCommentsWithMaximumCount:(NSInteger)maximumComments - options:(NSDictionary *)options - 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 - */ -- (void)createComment:(RemoteComment *)comment - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *error))failure; -/** - Updates the content of an existing comment - */ -- (void)updateComment:(RemoteComment *)commen - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *error))failure; - -/** - Updates the status of an existing comment - */ -- (void)moderateComment:(RemoteComment *)comment - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *error))failure; - -/** - Trashes a comment - */ -- (void)trashComment:(RemoteComment *)comment - success:(void (^)(void))success - failure:(void (^)(NSError *error))failure; - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST+ApiV2.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST+ApiV2.swift deleted file mode 100644 index d62044486e6..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST+ApiV2.swift +++ /dev/null @@ -1,65 +0,0 @@ -public extension CommentServiceRemoteREST { - /// Lists the available keys for the request parameter. - enum RequestKeys: String { - /// The parent comment's ID. In API v2, supplying this parameter filters the list to only contain - /// the child/reply comments of the specified ID. - case parent - - /// The dotcom user ID of the comment author. In API v2, supplying this parameter filters the list - /// to only contain comments authored by the specified ID. - case author - - /// Valid values are `view`, `edit`, or `embed`. When not specified, the default context is `view`. - case context - } - - /// Retrieves a list of comments in a site with the specified siteID. - /// - Parameters: - /// - siteID: The ID of the site that contains the specified comment. - /// - parameters: Additional request parameters. Optional. - /// - success: A closure that will be called when the request succeeds. - /// - failure: A closure that will be called when the request fails. - func getCommentsV2(for siteID: Int, - parameters: [RequestKeys: AnyHashable]? = nil, - success: @escaping ([RemoteCommentV2]) -> Void, - failure: @escaping (Error) -> Void) { - let path = coreV2Path(for: "sites/\(siteID)/comments") - let requestParameters: [String: AnyHashable] = { - guard let someParameters = parameters else { - return [:] - } - - return someParameters.reduce([String: AnyHashable]()) { result, pair in - var result = result - result[pair.key.rawValue] = pair.value - return result - } - }() - - Task { @MainActor in - await self.wordPressComRestApi - .perform( - .get, - URLString: path, - parameters: requestParameters as [String: AnyObject], - type: [RemoteCommentV2].self - ) - .map { $0.body } - .mapError { error -> Error in error.asNSError() } - .execute(onSuccess: success, onFailure: failure) - } - } - -} - -// MARK: - Private Helpers - -private extension CommentServiceRemoteREST { - struct Constants { - static let coreV2String = "wp/v2" - } - - func coreV2Path(for endpoint: String) -> String { - return "\(Constants.coreV2String)/\(endpoint)" - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST.h b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST.h deleted file mode 100644 index 241ab43109d..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST.h +++ /dev/null @@ -1,100 +0,0 @@ -#import -#import -#import - -@class RemoteUser; -@class RemoteLikeUser; - -@interface CommentServiceRemoteREST : SiteServiceRemoteWordPressComREST - -/** - Fetch a hierarchical list of comments for the specified post on the specified site. - The comments are returned in the order of nesting, not date. - The request fetches the default number of *parent* comments (20) but may return more - depending on the number of child comments. - - @param postID The ID of the post. - @param page The page number to fetch. - @param number The number to fetch per page. - @param success block called on a successful fetch. Returns the comments array and total comments count. - @param failure block called if there is any error. `error` can be any underlying network error. - */ -- (void)syncHierarchicalCommentsForPost:(NSNumber * _Nonnull)postID - page:(NSUInteger)page - number:(NSUInteger)number - success:(void (^ _Nullable)(NSArray * _Nullable comments, NSNumber * _Nonnull found))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - -/** - Update a comment with a commentID - */ -- (void)updateCommentWithID:(NSNumber * _Nonnull)commentID - content:(NSString * _Nonnull)content - success:(void (^ _Nullable)(void))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - -/** - Adds a reply to a post with postID - */ -- (void)replyToPostWithID:(NSNumber * _Nonnull)postID - content:(NSString * _Nonnull)content - success:(void (^ _Nullable)(RemoteComment * _Nullable comment))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - -/** - Adds a reply to a comment with commentID. - */ -- (void)replyToCommentWithID:(NSNumber * _Nonnull)commentID - content:(NSString * _Nonnull)content - success:(void (^ _Nullable)(RemoteComment * _Nullable comment))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - -/** - Moderate a comment with a commentID - */ -- (void)moderateCommentWithID:(NSNumber * _Nonnull)commentID - status:(NSString * _Nonnull)status - success:(void (^ _Nullable)(void))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - -/** - Trashes a comment with a commentID - */ -- (void)trashCommentWithID:(NSNumber * _Nonnull)commentID - success:(void (^ _Nullable)(void))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - -/** - Like a comment with a commentID - */ -- (void)likeCommentWithID:(NSNumber * _Nonnull)commentID - success:(void (^ _Nullable)(void))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - - -/** - Unlike a comment with a commentID - */ -- (void)unlikeCommentWithID:(NSNumber * _Nonnull)commentID - success:(void (^ _Nullable)(void))success - failure:(void (^ _Nullable)(NSError * _Nullable error))failure; - -/** - Requests a list of users that liked the comment with the specified ID. Due to - API limitation, up to 90 users will be returned from the endpoint. - - @param commentID The ID for the comment. Cannot be nil. - @param count Number of records to retrieve. Cannot be nil. If 0, will default to endpoint max. - @param before Filter results to Likes before this date/time string. Can be nil. - @param excludeUserIDs Array of user IDs to exclude from response. Can be nil. - @param success The block that will be executed on success. Can be nil. - @param failure The block that will be executed on failure. Can be nil. - */ -- (void)getLikesForCommentID:(NSNumber * _Nonnull)commentID - count:(NSNumber * _Nonnull)count - before:(NSString * _Nullable)before - excludeUserIDs:(NSArray * _Nullable)excludeUserIDs - success:(void (^ _Nullable)(NSArray * _Nonnull users, NSNumber * _Nonnull found))success - failure:(void (^ _Nullable)(NSError * _Nullable))failure; - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST.m b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST.m deleted file mode 100644 index 3863433aea4..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteREST.m +++ /dev/null @@ -1,538 +0,0 @@ -#import "CommentServiceRemoteREST.h" -#import "WordPressAuthenticator-Swift.h" -#import "RemoteComment.h" -#import "RemoteUser.h" - -@import NSObject_SafeExpectations; -@import WordPressShared; - -@implementation CommentServiceRemoteREST - -#pragma mark Public methods - -#pragma mark - Blog-centric methods - -- (void)getCommentsWithMaximumCount:(NSInteger)maximumComments - success:(void (^)(NSArray *comments))success - failure:(void (^)(NSError *error))failure -{ - [self getCommentsWithMaximumCount:maximumComments options:nil success:success failure:failure]; -} - -- (void)getCommentsWithMaximumCount:(NSInteger)maximumComments - options:(NSDictionary *)options - success:(void (^)(NSArray *posts))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments", self.siteID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:@{ - @"force": @"wpcom", // Force fetching data from shadow site on Jetpack sites - @"number": @(maximumComments) - }]; - - if (options) { - [parameters addEntriesFromDictionary:options]; - } - - NSNumber *statusFilter = [parameters numberForKey:@"status"]; - [parameters removeObjectForKey:@"status"]; - parameters[@"status"] = [self parameterForCommentStatus:statusFilter]; - - [self.wordPressComRESTAPI get:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success([self remoteCommentsFromJSONArray:responseObject[@"comments"]]); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; - -} - -- (NSString *)parameterForCommentStatus:(NSNumber *)status -{ - switch (status.intValue) { - case CommentStatusFilterUnapproved: - return @"unapproved"; - break; - case CommentStatusFilterApproved: - return @"approved"; - break; - case CommentStatusFilterTrash: - return @"trash"; - break; - case CommentStatusFilterSpam: - return @"spam"; - break; - default: - return @"all"; - break; - } -} - -- (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:WordPressComRESTAPIVersion_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 -{ - NSString *path; - if (comment.parentID) { - path = [NSString stringWithFormat:@"sites/%@/comments/%@/replies/new", self.siteID, comment.parentID]; - } else { - path = [NSString stringWithFormat:@"sites/%@/posts/%@/replies/new", self.siteID, comment.postID]; - } - - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{ - @"content": comment.content, - @"context": @"edit", - }; - [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - // TODO: validate response - RemoteComment *comment = [self remoteCommentFromJSONDictionary:responseObject]; - if (success) { - success(comment); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)updateComment:(RemoteComment *)comment - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@", self.siteID, comment.commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{ - @"content": comment.content, - @"author": comment.author, - @"author_email": comment.authorEmail, - @"author_url": comment.authorUrl, - @"context": @"edit", - }; - - [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - // TODO: validate response - RemoteComment *comment = [self remoteCommentFromJSONDictionary:responseObject]; - if (success) { - success(comment); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)moderateComment:(RemoteComment *)comment - success:(void (^)(RemoteComment *))success - failure:(void (^)(NSError *))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@", self.siteID, comment.commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{ - @"status": [self remoteStatusWithStatus:comment.status], - @"context": @"edit", - }; - [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - // TODO: validate response - RemoteComment *comment = [self remoteCommentFromJSONDictionary:responseObject]; - if (success) { - success(comment); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)trashComment:(RemoteComment *)comment - success:(void (^)(void))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@/delete", self.siteID, comment.commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - [self.wordPressComRESTAPI post:requestUrl - parameters:nil - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success(); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - - -#pragma mark Post-centric methods - -- (void)syncHierarchicalCommentsForPost:(NSNumber *)postID - page:(NSUInteger)page - number:(NSUInteger)number - success:(void (^)(NSArray *comments, NSNumber *found))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/posts/%@/replies?order=ASC&hierarchical=1&page=%lu&number=%lu", self.siteID, postID, (unsigned long)page, (unsigned long)number]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{ - @"force": @"wpcom" // Force fetching data from shadow site on Jetpack sites - }; - [self.wordPressComRESTAPI get:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - NSDictionary *dict = (NSDictionary *)responseObject; - NSArray *comments = [self remoteCommentsFromJSONArray:[dict arrayForKey:@"comments"]]; - NSNumber *found = [responseObject numberForKey:@"found"] ?: @0; - success(comments, found); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - - -#pragma mark - Public Methods - -- (void)updateCommentWithID:(NSNumber *)commentID - content:(NSString *)content - success:(void (^)(void))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@", self.siteID, commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{ - @"content": content, - @"context": @"edit", - }; - [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success(); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)replyToPostWithID:(NSNumber *)postID - content:(NSString *)content - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/posts/%@/replies/new", self.siteID, postID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{@"content": content}; - - [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - NSDictionary *commentDict = (NSDictionary *)responseObject; - RemoteComment *comment = [self remoteCommentFromJSONDictionary:commentDict]; - success(comment); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)replyToCommentWithID:(NSNumber *)commentID - content:(NSString *)content - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@/replies/new", self.siteID, commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{ - @"content": content, - @"context": @"edit", - }; - [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - NSDictionary *commentDict = (NSDictionary *)responseObject; - RemoteComment *comment = [self remoteCommentFromJSONDictionary:commentDict]; - success(comment); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)moderateCommentWithID:(NSNumber *)commentID - status:(NSString *)status - success:(void (^)(void))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@", self.siteID, commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary *parameters = @{ - @"status" : status, - @"context" : @"edit", - }; - - [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success(); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)trashCommentWithID:(NSNumber *)commentID - success:(void (^)(void))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@/delete", self.siteID, commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - [self.wordPressComRESTAPI post:requestUrl - parameters:nil - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success(); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)likeCommentWithID:(NSNumber *)commentID - success:(void (^)(void))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@/likes/new", self.siteID, commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - [self.wordPressComRESTAPI post:requestUrl - parameters:nil - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success(); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)unlikeCommentWithID:(NSNumber *)commentID - success:(void (^)(void))success - failure:(void (^)(NSError *error))failure -{ - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@/likes/mine/delete", self.siteID, commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - [self.wordPressComRESTAPI post:requestUrl - parameters:nil - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success(); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)getLikesForCommentID:(NSNumber *)commentID - count:(NSNumber *)count - before:(NSString *)before - excludeUserIDs:(NSArray *)excludeUserIDs - success:(void (^)(NSArray * _Nonnull users, NSNumber *found))success - failure:(void (^)(NSError *))failure -{ - NSParameterAssert(commentID); - - NSString *path = [NSString stringWithFormat:@"sites/%@/comments/%@/likes", self.siteID, commentID]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_2]; - NSNumber *siteID = self.siteID; - - // If no count provided, default to endpoint max. - if (count == 0) { - count = @90; - } - - NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:@{ @"number": count }]; - - if (before) { - parameters[@"before"] = before; - } - - if (excludeUserIDs) { - parameters[@"exclude"] = excludeUserIDs; - } - - [self.wordPressComRESTAPI get:requestUrl - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - NSArray *jsonUsers = responseObject[@"likes"] ?: @[]; - NSArray *users = [self remoteUsersFromJSONArray:jsonUsers commentID:commentID siteID:siteID]; - NSNumber *found = [responseObject numberForKey:@"found"] ?: @0; - success(users, found); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -#pragma mark - Private methods - -- (NSArray *)remoteCommentsFromJSONArray:(NSArray *)jsonComments -{ - return [jsonComments wp_map:^id(NSDictionary *jsonComment) { - return [self remoteCommentFromJSONDictionary:jsonComment]; - }]; -} - -- (RemoteComment *)remoteCommentFromJSONDictionary:(NSDictionary *)jsonDictionary -{ - RemoteComment *comment = [RemoteComment new]; - - comment.authorID = [jsonDictionary numberForKeyPath:@"author.ID"]; - comment.author = jsonDictionary[@"author"][@"name"]; - // Email might be `false`, turn into `nil` - comment.authorEmail = [jsonDictionary[@"author"] stringForKey:@"email"]; - comment.authorUrl = jsonDictionary[@"author"][@"URL"]; - comment.authorAvatarURL = [jsonDictionary stringForKeyPath:@"author.avatar_URL"]; - comment.authorIP = [jsonDictionary stringForKeyPath:@"author.ip_address"]; - comment.commentID = jsonDictionary[@"ID"]; - comment.date = [NSDate dateWithWordPressComJSONString:jsonDictionary[@"date"]]; - comment.link = jsonDictionary[@"URL"]; - comment.parentID = [jsonDictionary numberForKeyPath:@"parent.ID"]; - comment.postID = [jsonDictionary numberForKeyPath:@"post.ID"]; - comment.postTitle = [jsonDictionary stringForKeyPath:@"post.title"]; - comment.status = [self statusWithRemoteStatus:jsonDictionary[@"status"]]; - comment.type = jsonDictionary[@"type"]; - comment.isLiked = [[jsonDictionary numberForKey:@"i_like"] boolValue]; - comment.likeCount = [jsonDictionary numberForKey:@"like_count"]; - comment.canModerate = [[jsonDictionary numberForKey:@"can_moderate"] boolValue]; - comment.content = jsonDictionary[@"content"]; - comment.rawContent = jsonDictionary[@"raw_content"]; - - return comment; -} - -- (NSString *)statusWithRemoteStatus:(NSString *)remoteStatus -{ - NSString *status = remoteStatus; - if ([status isEqualToString:@"unapproved"]) { - status = @"hold"; - } else if ([status isEqualToString:@"approved"]) { - status = @"approve"; - } - return status; -} - -- (NSString *)remoteStatusWithStatus:(NSString *)status -{ - NSString *remoteStatus = status; - if ([remoteStatus isEqualToString:@"hold"]) { - remoteStatus = @"unapproved"; - } else if ([remoteStatus isEqualToString:@"approve"]) { - remoteStatus = @"approved"; - } - return remoteStatus; -} - -/** - Returns an array of RemoteLikeUser based on provided JSON representation of users. - - @param jsonUsers An array containing JSON representations of users. - @param commentID ID of the Comment the users liked. - @param siteID ID of the Comment's site. - */ -- (NSArray *)remoteUsersFromJSONArray:(NSArray *)jsonUsers - commentID:(NSNumber *)commentID - siteID:(NSNumber *)siteID -{ - return [jsonUsers wp_map:^id(NSDictionary *jsonUser) { - return [[RemoteLikeUser alloc] initWithDictionary:jsonUser commentID:commentID siteID:siteID]; - }]; -} - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteXMLRPC.h b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteXMLRPC.h deleted file mode 100644 index c50fccf77c6..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteXMLRPC.h +++ /dev/null @@ -1,7 +0,0 @@ -#import -#import -#import - -@interface CommentServiceRemoteXMLRPC : ServiceRemoteWordPressXMLRPC - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteXMLRPC.m b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteXMLRPC.m deleted file mode 100644 index 5243fbf6810..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/CommentServiceRemoteXMLRPC.m +++ /dev/null @@ -1,232 +0,0 @@ -#import "CommentServiceRemoteXMLRPC.h" -#import "WordPressAuthenticator-Swift.h" -#import "RemoteComment.h" - -@import wpxmlrpc; -@import WordPressShared; -@import NSObject_SafeExpectations; - -@implementation CommentServiceRemoteXMLRPC - -- (void)getCommentsWithMaximumCount:(NSInteger)maximumComments - success:(void (^)(NSArray *comments))success - failure:(void (^)(NSError *error))failure -{ - [self getCommentsWithMaximumCount:maximumComments options:nil success:success failure:failure]; -} - -- (void)getCommentsWithMaximumCount:(NSInteger)maximumComments - options:(NSDictionary *)options - success:(void (^)(NSArray *posts))success - failure:(void (^)(NSError *error))failure -{ - NSMutableDictionary *extraParameters = [@{ @"number": @(maximumComments) } mutableCopy]; - - if (options) { - [extraParameters addEntriesFromDictionary:options]; - } - - NSNumber *statusFilter = [extraParameters numberForKey:@"status"]; - [extraParameters removeObjectForKey:@"status"]; - extraParameters[@"status"] = [self parameterForCommentStatus:statusFilter]; - - NSArray *parameters = [self XMLRPCArgumentsWithExtra:extraParameters]; - - [self.api callMethod:@"wp.getComments" - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - NSAssert([responseObject isKindOfClass:[NSArray class]], @"Response should be an array."); - if (success) { - success([self remoteCommentsFromXMLRPCArray:responseObject]); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (NSString *)parameterForCommentStatus:(NSNumber *)status -{ - switch (status.intValue) { - case CommentStatusFilterUnapproved: - return @"hold"; - break; - case CommentStatusFilterApproved: - return @"approve"; - break; - case CommentStatusFilterTrash: - return @"trash"; - break; - case CommentStatusFilterSpam: - return @"spam"; - break; - default: - return @"all"; - break; - } -} - -- (void)getCommentWithID:(NSNumber *)commentID - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *))failure -{ - NSArray *parameters = [self XMLRPCArgumentsWithExtra:commentID]; - [self.api callMethod:@"wp.getComment" - parameters:parameters success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - // TODO: validate response - RemoteComment *comment = [self remoteCommentFromXMLRPCDictionary:responseObject]; - success(comment); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - failure(error); - }]; -} - -- (void)createComment:(RemoteComment *)comment - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *error))failure -{ - NSParameterAssert(comment.postID != nil); - NSDictionary *commentDictionary = @{ - @"content": comment.content, - @"comment_parent": comment.parentID, - }; - NSArray *extraParameters = @[ - comment.postID, - commentDictionary, - ]; - NSArray *parameters = [self XMLRPCArgumentsWithExtra:extraParameters]; - [self.api callMethod:@"wp.newComment" - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - NSNumber *commentID = responseObject; - // TODO: validate response - [self getCommentWithID:commentID - success:success - failure:failure]; - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)updateComment:(RemoteComment *)comment - success:(void (^)(RemoteComment *comment))success - failure:(void (^)(NSError *error))failure -{ - NSParameterAssert(comment.commentID != nil); - NSNumber *commentID = comment.commentID; - - NSDictionary *commentDictionary = @{ - @"content": comment.content, - @"author": comment.author, - @"author_email": comment.authorEmail, - @"author_url": comment.authorUrl, - }; - - NSArray *extraParameters = @[ - comment.commentID, - commentDictionary, - ]; - - NSArray *parameters = [self XMLRPCArgumentsWithExtra:extraParameters]; - - [self.api callMethod:@"wp.editComment" - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - // TODO: validate response - [self getCommentWithID:commentID - success:success - failure:failure]; - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -- (void)moderateComment:(RemoteComment *)comment - success:(void (^)(RemoteComment *))success - failure:(void (^)(NSError *))failure -{ - NSParameterAssert(comment.commentID != nil); - NSNumber *commentID = comment.commentID; - NSArray *extraParameters = @[ - commentID, - @{@"status": comment.status}, - ]; - NSArray *parameters = [self XMLRPCArgumentsWithExtra:extraParameters]; - [self.api callMethod:@"wp.editComment" - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - // TODO: validate response - [self getCommentWithID:commentID - success:success - failure:failure]; - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - // If the error is a 500 this could be a signal that the error changed status on the server - if ([error.domain isEqualToString:WPXMLRPCFaultErrorDomain] - && error.code == 500) { - if (success) { - success(comment); - } - return; - } - if (failure) { - failure(error); - } - }]; -} - -- (void)trashComment:(RemoteComment *)comment - success:(void (^)(void))success - failure:(void (^)(NSError *))failure -{ - NSParameterAssert(comment.commentID != nil); - NSArray *parameters = [self XMLRPCArgumentsWithExtra:comment.commentID]; - [self.api callMethod:@"wp.deleteComment" - parameters:parameters - success:^(id responseObject, NSHTTPURLResponse *httpResponse) { - if (success) { - success(); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -#pragma mark - Private methods - -- (NSArray *)remoteCommentsFromXMLRPCArray:(NSArray *)xmlrpcArray -{ - return [xmlrpcArray wp_map:^id(NSDictionary *xmlrpcComment) { - return [self remoteCommentFromXMLRPCDictionary:xmlrpcComment]; - }]; -} - -- (RemoteComment *)remoteCommentFromXMLRPCDictionary:(NSDictionary *)xmlrpcDictionary -{ - RemoteComment *comment = [RemoteComment new]; - comment.author = xmlrpcDictionary[@"author"]; - comment.authorEmail = xmlrpcDictionary[@"author_email"]; - comment.authorUrl = xmlrpcDictionary[@"author_url"]; - comment.authorIP = xmlrpcDictionary[@"author_ip"]; - comment.commentID = [xmlrpcDictionary numberForKey:@"comment_id"]; - comment.content = xmlrpcDictionary[@"content"]; - comment.date = xmlrpcDictionary[@"date_created_gmt"]; - comment.link = xmlrpcDictionary[@"link"]; - comment.parentID = [xmlrpcDictionary numberForKey:@"parent"]; - comment.postID = [xmlrpcDictionary numberForKey:@"post_id"]; - comment.postTitle = xmlrpcDictionary[@"post_title"]; - comment.status = xmlrpcDictionary[@"status"]; - comment.type = xmlrpcDictionary[@"type"]; - - return comment; -} - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/Domains/DomainsServiceRemote+AllDomains.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/Domains/DomainsServiceRemote+AllDomains.swift deleted file mode 100644 index f275784f254..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/Domains/DomainsServiceRemote+AllDomains.swift +++ /dev/null @@ -1,181 +0,0 @@ -import Foundation - -extension DomainsServiceRemote { - - // MARK: - API - - /// Makes a call request to `GET /v1.1/all-domains` and returns a list of domain objects. - /// - /// The endpoint accepts 3 **optionals** query params: - /// - `resolve_status` of type `boolean`. If `true`, the response will include a `status` attribute for each `domain` object. - /// - `no_wpcom`of type `boolean`. If `true`, the respnse won't include `wpcom` domains. - /// - `locale` of type `string`. Used for string localization. - public func fetchAllDomains(params: AllDomainsEndpointParams? = nil, completion: @escaping (AllDomainsEndpointResult) -> Void) { - let path = self.path(forEndpoint: "all-domains", withVersion: ._1_1) - let parameters: [String: AnyObject]? - - do { - parameters = try queryParameters(from: params) - } catch let error { - completion(.failure(error)) - return - } - - let decoder = JSONDecoder() - decoder.dateDecodingStrategy = .iso8601 - Task { @MainActor in - await self.wordPressComRestApi - .perform( - .get, - URLString: path, - parameters: parameters, - jsonDecoder: decoder, - type: AllDomainsEndpointResponse.self - ) - .map { $0.body.domains } - .mapError { error -> Error in error.asNSError() } - .execute(completion) - } - } - - private func queryParameters(from params: AllDomainsEndpointParams?) throws -> [String: AnyObject]? { - guard let params else { - return nil - } - let encoder = JSONEncoder() - let data = try encoder.encode(params) - let dict = try JSONSerialization.jsonObject(with: data) as? [String: AnyObject] - return dict - } - - // MARK: - Public Types - - public typealias AllDomainsEndpointResult = Result<[AllDomainsListItem], Error> - - public struct AllDomainsEndpointParams { - - public var resolveStatus: Bool = false - public var noWPCOM: Bool = false - public var locale: String? - - public init() {} - } - - public struct AllDomainsListItem { - - public enum StatusType: String { - case success - case premium - case neutral - case warning - case alert - case error - } - - public struct Status { - - public let value: String - public let type: StatusType - - public init(value: String, type: StatusType) { - self.value = value - self.type = type - } - } - - public let domain: String - public let blogId: Int - public let blogName: String - public let type: DomainType - public let isDomainOnlySite: Bool - public let isWpcomStagingDomain: Bool - public let hasRegistration: Bool - public let registrationDate: Date? - public let expiryDate: Date? - public let wpcomDomain: Bool - public let currentUserIsOwner: Bool? - public let siteSlug: String - public let status: Status? - } - - // MARK: - Private Types - - private struct AllDomainsEndpointResponse: Decodable { - let domains: [AllDomainsListItem] - } -} - -// MARK: - Encoding / Decoding - -extension DomainsServiceRemote.AllDomainsEndpointParams: Encodable { - - enum CodingKeys: String, CodingKey { - case resolveStatus = "resolve_status" - case locale - case noWPCOM = "no_wpcom" - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("\(resolveStatus)", forKey: .resolveStatus) - try container.encode("\(noWPCOM)", forKey: .noWPCOM) - try container.encodeIfPresent(locale, forKey: .locale) - } -} - -extension DomainsServiceRemote.AllDomainsListItem.StatusType: Decodable { -} - -extension DomainsServiceRemote.AllDomainsListItem.Status: Decodable { - enum CodingKeys: String, CodingKey { - case value = "status" - case type = "status_type" - } -} - -extension DomainsServiceRemote.AllDomainsListItem: Decodable { - - enum CodingKeys: String, CodingKey { - case domain - case blogId = "blog_id" - case blogName = "blog_name" - case type - case isDomainOnlySite = "is_domain_only_site" - case isWpcomStagingDomain = "is_wpcom_staging_domain" - case hasRegistration = "has_registration" - case registrationDate = "registration_date" - case expiryDate = "expiry" - case wpcomDomain = "wpcom_domain" - case currentUserIsOwner = "current_user_is_owner" - case siteSlug = "site_slug" - case status = "domain_status" - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.domain = try container.decode(String.self, forKey: .domain) - self.blogId = try container.decode(Int.self, forKey: .blogId) - self.blogName = try container.decode(String.self, forKey: .blogName) - self.isDomainOnlySite = try container.decode(Bool.self, forKey: .isDomainOnlySite) - self.isWpcomStagingDomain = try container.decode(Bool.self, forKey: .isWpcomStagingDomain) - self.hasRegistration = try container.decode(Bool.self, forKey: .hasRegistration) - self.wpcomDomain = try container.decode(Bool.self, forKey: .wpcomDomain) - self.currentUserIsOwner = try container.decode(Bool?.self, forKey: .currentUserIsOwner) - self.siteSlug = try container.decode(String.self, forKey: .siteSlug) - self.registrationDate = try { - if let timestamp = try? container.decodeIfPresent(String.self, forKey: .registrationDate), !timestamp.isEmpty { - return try container.decode(Date.self, forKey: .registrationDate) - } - return nil - }() - self.expiryDate = try { - if let timestamp = try? container.decodeIfPresent(String.self, forKey: .expiryDate), !timestamp.isEmpty { - return try container.decode(Date.self, forKey: .expiryDate) - } - return nil - }() - let type: String = try container.decode(String.self, forKey: .type) - self.type = .init(type: type, wpComDomain: wpcomDomain, hasRegistration: hasRegistration) - self.status = try container.decodeIfPresent(Status.self, forKey: .status) - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/Domains/DomainsServiceRemote.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/Domains/DomainsServiceRemote.swift deleted file mode 100644 index 898ddf9e32e..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/Domains/DomainsServiceRemote.swift +++ /dev/null @@ -1,321 +0,0 @@ -import Foundation - -/// Allows the construction of a request for domain suggestions. -/// -public struct DomainSuggestionRequest { - public typealias DomainSuggestionType = DomainsServiceRemote.DomainSuggestionType - - public let query: String - public let segmentID: Int64? - public let quantity: Int? - public let suggestionType: DomainSuggestionType? - - public init(query: String, segmentID: Int64? = nil, quantity: Int? = nil, suggestionType: DomainSuggestionType? = nil) { - self.query = query - self.segmentID = segmentID - self.quantity = quantity - self.suggestionType = suggestionType - } -} - -public struct DomainSuggestion: Codable { - public let domainName: String - public let productID: Int? - public let supportsPrivacy: Bool? - public let costString: String - public let cost: Double? - public let saleCost: Double? - public let isFree: Bool - public let currencyCode: String? - - public var domainNameStrippingSubdomain: String { - return domainName.components(separatedBy: ".").first ?? domainName - } - - public init( - domainName: String, - productID: Int?, - supportsPrivacy: Bool?, - costString: String, - cost: Double? = nil, - saleCost: Double? = nil, - isFree: Bool = false, - currencyCode: String? = nil - ) { - self.domainName = domainName - self.productID = productID - self.supportsPrivacy = supportsPrivacy - self.costString = costString - self.cost = cost - self.saleCost = saleCost - self.isFree = isFree - self.currencyCode = currencyCode - } - - public init(json: [String: AnyObject]) throws { - guard let domain = json["domain_name"] as? String else { - throw DomainsServiceRemote.ResponseError.decodingFailed - } - - self.domainName = domain - self.productID = json["product_id"] as? Int ?? nil - self.supportsPrivacy = json["supports_privacy"] as? Bool ?? nil - self.costString = json["cost"] as? String ?? "" - self.cost = json["raw_price"] as? Double - self.saleCost = json["sale_cost"] as? Double - self.isFree = json["is_free"] as? Bool ?? false - self.currencyCode = json["currency_code"] as? String - } -} - -public class DomainsServiceRemote: ServiceRemoteWordPressComREST { - public enum ResponseError: Error { - case decodingFailed - } - - public enum DomainSuggestionType { - case noWordpressDotCom - case includeWordPressDotCom - case onlyWordPressDotCom - case wordPressDotComAndDotBlogSubdomains - - /// Includes free dotcom sudomains and paid domains. - case freeAndPaid - - case allowlistedTopLevelDomains([String]) - - fileprivate func parameters() -> [String: AnyObject] { - switch self { - case .noWordpressDotCom: - return ["include_wordpressdotcom": false as AnyObject] - case .includeWordPressDotCom: - return ["include_wordpressdotcom": true as AnyObject, - "only_wordpressdotcom": false as AnyObject] - case .onlyWordPressDotCom: - return ["only_wordpressdotcom": true as AnyObject] - case .wordPressDotComAndDotBlogSubdomains: - return ["include_dotblogsubdomain": true as AnyObject, - "vendor": "dot" as AnyObject, - "only_wordpressdotcom": true as AnyObject, - "include_wordpressdotcom": true as AnyObject] - case .freeAndPaid: - return ["include_dotblogsubdomain": false as AnyObject, - "include_wordpressdotcom": true as AnyObject, - "vendor": "mobile" as AnyObject] - case .allowlistedTopLevelDomains(let allowlistedTLDs): - return ["tlds": allowlistedTLDs.joined(separator: ",") as AnyObject] - } - } - } - - public func getDomainsForSite(_ siteID: Int, success: @escaping ([RemoteDomain]) -> Void, failure: @escaping (Error) -> Void) { - let endpoint = "sites/\(siteID)/domains" - let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) - - wordPressComRESTAPI.get(path, parameters: nil, - success: { - response, _ in - do { - try success(mapDomainsResponse(response)) - } catch { - WPAuthenticatorLogError("Error parsing domains response (\(error)): \(response)") - failure(error) - } - }, failure: { - error, _ in - failure(error) - }) - } - - public func setPrimaryDomainForSite(siteID: Int, domain: String, success: @escaping () -> Void, failure: @escaping (Error) -> Void) { - let endpoint = "sites/\(siteID)/domains/primary" - let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) - - let parameters: [String: AnyObject] = ["domain": domain as AnyObject] - - wordPressComRESTAPI.post(path, parameters: parameters, - success: { _, _ in - - success() - }, failure: { error, _ in - - failure(error) - }) - } - - @objc public func getStates(for countryCode: String, - success: @escaping ([WPState]) -> Void, - failure: @escaping (Error) -> Void) { - let endPoint = "domains/supported-states/\(countryCode)" - let servicePath = path(forEndpoint: endPoint, withVersion: ._1_1) - - wordPressComRESTAPI.get( - servicePath, - parameters: nil, - success: { - response, _ in - do { - guard let json = response as? [AnyObject] else { - throw ResponseError.decodingFailed - } - let data = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) - let decodedResult = try JSONDecoder.apiDecoder.decode([WPState].self, from: data) - success(decodedResult) - } catch { - WPAuthenticatorLogError("Error parsing State list for country code (\(error)): \(response)") - failure(error) - } - }, failure: { error, _ in - failure(error) - }) - } - - public func getDomainContactInformation(success: @escaping (DomainContactInformation) -> Void, - failure: @escaping (Error) -> Void) { - let endPoint = "me/domain-contact-information" - let servicePath = path(forEndpoint: endPoint, withVersion: ._1_1) - - wordPressComRESTAPI.get( - servicePath, - parameters: nil, - success: { (response, _) in - do { - let data = try JSONSerialization.data(withJSONObject: response, options: .prettyPrinted) - let decodedResult = try JSONDecoder.apiDecoder.decode(DomainContactInformation.self, from: data) - success(decodedResult) - } catch { - WPAuthenticatorLogError("Error parsing DomainContactInformation (\(error)): \(response)") - failure(error) - } - }) { (error, _) in - failure(error) - } - } - - public func validateDomainContactInformation(contactInformation: [String: String], - domainNames: [String], - success: @escaping (ValidateDomainContactInformationResponse) -> Void, - failure: @escaping (Error) -> Void) { - let endPoint = "me/domain-contact-information/validate" - let servicePath = path(forEndpoint: endPoint, withVersion: ._1_1) - - let parameters: [String: AnyObject] = ["contact_information": contactInformation as AnyObject, - "domain_names": domainNames as AnyObject] - wordPressComRESTAPI.post( - servicePath, - parameters: parameters, - success: { response, _ in - do { - let data = try JSONSerialization.data(withJSONObject: response, options: .prettyPrinted) - let decodedResult = try JSONDecoder.apiDecoder.decode(ValidateDomainContactInformationResponse.self, from: data) - success(decodedResult) - } catch { - WPAuthenticatorLogError("Error parsing ValidateDomainContactInformationResponse (\(error)): \(response)") - failure(error) - } - }) { (error, _) in - failure(error) - } - } - - public func getDomainSuggestions(request: DomainSuggestionRequest, - success: @escaping ([DomainSuggestion]) -> Void, - failure: @escaping (Error) -> Void) { - let endPoint = "domains/suggestions" - let servicePath = path(forEndpoint: endPoint, withVersion: ._1_1) - var parameters: [String: AnyObject] = [ - "query": request.query as AnyObject - ] - - if let suggestionType = request.suggestionType { - parameters.merge(suggestionType.parameters(), uniquingKeysWith: { $1 }) - } - - if let segmentID = request.segmentID { - parameters["segment_id"] = segmentID as AnyObject - } - - if let quantity = request.quantity { - parameters["quantity"] = quantity as AnyObject - } - - wordPressComRESTAPI.get(servicePath, - parameters: parameters, - success: { - response, _ in - do { - let suggestions = try map(suggestions: response) - success(suggestions) - } catch { - WPAuthenticatorLogError("Error parsing domains response (\(error)): \(response)") - failure(error) - } - }, failure: { - error, _ in - failure(error) - }) - } -} - -private func map(suggestions response: Any) throws -> [DomainSuggestion] { - guard let jsonSuggestions = response as? [[String: AnyObject]] else { - throw DomainsServiceRemote.ResponseError.decodingFailed - } - - var suggestions: [DomainSuggestion] = [] - for jsonSuggestion in jsonSuggestions { - do { - let suggestion = try DomainSuggestion(json: jsonSuggestion) - suggestions.append(suggestion) - } - } - return suggestions -} - -private func mapDomainsResponse(_ response: Any) throws -> [RemoteDomain] { - guard let json = response as? [String: AnyObject], - let domainsJson = json["domains"] as? [[String: AnyObject]] else { - throw DomainsServiceRemote.ResponseError.decodingFailed - } - - let domains = try domainsJson.map { domainJson -> RemoteDomain in - - guard let domainName = domainJson["domain"] as? String, - let isPrimary = domainJson["primary_domain"] as? Bool else { - throw DomainsServiceRemote.ResponseError.decodingFailed - } - - let autoRenewing = domainJson["auto_renewing"] as? Bool - let autoRenewalDate = domainJson["auto_renewal_date"] as? String - let expirySoon = domainJson["expiry_soon"] as? Bool - let expired = domainJson["expired"] as? Bool - let expiryDate = domainJson["expiry"] as? String - - return RemoteDomain(domainName: domainName, - isPrimaryDomain: isPrimary, - domainType: domainTypeFromDomainJSON(domainJson), - autoRenewing: autoRenewing, - autoRenewalDate: autoRenewalDate, - expirySoon: expirySoon, - expired: expired, - expiryDate: expiryDate) - } - - return domains -} - -private func domainTypeFromDomainJSON(_ domainJson: [String: AnyObject]) -> DomainType { - if let type = domainJson["type"] as? String, type == "redirect" { - return .siteRedirect - } - - if let wpComDomain = domainJson["wpcom_domain"] as? Bool, wpComDomain == true { - return .wpCom - } - - if let hasRegistration = domainJson["has_registration"] as? Bool, hasRegistration == true { - return .registered - } - - return .mapped -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/GravatarServiceRemote.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/GravatarServiceRemote.swift deleted file mode 100644 index 2f12cb9e217..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/GravatarServiceRemote.swift +++ /dev/null @@ -1,158 +0,0 @@ -import Foundation -import WordPressShared - -/// This ServiceRemote encapsulates all of the interaction with the Gravatar endpoint. -/// -open class GravatarServiceRemote { - let baseGravatarURL = "https://www.gravatar.com/" - - public init() {} - - /// This method fetches the Gravatar profile for the specified email address. - /// - /// - Parameters: - /// - email: The email address of the gravatar profile to fetch. - /// - success: A success block. - /// - failure: A failure block. - /// - open func fetchProfile(_ email: String, success: @escaping ((_ profile: RemoteGravatarProfile) -> Void), failure: @escaping ((_ error: Error?) -> Void)) { - guard let hash = (email as NSString).md5() else { - assertionFailure() - return - } - - fetchProfile(hash: hash, success: success, failure: failure) - } - - /// This method fetches the Gravatar profile for the specified user hash value. - /// - /// - Parameters: - /// - hash: The hash value of the email address of the gravatar profile to fetch. - /// - success: A success block. - /// - failure: A failure block. - /// - open func fetchProfile(hash: String, success: @escaping ((_ profile: RemoteGravatarProfile) -> Void), failure: @escaping ((_ error: Error?) -> Void)) { - let path = baseGravatarURL + hash + ".json" - guard let targetURL = URL(string: path) else { - assertionFailure() - return - } - - let session = URLSession.shared - let task = session.dataTask(with: targetURL) { (data: Data?, _: URLResponse?, error: Error?) in - guard error == nil, let data = data else { - failure(error) - return - } - do { - let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) - - guard let jsonDictionary = jsonData as? [String: [Any]], - let entry = jsonDictionary["entry"], - let profileData = entry.first as? NSDictionary else { - DispatchQueue.main.async { - // This case typically happens when the endpoint does - // successfully return but doesn't find the user. - failure(nil) - } - return - } - - let profile = RemoteGravatarProfile(dictionary: profileData) - DispatchQueue.main.async { - success(profile) - } - return - - } catch { - failure(error) - return - } - } - - task.resume() - } - - /// This method hits the Gravatar Endpoint, and uploads a new image, to be used as profile. - /// - /// - Parameters: - /// - image: The new Gravatar Image, to be uploaded - /// - completion: An optional closure to be executed on completion. - /// - open func uploadImage(_ image: UIImage, accountEmail: String, accountToken: String, completion: ((_ error: NSError?) -> Void)?) { - guard let targetURL = URL(string: UploadParameters.endpointURL) else { - assertionFailure() - return - } - - // Boundary - let boundary = boundaryForRequest() - - // Request - let request = NSMutableURLRequest(url: targetURL) - request.httpMethod = UploadParameters.HTTPMethod - request.setValue("Bearer \(accountToken)", forHTTPHeaderField: "Authorization") - request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") - - // Body - let gravatarData = image.pngData()! - let requestBody = bodyWithGravatarData(gravatarData, account: accountEmail, boundary: boundary) - - // Task - let session = URLSession.shared - let task = session.uploadTask(with: request as URLRequest, from: requestBody, completionHandler: { (_, _, error) in - completion?(error as NSError?) - }) - - task.resume() - } - - // MARK: - Private Helpers - - /// Returns a new (randomized) Boundary String - /// - private func boundaryForRequest() -> String { - return "Boundary-" + UUID().uuidString - } - - /// Returns the Body for a Gravatar Upload OP. - /// - /// - Parameters: - /// - gravatarData: The NSData-Encoded Image - /// - account: The account that will get updated - /// - boundary: The request's Boundary String - /// - /// - Returns: A NSData instance, containing the Request's Payload. - /// - private func bodyWithGravatarData(_ gravatarData: Data, account: String, boundary: String) -> Data { - let body = NSMutableData() - - // Image Payload - body.appendString("--\(boundary)\r\n") - body.appendString("Content-Disposition: form-data; name=\(UploadParameters.imageKey); ") - body.appendString("filename=\(UploadParameters.filename)\r\n") - body.appendString("Content-Type: \(UploadParameters.contentType);\r\n\r\n") - body.append(gravatarData) - body.appendString("\r\n") - - // Account Payload - body.appendString("--\(boundary)\r\n") - body.appendString("Content-Disposition: form-data; name=\"\(UploadParameters.accountKey)\"\r\n\r\n") - body.appendString("\(account)\r\n") - - // EOF! - body.appendString("--\(boundary)--\r\n") - - return body as Data - } - - // MARK: - Private Structs - private struct UploadParameters { - static let endpointURL = "https://api.gravatar.com/v1/upload-image" - static let HTTPMethod = "POST" - static let contentType = "application/octet-stream" - static let filename = "profile.png" - static let imageKey = "filedata" - static let accountKey = "account" - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/PageLayoutServiceRemote.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/PageLayoutServiceRemote.swift deleted file mode 100644 index 53400558364..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/PageLayoutServiceRemote.swift +++ /dev/null @@ -1,32 +0,0 @@ -import Foundation - -public class PageLayoutServiceRemote { - - public typealias CompletionHandler = (Swift.Result) -> Void - public static func fetchLayouts(_ api: WordPressComRestApi, forBlogID blogID: Int?, withParameters parameters: [String: AnyObject]?, completion: @escaping CompletionHandler) { - let urlPath: String - if let blogID = blogID { - urlPath = "/wpcom/v2/sites/\(blogID)/block-layouts" - } else { - urlPath = "/wpcom/v2/common-block-layouts" - } - - api.GET(urlPath, parameters: parameters, success: { (responseObject, _) in - guard let result = parseLayouts(fromResponse: responseObject) else { - let error = NSError(domain: "PageLayoutService", code: 0, userInfo: [NSDebugDescriptionErrorKey: "Unable to parse response"]) - completion(.failure(error)) - return - } - completion(.success(result)) - }, failure: { (error, _) in - completion(.failure(error)) - }) - } - - private static func parseLayouts(fromResponse response: Any) -> RemotePageLayouts? { - guard let data = try? JSONSerialization.data(withJSONObject: response) else { - return nil - } - return try? JSONDecoder().decode(RemotePageLayouts.self, from: data) - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/ThemeServiceRemote.h b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/ThemeServiceRemote.h deleted file mode 100644 index 592213cef42..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/ThemeServiceRemote.h +++ /dev/null @@ -1,156 +0,0 @@ -#import -#import - -@class Blog; -@class RemoteTheme; - -typedef void(^ThemeServiceRemoteSuccessBlock)(void); -typedef void(^ThemeServiceRemoteThemeRequestSuccessBlock)(RemoteTheme *theme); -typedef void(^ThemeServiceRemoteThemesRequestSuccessBlock)(NSArray *themes, BOOL hasMore, NSInteger totalThemeCount); -typedef void(^ThemeServiceRemoteThemeIdentifiersRequestSuccessBlock)(NSArray *themeIdentifiers); -typedef void(^ThemeServiceRemoteFailureBlock)(NSError *error); - -@interface ThemeServiceRemote : ServiceRemoteWordPressComREST - -#pragma mark - Getting themes - -/** - * @brief Gets the active theme for a specific blog. - * - * @param blogId The ID of the blog to get the active theme for. Cannot be nil. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)getActiveThemeForBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -/** - * @brief Gets the list of purchased-theme-identifiers for a blog. - * - * @param blogId The ID of the blog to get the themes for. Cannot be nil. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)getPurchasedThemesForBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeIdentifiersRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -/** - * @brief Gets information for a specific theme. - * - * @param themeId The identifier of the theme to request info for. Cannot be nil. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)getThemeId:(NSString*)themeId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -/** - * @brief Gets the list of WP.com available themes. - * @details Includes premium themes even if not purchased. Don't call this method if the list - * you want to retrieve is for a specific blog. Use getThemesForBlogId instead. - * - * @param freeOnly Only fetch free themes, if false all WP themes will be returned - * @param page Results page to return. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)getWPThemesPage:(NSInteger)page - freeOnly:(BOOL)freeOnly - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -/** - * @brief Gets the list of available themes for a blog. - * @details Includes premium themes even if not purchased. The only difference with the - * regular getThemes method is that legacy themes that are no longer available to new - * blogs, can be accessible for older blogs through this call. This means that - * whenever we need to show the list of themes a blog can use, we should be calling - * this method and not getThemes. - * - * @param blogId The ID of the blog to get the themes for. Cannot be nil. - * @param page Results page to return. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)getThemesForBlogId:(NSNumber *)blogId - page:(NSInteger)page - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -/** - * @brief Gets the list of available custom themes for a blog. - * @details To be used with Jetpack sites, it returns the list of themes uploaded to the site. - * - * @param blogId The ID of the blog to get the themes for. Cannot be nil. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)getCustomThemesForBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -/** - * @brief Gets a list of suggested starter themes for the given site category - * (blog, website, portfolio). - * @details During the site creation process, a list of suggested mobile-friendly starter - * themes is displayed for the selected category. - * - * @param category The category for the site being created. Cannot be nil. - * @param page Results page to return. Cannot be nil. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - */ -- (void)getStartingThemesForCategory:(NSString *)category - page:(NSInteger)page - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -#pragma mark - Activating themes - -/** - * @brief Activates the specified theme for the specified blog. - * - * @param themeId The ID of the theme to activate. Cannot be nil. - * @param blogId The ID of the target blog. Cannot be nil. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)activateThemeId:(NSString*)themeId - forBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - - -/** - * @brief Installs the specified theme on the specified Jetpack blog. - * - * @param themeId The ID of the theme to install. Cannot be nil. - * @param blogId The ID of the target blog. Cannot be nil. - * @param success The success handler. Can be nil. - * @param failure The failure handler. Can be nil. - * - * @returns A progress object that can be used to track progress and/or cancel the task - */ -- (NSProgress *)installThemeId:(NSString*)themeId - forBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure; - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/ThemeServiceRemote.m b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/ThemeServiceRemote.m deleted file mode 100644 index 4eab24187a9..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/ThemeServiceRemote.m +++ /dev/null @@ -1,465 +0,0 @@ -#import "ThemeServiceRemote.h" - -#import "RemoteTheme.h" -#import "WordPressAuthenticator-Swift.h" -@import NSObject_SafeExpectations; - -// Service dictionary keys -static NSString* const ThemeServiceRemoteThemesKey = @"themes"; -static NSString* const ThemeServiceRemoteThemeCountKey = @"found"; -static NSString* const ThemeRequestTierKey = @"tier"; -static NSString* const ThemeRequestTierAllValue = @"all"; -static NSString* const ThemeRequestTierFreeValue = @"free"; -static NSString* const ThemeRequestNumberKey = @"number"; -static NSInteger const ThemeRequestNumberValue = 50; -static NSString* const ThemeRequestPageKey = @"page"; - -@implementation ThemeServiceRemote - -#pragma mark - Getting themes - -- (NSProgress *)getActiveThemeForBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert([blogId isKindOfClass:[NSNumber class]]); - - NSString *path = [NSString stringWithFormat:@"sites/%@/themes/mine", blogId]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSProgress *progress = [self.wordPressComRESTAPI get:requestUrl - parameters:nil - success:^(NSDictionary *themeDictionary, NSHTTPURLResponse *httpResponse) { - if (success) { - RemoteTheme *theme = [self themeFromDictionary:themeDictionary]; - theme.active = YES; - success(theme); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; - - return progress; -} - -- (NSProgress *)getPurchasedThemesForBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeIdentifiersRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert([blogId isKindOfClass:[NSNumber class]]); - - NSString *path = [NSString stringWithFormat:@"sites/%@/themes/purchased", blogId]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSProgress *progress = [self.wordPressComRESTAPI get:requestUrl - parameters:nil - success:^(NSDictionary *response, NSHTTPURLResponse *httpResponse) { - if (success) { - NSArray *themes = [self themeIdentifiersFromPurchasedThemesRequestResponse:response]; - success(themes); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; - - return progress; -} - -- (NSProgress *)getThemeId:(NSString*)themeId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert([themeId isKindOfClass:[NSString class]]); - - NSString *path = [NSString stringWithFormat:@"themes/%@", themeId]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSProgress *progress = [self.wordPressComRESTAPI get:requestUrl - parameters:nil - success:^(NSDictionary *themeDictionary, NSHTTPURLResponse *httpResponse) { - if (success) { - RemoteTheme *theme = [self themeFromDictionary:themeDictionary]; - success(theme); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; - - return progress; -} - -- (NSProgress *)getWPThemesPage:(NSInteger)page - freeOnly:(BOOL)freeOnly - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert(page > 0); - - NSString *requestUrl = [self pathForEndpoint:@"themes" - withVersion:WordPressComRESTAPIVersion_1_2]; - - NSDictionary *parameters = @{ThemeRequestTierKey: freeOnly ? ThemeRequestTierFreeValue : ThemeRequestTierAllValue, - ThemeRequestNumberKey: @(ThemeRequestNumberValue), - ThemeRequestPageKey: @(page), - }; - - return [self getThemesWithRequestUrl:requestUrl - page:page - parameters:parameters - success:success - failure:failure]; -} - -- (NSProgress *)getThemesPage:(NSInteger)page - path:(NSString *)path - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert(page > 0); - NSParameterAssert([path isKindOfClass:[NSString class]]); - - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_2]; - - NSDictionary *parameters = @{ThemeRequestTierKey: ThemeRequestTierAllValue, - ThemeRequestNumberKey: @(ThemeRequestNumberValue), - ThemeRequestPageKey: @(page), - }; - - return [self getThemesWithRequestUrl:requestUrl - page:page - parameters:parameters - success:success - failure:failure]; -} - -- (NSProgress *)getThemesForBlogId:(NSNumber *)blogId - page:(NSInteger)page - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert([blogId isKindOfClass:[NSNumber class]]); - NSParameterAssert(page > 0); - - NSProgress *progress = [self getThemesForBlogId:blogId - page:page - apiVersion:WordPressComRESTAPIVersion_1_2 - params:@{ThemeRequestTierKey: ThemeRequestTierAllValue} - success:success - failure:failure]; - - return progress; -} - -- (NSProgress *)getCustomThemesForBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - - NSParameterAssert([blogId isKindOfClass:[NSNumber class]]); - - NSProgress *progress = [self getThemesForBlogId:blogId - page:1 - apiVersion:WordPressComRESTAPIVersion_1_0 - params:@{} - success:success - failure:failure]; - - return progress; -} - -- (NSProgress *)getThemesForBlogId:(NSNumber *)blogId - page:(NSInteger)page - apiVersion:(WordPressComRESTAPIVersion) apiVersion - params:(NSDictionary *)params - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - - NSParameterAssert(page > 0); - - NSString *path = [NSString stringWithFormat:@"sites/%@/themes", blogId]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:apiVersion]; - - NSMutableDictionary *parameters = [params mutableCopy]; - parameters[ThemeRequestNumberKey] = @(ThemeRequestNumberValue); - parameters[ThemeRequestPageKey] = @(page); - - return [self getThemesWithRequestUrl:requestUrl - page:page - parameters:parameters - success:success - failure:failure]; -} - -- (void)getStartingThemesForCategory:(NSString *)category - page:(NSInteger)page - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert(page > 0); - NSParameterAssert([category isKindOfClass:[NSString class]]); - - NSString *path = [NSString stringWithFormat:@"themes/?filter=starting-%@", category]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_2]; - - NSDictionary *parameters = @{ - ThemeRequestNumberKey: @(ThemeRequestNumberValue), - ThemeRequestPageKey: @(page), - }; - - [self getThemesWithRequestUrl:requestUrl - page:page - parameters:parameters - success:success - failure:failure]; -} - -- (NSProgress *)getThemesWithRequestUrl:(NSString *)requestUrl - page:(NSInteger)page - parameters:(NSDictionary *)parameters - success:(ThemeServiceRemoteThemesRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - - return [self.wordPressComRESTAPI get:requestUrl - parameters:parameters - success:^(NSDictionary *response, NSHTTPURLResponse *httpResponse) { - if (success) { - NSArray *themes = [self themesFromMultipleThemesRequestResponse:response]; - NSInteger themesLoaded = (page - 1) * ThemeRequestNumberValue; - for (RemoteTheme *theme in themes){ - theme.order = ++themesLoaded; - } - // v1 of the API does not return the found field - NSInteger themesCount = MAX(themes.count, [[response numberForKey:ThemeServiceRemoteThemeCountKey] integerValue]); - BOOL hasMore = themesLoaded < themesCount; - success(themes, hasMore, themesCount); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; -} - -#pragma mark - Activating themes - -- (NSProgress *)activateThemeId:(NSString *)themeId - forBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert([themeId isKindOfClass:[NSString class]]); - NSParameterAssert([blogId isKindOfClass:[NSNumber class]]); - - NSString* const path = [NSString stringWithFormat:@"sites/%@/themes/mine", blogId]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSDictionary* parameters = @{@"theme": themeId}; - - NSProgress *progress = [self.wordPressComRESTAPI post:requestUrl - parameters:parameters - success:^(NSDictionary *themeDictionary, NSHTTPURLResponse *httpResponse) { - if (success) { - RemoteTheme *theme = [self themeFromDictionary:themeDictionary]; - theme.active = YES; - success(theme); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; - - return progress; -} - -- (NSProgress *)installThemeId:(NSString*)themeId - forBlogId:(NSNumber *)blogId - success:(ThemeServiceRemoteThemeRequestSuccessBlock)success - failure:(ThemeServiceRemoteFailureBlock)failure -{ - NSParameterAssert([themeId isKindOfClass:[NSString class]]); - NSParameterAssert([blogId isKindOfClass:[NSNumber class]]); - - NSString* const path = [NSString stringWithFormat:@"sites/%@/themes/%@/install", blogId, themeId]; - NSString *requestUrl = [self pathForEndpoint:path - withVersion:WordPressComRESTAPIVersion_1_1]; - - NSProgress *progress = [self.wordPressComRESTAPI post:requestUrl - parameters:nil - success:^(NSDictionary *themeDictionary, NSHTTPURLResponse *httpResponse) { - if (success) { - RemoteTheme *theme = [self themeFromDictionary:themeDictionary]; - success(theme); - } - } failure:^(NSError *error, NSHTTPURLResponse *httpResponse) { - if (failure) { - failure(error); - } - }]; - return progress; -} - -#pragma mark - Parsing responses - -/** - * @brief Parses a purchased-themes-request response. - * - * @param response The response object. Cannot be nil. - */ -- (NSArray *)themeIdentifiersFromPurchasedThemesRequestResponse:(id)response -{ - NSParameterAssert(response != nil); - - NSArray *themeIdentifiers = [response arrayForKey:ThemeServiceRemoteThemesKey]; - - return themeIdentifiers; -} - -/** - * @brief Parses a generic multi-themes-request response. - * - * @param response The response object. Cannot be nil. - */ -- (NSArray *)themesFromMultipleThemesRequestResponse:(id)response -{ - NSParameterAssert(response != nil); - - NSArray *themeDictionaries = [response arrayForKey:ThemeServiceRemoteThemesKey]; - NSArray *themes = [self themesFromDictionaries:themeDictionaries]; - - return themes; -} - -#pragma mark - Parsing the dictionary replies - -/** - * @brief Creates a remote theme object from the specified dictionary. - * - * @param dictionary The dictionary containing the theme information. Cannot be nil. - * - * @returns A remote theme object. - */ -- (RemoteTheme *)themeFromDictionary:(NSDictionary *)dictionary -{ - NSParameterAssert([dictionary isKindOfClass:[NSDictionary class]]); - - static NSString* const ThemeActiveKey = @"active"; - static NSString* const ThemeTypeKey = @"theme_type"; - static NSString* const ThemeAuthorKey = @"author"; - static NSString* const ThemeAuthorURLKey = @"author_uri"; - static NSString* const ThemeCostPath = @"cost.number"; - static NSString* const ThemeDemoURLKey = @"demo_uri"; - static NSString* const ThemeURL = @"theme_uri"; - static NSString* const ThemeDescriptionKey = @"description"; - static NSString* const ThemeDownloadURLKey = @"download_uri"; - static NSString* const ThemeIdKey = @"id"; - static NSString* const ThemeNameKey = @"name"; - static NSString* const ThemePreviewURLKey = @"preview_url"; - static NSString* const ThemePriceKey = @"price"; - static NSString* const ThemePurchasedKey = @"purchased"; - static NSString* const ThemePopularityRankKey = @"rank_popularity"; - static NSString* const ThemeScreenshotKey = @"screenshot"; - static NSString* const ThemeStylesheetKey = @"stylesheet"; - static NSString* const ThemeTrendingRankKey = @"rank_trending"; - static NSString* const ThemeVersionKey = @"version"; - static NSString* const ThemeDomainPublic = @"pub"; - static NSString* const ThemeDomainPremium = @"premium"; - - RemoteTheme *theme = [RemoteTheme new]; - - [self loadLaunchDateForTheme:theme fromDictionary:dictionary]; - - theme.active = [[dictionary numberForKey:ThemeActiveKey] boolValue]; - theme.type = [dictionary stringForKey:ThemeTypeKey]; - theme.author = [dictionary stringForKey:ThemeAuthorKey]; - theme.authorUrl = [dictionary stringForKey:ThemeAuthorURLKey]; - theme.demoUrl = [dictionary stringForKey:ThemeDemoURLKey]; - theme.themeUrl = [dictionary stringForKey:ThemeURL]; - theme.desc = [dictionary stringForKey:ThemeDescriptionKey]; - theme.downloadUrl = [dictionary stringForKey:ThemeDownloadURLKey]; - theme.name = [dictionary stringForKey:ThemeNameKey]; - theme.popularityRank = [dictionary numberForKey:ThemePopularityRankKey]; - theme.previewUrl = [dictionary stringForKey:ThemePreviewURLKey]; - theme.price = [dictionary stringForKey:ThemePriceKey]; - theme.purchased = [dictionary numberForKey:ThemePurchasedKey]; - theme.screenshotUrl = [dictionary stringForKey:ThemeScreenshotKey]; - theme.stylesheet = [dictionary stringForKey:ThemeStylesheetKey]; - theme.themeId = [dictionary stringForKey:ThemeIdKey]; - theme.trendingRank = [dictionary numberForKey:ThemeTrendingRankKey]; - theme.version = [dictionary stringForKey:ThemeVersionKey]; - - if (!theme.stylesheet) { - NSString *domain = [dictionary numberForKeyPath:ThemeCostPath].intValue > 0 ? ThemeDomainPremium : ThemeDomainPublic; - theme.stylesheet = [NSString stringWithFormat:@"%@/%@", domain, theme.themeId]; - } - - return theme; -} - -/** - * @brief Creates remote theme objects from the specified array of dictionaries. - * - * @param dictionaries The array of dictionaries containing the themes information. Cannot - * be nil. - * - * @returns An array of remote theme objects. - */ -- (NSArray *)themesFromDictionaries:(NSArray *)dictionaries -{ - NSParameterAssert([dictionaries isKindOfClass:[NSArray class]]); - - NSMutableArray *themes = [[NSMutableArray alloc] initWithCapacity:dictionaries.count]; - - for (NSDictionary *dictionary in dictionaries) { - NSAssert([dictionary isKindOfClass:[NSDictionary class]], - @"Expected a dictionary."); - - RemoteTheme *theme = [self themeFromDictionary:dictionary]; - - [themes addObject:theme]; - } - - return [NSArray arrayWithArray:themes]; -} - -#pragma mark - Field parsing - -/** - * @brief Loads a theme's launch date from a dictionary into the specified remote theme - * object. - * - * @param theme The theme to load the info into. Cannot be nil. - * @param dictionary The dictionary to load the info from. Cannot be nil. - */ -- (void)loadLaunchDateForTheme:(RemoteTheme *)theme - fromDictionary:(NSDictionary *)dictionary -{ - NSParameterAssert([theme isKindOfClass:[RemoteTheme class]]); - NSParameterAssert([dictionary isKindOfClass:[NSDictionary class]]); - - static NSString* const ThemeLaunchDateKey = @"date_launched"; - - NSString *launchDateString = [dictionary stringForKey:ThemeLaunchDateKey]; - - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - [formatter setDateFormat:@"yyyy-mm-dd"]; - - theme.launchDate = [formatter dateFromString:launchDateString]; -} - -@end diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/TimeZoneServiceRemote.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/TimeZoneServiceRemote.swift deleted file mode 100644 index 42e4239fa63..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/TimeZoneServiceRemote.swift +++ /dev/null @@ -1,60 +0,0 @@ -import Foundation -import WordPressShared - -public class TimeZoneServiceRemote: ServiceRemoteWordPressComREST { - public enum ResponseError: Error { - case decodingFailed - } - - public func getTimezones(success: @escaping (([TimeZoneGroup]) -> Void), failure: @escaping ((Error) -> Void)) { - let endpoint = "timezones" - let path = self.path(forEndpoint: endpoint, withVersion: ._2_0) - wordPressComRESTAPI.get(path, parameters: nil, success: { (response, _) in - do { - let groups = try self.timezoneGroupsFromResponse(response) - success(groups) - } catch { - failure(error) - } - }) { (error, _) in - failure(error) - } - } -} - -private extension TimeZoneServiceRemote { - func timezoneGroupsFromResponse(_ response: Any) throws -> [TimeZoneGroup] { - guard let response = response as? [String: Any], - let timeZonesByContinent = response["timezones_by_continent"] as? [String: [[String: String]]], - let manualUTCOffsets = response["manual_utc_offsets"] as? [[String: String]] else { - throw ResponseError.decodingFailed - } - let continentGroups: [TimeZoneGroup] = try timeZonesByContinent.map({ - let (groupName, rawZones) = $0 - let zones = try rawZones.map({ try parseNamedTimezone(response: $0) }) - return TimeZoneGroup(name: groupName, timezones: zones) - }).sorted(by: { return $0.name < $1.name }) - - let utcOffsets: [WPTimeZone] = try manualUTCOffsets.map({ try parseOffsetTimezone(response: $0) }) - let utcOffsetsGroup = TimeZoneGroup( - name: NSLocalizedString("Manual Offsets", comment: "Section name for manual offsets in time zone selector"), - timezones: utcOffsets) - return continentGroups + [utcOffsetsGroup] - } - - func parseNamedTimezone(response: [String: String]) throws -> WPTimeZone { - guard let label = response["label"], - let value = response["value"] else { - throw ResponseError.decodingFailed - } - return NamedTimeZone(label: label, value: value) - } - - func parseOffsetTimezone(response: [String: String]) throws -> WPTimeZone { - guard let value = response["value"], - let zone = OffsetTimeZone.fromValue(value) else { - throw ResponseError.decodingFailed - } - return zone - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/TransactionsServiceRemote.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/TransactionsServiceRemote.swift index 1152679f54e..db27745d0a9 100644 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/TransactionsServiceRemote.swift +++ b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/TransactionsServiceRemote.swift @@ -11,31 +11,6 @@ import WordPressShared static let freeDomainPaymentMethod = "WPCOM_Billing_WPCOM" } - @objc public func getSupportedCountries(success: @escaping ([WPCountry]) -> Void, - failure: @escaping (Error) -> Void) { - let endPoint = "me/transactions/supported-countries/" - let servicePath = path(forEndpoint: endPoint, withVersion: ._1_1) - - wordPressComRESTAPI.get(servicePath, - parameters: nil, - success: { - response, _ in - do { - guard let json = response as? [AnyObject] else { - throw ResponseError.decodingFailure - } - let data = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) - let decodedResult = try JSONDecoder.apiDecoder.decode([WPCountry].self, from: data) - success(decodedResult) - } catch { - WPAuthenticatorLogError("Error parsing Supported Countries (\(error)): \(response)") - failure(error) - } - }, failure: { error, _ in - failure(error) - }) - } - /// Creates a shopping cart with products /// - Parameters: /// - siteID: id of the current site @@ -54,11 +29,6 @@ import WordPressShared for product in products { switch product { - case .domain(let domainSuggestion, let privacyProtectionEnabled): - productsDictionary.append(["product_id": domainSuggestion.productID as AnyObject, - "meta": domainSuggestion.domainName as AnyObject, - "extra": ["privacy": privacyProtectionEnabled] as AnyObject]) - case .plan(let productId): productsDictionary.append(["product_id": productId as AnyObject]) case .other(let productDict): @@ -110,41 +80,12 @@ import WordPressShared failure(error) } } - - /// Creates a temporary shopping cart for a domain purchase - @available(*, deprecated, message: "Use createShoppingCart(_:) and pass an array of specific products instead") - public func createTemporaryDomainShoppingCart(siteID: Int, - domainSuggestion: DomainSuggestion, - privacyProtectionEnabled: Bool, - success: @escaping (CartResponse) -> Void, - failure: @escaping (Error) -> Void) { - createShoppingCart(siteID: siteID, - products: [.domain(domainSuggestion, privacyProtectionEnabled)], - temporary: true, - success: success, - failure: failure) - } - - /// Creates a persistent shopping cart for a domain purchase - @available(*, deprecated, message: "Use createShoppingCart(_:) and pass an array of specific products instead") - public func createPersistentDomainShoppingCart(siteID: Int, - domainSuggestion: DomainSuggestion, - privacyProtectionEnabled: Bool, - success: @escaping (CartResponse) -> Void, - failure: @escaping (Error) -> Void) { - createShoppingCart(siteID: siteID, - products: [.domain(domainSuggestion, privacyProtectionEnabled)], - temporary: false, - success: success, - failure: failure) - } } public enum TransactionsServiceProduct { public typealias ProductId = Int public typealias PrivacyProtection = Bool - case domain(DomainSuggestion, PrivacyProtection) case plan(ProductId) case other([String: AnyObject]) } diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteCreation.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteCreation.swift deleted file mode 100644 index 0d3ebfd9316..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteCreation.swift +++ /dev/null @@ -1,259 +0,0 @@ -import Foundation - -// MARK: - SiteCreationRequest - -/// This value type is intended to express a site creation request. -/// -public struct SiteCreationRequest: Encodable { - public let segmentIdentifier: Int64? - public let verticalIdentifier: String? - public let title: String - public let tagline: String? - public let siteURLString: String - public let isPublic: Bool - public let languageIdentifier: String - public let shouldValidate: Bool - public let clientIdentifier: String - public let clientSecret: String - public let siteDesign: String? - public let timezoneIdentifier: String? - public let siteCreationFlow: String? - public let findAvailableURL: Bool - - public init(segmentIdentifier: Int64?, - siteDesign: String?, - verticalIdentifier: String?, - title: String, - tagline: String?, - siteURLString: String, - isPublic: Bool, - languageIdentifier: String, - shouldValidate: Bool, - clientIdentifier: String, - clientSecret: String, - timezoneIdentifier: String?, - siteCreationFlow: String?, - findAvailableURL: Bool) { - - self.segmentIdentifier = segmentIdentifier - self.siteDesign = siteDesign - self.verticalIdentifier = verticalIdentifier - self.title = title - self.tagline = tagline - self.siteURLString = siteURLString - self.isPublic = isPublic - self.languageIdentifier = languageIdentifier - self.shouldValidate = shouldValidate - self.clientIdentifier = clientIdentifier - self.clientSecret = clientSecret - self.timezoneIdentifier = timezoneIdentifier - self.siteCreationFlow = siteCreationFlow - self.findAvailableURL = findAvailableURL - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - try container.encode(clientIdentifier, forKey: .clientIdentifier) - try container.encode(clientSecret, forKey: .clientSecret) - try container.encode(languageIdentifier, forKey: .languageIdentifier) - try container.encode(shouldValidate, forKey: .shouldValidate) - try container.encode(siteURLString, forKey: .siteURLString) - try container.encode(title, forKey: .title) - try container.encode(findAvailableURL, forKey: .findAvailableURL) - - let publicValue = isPublic ? 1 : 0 - try container.encode(publicValue, forKey: .isPublic) - - let siteInfo: SiteInformation? - if let tagline = tagline { - siteInfo = SiteInformation(tagline: tagline) - } else { - siteInfo = nil - } - let options = SiteCreationOptions(segmentIdentifier: segmentIdentifier, - verticalIdentifier: verticalIdentifier, - siteInformation: siteInfo, - siteDesign: siteDesign, - timezoneIdentifier: timezoneIdentifier, - siteCreationFlow: siteCreationFlow) - - try container.encode(options, forKey: .options) - } - - private enum CodingKeys: String, CodingKey { - case clientIdentifier = "client_id" - case clientSecret = "client_secret" - case languageIdentifier = "lang_id" - case isPublic = "public" - case shouldValidate = "validate" - case siteURLString = "blog_name" - case title = "blog_title" - case options = "options" - case findAvailableURL = "find_available_url" - } -} - -private struct SiteCreationOptions: Encodable { - let segmentIdentifier: Int64? - let verticalIdentifier: String? - let siteInformation: SiteInformation? - let siteDesign: String? - let timezoneIdentifier: String? - let siteCreationFlow: String? - - enum CodingKeys: String, CodingKey { - case segmentIdentifier = "site_segment" - case verticalIdentifier = "site_vertical" - case siteInformation = "site_information" - case siteDesign = "template" - case timezoneIdentifier = "timezone_string" - case siteCreationFlow = "site_creation_flow" - } -} - -private struct SiteInformation: Encodable { - let tagline: String? - - enum CodingKeys: String, CodingKey { - case tagline = "site_tagline" - } -} - -// MARK: - SiteCreationResponse - -/// This value type is intended to express a site creation response. -/// -public struct SiteCreationResponse: Decodable { - public let createdSite: CreatedSite - public let success: Bool - - enum CodingKeys: String, CodingKey { - case createdSite = "blog_details" - case success - } -} - -/// This value type describes the site that was created. -/// -public struct CreatedSite: Decodable { - public let identifier: String - public let title: String - public let urlString: String - public let xmlrpcString: String - - enum CodingKeys: String, CodingKey { - case identifier = "blogid" - case title = "blogname" - case urlString = "url" - case xmlrpcString = "xmlrpc" - } -} - -// MARK: - WordPressComServiceRemote (Site Creation) - -/// Describes the errors that could arise during the process of site creation. -/// -/// - requestEncodingFailure: unable to encode the request parameters. -/// - responseDecodingFailure: unable to decode the server response. -/// - serviceFailure: the service returned an unexpected error. -/// -public enum SiteCreationError: Error { - case requestEncodingFailure - case responseDecodingFailure - case serviceFailure -} - -/// Advises the caller of results related to site creation requests. -/// -/// - success: the site creation request succeeded with the accompanying result. -/// - failure: the site creation request failed due to the accompanying error. -/// -public enum SiteCreationResult { - case success(SiteCreationResponse) - case failure(SiteCreationError) -} - -public typealias SiteCreationResultHandler = ((SiteCreationResult) -> Void) - -/// Site creation services, exclusive to WordPress.com. -/// -public extension WordPressComServiceRemote { - - /// Initiates a request to create a new WPCOM site. - /// - /// - Parameters: - /// - request: the value object with which to compose the request. - /// - completion: a closure including the result of the site creation attempt. - /// - func createWPComSite(request: SiteCreationRequest, completion: @escaping SiteCreationResultHandler) { - - let endpoint = "sites/new" - let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) - - let requestParameters: [String: AnyObject] - do { - requestParameters = try encodeRequestParameters(request: request) - } catch { - WPAuthenticatorLogError("Failed to encode \(SiteCreationRequest.self) : \(error)") - - completion(.failure(SiteCreationError.requestEncodingFailure)) - return - } - - wordPressComRESTAPI.post( - path, - parameters: requestParameters, - success: { [weak self] responseObject, httpResponse in - WPAuthenticatorLogInfo("\(responseObject) | \(String(describing: httpResponse))") - - guard let self = self else { - return - } - - do { - let response = try self.decodeResponse(responseObject: responseObject) - completion(.success(response)) - } catch { - WPAuthenticatorLogError("Failed to decode \(SiteCreationResponse.self) : \(error.localizedDescription)") - completion(.failure(SiteCreationError.responseDecodingFailure)) - } - }, - failure: { error, httpResponse in - WPAuthenticatorLogError("\(error) | \(String(describing: httpResponse))") - completion(.failure(SiteCreationError.serviceFailure)) - }) - } -} - -// MARK: - Serialization support - -private extension WordPressComServiceRemote { - - func encodeRequestParameters(request: SiteCreationRequest) throws -> [String: AnyObject] { - - let encoder = JSONEncoder() - - let jsonData = try encoder.encode(request) - let serializedJSON = try JSONSerialization.jsonObject(with: jsonData, options: []) - - let requestParameters: [String: AnyObject] - if let jsonDictionary = serializedJSON as? [String: AnyObject] { - requestParameters = jsonDictionary - } else { - requestParameters = [:] - } - - return requestParameters - } - - func decodeResponse(responseObject: Any) throws -> SiteCreationResponse { - - let decoder = JSONDecoder() - - let data = try JSONSerialization.data(withJSONObject: responseObject, options: []) - let response = try decoder.decode(SiteCreationResponse.self, from: data) - - return response - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteSegments.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteSegments.swift deleted file mode 100644 index b98abd1eabc..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteSegments.swift +++ /dev/null @@ -1,138 +0,0 @@ -/// Models a type of site. -public struct SiteSegment { - public let identifier: Int64 // we use a numeric ID for segments; see p9wMUP-bH-612-p2 for discussion - public let title: String - public let subtitle: String - public let icon: URL? - public let iconColor: String? - public let mobile: Bool - - public init(identifier: Int64, title: String, subtitle: String, icon: URL?, iconColor: String?, mobile: Bool) { - self.identifier = identifier - self.title = title - self.subtitle = subtitle - self.icon = icon - self.iconColor = iconColor - self.mobile = mobile - } -} - -extension SiteSegment: Equatable { - public static func ==(lhs: SiteSegment, rhs: SiteSegment) -> Bool { - return lhs.identifier == rhs.identifier - } -} - -extension SiteSegment: Decodable { - enum CodingKeys: String, CodingKey { - case segmentId = "id" - case segmentTypeTitle = "segment_type_title" - case segmentTypeSubtitle = "segment_type_subtitle" - case iconURL = "icon_URL" - case iconColor = "icon_color" - case mobile = "mobile" - } - - public init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - identifier = try values.decode(Int64.self, forKey: .segmentId) - title = try values.decode(String.self, forKey: .segmentTypeTitle) - subtitle = try values.decode(String.self, forKey: .segmentTypeSubtitle) - if let iconString = try values.decodeIfPresent(String.self, forKey: .iconURL) { - icon = URL(string: iconString) - } else { - icon = nil - } - - if let iconColorString = try values.decodeIfPresent(String.self, forKey: .iconColor) { - var cleanIconColorString = iconColorString - if iconColorString.hasPrefix("#") { - cleanIconColorString = String(iconColorString.dropFirst(1)) - } - - iconColor = cleanIconColorString - } else { - iconColor = nil - } - - mobile = try values.decode(Bool.self, forKey: .mobile) - - } -} - -// MARK: - WordPressComServiceRemote (Site Segments) - -/// Describes the errors that could arise when searching for site verticals. -/// -/// - requestEncodingFailure: unable to encode the request parameters. -/// - responseDecodingFailure: unable to decode the server response. -/// - serviceFailure: the service returned an unexpected error. -/// -public enum SiteSegmentsError: Error { - case requestEncodingFailure - case responseDecodingFailure - case serviceFailure -} - -/// Advises the caller of results related to requests for site segments. -/// -/// - success: the site segments request succeeded with the accompanying result. -/// - failure: the site segments request failed due to the accompanying error. -/// -public enum SiteSegmentsResult { - case success([SiteSegment]) - case failure(SiteSegmentsError) -} - -public typealias SiteSegmentsServiceCompletion = (SiteSegmentsResult) -> Void - -/// Site segments service, exclusive to WordPress.com. -/// -public extension WordPressComServiceRemote { - func retrieveSegments(completion: @escaping SiteSegmentsServiceCompletion) { - let endpoint = "segments" - let remotePath = path(forEndpoint: endpoint, withVersion: ._2_0) - - wordPressComRESTAPI.get( - remotePath, - parameters: nil, - success: { [weak self] responseObject, httpResponse in - WPAuthenticatorLogInfo("\(responseObject) | \(String(describing: httpResponse))") - - guard let self = self else { - return - } - - do { - let response = try self.decodeResponse(responseObject: responseObject) - let validContent = self.validSegments(response) - completion(.success(validContent)) - } catch { - WPAuthenticatorLogError("Failed to decode \([SiteVertical].self) : \(error.localizedDescription)") - completion(.failure(SiteSegmentsError.responseDecodingFailure)) - } - }, - failure: { error, httpResponse in - WPAuthenticatorLogError("\(error) | \(String(describing: httpResponse))") - completion(.failure(SiteSegmentsError.serviceFailure)) - }) - } -} - -// MARK: - Serialization support - -private extension WordPressComServiceRemote { - private func decodeResponse(responseObject: Any) throws -> [SiteSegment] { - let decoder = JSONDecoder() - let data = try JSONSerialization.data(withJSONObject: responseObject, options: []) - let response = try decoder.decode([SiteSegment].self, from: data) - - return response - } - - private func validSegments(_ allSegments: [SiteSegment]) -> [SiteSegment] { - return allSegments.filter { - return $0.mobile == true - } - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteVerticals.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteVerticals.swift deleted file mode 100644 index 529c7a6f3d4..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteVerticals.swift +++ /dev/null @@ -1,150 +0,0 @@ -import Foundation - -// MARK: - SiteVerticalsRequest - -/// Allows the construction of a request for site verticals. -/// -/// NB: The default limit (5) applies to the number of results returned by the service. If a search with limit n evinces no exact match, (n - 1) server-unique results are returned. -/// -public struct SiteVerticalsRequest: Encodable { - public let search: String - public let limit: Int - - public init(search: String, limit: Int = 5) { - self.search = search - self.limit = limit - } -} - -// MARK: - SiteVertical(s) : Response - -/// Models a Site Vertical -/// -public struct SiteVertical: Decodable, Equatable { - public let identifier: String // vertical IDs mix parent/child taxonomy (String) - public let title: String - public let isNew: Bool - - public init(identifier: String, - title: String, - isNew: Bool) { - - self.identifier = identifier - self.title = title - self.isNew = isNew - } - - private enum CodingKeys: String, CodingKey { - case identifier = "vertical_id" - case title = "vertical_name" - case isNew = "is_user_input_vertical" - } -} - -// MARK: - WordPressComServiceRemote (Site Verticals) - -/// Describes the errors that could arise when searching for site verticals. -/// -/// - requestEncodingFailure: unable to encode the request parameters. -/// - responseDecodingFailure: unable to decode the server response. -/// - serviceFailure: the service returned an unexpected error. -/// -public enum SiteVerticalsError: Error { - case requestEncodingFailure - case responseDecodingFailure - case serviceFailure -} - -/// Advises the caller of results related to requests for site verticals. -/// -/// - success: the site verticals request succeeded with the accompanying result. -/// - failure: the site verticals request failed due to the accompanying error. -/// -public enum SiteVerticalsResult { - case success([SiteVertical]) - case failure(SiteVerticalsError) -} - -public typealias SiteVerticalsServiceCompletion = ((SiteVerticalsResult) -> Void) - -/// Site verticals services, exclusive to WordPress.com. -/// -public extension WordPressComServiceRemote { - - /// Retrieves Verticals matching the specified criteria. - /// - /// - Parameters: - /// - request: the value object with which to compose the request. - /// - completion: a closure including the result of the request for site verticals. - /// - func retrieveVerticals(request: SiteVerticalsRequest, completion: @escaping SiteVerticalsServiceCompletion) { - - let endpoint = "verticals" - let path = self.path(forEndpoint: endpoint, withVersion: ._2_0) - - let requestParameters: [String: AnyObject] - do { - requestParameters = try encodeRequestParameters(request: request) - } catch { - WPAuthenticatorLogError("Failed to encode \(SiteCreationRequest.self) : \(error)") - - completion(.failure(SiteVerticalsError.requestEncodingFailure)) - return - } - - wordPressComRESTAPI.get( - path, - parameters: requestParameters, - success: { [weak self] responseObject, httpResponse in - WPAuthenticatorLogInfo("\(responseObject) | \(String(describing: httpResponse))") - - guard let self = self else { - return - } - - do { - let response = try self.decodeResponse(responseObject: responseObject) - completion(.success(response)) - } catch { - WPAuthenticatorLogError("Failed to decode \([SiteVertical].self) : \(error.localizedDescription)") - completion(.failure(SiteVerticalsError.responseDecodingFailure)) - } - }, - failure: { error, httpResponse in - WPAuthenticatorLogError("\(error) | \(String(describing: httpResponse))") - completion(.failure(SiteVerticalsError.serviceFailure)) - }) - } -} - -// MARK: - Serialization support - -private extension WordPressComServiceRemote { - - func encodeRequestParameters(request: SiteVerticalsRequest) throws -> [String: AnyObject] { - - let encoder = JSONEncoder() - - let jsonData = try encoder.encode(request) - let serializedJSON = try JSONSerialization.jsonObject(with: jsonData, options: []) - - let requestParameters: [String: AnyObject] - if let jsonDictionary = serializedJSON as? [String: AnyObject] { - requestParameters = jsonDictionary - } else { - requestParameters = [:] - } - - return requestParameters - } - - func decodeResponse(responseObject: Any) throws -> [SiteVertical] { - - let decoder = JSONDecoder() - - let data = try JSONSerialization.data(withJSONObject: responseObject, options: []) - let response = try decoder.decode([SiteVertical].self, from: data) - - return response - } -} diff --git a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteVerticalsPrompt.swift b/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteVerticalsPrompt.swift deleted file mode 100644 index fb662c01699..00000000000 --- a/WooCommerce/WordPressAuthenticator/WordPressKit/Services/WordPressComServiceRemote+SiteVerticalsPrompt.swift +++ /dev/null @@ -1,86 +0,0 @@ -import Foundation - -// MARK: - Site Verticals Prompt : Request - -public typealias SiteVerticalsPromptRequest = Int64 - -// MARK: - Site Verticals Prompt : Response - -public struct SiteVerticalsPrompt: Decodable { - public let title: String - public let subtitle: String - public let hint: String - - public init(title: String, subtitle: String, hint: String) { - self.title = title - self.subtitle = subtitle - self.hint = hint - } - - private enum CodingKeys: String, CodingKey { - case title = "site_topic_header" - case subtitle = "site_topic_subheader" - case hint = "site_topic_placeholder" - } -} - -public typealias SiteVerticalsPromptServiceCompletion = ((SiteVerticalsPrompt?) -> Void) - -/// Site verticals services, exclusive to WordPress.com. -/// -public extension WordPressComServiceRemote { - - /// Retrieves the prompt information presented to users when searching Verticals. - /// - /// - Parameters: - /// - request: the value object with which to compose the request. - /// - completion: a closure including the result of the request for site verticals. - /// - func retrieveVerticalsPrompt(request: SiteVerticalsPromptRequest, completion: @escaping SiteVerticalsPromptServiceCompletion) { - - let endpoint = "verticals/prompt" - let path = self.path(forEndpoint: endpoint, withVersion: ._2_0) - - let requestParameters: [String: AnyObject] = [ - "segment_id": request as AnyObject - ] - - wordPressComRESTAPI.get( - path, - parameters: requestParameters, - success: { [weak self] responseObject, httpResponse in - WPAuthenticatorLogInfo("\(responseObject) | \(String(describing: httpResponse))") - - guard let self = self else { - return - } - - do { - let response = try self.decodeResponse(responseObject: responseObject) - completion(response) - } catch { - WPAuthenticatorLogError("Failed to decode SiteVerticalsPrompt : \(error.localizedDescription)") - completion(nil) - } - }, - failure: { error, httpResponse in - WPAuthenticatorLogError("\(error) | \(String(describing: httpResponse))") - completion(nil) - }) - } -} - -// MARK: - Serialization support -// -private extension WordPressComServiceRemote { - - func decodeResponse(responseObject: Any) throws -> SiteVerticalsPrompt { - - let decoder = JSONDecoder() - - let data = try JSONSerialization.data(withJSONObject: responseObject, options: []) - let response = try decoder.decode(SiteVerticalsPrompt.self, from: data) - - return response - } -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/Domains/get-all-domains-response.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/Domains/get-all-domains-response.json deleted file mode 100644 index f338801e9cb..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/Domains/get-all-domains-response.json +++ /dev/null @@ -1,180 +0,0 @@ -{ - "domains": [ - { - "domain": "example1.com", - "blog_id": 12345, - "blog_name": "Example Blog 1", - "type": "redirect", - "is_domain_only_site": false, - "is_wpcom_staging_domain": false, - "has_registration": true, - "registration_date": "2022-01-01T00:00:00+00:00", - "expiry": "2023-01-01T00:00:00+00:00", - "wpcom_domain": false, - "current_user_is_owner": false, - "site_slug": "exampleblog1.wordpress.com", - "domain_status": { - "status": "Active", - "status_type": "success" - } - }, - { - "domain": "sample2.net", - "blog_id": 67890, - "blog_name": "Sample Blog 2", - "type": "mapping", - "is_domain_only_site": true, - "is_wpcom_staging_domain": true, - "has_registration": false, - "registration_date": "2022-02-02T00:00:00+00:00", - "expiry": "2023-02-02T00:00:00+00:00", - "wpcom_domain": true, - "current_user_is_owner": true, - "site_slug": "sampleblog2.wordpress.com", - "domain_status": { - "status": "Expiring soon", - "status_type": "success" - } - }, - { - "domain": "testsite3.org", - "blog_id": 98765, - "blog_name": "Test Site 3", - "type": "mapping", - "is_domain_only_site": false, - "is_wpcom_staging_domain": false, - "has_registration": true, - "registration_date": "2022-03-03T00:00:00+00:00", - "expiry": "2023-03-03T00:00:00+00:00", - "wpcom_domain": false, - "current_user_is_owner": true, - "site_slug": "testsite3.wordpress.com", - "domain_status": { - "status": "Error", - "status_type": "error" - } - }, - { - "domain": "demo4.com", - "blog_id": 54321, - "blog_name": "Demo Blog 4", - "type": "mapping", - "is_domain_only_site": false, - "is_wpcom_staging_domain": false, - "has_registration": false, - "registration_date": "2022-04-04T00:00:00+00:00", - "expiry": "2023-04-04T00:00:00+00:00", - "wpcom_domain": false, - "current_user_is_owner": false, - "site_slug": "demoblog4.wordpress.com", - "domain_status": { - "status": "Active", - "status_type": "success" - } - }, - { - "domain": "fake5.net", - "blog_id": 13579, - "blog_name": "Fake Blog 5", - "type": "redirect", - "is_domain_only_site": true, - "is_wpcom_staging_domain": false, - "has_registration": true, - "registration_date": "2022-05-05T00:00:00+00:00", - "expiry": "2023-05-05T00:00:00+00:00", - "wpcom_domain": false, - "current_user_is_owner": true, - "site_slug": "fakeblog5.wordpress.com", - "domain_status": { - "status": "Expired", - "status_type": "success" - } - }, - { - "domain": "mocksite6.org", - "blog_id": 86420, - "blog_name": "Mock Site 6", - "type": "mapping", - "is_domain_only_site": false, - "is_wpcom_staging_domain": false, - "has_registration": true, - "registration_date": "2022-06-06T00:00:00+00:00", - "expiry": "2023-06-06T00:00:00+00:00", - "wpcom_domain": true, - "current_user_is_owner": false, - "site_slug": "mocksite6.wordpress.com", - "domain_status": { - "status": "Active", - "status_type": "success" - } - }, - { - "domain": "example7.com", - "blog_id": 98765, - "blog_name": "Example Blog 7", - "type": "mapping", - "is_domain_only_site": false, - "is_wpcom_staging_domain": true, - "has_registration": false, - "registration_date": "2022-07-07T00:00:00+00:00", - "expiry": "2023-07-07T00:00:00+00:00", - "wpcom_domain": false, - "current_user_is_owner": true, - "site_slug": "exampleblog7.wordpress.com", - "domain_status": { - "status": "Active", - "status_type": "success" - } - }, - { - "domain": "testsite8.net", - "blog_id": 24680, - "blog_name": "Test Site 8", - "type": "redirect", - "is_domain_only_site": true, - "is_wpcom_staging_domain": true, - "has_registration": true, - "registration_date": "2022-08-08T00:00:00+00:00", - "expiry": "2023-08-08T00:00:00+00:00", - "wpcom_domain": false, - "current_user_is_owner": true, - "site_slug": "testsite8.wordpress.com", - "domain_status": { - "status": "Active", - "status_type": "success" - } - }, - { - "domain": "fakesite9.org", - "blog_id": 11111, - "blog_name": "Fake Site 9", - "type": "mapping", - "is_domain_only_site": false, - "is_wpcom_staging_domain": false, - "has_registration": true, - "registration_date": "2022-09-09T00:00:00+00:00", - "expiry": "2023-09-09T00:00:00+00:00", - "wpcom_domain": true, - "current_user_is_owner": false, - "site_slug": "fakesite9.wordpress.com", - "domain_status": { - "status": "Active", - "status_type": "success" - } - }, - { - "domain": "imaginary10.com", - "blog_id": 22222, - "blog_name": "Imaginary Blog 10", - "type": "redirect", - "is_domain_only_site": true, - "is_wpcom_staging_domain": false, - "has_registration": false, - "registration_date": "2022-10-10T00:00:00+00:00", - "expiry": "2023-10-10T00:00:00+00:00", - "wpcom_domain": true, - "current_user_is_owner": false, - "site_slug": "imaginaryblog10.wordpress.com" - } - ] -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-fetch-success.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-fetch-success.json deleted file mode 100644 index a85b2f8e566..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-fetch-success.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "prompts_card_opted_in": true, - "prompts_reminders_opted_in": true, - "reminders_days": { - "monday": false, - "tuesday": true, - "wednesday": false, - "thursday": true, - "friday": false, - "saturday": true, - "sunday": false - }, - "reminders_time": "14.30", - "is_potential_blogging_site": true -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-update-empty-response.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-update-empty-response.json deleted file mode 100644 index abe6693110f..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-update-empty-response.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "updated": [] -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-update-with-response.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-update-with-response.json deleted file mode 100644 index b0b66271cf9..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-settings-update-with-response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "updated": { - "prompts_card_opted_in": false, - "prompts_reminders_opted_in": true, - "reminders_days": { - "monday": true, - "tuesday": false, - "wednesday": true, - "thursday": false, - "friday": true, - "saturday": false, - "sunday": true - }, - "reminders_time": "12.59", - "is_potential_blogging_site": true - } -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-success.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-success.json deleted file mode 100644 index 1ec4c3fc676..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/blogging-prompts-success.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "prompts": [ - { - "id": 239, - "text": "Was there a toy or thing you always wanted as a child, during the holidays or on your birthday, but never received? Tell us about it.", - "title": "Prompt number 1", - "content": "\n

Was there a toy or thing you always wanted as a child, during the holidays or on your birthday, but never received? Tell us about it.

(courtesy of plinky.com)
\n", - "attribution": "dayone", - "date": "2022-05-03", - "answered": false, - "answered_users_count": 0, - "answered_users_sample": [] - }, - { - "id": 248, - "text": "Tell us about a time when you felt out of place.", - "title": "Prompt number 10", - "content": "\n

Tell us about a time when you felt out of place.

(courtesy of plinky.com)
\n", - "attribution": "", - "date": "2021-09-12", - "answered": false, - "answered_users_count": 1, - "answered_users_sample": [ - { - "avatar": "https://0.gravatar.com/avatar/example?s=96&d=identicon&r=G" - } - ] - } - ] -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-contact-information-response-success.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-contact-information-response-success.json deleted file mode 100644 index f55618d0461..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-contact-information-response-success.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "address_1": null, - "address_2": null, - "city" : null, - "country_code" : null, - "email" : "pinar@yahoo.com", - "fax" : null, - "first_name" : "Pinar", - "last_name" : null, - "organization" : null, - "phone": null, - "postal_code" : "12345", - "state" : null -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-all-domain-types.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-all-domain-types.json deleted file mode 100644 index e0343664712..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-all-domain-types.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "domains": [ - { - "primary_domain": true, - "blog_id": 12345, - "domain": "example.com", - "expiry": "2016-11-30T00:00:00+00:00", - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": 1, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": true, - "private_domain": true, - "partner_domain": false, - "wpcom_domain": false, - "has_zone": true, - "type": "mapping", - "registration_date": "November 30, 2015", - "auto_renewal_date": "October 30, 2016", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": true, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - }, - { - "primary_domain": false, - "blog_id": 12345, - "domain": "example2.com", - "expiry": false, - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": false, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": false, - "private_domain": false, - "partner_domain": false, - "wpcom_domain": true, - "has_zone": false, - "type": "wpcom", - "registration_date": "", - "auto_renewal_date": "", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": false, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - }, - { - "primary_domain": false, - "blog_id": 12345, - "domain": "example3.com", - "expiry": false, - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": false, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": false, - "private_domain": false, - "partner_domain": false, - "wpcom_domain": true, - "has_zone": false, - "type": "redirect", - "registration_date": "", - "auto_renewal_date": "", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": false, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - }, - { - "primary_domain": false, - "blog_id": 12345, - "domain": "example4.com", - "expiry": false, - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": false, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": false, - "private_domain": false, - "partner_domain": false, - "wpcom_domain": false, - "has_zone": false, - "type": "mapping", - "registration_date": "", - "auto_renewal_date": "", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": false, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - } - ] -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-bad-json.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-bad-json.json deleted file mode 100644 index bfc2a4f4265..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-bad-json.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "domains": [ - { - "primary_domain": true, - "blog_id": 12345, - "domain": "example.com", - "expiry": "2016-11-30T00:00:00+00:00", - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": 1, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": true, - "private_domain": true, - "partner_domain": false, - "wpcom_domain": false, - "has_zone": true, - "type": "mapping", - "registration_date": "November 30, 2015", - "auto_renewal_date": "October 30, 2016", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": true, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - }, - { - "primary_domain": false, - "blog_id": 12345, - "domain": "example2.com", - "expiry": false, - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": false, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": false, - "private_domain": false, - "partner_domain": false, - "wpcom_domain": true, - "has_zone": false, - "type": "wpcom", - "registration_date": "", - "auto_renewal_date": "", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": false, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - }, - { - "primary_domain": false, - "blog_id": 12345, - "domain": "example3.com", - "expiry": false, - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": false, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": false, - "private_domain": false, - "partner_domain": false, - "wpcom_domain": true, - "has_zone": false, - "type": "redirect", - "registration_date": "", - "auto_renewal_date": "", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": false, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - }, - { - "primary_domain": false, - "blog_id": 12345, - "domain": "example4.com", - "expiry": false, - "expiry_soon": false, - "expired": false, - "new_registration": false, - "auto_renewing": false, - "pending_registration": false, - "pending_registration_time": "", - "has_registration": false, - "private_domain": false, - "partner_domain": false, - "wpcom_domain": false, - "has_zone": false, - "type": "mapping", - "registration_date": "", - "auto_renewal_date": "", - "google_apps_subscription": { - "status": "no_subscription" - }, - "has_private_registration": false, - "is_pending_icann_verification": false, - "manual_transfer_required": false, - "can_set_as_primary": true - } diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-empty.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-empty.json deleted file mode 100644 index c9ab2edc108..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-empty.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "domains": [ - ] -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-invalid-query.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-invalid-query.json deleted file mode 100644 index 384365e9f24..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/domain-service-invalid-query.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "error": "invalid_query", - "message": "Domain searches only support the following characters (many accents are also allowed): A-Z, a-z, 0-9, -, ., space. You searched for the following unsupported characters: t" -} diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-multiple-themes-v1.2.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-multiple-themes-v1.2.json deleted file mode 100644 index 94f320029b1..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-multiple-themes-v1.2.json +++ /dev/null @@ -1 +0,0 @@ -{"themes":[{"id":"melody","author":"Nudge Themes","screenshot":"https:\/\/i2.wp.com\/s0.wp.com\/wp-content\/themes\/premium\/melody\/screenshot.png","author_uri":"http:\/\/nudgethemes.com","demo_uri":"https:\/\/melodydemo.wordpress.com\/","name":"Melody","stylesheet":"premium\/melody","price":"C$93"},{"id":"jason","author":"PixelGrade","screenshot":"https:\/\/i2.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/jason\/screenshot.png","author_uri":"https:\/\/pixelgrade.com\/","demo_uri":"https:\/\/jasondemo.wordpress.com\/","name":"Jason","stylesheet":"premium\/jason","price":"C$169"},{"id":"veggie","author":"Anariel Design","screenshot":"https:\/\/i0.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/veggie\/screenshot.png","author_uri":"http:\/\/theme.wordpress.com\/themes\/by\/anariel-design\/","demo_uri":"https:\/\/veggiedemo.wordpress.com\/","name":"Veggie","stylesheet":"premium\/veggie","price":"C$107"},{"id":"sapor","author":"Automattic","screenshot":"https:\/\/i0.wp.com\/theme.wordpress.com\/wp-content\/themes\/pub\/sapor\/screenshot.png","author_uri":"http:\/\/wordpress.com\/themes","demo_uri":"https:\/\/sapordemo.wordpress.com\/","name":"Sapor","stylesheet":"pub\/sapor"},{"id":"corporate","author":"Professional Themes","screenshot":"https:\/\/i2.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/corporate\/screenshot.png","author_uri":"http:\/\/professionalthemes.nyc\/","demo_uri":"https:\/\/corporatethemedemo.wordpress.com\/","name":"Corporate","stylesheet":"premium\/corporate","price":"C$236"},{"id":"restaurant","author":"Organic Themes","screenshot":"https:\/\/i0.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/restaurant\/screenshot.png","author_uri":"http:\/\/www.organicthemes.com","demo_uri":"https:\/\/restaurantthemedemo.wordpress.com\/","name":"Restaurant","stylesheet":"premium\/restaurant","price":"C$93"},{"id":"anemone","author":"DesignOrbital","screenshot":"https:\/\/i1.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/anemone\/screenshot.png","author_uri":"http:\/\/designorbital.com\/","demo_uri":"https:\/\/anemonedemo.wordpress.com\/","name":"Anemone","stylesheet":"premium\/anemone","price":"C$101"},{"id":"qua","author":"Graph Paper Press","screenshot":"https:\/\/i1.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/qua\/screenshot.png","author_uri":"http:\/\/graphpaperpress.com","demo_uri":"https:\/\/quademo.wordpress.com\/","name":"Qua","stylesheet":"premium\/qua","price":"C$107"},{"id":"watermark","author":"Array","screenshot":"https:\/\/i2.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/watermark\/screenshot.png","author_uri":"https:\/\/array.is\/","demo_uri":"https:\/\/watermarkdemo.wordpress.com\/","name":"Watermark","stylesheet":"premium\/watermark","price":"C$93"},{"id":"silvio","author":"SiloCreativo","screenshot":"https:\/\/i1.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/silvio\/screenshot.png","author_uri":"http:\/\/www.silocreativo.com","demo_uri":"https:\/\/silviodemo.wordpress.com\/","name":"Silvio","stylesheet":"premium\/silvio","price":"C$101"},{"id":"franklin","author":"Michael Burrows","screenshot":"https:\/\/i0.wp.com\/theme.wordpress.com\/wp-content\/themes\/pub\/franklin\/screenshot.png","author_uri":"http:\/\/www.wpmultiverse.com\/","demo_uri":"https:\/\/franklindemo.wordpress.com\/","name":"Franklin","stylesheet":"pub\/franklin"},{"id":"colinear","author":"Automattic","screenshot":"https:\/\/i0.wp.com\/theme.wordpress.com\/wp-content\/themes\/pub\/colinear\/screenshot.png","author_uri":"https:\/\/wordpress.com\/themes\/","demo_uri":"https:\/\/colineardemo.wordpress.com\/","name":"Colinear","stylesheet":"pub\/colinear"},{"id":"paulie","author":"SiloCreativo","screenshot":"https:\/\/i2.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/paulie\/screenshot.png","author_uri":"http:\/\/www.silocreativo.com","demo_uri":"https:\/\/pauliedemo.wordpress.com\/","name":"Paulie","stylesheet":"premium\/paulie","price":"C$66"},{"id":"exhibit","author":"Pro Theme Design","screenshot":"https:\/\/i1.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/exhibit\/screenshot.png","author_uri":"http:\/\/theme.wordpress.com\/themes\/by\/pro-theme-design\/","demo_uri":"https:\/\/exhibitdemo.wordpress.com\/","name":"Exhibit","stylesheet":"premium\/exhibit","price":"C$107"},{"id":"huesos","author":"Cedaro","screenshot":"https:\/\/i1.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/huesos\/screenshot.png","author_uri":"http:\/\/www.cedaro.com\/","demo_uri":"https:\/\/huesosdemo.wordpress.com\/","name":"Huesos","stylesheet":"premium\/huesos","price":"C$107"},{"id":"independent-publisher","author":"Raam Dev","screenshot":"https:\/\/i2.wp.com\/theme.wordpress.com\/wp-content\/themes\/pub\/independent-publisher\/screenshot.png","author_uri":"http:\/\/raamdev.com\/","demo_uri":"https:\/\/independentpublisherdemo.wordpress.com\/","name":"Independent Publisher","stylesheet":"pub\/independent-publisher"},{"id":"blask","author":"Automattic","screenshot":"https:\/\/i1.wp.com\/theme.wordpress.com\/wp-content\/themes\/pub\/blask\/screenshot.png","author_uri":"http:\/\/wordpress.com","demo_uri":"https:\/\/blaskdemo.wordpress.com\/","name":"Blask","stylesheet":"pub\/blask"},{"id":"blink","author":"Codestag","screenshot":"https:\/\/i1.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/blink\/screenshot.png","author_uri":"https:\/\/codestag.com\/","demo_uri":"https:\/\/blinkdemo.wordpress.com\/","name":"Blink","stylesheet":"premium\/blink","price":"C$74"},{"id":"maisha","author":"Anariel Design","screenshot":"https:\/\/i0.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/maisha\/screenshot.png","author_uri":"http:\/\/theme.wordpress.com\/themes\/by\/anariel-design\/","demo_uri":"https:\/\/maishademo.wordpress.com\/","name":"Maisha","stylesheet":"premium\/maisha","price":"C$120"},{"id":"appetite","author":"Tasko","screenshot":"https:\/\/i0.wp.com\/theme.wordpress.com\/wp-content\/themes\/premium\/appetite\/screenshot.png","author_uri":"http:\/\/tdwp.us\/","demo_uri":"https:\/\/appetitedemo.wordpress.com\/","name":"Appetite","stylesheet":"premium\/appetite","price":"C$203"}],"found":20} \ No newline at end of file diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-purchased-themes-v1.1.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-purchased-themes-v1.1.json deleted file mode 100644 index 16b9f047ea7..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-purchased-themes-v1.1.json +++ /dev/null @@ -1 +0,0 @@ -{"themes":["a-simpler-time","adventure","album","alto","ampersand","antenna","anthem","appetite","arcade","atlas","atrium","avid","awesome","axon","bailey","basic-maths","basis","beacon","bexley","bindery","blink","blocco","blog-simple","bloggy","blogly","bold-news","bon-vivant","bridger","broadsheet","bromley","business-identity","caldwell","camera","candela","carmela","chalk","chapters","christopher","chronicle","clear-news","cocoa","collections","collective","connect","creative-portfolio","creative","crisp","curator","currents","debut","delicious-magazine","delight","demand","designer","designfolio","dicot","duet","dynamic-news","eight","elemin","encore","espresso","everyday","exhibit","finder","flora-and-fauna","forefront","fortune","fresh-news","full-frame","funki","further","gallery","gigawatt","gridiculous-pro","gridspace","handmade","headlines","healthy-living","hermes","hive","huesos","huntt","hustle-express","hyalite","infoway","inspiration-laboratory","isca","just-desserts","kent","kiore-moana","ladder","largo","lens","lifestyle","linen","little-story","luscious","magazine","magnate-express","maisha","massive-press","mayer","mellow","mh-magazine","mimbopro","mina-olen","minimum","mirror","modern-news","moka","monet","mood","newsy","nexus","notebook","nowell","nurture","obsidian","on-a-whim","on-demand","onigiri","opti","organization","oslo","outspoken","oxford","patch","paulie","personal","petite-melodies","photographer","photography-classic","photography","photolia","pinboard","pocket","poly","port","portfolio","pretty-young-thing","profile","promenade","publisher","purpose","puzzle","react","romero","scrollider-express","shelf","shrake","simfo","sixteen-nine","snap","soho","solar","soundcheck","standard","studio","suidobashi","sweet-life","swell","tapestry","tdeditor","the-great-adventure","the-parisian","the-writer","thememin","thestyle","traction","traveler","tuned-balloon","ubud","vagabond","veeva","vintage-kitchen","vision","watson","wedding","wire","worldview","yumblog","zuki"],"count":183} \ No newline at end of file diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-single-theme-v1.1.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-single-theme-v1.1.json deleted file mode 100644 index cac920cb5c9..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/get-single-theme-v1.1.json +++ /dev/null @@ -1 +0,0 @@ -{"id":"twentythirteen","screenshot":"https:\/\/i1.wp.com\/s0.wp.com\/wp-content\/themes\/pub\/twentythirteen\/screenshot.png","cost":{"currency":"USD","number":0,"display":""},"version":"1.0.1","download_url":"https:\/\/public-api.wordpress.com\/rest\/v1\/themes\/download\/twentythirteen.zip","trending_rank":44,"popularity_rank":6,"launch_date":"2013-04-24","name":"Twenty Thirteen","description":"The 2013 theme for WordPress takes us back to the blog, featuring a full range of post formats, each displayed beautifully in their own unique way. Design details abound, starting with a vibrant color scheme and matching header images, beautiful typography and icons, and a flexible layout that looks great on any device, big or small.","tags":["black","brown","orange","tan","white","yellow","light","one-column","two-columns","right-sidebar","fluid-layout","responsive-layout","custom-header","custom-menu","editor-style","featured-images","microformats","post-formats","rtl-language-support","sticky-post","translation-ready","accessibility-ready","infinite-scroll","blog","journal","lifestream","tumblelog","abstract","bright","clean","colorful","flamboyant","playful","vibrant"],"preview_url":"https:\/\/diegotest002.wordpress.com\/?theme=pub\/twentythirteen&hide_banners=true"} \ No newline at end of file diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/page-layout-blog-layouts-malformed.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/page-layout-blog-layouts-malformed.json deleted file mode 100644 index 023d2bec83a..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/page-layout-blog-layouts-malformed.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "layouts": [ - { - "slug": "about-4", - "title": "About", - "content": "\n
\n\n\n\n
\"\"
\n
\n\n\n\n

Add Your Name

\n\n\n\n

Add your job title

\n\n\n\n\n\n\n\n

Add more information about yourself. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sit amet eros eget justo elementum interdum. Cras vestibulum nulla id aliquam rutrum. Vestibulum aliquet mauris ut augue ultrices facilisis. Vestibulum pretium ligula sed ipsum dapibus, tempus iaculis felis ornare. Morbi pretium sed est tincidunt hendrerit. Curabitur id elit scelerisque, pharetra tellus sit amet, dictum mi. Aliquam consectetur tristique metus non pulvinar. Donec luctus magna quis justo tincidunt, eu euismod lacus faucibus.

\n\n\n\n
Add What You Do
\n\n\n\n
\n
\n
  • What you do
  • What you do
\n
\n\n\n\n
\n
  • What you do
  • What you do
\n
\n
\n\n\n\n
    \n\n\n\n\n\n\n\n\n\n
\n\n\n\n
\n
\n", - "categories": [ - { - "slug": "about", - "title": "About", - "description": "About pages", - "emoji": "👋" - } - diff --git a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/page-layout-blog-layouts-success.json b/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/page-layout-blog-layouts-success.json deleted file mode 100644 index 8408705c389..00000000000 --- a/WooCommerce/WordPressAuthenticatorTests/WordPressKit/WordPressKitTests/Mock Data/page-layout-blog-layouts-success.json +++ /dev/null @@ -1 +0,0 @@ -{"layouts":[{"slug":"about-4","title":"About","content":"\n
<\/div>\n\n\n\n
\"\"<\/figure>
\n
<\/div>\n\n\n\n

Add Your Name<\/h2>\n\n\n\n

Add your job title<\/p>\n\n\n\n

Contact me<\/a><\/div>\n\n\n\n

Add more information about yourself. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sit amet eros eget justo elementum interdum. Cras vestibulum nulla id aliquam rutrum. Vestibulum aliquet mauris ut augue ultrices facilisis. Vestibulum pretium ligula sed ipsum dapibus, tempus iaculis felis ornare. Morbi pretium sed est tincidunt hendrerit. Curabitur id elit scelerisque, pharetra tellus sit amet, dictum mi. Aliquam consectetur tristique metus non pulvinar. Donec luctus magna quis justo tincidunt, eu euismod lacus faucibus.<\/p>\n\n\n\n

Add What You Do<\/strong><\/h5>\n\n\n\n
\n
\n