Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ coverage:
status:
patch:
default:
target: 78
target: auto
changes: false
project:
default:
Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@

### main

[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.0.0...main)
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.0.1...main)
* _Contributing to this repo? Add info about your change here to be included in the next release_

### 4.0.1
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.0.0...4.0.1)

__Fixes__
- Allow ParseRole's to be updated when the SDK is allowing custom objectId's ([#338](https://github.com/parse-community/Parse-Swift/pull/338)), thanks to [Corey Baker](https://github.com/cbaker6).

### 4.0.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.2...4.0.0)

Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/ParseConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

enum ParseConstants {
static let sdk = "swift"
static let version = "4.0.0"
static let version = "4.0.1"
static let fileManagementDirectory = "parse/"
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
static let fileManagementLibraryDirectory = "Library/"
Expand Down
4 changes: 2 additions & 2 deletions Sources/ParseSwift/Types/ParseOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ extension ParseOperation {
- returns: Returns saved `ParseObject`.
*/
public func save(options: API.Options = []) throws -> T {
if !target.isSaved {
guard target.objectId != nil else {
throw ParseError(code: .missingObjectId, message: "ParseObject isn't saved.")
}
return try saveCommand()
Expand All @@ -406,7 +406,7 @@ extension ParseOperation {
callbackQueue: DispatchQueue = .main,
completion: @escaping (Result<T, ParseError>) -> Void
) {
if !target.isSaved {
guard target.objectId != nil else {
callbackQueue.async {
let error = ParseError(code: .missingObjectId, message: "ParseObject isn't saved.")
completion(.failure(error))
Expand Down
6 changes: 3 additions & 3 deletions Tests/ParseSwiftTests/ParseRelationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class ParseRelationTests: XCTestCase {
XCTAssertThrowsError(try relation.add("level", objects: [level]))
}

func testAddOperations() throws {
func testAddOperation() throws {
var score = GameScore(points: 10)
let objectId = "hello"
score.objectId = objectId
Expand Down Expand Up @@ -252,7 +252,7 @@ class ParseRelationTests: XCTestCase {
XCTAssertThrowsError(try relation.add("yolo", objects: [level]))
}

func testAddOperationsNoKey() throws {
func testAddOperationNoKey() throws {
var score = GameScore(points: 10)
let objectId = "hello"
score.objectId = objectId
Expand All @@ -274,7 +274,7 @@ class ParseRelationTests: XCTestCase {
XCTAssertEqual(decoded, expected)
}

func testAddOperationsKeyCheck() throws {
func testAddOperationKeyCheck() throws {
var score = GameScore(points: 10)
let objectId = "hello"
score.objectId = objectId
Expand Down
312 changes: 312 additions & 0 deletions Tests/ParseSwiftTests/ParseRoleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,318 @@ class ParseRoleTests: XCTestCase {
XCTAssertEqual(decoded2, expected2)
}

func testRoleAddOperationSaveSynchronous() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
let operation = try roles.add([newRole])

var serverResponse = role
serverResponse.createdAt = nil
serverResponse.updatedAt = Date()

let encoded: Data!
do {
encoded = try ParseCoding.jsonEncoder().encode(serverResponse)
//Get dates in correct format from ParseDecoding strategy
serverResponse = try serverResponse.getDecoder().decode(Role<User>.self, from: encoded)
} catch {
XCTFail("Should encode/decode. Error \(error)")
return
}

MockURLProtocol.mockRequests { _ in
return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0)
}

let updatedRole = try operation.save()
XCTAssertEqual(updatedRole.updatedAt, serverResponse.updatedAt)
XCTAssertTrue(updatedRole.hasSameObjectId(as: serverResponse))
}

func testRoleAddOperationSaveSynchronousError() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
var operation = try roles.add([newRole])
operation.target.objectId = nil

do {
_ = try operation.save()
XCTFail("Should have failed")
} catch {
XCTAssertTrue(error.containedIn([.missingObjectId]))
}
}

func testRoleAddOperationSaveSynchronousCustomObjectId() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

ParseSwift.configuration.isAllowingCustomObjectIds = true
var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
let operation = try roles.add([newRole])

var serverResponse = role
serverResponse.createdAt = nil
serverResponse.updatedAt = Date()

let encoded: Data!
do {
encoded = try ParseCoding.jsonEncoder().encode(serverResponse)
//Get dates in correct format from ParseDecoding strategy
serverResponse = try serverResponse.getDecoder().decode(Role<User>.self, from: encoded)
} catch {
XCTFail("Should encode/decode. Error \(error)")
return
}

MockURLProtocol.mockRequests { _ in
return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0)
}

let updatedRole = try operation.save()
XCTAssertEqual(updatedRole.updatedAt, serverResponse.updatedAt)
XCTAssertTrue(updatedRole.hasSameObjectId(as: serverResponse))
}

func testRoleAddOperationSaveSynchronousCustomObjectIdError() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

ParseSwift.configuration.isAllowingCustomObjectIds = true
var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
var operation = try roles.add([newRole])
operation.target.objectId = nil

do {
_ = try operation.save()
XCTFail("Should have failed")
} catch {
XCTAssertTrue(error.containedIn([.missingObjectId]))
}
}

func testRoleAddOperationSaveAsynchronous() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
let operation = try roles.add([newRole])

var serverResponse = role
serverResponse.createdAt = nil
serverResponse.updatedAt = Date()

let encoded: Data!
do {
encoded = try ParseCoding.jsonEncoder().encode(serverResponse)
//Get dates in correct format from ParseDecoding strategy
serverResponse = try serverResponse.getDecoder().decode(Role<User>.self, from: encoded)
} catch {
XCTFail("Should encode/decode. Error \(error)")
return
}

MockURLProtocol.mockRequests { _ in
return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0)
}

let expectation1 = XCTestExpectation(description: "Save object1")
operation.save { result in
switch result {
case .success(let updatedRole):
XCTAssertEqual(updatedRole.updatedAt, serverResponse.updatedAt)
XCTAssertTrue(updatedRole.hasSameObjectId(as: serverResponse))
case .failure(let error):
XCTFail(error.localizedDescription)
}
expectation1.fulfill()
}
wait(for: [expectation1], timeout: 20.0)
}

func testRoleAddOperationSaveAsynchronousError() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

ParseSwift.configuration.isAllowingCustomObjectIds = true
var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
var operation = try roles.add([newRole])
operation.target.objectId = nil

let expectation1 = XCTestExpectation(description: "Save object1")
operation.save { result in
switch result {
case .success:
XCTFail("Should have failed")
case .failure(let error):
XCTAssertEqual(error.code, .missingObjectId)
}
expectation1.fulfill()
}
wait(for: [expectation1], timeout: 20.0)
}

func testRoleAddOperationSaveAsynchronousCustomObjectId() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

ParseSwift.configuration.isAllowingCustomObjectIds = true
var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
let operation = try roles.add([newRole])

var serverResponse = role
serverResponse.createdAt = nil
serverResponse.updatedAt = Date()

let encoded: Data!
do {
encoded = try ParseCoding.jsonEncoder().encode(serverResponse)
//Get dates in correct format from ParseDecoding strategy
serverResponse = try serverResponse.getDecoder().decode(Role<User>.self, from: encoded)
} catch {
XCTFail("Should encode/decode. Error \(error)")
return
}

MockURLProtocol.mockRequests { _ in
return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0)
}

let expectation1 = XCTestExpectation(description: "Save object1")
operation.save { result in
switch result {
case .success(let updatedRole):
XCTAssertEqual(updatedRole.updatedAt, serverResponse.updatedAt)
XCTAssertTrue(updatedRole.hasSameObjectId(as: serverResponse))
case .failure(let error):
XCTFail(error.localizedDescription)
}
expectation1.fulfill()
}
wait(for: [expectation1], timeout: 20.0)
}

func testRoleAddOperationSaveAsynchronousCustomObjectIdError() throws {
var acl = ParseACL()
acl.publicWrite = false
acl.publicRead = true

var role = try Role<User>(name: "Administrator", acl: acl)
role.createdAt = Date()
role.updatedAt = Date()
XCTAssertNil(role.roles) // Shouldn't produce a relation without an objectId.
role.objectId = "yolo"
guard let roles = role.roles else {
XCTFail("Should have unwrapped")
return
}

var newRole = try Role<User>(name: "Moderator", acl: acl)
newRole.objectId = "heel"
var operation = try roles.add([newRole])
operation.target.objectId = nil

let expectation1 = XCTestExpectation(description: "Save object1")
operation.save { result in
switch result {
case .success:
XCTFail("Should have failed")
case .failure(let error):
XCTAssertEqual(error.code, .missingObjectId)
}
expectation1.fulfill()
}
wait(for: [expectation1], timeout: 20.0)
}

func testRoleAddOperationNoKey() throws {
var acl = ParseACL()
acl.publicWrite = false
Expand Down