Skip to content

Commit a4e8d30

Browse files
committed
Yosemite layer changes from remote API changes.
1 parent f07849f commit a4e8d30

File tree

3 files changed

+132
-112
lines changed

3 files changed

+132
-112
lines changed

Yosemite/Yosemite/Actions/MediaAction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public enum MediaAction: Action {
1414
case retrieveMediaLibrary(siteID: Int64,
1515
pageNumber: Int,
1616
pageSize: Int,
17-
onCompletion: (_ mediaItems: [Media], _ error: Error?) -> Void)
17+
onCompletion: (Result<[Media], Error>) -> Void)
1818

1919
/// Uploads an exportable media asset to the site's WP Media Library.
2020
///

Yosemite/Yosemite/Stores/MediaStore.swift

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,11 @@ private extension MediaStore {
4949
func retrieveMediaLibrary(siteID: Int64,
5050
pageNumber: Int,
5151
pageSize: Int,
52-
onCompletion: @escaping (_ mediaItems: [Media], _ error: Error?) -> Void) {
52+
onCompletion: @escaping (Result<[Media], Error>) -> Void) {
5353
remote.loadMediaLibrary(for: siteID,
54-
pageNumber: pageNumber,
55-
pageSize: pageSize) { (mediaItems, error) in
56-
onCompletion(mediaItems ?? [], error)
57-
}
54+
pageNumber: pageNumber,
55+
pageSize: pageSize,
56+
completion: onCompletion)
5857
}
5958

6059
/// Uploads an exportable media asset to the site's WP Media Library with 2 steps:
@@ -67,36 +66,47 @@ private extension MediaStore {
6766
onCompletion: @escaping (Result<Media, Error>) -> Void) {
6867
mediaExportService.export(mediaAsset,
6968
onCompletion: { [weak self] (uploadableMedia, error) in
70-
guard let uploadableMedia = uploadableMedia, error == nil else {
71-
onCompletion(nil, error)
72-
return
73-
}
74-
self?.uploadMedia(siteID: siteID,
75-
productID: productID,
76-
uploadableMedia: uploadableMedia,
77-
onCompletion: onCompletion)
69+
guard let uploadableMedia = uploadableMedia, error == nil else {
70+
onCompletion(.failure(error ?? MediaActionError.unknown))
71+
return
72+
}
73+
self?.uploadMedia(siteID: siteID,
74+
productID: productID,
75+
uploadableMedia: uploadableMedia,
76+
onCompletion: onCompletion)
7877
})
7978
}
8079

8180
func uploadMedia(siteID: Int64,
8281
productID: Int64,
8382
uploadableMedia media: UploadableMedia,
83+
onCompletion: @escaping (Result<Media, Error>) -> Void) {
8484
remote.uploadMedia(for: siteID,
8585
productID: productID,
86-
mediaItems: [media]) { (uploadedMediaItems, error) in
87-
// Removes local media after the upload API request.
88-
do {
89-
try MediaFileManager().removeLocalMedia(at: media.localURL)
90-
} catch {
91-
onCompletion(nil, error)
92-
return
93-
}
94-
guard let uploadedMedia = uploadedMediaItems?.first, uploadedMediaItems?.count == 1 && error == nil else {
95-
onCompletion(nil, error)
96-
return
97-
}
98-
onCompletion(uploadedMedia, nil)
99-
onCompletion: @escaping (Result<Media, Error>) -> Void) {
86+
mediaItems: [media]) { result in
87+
// Removes local media after the upload API request.
88+
do {
89+
try MediaFileManager().removeLocalMedia(at: media.localURL)
90+
} catch {
91+
onCompletion(.failure(error))
92+
return
93+
}
94+
95+
switch result {
96+
case .success(let uploadedMediaItems):
97+
guard let uploadedMedia = uploadedMediaItems.first, uploadedMediaItems.count == 1 else {
98+
onCompletion(.failure(MediaActionError.unexpectedMediaCount(count: uploadedMediaItems.count)))
99+
return
100+
}
101+
onCompletion(.success(uploadedMedia))
102+
case .failure(let error):
103+
onCompletion(.failure(error))
104+
}
100105
}
101106
}
102107
}
108+
109+
public enum MediaActionError: Error {
110+
case unexpectedMediaCount(count: Int)
111+
case unknown
112+
}

Yosemite/YosemiteTests/Stores/MediaStoreTests.swift

Lines changed: 94 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,9 @@ final class MediaStoreTests: XCTestCase {
3737

3838
/// Verifies that `MediaAction.retrieveMediaLibrary` returns the expected response.
3939
///
40-
func testRetrieveMediaLibraryUponSuccessfulResponse() {
41-
let expectation = self.expectation(description: "Retrieve media library")
42-
40+
func test_retrieveMediaLibrary_returns_media_list() throws {
41+
// Given
4342
network.simulateResponse(requestUrlSuffix: "media", filename: "media-library")
44-
4543
let expectedMedia = Media(mediaID: 2352,
4644
date: date(with: "2020-02-21T12:15:38+08:00"),
4745
fileExtension: "jpeg",
@@ -53,30 +51,30 @@ final class MediaStoreTests: XCTestCase {
5351
alt: "",
5452
height: nil,
5553
width: nil)
56-
57-
let action = MediaAction.retrieveMediaLibrary(siteID: sampleSiteID,
58-
pageNumber: 1,
59-
pageSize: 20) { mediaItems, error in
60-
XCTAssertNil(error)
61-
XCTAssertEqual(mediaItems.count, 5)
62-
XCTAssertEqual(mediaItems.first, expectedMedia)
63-
64-
65-
expectation.fulfill()
66-
}
67-
6854
let mediaStore = MediaStore(dispatcher: dispatcher,
6955
storageManager: storageManager,
7056
network: network)
71-
mediaStore.onAction(action)
72-
wait(for: [expectation], timeout: Constants.expectationTimeout)
57+
58+
// When
59+
let result: Result<[Media], Error> = waitFor { promise in
60+
let action = MediaAction.retrieveMediaLibrary(siteID: self.sampleSiteID,
61+
pageNumber: 1,
62+
pageSize: 20) { result in
63+
promise(result)
64+
}
65+
mediaStore.onAction(action)
66+
}
67+
68+
// Then
69+
let mediaItems = try XCTUnwrap(result.get())
70+
XCTAssertEqual(mediaItems.count, 5)
71+
XCTAssertEqual(mediaItems.first, expectedMedia)
7372
}
7473

7574
/// Verifies that `MediaAction.retrieveMediaLibrary` returns the expected response for cases where URLs contain special chars.
7675
///
77-
func testRetrieveMediaLibraryUponSuccessfulResponseWhereURLsContainSpecialChars() {
78-
let expectation = self.expectation(description: "Retrieve media library")
79-
76+
func test_retrieveMediaLibrary_returns_media_list_when_URLs_contain_special_chars() throws {
77+
// Given
8078
network.simulateResponse(requestUrlSuffix: "media", filename: "media-library")
8179

8280
let expectedMedia = Media(mediaID: 2348,
@@ -90,69 +88,75 @@ final class MediaStoreTests: XCTestCase {
9088
alt: "",
9189
height: nil,
9290
width: nil)
93-
94-
let action = MediaAction.retrieveMediaLibrary(siteID: sampleSiteID,
95-
pageNumber: 1,
96-
pageSize: 20) { mediaItems, error in
97-
XCTAssertNil(error)
98-
XCTAssertEqual(mediaItems.count, 5)
99-
XCTAssertTrue(mediaItems.contains(expectedMedia))
100-
101-
expectation.fulfill()
102-
}
103-
10491
let mediaStore = MediaStore(dispatcher: dispatcher,
10592
storageManager: storageManager,
10693
network: network)
107-
mediaStore.onAction(action)
108-
wait(for: [expectation], timeout: Constants.expectationTimeout)
94+
95+
// When
96+
let result: Result<[Media], Error> = waitFor { promise in
97+
let action = MediaAction.retrieveMediaLibrary(siteID: self.sampleSiteID,
98+
pageNumber: 1,
99+
pageSize: 20) { result in
100+
promise(result)
101+
}
102+
mediaStore.onAction(action)
103+
}
104+
105+
// Then
106+
let mediaItems = try XCTUnwrap(result.get())
107+
XCTAssertEqual(mediaItems.count, 5)
108+
XCTAssertTrue(mediaItems.contains(expectedMedia))
109109
}
110110

111111
/// Verifies that `MediaAction.retrieveMediaLibrary` returns an error whenever there is an error response from the backend.
112112
///
113-
func testRetrieveMediaLibraryReturnsErrorUponReponseError() {
114-
let expectation = self.expectation(description: "Retrieve media library")
115-
113+
func test_retrieveMediaLibrary_returns_error_upon_response_error() throws {
114+
// Given
116115
network.simulateResponse(requestUrlSuffix: "media", filename: "generic_error")
117-
let action = MediaAction.retrieveMediaLibrary(siteID: sampleSiteID,
118-
pageNumber: 1,
119-
pageSize: 20) { mediaItems, error in
120-
XCTAssertNotNil(error)
121-
XCTAssertNotNil(mediaItems)
122-
XCTAssertTrue(mediaItems.isEmpty)
123-
expectation.fulfill()
124-
}
125-
126116
let mediaStore = MediaStore(dispatcher: dispatcher,
127117
storageManager: storageManager,
128118
network: network)
129-
mediaStore.onAction(action)
130-
wait(for: [expectation], timeout: Constants.expectationTimeout)
119+
120+
// When
121+
let result: Result<[Media], Error> = waitFor { promise in
122+
let action = MediaAction.retrieveMediaLibrary(siteID: self.sampleSiteID,
123+
pageNumber: 1,
124+
pageSize: 20) { result in
125+
promise(result)
126+
}
127+
mediaStore.onAction(action)
128+
}
129+
130+
// Then
131+
let error = try XCTUnwrap(result.failure as? DotcomError)
132+
XCTAssertEqual(error, .unauthorized)
131133
}
132134

133135
/// Verifies that `MediaAction.retrieveMediaLibrary` returns an error whenever there is no backend response.
134136
///
135-
func testRetrieveMediaLibraryReturnsErrorUponEmptyResponse() {
136-
let expectation = self.expectation(description: "Retrieve media library")
137-
138-
let action = MediaAction.retrieveMediaLibrary(siteID: sampleSiteID,
139-
pageNumber: 1,
140-
pageSize: 20) { mediaItems, error in
141-
XCTAssertNotNil(error)
142-
expectation.fulfill()
143-
}
144-
137+
func test_retrieveMediaLibrary_returns_error_upon_empty_response() {
138+
// Given
145139
let mediaStore = MediaStore(dispatcher: dispatcher,
146140
storageManager: storageManager,
147141
network: network)
148-
mediaStore.onAction(action)
149-
wait(for: [expectation], timeout: Constants.expectationTimeout)
142+
// When
143+
let result: Result<[Media], Error> = waitFor { promise in
144+
let action = MediaAction.retrieveMediaLibrary(siteID: self.sampleSiteID,
145+
pageNumber: 1,
146+
pageSize: 20) { result in
147+
promise(result)
148+
}
149+
mediaStore.onAction(action)
150+
}
151+
152+
// Then
153+
XCTAssertTrue(result.isFailure)
150154
}
151155

152156
// MARK: test cases for `MediaAction.uploadMedia`
153157

154-
func testUploadingMedia() {
155-
let expectation = self.expectation(description: "Upload a media asset")
158+
func test_uploadMedia_returns_uploaded_media_and_deletes_input_media_file() throws {
159+
// Given
156160

157161
// Creates a temporary file to simulate a uploadable media file.
158162
let filename = "test.txt"
@@ -177,27 +181,29 @@ final class MediaStoreTests: XCTestCase {
177181
network: network)
178182

179183
let path = "sites/\(sampleSiteID)/media/new"
180-
181184
network.simulateResponse(requestUrlSuffix: path, filename: "media-upload")
182185

183186
let asset = PHAsset()
184-
let action = MediaAction.uploadMedia(siteID: sampleSiteID, productID: sampleProductID, mediaAsset: asset) { (uploadedMedia, error) in
185-
XCTAssertNotNil(uploadedMedia)
186-
XCTAssertNil(error)
187-
188-
// Verifies that the temporary file is removed after the media is uploaded.
189-
XCTAssertFalse(fileManager.fileExists(atPath: targetURL.path))
190187

191-
expectation.fulfill()
188+
// When
189+
let result: Result<Media, Error> = waitFor { promise in
190+
let action = MediaAction.uploadMedia(siteID: self.sampleSiteID,
191+
productID: self.sampleProductID,
192+
mediaAsset: asset) { result in
193+
promise(result)
194+
}
195+
mediaStore.onAction(action)
192196
}
193197

194-
mediaStore.onAction(action)
195-
wait(for: [expectation], timeout: Constants.expectationTimeout)
196-
}
198+
// Then
199+
_ = try XCTUnwrap(result.get())
197200

198-
func testUploadingMediaWithErrorUponReponseError() {
199-
let expectation = self.expectation(description: "Upload a media asset")
201+
// Verifies that the temporary file is removed after the media is uploaded.
202+
XCTAssertFalse(fileManager.fileExists(atPath: targetURL.path))
203+
}
200204

205+
func test_uploadMedia_returns_error_upon_response_error() {
206+
// Given
201207
// Creates a temporary file to simulate a uploadable media file.
202208
let filename = "test.txt"
203209
let fileManager = FileManager.default
@@ -225,18 +231,22 @@ final class MediaStoreTests: XCTestCase {
225231
network.simulateResponse(requestUrlSuffix: path, filename: "generic_error")
226232

227233
let asset = PHAsset()
228-
let action = MediaAction.uploadMedia(siteID: sampleSiteID, productID: sampleProductID, mediaAsset: asset) { (uploadedMedia, error) in
229-
XCTAssertNil(uploadedMedia)
230-
XCTAssertNotNil(error)
231234

232-
// Verifies that the temporary file is removed after the media is uploaded.
233-
XCTAssertFalse(fileManager.fileExists(atPath: targetURL.path))
234-
235-
expectation.fulfill()
235+
// When
236+
let result: Result<Media, Error> = waitFor { promise in
237+
let action = MediaAction.uploadMedia(siteID: self.sampleSiteID,
238+
productID: self.sampleProductID,
239+
mediaAsset: asset) { result in
240+
promise(result)
241+
}
242+
mediaStore.onAction(action)
236243
}
237244

238-
mediaStore.onAction(action)
239-
wait(for: [expectation], timeout: Constants.expectationTimeout)
245+
// Then
246+
XCTAssertTrue(result.isFailure)
247+
248+
// Verifies that the temporary file is removed after the media is uploaded.
249+
XCTAssertFalse(fileManager.fileExists(atPath: targetURL.path))
240250
}
241251
}
242252

0 commit comments

Comments
 (0)