Skip to content

Commit b196fca

Browse files
authored
Error when attempting to update ParseFile (#144)
* Error when attempting to update ParseFile * add changelog
1 parent f1ddaab commit b196fca

File tree

4 files changed

+90
-28
lines changed

4 files changed

+90
-28
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* _Contributing to this repo? Add info about your change here to be included in the next release_
66

77
__Fixes__
8+
- ParseFiles can't be updated from the client and will now throw an error if attempted. Instead another file should be created and the older file should be deleted by the developer. ([#144](https://github.com/parse-community/Parse-Swift/pull/144)), thanks to [Corey Baker](https://github.com/cbaker6).
89
- Fixed issue where Swift SDK prevented fetching of Parse objects when custom objectId was enabled ([#139](https://github.com/parse-community/Parse-Swift/pull/139)), thanks to [Corey Baker](https://github.com/cbaker6).
910

1011
__Improvements__

Sources/ParseSwift/API/API+Commands.swift

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,13 @@ internal extension API {
254254

255255
internal extension API.Command {
256256
// MARK: Uploading File
257-
static func uploadFileCommand(_ object: ParseFile) -> API.Command<ParseFile, ParseFile> {
258-
if object.isSaved {
259-
return updateFileCommand(object)
257+
static func uploadFileCommand(_ object: ParseFile) throws -> API.Command<ParseFile, ParseFile> {
258+
if !object.isSaved {
259+
return createFileCommand(object)
260+
} else {
261+
throw ParseError(code: .unknownError,
262+
message: "File is already saved and cannot be updated.")
260263
}
261-
return createFileCommand(object)
262264
}
263265

264266
// MARK: Uploading File - private
@@ -271,15 +273,6 @@ internal extension API.Command {
271273
}
272274
}
273275

274-
private static func updateFileCommand(_ object: ParseFile) -> API.Command<ParseFile, ParseFile> {
275-
API.Command(method: .PUT,
276-
path: .file(fileName: object.name),
277-
uploadData: object.data,
278-
uploadFile: object.localURL) { (data) -> ParseFile in
279-
try ParseCoding.jsonDecoder().decode(FileUploadResponse.self, from: data).apply(to: object)
280-
}
281-
}
282-
283276
// MARK: Downloading File
284277
static func downloadFileCommand(_ object: ParseFile) -> API.Command<ParseFile, ParseFile> {
285278
API.Command(method: .GET,

Sources/ParseSwift/Types/ParseFile.swift

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -427,35 +427,57 @@ extension ParseFile {
427427
switch result {
428428

429429
case .success(let fetched):
430-
fetched.uploadFileCommand()
431-
.executeAsync(options: options,
430+
do {
431+
try fetched.uploadFileCommand()
432+
.executeAsync(options: options,
432433
callbackQueue: callbackQueue,
433434
uploadProgress: progress) { result in
434-
callbackQueue.async {
435-
completion(result)
435+
callbackQueue.async {
436+
completion(result)
437+
}
438+
}
439+
} catch {
440+
callbackQueue.async {
441+
if let parseError = error as? ParseError {
442+
completion(.failure(parseError))
443+
} else {
444+
let parseError = ParseError(code: .unknownError, message: error.localizedDescription)
445+
completion(.failure(parseError))
436446
}
437447
}
448+
}
438449
case .failure(let error):
439450
callbackQueue.async {
440451
completion(.failure(error))
441452
}
442453
}
443454
}
444455
} else {
445-
uploadFileCommand()
446-
.executeAsync(options: options,
447-
callbackQueue: callbackQueue,
448-
uploadProgress: progress) { result in
449-
callbackQueue.async {
450-
completion(result)
456+
do {
457+
try uploadFileCommand()
458+
.executeAsync(options: options,
459+
callbackQueue: callbackQueue,
460+
uploadProgress: progress) { result in
461+
callbackQueue.async {
462+
completion(result)
463+
}
464+
}
465+
} catch {
466+
callbackQueue.async {
467+
if let parseError = error as? ParseError {
468+
completion(.failure(parseError))
469+
} else {
470+
let parseError = ParseError(code: .unknownError, message: error.localizedDescription)
471+
completion(.failure(parseError))
451472
}
452473
}
474+
}
453475
}
454476

455477
}
456478

457-
internal func uploadFileCommand() -> API.Command<Self, Self> {
458-
return API.Command<Self, Self>.uploadFileCommand(self)
479+
internal func uploadFileCommand() throws -> API.Command<Self, Self> {
480+
try API.Command<Self, Self>.uploadFileCommand(self)
459481
}
460482
}
461483

Tests/ParseSwiftTests/ParseFileTests.swift

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ class ParseFileTests: XCTestCase { // swiftlint:disable:this type_body_length
6868
wait(for: [expectation1, expectation2], timeout: 20.0)
6969
}
7070

71-
func testUploadCommand() {
71+
func testUploadCommand() throws {
7272
guard let url = URL(string: "http://localhost/") else {
7373
XCTFail("Should have created url")
7474
return
7575
}
7676
let file = ParseFile(name: "a", cloudURL: url)
7777

78-
let command = file.uploadFileCommand()
78+
let command = try file.uploadFileCommand()
7979
XCTAssertNotNil(command)
8080
XCTAssertEqual(command.path.urlComponent, "/files/a")
8181
XCTAssertEqual(command.method, API.Method.POST)
@@ -84,14 +84,25 @@ class ParseFileTests: XCTestCase { // swiftlint:disable:this type_body_length
8484

8585
let file2 = ParseFile(cloudURL: url)
8686

87-
let command2 = file2.uploadFileCommand()
87+
let command2 = try file2.uploadFileCommand()
8888
XCTAssertNotNil(command2)
8989
XCTAssertEqual(command2.path.urlComponent, "/files/file")
9090
XCTAssertEqual(command2.method, API.Method.POST)
9191
XCTAssertNil(command2.params)
9292
XCTAssertNil(command2.body)
9393
}
9494

95+
func testUploadCommandDontAllowUpdate() throws {
96+
guard let url = URL(string: "http://localhost/") else {
97+
XCTFail("Should have created url")
98+
return
99+
}
100+
101+
var file = ParseFile(cloudURL: url)
102+
file.url = url
103+
XCTAssertThrowsError(try file.uploadFileCommand())
104+
}
105+
95106
func testDeleteCommand() {
96107
guard let url = URL(string: "http://localhost/") else {
97108
XCTFail("Should have created url")
@@ -375,6 +386,19 @@ class ParseFileTests: XCTestCase { // swiftlint:disable:this type_body_length
375386
}
376387
}
377388

389+
func testUpdateFileError() throws {
390+
guard let sampleData = "Hello World".data(using: .utf8) else {
391+
throw ParseError(code: .unknownError, message: "Should have converted to data")
392+
}
393+
var parseFile = ParseFile(name: "sampleData.txt",
394+
data: sampleData,
395+
metadata: ["Testing": "123"],
396+
tags: ["Hey": "now"])
397+
parseFile.url = URL(string: "http://localhost/")
398+
399+
XCTAssertThrowsError(try parseFile.save())
400+
}
401+
378402
func testFetchFileStream() throws {
379403
let tempFilePath = URL(fileURLWithPath: "\(temporaryDirectory)sampleData.dat")
380404
guard let sampleData = "Hello World".data(using: .utf8) else {
@@ -642,6 +666,28 @@ class ParseFileTests: XCTestCase { // swiftlint:disable:this type_body_length
642666
wait(for: [expectation1], timeout: 20.0)
643667
}
644668

669+
func testUpdateErrorAysnc() throws {
670+
671+
guard let sampleData = "Hello World".data(using: .utf8) else {
672+
throw ParseError(code: .unknownError, message: "Should have converted to data")
673+
}
674+
var parseFile = ParseFile(name: "sampleData.txt", data: sampleData)
675+
parseFile.url = URL(string: "http://localhost/")
676+
677+
let expectation1 = XCTestExpectation(description: "ParseFile async")
678+
parseFile.save { result in
679+
680+
switch result {
681+
case .success:
682+
XCTFail("Should have returned error")
683+
case .failure(let error):
684+
XCTAssertTrue(error.message.contains("File is already"))
685+
}
686+
expectation1.fulfill()
687+
}
688+
wait(for: [expectation1], timeout: 20.0)
689+
}
690+
645691
#if !os(Linux) && !os(Android)
646692
// swiftlint:disable:next inclusive_language
647693
func testDeleteNoMasterKeyFileAysnc() throws {

0 commit comments

Comments
 (0)