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
26 changes: 8 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_13 }}
- name: Build-Test
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace Parse.xcworkspace -scheme ParseSwift\ \(iOS\) -destination platform\=iOS\ Simulator,name\=iPhone\ 12\ Pro\ Max -derivedDataPath DerivedData clean test | xcpretty
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace Parse.xcworkspace -scheme ParseSwift\ \(iOS\) -destination platform\=iOS\ Simulator,name\=iPhone\ 12\ Pro\ Max -derivedDataPath DerivedData -test-iterations 10 -retry-tests-on-failure clean test | xcpretty
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_13 }}
- name: Prepare codecov
Expand Down Expand Up @@ -49,7 +49,7 @@ jobs:
security unlock-keychain -p "" temporary
security set-keychain-settings -lut 7200 temporary
- name: Build-Test
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace Parse.xcworkspace -scheme ParseSwift\ \(macOS\) -destination platform\=macOS -derivedDataPath DerivedData clean test | xcpretty
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace Parse.xcworkspace -scheme ParseSwift\ \(macOS\) -destination platform\=macOS -derivedDataPath DerivedData -test-iterations 10 -retry-tests-on-failure clean test | xcpretty
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_13 }}
- name: Prepare codecov
Expand All @@ -74,7 +74,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Build
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace Parse.xcworkspace -scheme ParseSwift\ \(tvOS\) -destination platform\=tvOS\ Simulator,name\=Apple\ TV -derivedDataPath DerivedData clean test | xcpretty
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace Parse.xcworkspace -scheme ParseSwift\ \(tvOS\) -destination platform\=tvOS\ Simulator,name\=Apple\ TV -derivedDataPath DerivedData -test-iterations 10 -retry-tests-on-failure clean test | xcpretty
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_13 }}
- name: Prepare codecov
Expand Down Expand Up @@ -119,11 +119,7 @@ jobs:
security default-keychain -s temporary
security unlock-keychain -p "" temporary
security set-keychain-settings -lut 7200 temporary
- name: Build
run: swift build -v
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_13 }}
- name: Test
- name: Build and Test
run: swift test --enable-code-coverage -v
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_13 }}
Expand Down Expand Up @@ -155,11 +151,7 @@ jobs:
security default-keychain -s temporary
security unlock-keychain -p "" temporary
security set-keychain-settings -lut 7200 temporary
- name: Build
run: swift build -v
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_VER }}
- name: Test
- name: Build and Test
run: swift test --enable-code-coverage -v
env:
DEVELOPER_DIR: ${{ env.CI_XCODE_VER }}
Expand All @@ -186,10 +178,8 @@ jobs:
with:
release-version: "5"
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build
run: swift build
- name: Test
run: swift test --enable-test-discovery --enable-code-coverage
- name: Build and Test
run: swift test --enable-test-discovery --enable-code-coverage -v
- name: Prepare codecov
run: |
llvm-cov export -format="lcov" .build/x86_64-unknown-linux-gnu/debug/ParseSwiftPackageTests.xctest -instr-profile .build/x86_64-unknown-linux-gnu/debug/codecov/default.profdata > info_linux.lcov
Expand All @@ -206,7 +196,7 @@ jobs:
- uses: MaxDesiatov/swift-windows-action@v1
with:
swift-version: "5.5.1"
shell-action: swift test --enable-test-discovery --enable-code-coverage
shell-action: swift test --enable-test-discovery --enable-code-coverage -v
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

__New features__
- Add a retry mechanism to the SDK that randomly (up to 3 seconds each) tries to reconnect up to 5 times. The developer can increase or reduce the amount of retries when configuring the SDK ([#291](https://github.com/parse-community/Parse-Swift/pull/291)), thanks to [Corey Baker](https://github.com/cbaker6).
- Add toCLLocation and toCLLocationCoordinate2D methods for easy conversion from a ParseGeoPoint object. ([#287](https://github.com/parse-community/Parse-Swift/pull/287)), thanks to [Jayson Ng](https://github.com/jaysonng).
- Add toCLLocation and toCLLocationCoordinate2D methods for easy conversion from a ParseGeoPoint object ([#287](https://github.com/parse-community/Parse-Swift/pull/287)), thanks to [Jayson Ng](https://github.com/jaysonng).

__Fixes__
- Fixed an issue where an annonymous couldn't be turned into a regular user using signup ([#291](https://github.com/parse-community/Parse-Swift/pull/291)), thanks to [Corey Baker](https://github.com/cbaker6).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,15 @@ public extension ParseUser {
}
}

internal func linkCommand() -> API.Command<Self, Self> {
var mutableSelf = self
mutableSelf = mutableSelf.anonymous.strip(mutableSelf)
internal func linkCommand() throws -> API.Command<Self, Self> {
var mutableSelf = self.anonymous.strip(self)
if let current = Self.current {
guard current.hasSameObjectId(as: self) else {
let error = ParseError(code: .unknownError,
message: "Can't signup a user with a different objectId than the current user")
throw error
}
}
return API.Command<Self, Self>(method: .PUT,
path: endpoint,
body: mutableSelf) { (data) -> Self in
Expand Down
33 changes: 16 additions & 17 deletions Sources/ParseSwift/Objects/ParseUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -557,12 +557,7 @@ extension ParseUser {
public func signup(options: API.Options = []) throws -> Self {
var options = options
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
if let current = Self.current {
guard current.hasSameObjectId(as: self) else {
let error = ParseError(code: .unknownError,
message: "Can't signup a user with a different objectId than the current user")
throw error
}
if Self.current != nil {
return try self.linkCommand()
.execute(options: options)
} else {
Expand All @@ -587,20 +582,24 @@ extension ParseUser {
completion: @escaping (Result<Self, ParseError>) -> Void) {
var options = options
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
if let current = Self.current {
guard current.hasSameObjectId(as: self) else {
let error = ParseError(code: .unknownError,
message: "Can't signup a user with a different objectId than the current user")
if Self.current != nil {
do {
try self.linkCommand()
.executeAsync(options: options,
callbackQueue: callbackQueue) { result in
completion(result)
}
} catch {
callbackQueue.async {
completion(.failure(error))
if let parseError = error as? ParseError {
completion(.failure(parseError))
} else {
let parseError = ParseError(code: .unknownError,
message: error.localizedDescription)
completion(.failure(parseError))
}
}
return
}
self.linkCommand()
.executeAsync(options: options,
callbackQueue: callbackQueue) { result in
completion(result)
}
} else {
do {
try signupCommand()
Expand Down
29 changes: 26 additions & 3 deletions Tests/ParseSwiftTests/APICommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,34 @@ class APICommandTests: XCTestCase {
}
}

//This is less common as the HTTP won't be able to produce ParseErrors directly, but used for testing
func testErrorHTTPReturnsParseError1() {
func testErrorHTTPReturns400NoDataFromServer() {
let originalError = ParseError(code: .unknownError, message: "Couldn't decode")
MockURLProtocol.mockRequests { _ in
return MockURLResponse(error: originalError)
return MockURLResponse(error: originalError) // Status code defaults to 400
}
do {
_ = try API.NonParseBodyCommand<NoBody, NoBody>(method: .GET,
path: .login,
params: nil,
mapper: { (_) -> NoBody in
throw originalError
}).execute(options: [])
XCTFail("Should have thrown an error")
} catch {
guard let error = error as? ParseError else {
XCTFail("should be able unwrap final error to ParseError")
return
}
XCTAssertEqual(originalError.code, error.code)
}
}

func testErrorHTTPReturns500NoDataFromServer() {
let originalError = ParseError(code: .unknownError, message: "Couldn't decode")
MockURLProtocol.mockRequests { _ in
var response = MockURLResponse(error: originalError)
response.statusCode = 500
return response
}
do {
_ = try API.NonParseBodyCommand<NoBody, NoBody>(method: .GET,
Expand Down
19 changes: 11 additions & 8 deletions Tests/ParseSwiftTests/NetworkMocking/MockURLProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class MockURLProtocol: URLProtocol {
mockRequestsPassing(Int.max, test: test, with: response)
}

class func mockRequestsPassing(_ attempts: Int, test: @escaping (URLRequest) -> Bool,
class func mockRequestsPassing(_ attempts: Int,
test: @escaping (URLRequest) -> Bool,
with response: @escaping (URLRequest) -> MockURLResponse?) {
let mock = MockURLProtocolMock(attempts: attempts, test: test, response: response)
mocks.append(mock)
Expand Down Expand Up @@ -77,7 +78,9 @@ class MockURLProtocol: URLProtocol {
return request
}

override required init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
override required init(request: URLRequest,
cachedResponse: CachedURLResponse?,
client: URLProtocolClient?) {
super.init(request: request, cachedResponse: cachedResponse, client: client)
guard let mock = MockURLProtocol.firstMockForRequest(request) else {
self.mock = nil
Expand Down Expand Up @@ -105,17 +108,17 @@ class MockURLProtocol: URLProtocol {
}

guard let url = request.url,
let urlResponse = HTTPURLResponse(url: url, statusCode: response.statusCode,
httpVersion: "HTTP/2", headerFields: response.headerFields) else {
return
}
let urlResponse = HTTPURLResponse(url: url,
statusCode: response.statusCode,
httpVersion: "HTTP/2",
headerFields: response.headerFields) else {
return
}

DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + response.delay) {

if !self.loading {
return
}

self.client?.urlProtocol(self, didReceive: urlResponse, cacheStoragePolicy: .notAllowed)
if let data = response.responseData {
self.client?.urlProtocol(self, didLoad: data)
Expand Down
17 changes: 8 additions & 9 deletions Tests/ParseSwiftTests/NetworkMocking/MockURLResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@ struct MockURLResponse {
try self.init(string: string, statusCode: 200, delay: .init(0.0))
}

init(string: String, statusCode: Int, delay: TimeInterval,
init(string: String,
statusCode: Int,
delay: TimeInterval,
headerFields: [String: String] = ["Content-Type": "application/json"]) throws {

do {
let encoded = try JSONEncoder().encode(string)
self.init(data: encoded, statusCode: statusCode, delay: delay, headerFields: headerFields)
} catch {
throw ParseError(code: .unknownError, message: "unable to convert string to data")
}
let encoded = try JSONEncoder().encode(string)
self.init(data: encoded, statusCode: statusCode, delay: delay, headerFields: headerFields)
}

init(data: Data, statusCode: Int, delay: TimeInterval,
init(data: Data,
statusCode: Int,
delay: TimeInterval,
headerFields: [String: String] = ["Content-Type": "application/json"]) {
self.statusCode = statusCode
self.headerFields = headerFields
Expand Down
4 changes: 2 additions & 2 deletions Tests/ParseSwiftTests/ParseAuthenticationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class ParseAuthenticationTests: XCTestCase {
var user = User()
user.username = "hello"
user.password = "world"
let command = user.linkCommand()
let command = try user.linkCommand()
XCTAssertNotNil(command)
XCTAssertEqual(command.path.urlComponent, "/users")
XCTAssertEqual(command.method, API.Method.PUT)
Expand All @@ -188,7 +188,7 @@ class ParseAuthenticationTests: XCTestCase {

func testLinkCommandNoBodyLoggedIn() throws {
let user = try loginNormally()
let command = user.linkCommand()
let command = try user.linkCommand()
XCTAssertNotNil(command)
XCTAssertEqual(command.path.urlComponent, "/users/\("yarr")")
XCTAssertEqual(command.method, API.Method.PUT)
Expand Down