Skip to content

Commit 462f0f0

Browse files
authored
Jetpack Setup: Update response for Jetpack connection data request (#15971)
2 parents fe04802 + 3d6c766 commit 462f0f0

File tree

17 files changed

+210
-106
lines changed

17 files changed

+210
-106
lines changed

Modules/Sources/Fakes/Networking.generated.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,18 @@ extension Networking.InboxNote {
631631
)
632632
}
633633
}
634+
extension Networking.JetpackConnectionData {
635+
/// Returns a "ready to use" type filled with fake values.
636+
///
637+
public static func fake() -> Networking.JetpackConnectionData {
638+
.init(
639+
currentUser: .fake(),
640+
isRegistered: .fake(),
641+
connectionOwner: .fake(),
642+
blogID: .fake()
643+
)
644+
}
645+
}
634646
extension Networking.JetpackUser {
635647
/// Returns a "ready to use" type filled with fake values.
636648
///
@@ -640,7 +652,8 @@ extension Networking.JetpackUser {
640652
isPrimary: .fake(),
641653
username: .fake(),
642654
wpcomUser: .fake(),
643-
gravatar: .fake()
655+
gravatar: .fake(),
656+
blogID: .fake()
644657
)
645658
}
646659
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import Codegen
2+
import Foundation
3+
4+
/// Mapper: Jetpack connection data
5+
///
6+
struct JetpackConnectionDataMapper: Mapper {
7+
8+
func map(response: Data) throws -> JetpackConnectionData {
9+
let decoder = JSONDecoder()
10+
return try decoder.decode(JetpackConnectionData.self, from: response)
11+
}
12+
}
13+
14+
/// JetpackConnectionData Disposable Entity:
15+
/// This entity allows us to parse JetpackUser with JSONDecoder.
16+
///
17+
public struct JetpackConnectionData: Decodable, GeneratedFakeable, GeneratedCopiable {
18+
/// The connection state for the authenticated user
19+
public let currentUser: JetpackUser
20+
21+
/// Whether the site is already registered with Jetpack.
22+
/// This field is available only from Jetpack 14.4, so would be nil on older versions.
23+
/// Ref: pe5sF9-401-p2
24+
/// periphery: ignore - used in UI module
25+
public let isRegistered: Bool?
26+
27+
/// Username of the Jetpack connection owner.
28+
/// This field is non-nil for sites that already register a connection with Jetpack.
29+
/// periphery: ignore - used in UI module
30+
public let connectionOwner: String?
31+
32+
/// WP blog ID, available only if site has once connected to Jetpack.
33+
/// periphery: ignore - used in UI module
34+
public let blogID: Int64?
35+
36+
/// periphery: ignore - used by codegen
37+
public init(currentUser: JetpackUser,
38+
isRegistered: Bool?,
39+
connectionOwner: String?,
40+
blogID: Int64?) {
41+
self.currentUser = currentUser
42+
self.isRegistered = isRegistered
43+
self.connectionOwner = connectionOwner
44+
self.blogID = blogID
45+
}
46+
47+
public init(from decoder: Decoder) throws {
48+
let container = try decoder.container(keyedBy: CodingKeys.self)
49+
currentUser = try container.decode(JetpackUser.self, forKey: .currentUser)
50+
isRegistered = try container.decodeIfPresent(Bool.self, forKey: .isRegistered)
51+
connectionOwner = try? container.decodeIfPresent(String.self, forKey: .connectionOwner)
52+
blogID = currentUser.blogID // moved to data for easier access
53+
}
54+
55+
private enum CodingKeys: String, CodingKey {
56+
case currentUser
57+
case isRegistered
58+
case connectionOwner
59+
}
60+
}

Modules/Sources/Networking/Mapper/JetpackUserMapper.swift

Lines changed: 0 additions & 24 deletions
This file was deleted.

Modules/Sources/Networking/Model/Copiable/Models+Copiable.generated.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -994,26 +994,50 @@ extension Networking.InboxNote {
994994
}
995995
}
996996

997+
extension Networking.JetpackConnectionData {
998+
public func copy(
999+
currentUser: CopiableProp<JetpackUser> = .copy,
1000+
isRegistered: NullableCopiableProp<Bool> = .copy,
1001+
connectionOwner: NullableCopiableProp<String> = .copy,
1002+
blogID: NullableCopiableProp<Int64> = .copy
1003+
) -> Networking.JetpackConnectionData {
1004+
let currentUser = currentUser ?? self.currentUser
1005+
let isRegistered = isRegistered ?? self.isRegistered
1006+
let connectionOwner = connectionOwner ?? self.connectionOwner
1007+
let blogID = blogID ?? self.blogID
1008+
1009+
return Networking.JetpackConnectionData(
1010+
currentUser: currentUser,
1011+
isRegistered: isRegistered,
1012+
connectionOwner: connectionOwner,
1013+
blogID: blogID
1014+
)
1015+
}
1016+
}
1017+
9971018
extension Networking.JetpackUser {
9981019
public func copy(
9991020
isConnected: CopiableProp<Bool> = .copy,
10001021
isPrimary: CopiableProp<Bool> = .copy,
10011022
username: CopiableProp<String> = .copy,
10021023
wpcomUser: NullableCopiableProp<DotcomUser> = .copy,
1003-
gravatar: NullableCopiableProp<String> = .copy
1024+
gravatar: NullableCopiableProp<String> = .copy,
1025+
blogID: NullableCopiableProp<Int64> = .copy
10041026
) -> Networking.JetpackUser {
10051027
let isConnected = isConnected ?? self.isConnected
10061028
let isPrimary = isPrimary ?? self.isPrimary
10071029
let username = username ?? self.username
10081030
let wpcomUser = wpcomUser ?? self.wpcomUser
10091031
let gravatar = gravatar ?? self.gravatar
1032+
let blogID = blogID ?? self.blogID
10101033

10111034
return Networking.JetpackUser(
10121035
isConnected: isConnected,
10131036
isPrimary: isPrimary,
10141037
username: username,
10151038
wpcomUser: wpcomUser,
1016-
gravatar: gravatar
1039+
gravatar: gravatar,
1040+
blogID: blogID
10171041
)
10181042
}
10191043
}

Modules/Sources/Networking/Model/JetpackUser.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,23 @@ public struct JetpackUser: Decodable, GeneratedFakeable, GeneratedCopiable {
1919
/// Gravatar link of the user
2020
public let gravatar: String?
2121

22+
/// WP blog ID, available only if site has once connected to Jetpack.
23+
public let blogID: Int64?
24+
2225
/// Member-wise initializer
23-
public init(isConnected: Bool, isPrimary: Bool, username: String, wpcomUser: DotcomUser?, gravatar: String?) {
26+
/// periphery: ignore - used by codegen
27+
public init(isConnected: Bool,
28+
isPrimary: Bool,
29+
username: String,
30+
wpcomUser: DotcomUser?,
31+
gravatar: String?,
32+
blogID: Int64?) {
2433
self.isConnected = isConnected
2534
self.isPrimary = isPrimary
2635
self.username = username
2736
self.wpcomUser = wpcomUser
2837
self.gravatar = gravatar
38+
self.blogID = blogID
2939
}
3040

3141
public init(from decoder: Decoder) throws {
@@ -35,6 +45,7 @@ public struct JetpackUser: Decodable, GeneratedFakeable, GeneratedCopiable {
3545
username = try container.decode(String.self, forKey: .username)
3646
wpcomUser = try? container.decode(DotcomUser.self, forKey: .wpcomUser)
3747
gravatar = try? container.decode(String.self, forKey: .gravatar)
48+
blogID = try? container.decodeIfPresent(Int64.self, forKey: .blogId)
3849
}
3950
}
4051

@@ -48,5 +59,6 @@ private extension JetpackUser {
4859
case username
4960
case wpcomUser
5061
case gravatar
62+
case blogId
5163
}
5264
}

Modules/Sources/Networking/Remote/JetpackConnectionRemote.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ public final class JetpackConnectionRemote: Remote {
4949
enqueue(request, mapper: mapper, completion: completion)
5050
}
5151

52-
/// Fetches the user connection state with the site's Jetpack.
52+
/// Fetches the connection state with the site's Jetpack for the authenticated user.
5353
///
54-
public func fetchJetpackUser(completion: @escaping (Result<JetpackUser, Error>) -> Void) {
55-
let request = RESTRequest(siteURL: siteURL, method: .get, path: Path.jetpackConnectionUser)
56-
let mapper = JetpackUserMapper()
54+
public func fetchJetpackConnectionData(completion: @escaping (Result<JetpackConnectionData, Error>) -> Void) {
55+
let request = RESTRequest(siteURL: siteURL, method: .get, path: Path.jetpackConnectionData)
56+
let mapper = JetpackConnectionDataMapper()
5757
enqueue(request, mapper: mapper, completion: completion)
5858
}
5959
}
@@ -68,7 +68,7 @@ public extension JetpackConnectionRemote {
6868
private extension JetpackConnectionRemote {
6969
enum Path {
7070
static let jetpackConnectionURL = "/jetpack/v4/connection/url"
71-
static let jetpackConnectionUser = "/jetpack/v4/connection/data"
71+
static let jetpackConnectionData = "/jetpack/v4/connection/data"
7272
static let plugins = "/wp/v2/plugins"
7373
static let jetpackModule = "/jetpack/v4/module"
7474
}

Modules/Sources/Yosemite/Actions/JetpackConnectionAction.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public enum JetpackConnectionAction: Action {
1414
case activateJetpackPlugin(completion: (Result<Void, Error>) -> Void)
1515
/// Fetches the URL used for setting up Jetpack connection.
1616
case fetchJetpackConnectionURL(completion: (Result<URL, Error>) -> Void)
17-
/// Fetches the user connection state with the given site's Jetpack.
18-
case fetchJetpackUser(completion: (Result<JetpackUser, Error>) -> Void)
17+
/// Fetches connection state with the given site's Jetpack.
18+
case fetchJetpackConnectionData(completion: (Result<JetpackConnectionData, Error>) -> Void)
1919
/// Fetches the WPCom account with the given network
2020
case loadWPComAccount(network: Network, onCompletion: (Account?) -> Void)
2121
}

Modules/Sources/Yosemite/Model/Model.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public typealias GoogleAdsCampaignStatsTotals = Networking.GoogleAdsCampaignStat
5050
public typealias GoogleAdsCampaignStatsItem = Networking.GoogleAdsCampaignStatsItem
5151
public typealias InboxNote = Networking.InboxNote
5252
public typealias InboxAction = Networking.InboxAction
53-
public typealias JetpackUser = Networking.JetpackUser
53+
public typealias JetpackConnectionData = Networking.JetpackConnectionData
5454
public typealias JustInTimeMessageHook = Networking.JustInTimeMessagesRemote.MessagePath.Hook
5555
public typealias Media = Networking.Media
5656
public typealias MetaContainer = Networking.MetaContainer

Modules/Sources/Yosemite/Stores/JetpackConnectionStore.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public final class JetpackConnectionStore: DeauthenticatedStore {
4040
activateJetpackPlugin(completion: completion)
4141
case .fetchJetpackConnectionURL(let completion):
4242
fetchJetpackConnectionURL(completion: completion)
43-
case .fetchJetpackUser(let completion):
44-
fetchJetpackUser(completion: completion)
43+
case .fetchJetpackConnectionData(let completion):
44+
fetchJetpackConnectionData(completion: completion)
4545
case .loadWPComAccount(let network, let onCompletion):
4646
loadWPComAccount(network: network, onCompletion: onCompletion)
4747
}
@@ -83,8 +83,8 @@ private extension JetpackConnectionStore {
8383
jetpackConnectionRemote?.fetchJetpackConnectionURL(completion: completion)
8484
}
8585

86-
func fetchJetpackUser(completion: @escaping (Result<JetpackUser, Error>) -> Void) {
87-
jetpackConnectionRemote?.fetchJetpackUser(completion: completion)
86+
func fetchJetpackConnectionData(completion: @escaping (Result<JetpackConnectionData, Error>) -> Void) {
87+
jetpackConnectionRemote?.fetchJetpackConnectionData(completion: completion)
8888
}
8989

9090
func loadWPComAccount(network: Network, onCompletion: @escaping (Account?) -> Void) {

Modules/Tests/NetworkingTests/Mapper/JetpackUserMapperTests.swift renamed to Modules/Tests/NetworkingTests/Mapper/JetpackConnectionDataMapperTests.swift

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import XCTest
44

55
/// JetpackUserMapper Unit Tests
66
///
7-
final class JetpackUserMapperTests: XCTestCase {
7+
final class JetpackConnectionDataMapperTests: XCTestCase {
88

99
func test_all_fields_are_parsed_properly_when_user_is_connected() throws {
1010
// Given
11-
let user = try mapUserFromMockResponse()
11+
let data = try mapUserFromMockResponse()
12+
let user = data.currentUser
1213
let wpcomUser = try XCTUnwrap(user.wpcomUser)
1314

1415
// Then
16+
XCTAssertEqual(data.isRegistered, true)
17+
XCTAssertEqual(data.connectionOwner, "testuser")
18+
XCTAssertEqual(data.blogID, 1244634)
19+
1520
XCTAssertEqual(user.username, "admin")
1621
XCTAssertEqual(user.gravatar, "<img alt='' src='http://2.gravatar.com/avatar/5e1a8fhjd'/>")
1722
XCTAssertTrue(user.isPrimary)
@@ -26,9 +31,14 @@ final class JetpackUserMapperTests: XCTestCase {
2631

2732
func test_all_fields_are_parsed_properly_when_user_is_not_connected() throws {
2833
// Given
29-
let user = try mapNotConnectedUserFromMockResponse()
34+
let data = try mapNotConnectedUserFromMockResponse()
35+
let user = data.currentUser
3036

3137
// Then
38+
XCTAssertNil(data.isRegistered)
39+
XCTAssertEqual(data.connectionOwner, "demo")
40+
XCTAssertNil(data.blogID)
41+
3242
XCTAssertFalse(user.isPrimary)
3343
XCTAssertFalse(user.isConnected)
3444
XCTAssertEqual(user.username, "test")
@@ -37,21 +47,21 @@ final class JetpackUserMapperTests: XCTestCase {
3747
}
3848
}
3949

40-
private extension JetpackUserMapperTests {
41-
func mapUserFromMockResponse() throws -> JetpackUser {
50+
private extension JetpackConnectionDataMapperTests {
51+
func mapUserFromMockResponse() throws -> JetpackConnectionData {
4252
guard let response = Loader.contentsOf("jetpack-connected-user") else {
4353
throw FileNotFoundError()
4454
}
4555

46-
return try JetpackUserMapper().map(response: response)
56+
return try JetpackConnectionDataMapper().map(response: response)
4757
}
4858

49-
func mapNotConnectedUserFromMockResponse() throws -> JetpackUser {
59+
func mapNotConnectedUserFromMockResponse() throws -> JetpackConnectionData {
5060
guard let response = Loader.contentsOf("jetpack-user-not-connected") else {
5161
throw FileNotFoundError()
5262
}
5363

54-
return try JetpackUserMapper().map(response: response)
64+
return try JetpackConnectionDataMapper().map(response: response)
5565
}
5666

5767
struct FileNotFoundError: Error {}

0 commit comments

Comments
 (0)