Skip to content

Commit 9f70977

Browse files
committed
Merge branch 'develop' into issue/9-fullfill-order
2 parents e776b8e + 317eae7 commit 9f70977

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+938
-666
lines changed

Networking/Networking.xcodeproj/project.pbxproj

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
B505F6CD20BEE37E00BB1B69 /* AccountMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B505F6CC20BEE37E00BB1B69 /* AccountMapper.swift */; };
11+
B505F6CF20BEE38B00BB1B69 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = B505F6CE20BEE38B00BB1B69 /* Account.swift */; };
12+
B505F6D120BEE39600BB1B69 /* AccountRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = B505F6D020BEE39600BB1B69 /* AccountRemote.swift */; };
13+
B505F6D320BEE3A500BB1B69 /* AccountMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B505F6D220BEE3A500BB1B69 /* AccountMapperTests.swift */; };
14+
B505F6D520BEE4E700BB1B69 /* me.json in Resources */ = {isa = PBXBuildFile; fileRef = B505F6D420BEE4E600BB1B69 /* me.json */; };
15+
B505F6D720BEE58800BB1B69 /* AccountRemoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B505F6D620BEE58800BB1B69 /* AccountRemoteTests.swift */; };
16+
B505F6EA20BEFC3700BB1B69 /* MockupNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518662620A09BCC00037A38 /* MockupNetwork.swift */; };
17+
B505F6EC20BEFDC200BB1B69 /* Loader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518663420A0A2E800037A38 /* Loader.swift */; };
1018
B518662220A097C200037A38 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518662120A097C200037A38 /* Network.swift */; };
11-
B518662420A099BF00037A38 /* AlamofireWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518662320A099BF00037A38 /* AlamofireWrapper.swift */; };
12-
B518662720A09BCC00037A38 /* NetworkMockup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518662620A09BCC00037A38 /* NetworkMockup.swift */; };
19+
B518662420A099BF00037A38 /* AlamofireNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518662320A099BF00037A38 /* AlamofireNetwork.swift */; };
1320
B518662A20A09C6F00037A38 /* OrdersRemoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518662920A09C6F00037A38 /* OrdersRemoteTests.swift */; };
1421
B518663520A0A2E800037A38 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518663320A0A2E800037A38 /* Constants.swift */; };
15-
B518663620A0A2E800037A38 /* Loader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B518663420A0A2E800037A38 /* Loader.swift */; };
1622
B557D9ED209753AA005962F4 /* Networking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B557D9E3209753AA005962F4 /* Networking.framework */; };
1723
B557D9F4209753AA005962F4 /* Networking.h in Headers */ = {isa = PBXBuildFile; fileRef = B557D9E6209753AA005962F4 /* Networking.h */; settings = {ATTRIBUTES = (Public, ); }; };
1824
B557DA0220975500005962F4 /* JetpackRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B557D9FF209754FF005962F4 /* JetpackRequest.swift */; };
@@ -56,9 +62,15 @@
5662

5763
/* Begin PBXFileReference section */
5864
97F8D9516BAC88E8A25EF46D /* Pods_Networking.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Networking.framework; sourceTree = BUILT_PRODUCTS_DIR; };
65+
B505F6CC20BEE37E00BB1B69 /* AccountMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountMapper.swift; sourceTree = "<group>"; };
66+
B505F6CE20BEE38B00BB1B69 /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
67+
B505F6D020BEE39600BB1B69 /* AccountRemote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountRemote.swift; sourceTree = "<group>"; };
68+
B505F6D220BEE3A500BB1B69 /* AccountMapperTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountMapperTests.swift; sourceTree = "<group>"; };
69+
B505F6D420BEE4E600BB1B69 /* me.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = me.json; sourceTree = "<group>"; };
70+
B505F6D620BEE58800BB1B69 /* AccountRemoteTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRemoteTests.swift; sourceTree = "<group>"; };
5971
B518662120A097C200037A38 /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = "<group>"; };
60-
B518662320A099BF00037A38 /* AlamofireWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlamofireWrapper.swift; sourceTree = "<group>"; };
61-
B518662620A09BCC00037A38 /* NetworkMockup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMockup.swift; sourceTree = "<group>"; };
72+
B518662320A099BF00037A38 /* AlamofireNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlamofireNetwork.swift; sourceTree = "<group>"; };
73+
B518662620A09BCC00037A38 /* MockupNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockupNetwork.swift; sourceTree = "<group>"; };
6274
B518662920A09C6F00037A38 /* OrdersRemoteTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrdersRemoteTests.swift; sourceTree = "<group>"; };
6375
B518663320A0A2E800037A38 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
6476
B518663420A0A2E800037A38 /* Loader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Loader.swift; sourceTree = "<group>"; };
@@ -140,11 +152,21 @@
140152
name = Frameworks;
141153
sourceTree = "<group>";
142154
};
155+
B505F6EB20BEFD9100BB1B69 /* Tools */ = {
156+
isa = PBXGroup;
157+
children = (
158+
B518663420A0A2E800037A38 /* Loader.swift */,
159+
);
160+
name = Tools;
161+
path = Network/Tools;
162+
sourceTree = "<group>";
163+
};
143164
B518662020A097B200037A38 /* Network */ = {
144165
isa = PBXGroup;
145166
children = (
146167
B518662120A097C200037A38 /* Network.swift */,
147-
B518662320A099BF00037A38 /* AlamofireWrapper.swift */,
168+
B518662320A099BF00037A38 /* AlamofireNetwork.swift */,
169+
B518662620A09BCC00037A38 /* MockupNetwork.swift */,
148170
);
149171
path = Network;
150172
sourceTree = "<group>";
@@ -153,19 +175,18 @@
153175
isa = PBXGroup;
154176
children = (
155177
B5969E1420A47F99005E9DF1 /* RemoteTests.swift */,
178+
B505F6D620BEE58800BB1B69 /* AccountRemoteTests.swift */,
156179
B518662920A09C6F00037A38 /* OrdersRemoteTests.swift */,
157180
);
158181
path = Remote;
159182
sourceTree = "<group>";
160183
};
161-
B518663220A0A2E800037A38 /* Tools */ = {
184+
B518663220A0A2E800037A38 /* Settings */ = {
162185
isa = PBXGroup;
163186
children = (
164187
B518663320A0A2E800037A38 /* Constants.swift */,
165-
B518663420A0A2E800037A38 /* Loader.swift */,
166-
B518662620A09BCC00037A38 /* NetworkMockup.swift */,
167188
);
168-
path = Tools;
189+
path = Settings;
169190
sourceTree = "<group>";
170191
};
171192
B519A3E82097A91800E2603A /* Requests */ = {
@@ -208,6 +229,7 @@
208229
B557DA0620975515005962F4 /* Requests */,
209230
B557DA0520975507005962F4 /* Remote */,
210231
B557DA1020975F60005962F4 /* Settings */,
232+
B505F6EB20BEFD9100BB1B69 /* Tools */,
211233
B557D9E6209753AA005962F4 /* Networking.h */,
212234
B557D9E7209753AA005962F4 /* Info.plist */,
213235
);
@@ -218,7 +240,7 @@
218240
isa = PBXGroup;
219241
children = (
220242
B559EBA820A0B5B100836CD4 /* Responses */,
221-
B518663220A0A2E800037A38 /* Tools */,
243+
B518663220A0A2E800037A38 /* Settings */,
222244
B5C6FCC620A32E3100A4F8E4 /* Extensions */,
223245
B5C6FCCB20A34B5E00A4F8E4 /* Mapper */,
224246
B518662820A09C5D00037A38 /* Remote */,
@@ -232,6 +254,7 @@
232254
isa = PBXGroup;
233255
children = (
234256
B557DA0020975500005962F4 /* Remote.swift */,
257+
B505F6D020BEE39600BB1B69 /* AccountRemote.swift */,
235258
B557DA0120975500005962F4 /* OrdersRemote.swift */,
236259
);
237260
path = Remote;
@@ -261,6 +284,7 @@
261284
B557DA1B20979E6D005962F4 /* Model */ = {
262285
isa = PBXGroup;
263286
children = (
287+
B505F6CE20BEE38B00BB1B69 /* Account.swift */,
264288
B5BB1D0F20A237FB00112D92 /* Address.swift */,
265289
B557DA1C20979E7D005962F4 /* Order.swift */,
266290
B5BB1D1120A255EC00112D92 /* OrderStatus.swift */,
@@ -272,6 +296,7 @@
272296
B559EBA820A0B5B100836CD4 /* Responses */ = {
273297
isa = PBXGroup;
274298
children = (
299+
B505F6D420BEE4E600BB1B69 /* me.json */,
275300
B559EBA920A0B5CD00836CD4 /* orders-load-all.json */,
276301
B5C6FCD520A3768900A4F8E4 /* order.json */,
277302
);
@@ -282,6 +307,7 @@
282307
isa = PBXGroup;
283308
children = (
284309
B567AF2820A0FA1E00AB6C62 /* Mapper.swift */,
310+
B505F6CC20BEE37E00BB1B69 /* AccountMapper.swift */,
285311
B5C6FCD320A373BA00A4F8E4 /* OrderMapper.swift */,
286312
B567AF2A20A0FA4200AB6C62 /* OrderListMapper.swift */,
287313
);
@@ -307,6 +333,7 @@
307333
B5C6FCCB20A34B5E00A4F8E4 /* Mapper */ = {
308334
isa = PBXGroup;
309335
children = (
336+
B505F6D220BEE3A500BB1B69 /* AccountMapperTests.swift */,
310337
B5C6FCCC20A34B8300A4F8E4 /* OrderListMapperTests.swift */,
311338
);
312339
path = Mapper;
@@ -414,6 +441,7 @@
414441
isa = PBXResourcesBuildPhase;
415442
buildActionMask = 2147483647;
416443
files = (
444+
B505F6D520BEE4E700BB1B69 /* me.json in Resources */,
417445
B5C6FCD620A3768900A4F8E4 /* order.json in Resources */,
418446
B559EBAA20A0B5CD00836CD4 /* orders-load-all.json in Resources */,
419447
);
@@ -486,36 +514,41 @@
486514
B557DA1A20979D66005962F4 /* Settings.swift in Sources */,
487515
B5BB1D0C20A2050300112D92 /* DateFormatter+Woo.swift in Sources */,
488516
B567AF2520A0CCA300AB6C62 /* AuthenticatedRequest.swift in Sources */,
517+
B505F6EA20BEFC3700BB1B69 /* MockupNetwork.swift in Sources */,
489518
B557DA0220975500005962F4 /* JetpackRequest.swift in Sources */,
519+
B505F6CD20BEE37E00BB1B69 /* AccountMapper.swift in Sources */,
490520
B557DA0D20975DB1005962F4 /* WordPressAPIVersion.swift in Sources */,
491521
B557DA1D20979E7D005962F4 /* Order.swift in Sources */,
492522
B557DA0320975500005962F4 /* Remote.swift in Sources */,
493523
B567AF2920A0FA1E00AB6C62 /* Mapper.swift in Sources */,
494524
B518662220A097C200037A38 /* Network.swift in Sources */,
495-
B518662420A099BF00037A38 /* AlamofireWrapper.swift in Sources */,
525+
B518662420A099BF00037A38 /* AlamofireNetwork.swift in Sources */,
496526
B557DA1820979D51005962F4 /* Credentials.swift in Sources */,
497527
B5C6FCCF20A3592900A4F8E4 /* OrderItem.swift in Sources */,
528+
B505F6EC20BEFDC200BB1B69 /* Loader.swift in Sources */,
498529
B5BB1D1220A255EC00112D92 /* OrderStatus.swift in Sources */,
499530
B5BB1D1020A237FB00112D92 /* Address.swift in Sources */,
500531
B557DA0420975500005962F4 /* OrdersRemote.swift in Sources */,
501532
B5C6FCD420A373BB00A4F8E4 /* OrderMapper.swift in Sources */,
502533
B557DA0F20975E07005962F4 /* DotcomRequest.swift in Sources */,
503534
B557DA0B20975D7E005962F4 /* WooAPIVersion.swift in Sources */,
535+
B505F6D120BEE39600BB1B69 /* AccountRemote.swift in Sources */,
504536
B567AF2B20A0FA4200AB6C62 /* OrderListMapper.swift in Sources */,
537+
B505F6CF20BEE38B00BB1B69 /* Account.swift in Sources */,
505538
);
506539
runOnlyForDeploymentPostprocessing = 0;
507540
};
508541
B557D9E8209753AA005962F4 /* Sources */ = {
509542
isa = PBXSourcesBuildPhase;
510543
buildActionMask = 2147483647;
511544
files = (
545+
B505F6D320BEE3A500BB1B69 /* AccountMapperTests.swift in Sources */,
512546
B5C6FCC820A32E4800A4F8E4 /* DateFormatterWooTests.swift in Sources */,
513547
B567AF3120A0FB8F00AB6C62 /* JetpackRequestTests.swift in Sources */,
548+
B505F6D720BEE58800BB1B69 /* AccountRemoteTests.swift in Sources */,
514549
B518662A20A09C6F00037A38 /* OrdersRemoteTests.swift in Sources */,
515550
B5969E1520A47F99005E9DF1 /* RemoteTests.swift in Sources */,
516551
B567AF2F20A0FB8F00AB6C62 /* AuthenticatedRequestTests.swift in Sources */,
517-
B518663620A0A2E800037A38 /* Loader.swift in Sources */,
518-
B518662720A09BCC00037A38 /* NetworkMockup.swift in Sources */,
519552
B5C6FCCD20A34B8300A4F8E4 /* OrderListMapperTests.swift in Sources */,
520553
B518663520A0A2E800037A38 /* Constants.swift in Sources */,
521554
B567AF3020A0FB8F00AB6C62 /* DotcomRequestTests.swift in Sources */,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Foundation
2+
3+
4+
/// Mapper: Account
5+
///
6+
class AccountMapper: Mapper {
7+
8+
/// (Attempts) to convert a dictionary into an Account entity.
9+
///
10+
func map(response: Data) throws -> Account {
11+
let decoder = JSONDecoder()
12+
return try decoder.decode(Account.self, from: response)
13+
}
14+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import Foundation
2+
3+
4+
/// WordPress.com Account
5+
///
6+
public struct Account: Decodable {
7+
8+
/// Dotcom UserID
9+
///
10+
public let userID: Int
11+
12+
/// Display Name
13+
///
14+
public let displayName: String
15+
16+
/// Account's Email
17+
///
18+
public let email: String
19+
20+
/// Account's Username
21+
///
22+
public let username: String
23+
24+
/// Account's Gravatar
25+
///
26+
public let gravatarUrl: String?
27+
}
28+
29+
30+
/// Defines all of the Account CodingKeys
31+
///
32+
private extension Account {
33+
34+
enum CodingKeys: String, CodingKey {
35+
case userID = "ID"
36+
case displayName = "display_name"
37+
case email = "email"
38+
case username = "username"
39+
case gravatarUrl = "avatar_URL"
40+
}
41+
}

Networking/Networking/Network/AlamofireWrapper.swift renamed to Networking/Networking/Network/AlamofireNetwork.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ import Alamofire
44

55
/// AlamofireWrapper: Encapsulates all of the Alamofire OP's
66
///
7-
public struct AlamofireWrapper: Network {
7+
public struct AlamofireNetwork: Network {
88

99
/// Public Initializer
1010
///
11-
public init() {
12-
}
11+
public init() { }
1312

1413
/// Executes the specified Network Request. Upon completion, the payload will be parsed as JSON, and sent back to the caller.
1514
///

Networking/NetworkingTests/Tools/NetworkMockup.swift renamed to Networking/Networking/Network/MockupNetwork.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import Foundation
22
import Alamofire
3-
@testable import Networking
43

54

65
/// Network Mockup: Allows us to simulate HTTP Responses.
76
///
8-
class NetworkMockup: Network {
7+
class MockupNetwork: Network {
98

109
/// Mapping between URL Suffix and JSON Mockup responses.
1110
///
@@ -40,7 +39,7 @@ class NetworkMockup: Network {
4039

4140
/// Public Methods
4241
///
43-
extension NetworkMockup {
42+
extension MockupNetwork {
4443

4544
/// Whenever a request is enqueued, we'll return the specified JSON Encoded file, whenever the Request's URL suffix matches with
4645
/// the specified one.

Networking/NetworkingTests/Tools/Loader.swift renamed to Networking/Networking/Network/Tools/Loader.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,24 @@ class Loader {
3030
/// Loads the contents of the specified file (in the current bundle), and returns it's contents as `Data`.
3131
///
3232
static func contentsOf(_ filename: String, extension: String = jsonExtension) -> Data? {
33-
guard let url = Bundle(for: self).url(forResource: filename, withExtension: `extension`) else {
33+
guard let url = path(for: filename, extension: `extension`) else {
3434
return nil
3535
}
3636

3737
return try? Data(contentsOf: url)
3838
}
39+
40+
/// Fins the specified resource in *all* of the available bundles.
41+
///
42+
private static func path(for filename: String, extension: String = jsonExtension) -> URL? {
43+
for bundle in Bundle.allBundles {
44+
guard let path = bundle.url(forResource: filename, withExtension: `extension`) else {
45+
continue
46+
}
47+
48+
return path
49+
}
50+
51+
return nil
52+
}
3953
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Foundation
2+
import Alamofire
3+
4+
5+
/// Account: Remote Endpoints
6+
///
7+
public class AccountRemote: Remote {
8+
9+
/// Loads the Account Details associated with the Credential's authToken.
10+
///
11+
public func loadAccountDetails(completion: @escaping (Account?, Error?) -> Void) {
12+
let path = "me"
13+
let request = DotcomRequest(wordpressApiVersion: .mark1_1, method: .get, path: path)
14+
let mapper = AccountMapper()
15+
16+
enqueue(request, mapper: mapper, completion: completion)
17+
}
18+
}

Networking/Networking/Remote/Remote.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class Remote {
1919
/// by Alamofire.
2020
///
2121
public convenience init(credentials: Credentials) {
22-
self.init(credentials: credentials, network: AlamofireWrapper())
22+
self.init(credentials: credentials, network: AlamofireNetwork())
2323
}
2424

2525
/// Designated Initializer.

Networking/Networking/Settings/Credentials.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ public struct Credentials: Equatable {
88
/// WordPress.com Authentication Token
99
///
1010
public let authToken: String
11+
12+
/// Designated Initializer
13+
///
14+
public init(authToken: String) {
15+
self.authToken = authToken
16+
}
1117
}
1218

1319

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import XCTest
2+
@testable import Networking
3+
4+
5+
/// AccountMapper Unit Tests
6+
///
7+
class AccountMapperTests: XCTestCase {
8+
9+
/// Verifies that all of the Account fields are properly parsed.
10+
///
11+
func testAccountFieldsArePropertlyParsed() {
12+
guard let account = mapLoadAccountResponse() else {
13+
XCTFail()
14+
return
15+
}
16+
17+
XCTAssertEqual(account.displayName, "apiexamples")
18+
XCTAssertEqual(account.email, "[email protected]")
19+
XCTAssertEqual(account.gravatarUrl, "https://1.gravatar.com/avatar/a2afb7b6c0e23e5d363d8612fb1bd5ad?s=96&d=identicon&r=G")
20+
XCTAssertEqual(account.userID, 78972699)
21+
XCTAssertEqual(account.username, "apiexamples")
22+
}
23+
}
24+
25+
26+
27+
// MARK: - Private Methods.
28+
//
29+
private extension AccountMapperTests {
30+
31+
/// Returns the AccountMapper output upon receiving `me` (Data Encoded)
32+
///
33+
func mapLoadAccountResponse() -> Account? {
34+
guard let response = Loader.contentsOf("me") else {
35+
return nil
36+
}
37+
38+
return try? AccountMapper().map(response: response)
39+
}
40+
}

0 commit comments

Comments
 (0)