Skip to content

Commit ca096b5

Browse files
authored
Bug fix: issue when encoding objects that are already saved (#48)
* Bug fix: issue when encoding objects that are already saved * Add test cases to detect if ParseObject body encoding breaks * Add dates to ensure skipKeys doesn't break * codecov patch set back to auto
1 parent 9575409 commit ca096b5

File tree

5 files changed

+99
-9
lines changed

5 files changed

+99
-9
lines changed

.codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ coverage:
55
status:
66
patch:
77
default:
8-
target: 69
8+
target: auto
99
changes: false
1010
project:
1111
default:

Sources/ParseSwift/Coding/ParseEncoder.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ private class _ParseEncoder: JSONEncoder, Encoder {
262262
throw ParseError(code: .unknownError, message: "Found a circular dependency when encoding.")
263263
}
264264
self.uniqueObjects.insert(object)
265-
if !self.collectChildren {
265+
if !self.collectChildren && codingPath.count > 0 {
266+
valueToEncode = value
267+
} else if !self.collectChildren {
266268
valueToEncode = value.toPointer()
267269
}
268270
} else {

Sources/ParseSwift/LiveQuery/ParseLiveQuery.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ extension ParseLiveQuery {
683683
}
684684
}
685685

686-
// MARK: Query - Subscribe
686+
// MARK: ParseLiveQuery - Subscribe
687687
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
688688
public extension Query {
689689
/**
@@ -728,7 +728,7 @@ public extension Query {
728728
}
729729
}
730730

731-
// MARK: Query - Unsubscribe
731+
// MARK: ParseLiveQuery - Unsubscribe
732732
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
733733
public extension Query {
734734
/**
@@ -768,7 +768,7 @@ public extension Query {
768768
}
769769
}
770770

771-
// MARK: Query - Update
771+
// MARK: ParseLiveQuery - Update
772772
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
773773
public extension Query {
774774
/**

Tests/ParseSwiftTests/ParseObjectBatchTests.swift

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ class ParseObjectBatchTests: XCTestCase { // swiftlint:disable:this type_body_le
5252
try? ParseStorage.shared.deleteAll()
5353
}
5454

55+
func testSaveAllCommand() throws {
56+
let score = GameScore(score: 10)
57+
let score2 = GameScore(score: 20)
58+
59+
var scoreOnServer = score
60+
scoreOnServer.objectId = "yarr"
61+
scoreOnServer.createdAt = Date()
62+
scoreOnServer.updatedAt = scoreOnServer.createdAt
63+
scoreOnServer.ACL = nil
64+
65+
var scoreOnServer2 = score2
66+
scoreOnServer2.objectId = "yolo"
67+
scoreOnServer2.createdAt = Date()
68+
scoreOnServer2.updatedAt = scoreOnServer2.createdAt
69+
scoreOnServer2.ACL = nil
70+
71+
let objects = [score, score2]
72+
let commands = objects.map { $0.saveCommand() }
73+
let body = BatchCommand(requests: commands)
74+
// swiftlint:disable:next line_length
75+
let expected = "{\"requests\":[{\"path\":\"\\/classes\\/GameScore\",\"method\":\"POST\",\"body\":{\"score\":10}},{\"path\":\"\\/classes\\/GameScore\",\"method\":\"POST\",\"body\":{\"score\":20}}]}"
76+
let encoded = try ParseCoding.parseEncoder()
77+
.encode(body, collectChildren: false,
78+
objectsSavedBeforeThisOne: nil,
79+
filesSavedBeforeThisOne: nil).encoded
80+
let decoded = String(data: encoded, encoding: .utf8)
81+
XCTAssertEqual(decoded, expected)
82+
}
83+
5584
func testSaveAll() { // swiftlint:disable:this function_body_length cyclomatic_complexity
5685
let score = GameScore(score: 10)
5786
let score2 = GameScore(score: 20)
@@ -235,6 +264,39 @@ class ParseObjectBatchTests: XCTestCase { // swiftlint:disable:this type_body_le
235264
}
236265
}
237266

267+
func testUpdateAllCommand() throws {
268+
var score = GameScore(score: 10)
269+
var score2 = GameScore(score: 20)
270+
271+
score.objectId = "yarr"
272+
score.createdAt = Date()
273+
score.updatedAt = Date()
274+
score2.objectId = "yolo"
275+
score2.createdAt = Date()
276+
score2.updatedAt = Date()
277+
278+
let objects = [score, score2]
279+
let initialCommands = objects.map { $0.saveCommand() }
280+
let commands = initialCommands.compactMap { (command) -> API.Command<GameScore, GameScore>? in
281+
let path = ParseConfiguration.mountPath + command.path.urlComponent
282+
guard let body = command.body else {
283+
return nil
284+
}
285+
return API.Command<GameScore, GameScore>(method: command.method, path: .any(path),
286+
body: body, mapper: command.mapper)
287+
}
288+
let body = BatchCommand(requests: commands)
289+
// swiftlint:disable:next line_length
290+
let expected = "{\"requests\":[{\"path\":\"\\/1\\/classes\\/GameScore\\/yarr\",\"method\":\"PUT\",\"body\":{\"score\":10}},{\"path\":\"\\/1\\/classes\\/GameScore\\/yolo\",\"method\":\"PUT\",\"body\":{\"score\":20}}]}"
291+
292+
let encoded = try ParseCoding.parseEncoder()
293+
.encode(body, collectChildren: false,
294+
objectsSavedBeforeThisOne: nil,
295+
filesSavedBeforeThisOne: nil).encoded
296+
let decoded = String(data: encoded, encoding: .utf8)
297+
XCTAssertEqual(decoded, expected)
298+
}
299+
238300
func testUpdateAll() { // swiftlint:disable:this function_body_length cyclomatic_complexity
239301
var score = GameScore(score: 10)
240302
score.objectId = "yarr"

Tests/ParseSwiftTests/ParseObjectTests.swift

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length
461461
self.fetchAsync(score: score, scoreOnServer: scoreOnServer, callbackQueue: .main)
462462
}
463463

464-
func testSaveCommand() {
464+
func testSaveCommand() throws {
465465
let score = GameScore(score: 10)
466466
let className = score.className
467467

@@ -470,23 +470,49 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length
470470
XCTAssertEqual(command.path.urlComponent, "/classes/\(className)")
471471
XCTAssertEqual(command.method, API.Method.POST)
472472
XCTAssertNil(command.params)
473-
XCTAssertNotNil(command.body)
474473
XCTAssertNotNil(command.data)
474+
475+
guard let body = command.body else {
476+
XCTFail("Should be able to unwrap")
477+
return
478+
}
479+
480+
let expected = "{\"score\":10,\"player\":\"Jen\"}"
481+
let encoded = try ParseCoding.parseEncoder()
482+
.encode(body, collectChildren: false,
483+
objectsSavedBeforeThisOne: nil,
484+
filesSavedBeforeThisOne: nil).encoded
485+
let decoded = String(data: encoded, encoding: .utf8)
486+
XCTAssertEqual(decoded, expected)
475487
}
476488

477-
func testUpdateCommand() {
489+
func testUpdateCommand() throws {
478490
var score = GameScore(score: 10)
479491
let className = score.className
480492
let objectId = "yarr"
481493
score.objectId = objectId
494+
score.createdAt = Date()
495+
score.updatedAt = Date()
482496

483497
let command = score.saveCommand()
484498
XCTAssertNotNil(command)
485499
XCTAssertEqual(command.path.urlComponent, "/classes/\(className)/\(objectId)")
486500
XCTAssertEqual(command.method, API.Method.PUT)
487501
XCTAssertNil(command.params)
488-
XCTAssertNotNil(command.body)
489502
XCTAssertNotNil(command.data)
503+
504+
guard let body = command.body else {
505+
XCTFail("Should be able to unwrap")
506+
return
507+
}
508+
509+
let expected = "{\"score\":10,\"player\":\"Jen\"}"
510+
let encoded = try ParseCoding.parseEncoder()
511+
.encode(body, collectChildren: false,
512+
objectsSavedBeforeThisOne: nil,
513+
filesSavedBeforeThisOne: nil).encoded
514+
let decoded = String(data: encoded, encoding: .utf8)
515+
XCTAssertEqual(decoded, expected)
490516
}
491517

492518
func testSave() { // swiftlint:disable:this function_body_length

0 commit comments

Comments
 (0)