Skip to content

Commit 62eee27

Browse files
authored
feat: Add missing become() type methods (#66)
1 parent ed55608 commit 62eee27

File tree

5 files changed

+154
-0
lines changed

5 files changed

+154
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.0.1...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift)
66
* _Contributing to this repo? Add info about your change here to be included in the next release_
77

8+
__New features__
9+
* Add missing async/await and Combine ParseUser.become() type methods ([#66](https://github.com/netreconlab/Parse-Swift/pull/66)), thanks to [Corey Baker](https://github.com/cbaker6).
10+
811
### 5.0.1
912
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.0.0...5.0.1), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.0.1/documentation/parseswift)
1013

Sources/ParseSwift/Objects/ParseUser+async.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,25 @@ public extension ParseUser {
9999
}
100100
}
101101

102+
/**
103+
Logs in a `ParseUser` *asynchronously* with a session token. On success, this saves the logged in
104+
`ParseUser`with this session to the keychain, so you can retrieve the currently logged in user using
105+
*current*.
106+
107+
- parameter sessionToken: The sessionToken of the user to login.
108+
- parameter options: A set of header options sent to the server. Defaults to an empty set.
109+
- returns: Returns the logged in `ParseUser`.
110+
- throws: An error of type `ParseError`.
111+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
112+
desires a different policy, it should be inserted in `options`.
113+
*/
114+
@discardableResult static func become(sessionToken: String,
115+
options: API.Options = []) async throws -> Self {
116+
try await withCheckedThrowingContinuation { continuation in
117+
Self.become(sessionToken: sessionToken, options: options, completion: continuation.resume)
118+
}
119+
}
120+
102121
#if !os(Linux) && !os(Android) && !os(Windows)
103122
/**
104123
Logs in a `ParseUser` *asynchronously* using the session token from the Parse Objective-C SDK Keychain.

Sources/ParseSwift/Objects/ParseUser+combine.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,24 @@ public extension ParseUser {
9696
}
9797
}
9898

99+
/**
100+
Logs in a `ParseUser` *asynchronously* with a session token. On success, this saves the logged in
101+
`ParseUser`with this session to the keychain, so you can retrieve the currently logged in user using
102+
*current*.
103+
104+
- parameter sessionToken: The sessionToken of the user to login.
105+
- parameter options: A set of header options sent to the server. Defaults to an empty set.
106+
- returns: A publisher that eventually produces a single value and then finishes or fails.
107+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
108+
desires a different policy, it should be inserted in `options`.
109+
*/
110+
static func becomePublisher(sessionToken: String,
111+
options: API.Options = []) -> Future<Self, ParseError> {
112+
Future { promise in
113+
Self.become(sessionToken: sessionToken, options: options, completion: promise)
114+
}
115+
}
116+
99117
#if !os(Linux) && !os(Android) && !os(Windows)
100118
/**
101119
Logs in a `ParseUser` *asynchronously* using the session token from the Parse Objective-C SDK Keychain.

Tests/ParseSwiftTests/ParseUserCombineTests.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,73 @@ class ParseUserCombineTests: XCTestCase { // swiftlint:disable:this type_body_le
349349
wait(for: [expectation1], timeout: 20.0)
350350
}
351351

352+
func testBecomeTypeMethod() async throws {
353+
try await login()
354+
MockURLProtocol.removeAll()
355+
356+
let user = try await User.current()
357+
XCTAssertNotNil(user.objectId)
358+
359+
var serverResponse = LoginSignupResponse()
360+
serverResponse.createdAt = user.createdAt
361+
serverResponse.updatedAt = user.updatedAt?.addingTimeInterval(+300)
362+
serverResponse.sessionToken = "newValue"
363+
serverResponse.username = "stop"
364+
365+
var subscriptions = Set<AnyCancellable>()
366+
MockURLProtocol.mockRequests { _ in
367+
do {
368+
let encoded = try serverResponse.getEncoder().encode(serverResponse, skipKeys: .none)
369+
return MockURLResponse(data: encoded, statusCode: 200)
370+
} catch {
371+
return nil
372+
}
373+
}
374+
375+
let expectation1 = XCTestExpectation(description: "Become user1")
376+
let expectation2 = XCTestExpectation(description: "Become user2")
377+
let publisher = User.becomePublisher(sessionToken: serverResponse.sessionToken)
378+
.sink(receiveCompletion: { result in
379+
380+
if case let .failure(error) = result {
381+
XCTFail(error.localizedDescription)
382+
expectation2.fulfill()
383+
}
384+
expectation1.fulfill()
385+
386+
}, receiveValue: { signedUp in
387+
XCTAssertNotNil(signedUp)
388+
XCTAssertNotNil(signedUp.createdAt)
389+
XCTAssertNotNil(signedUp.updatedAt)
390+
XCTAssertNotNil(signedUp.email)
391+
XCTAssertNotNil(signedUp.username)
392+
XCTAssertNil(signedUp.password)
393+
XCTAssertNotNil(signedUp.objectId)
394+
XCTAssertNotNil(signedUp.customKey)
395+
XCTAssertNil(signedUp.ACL)
396+
397+
Task {
398+
do {
399+
let userFromKeychain = try await BaseParseUser.current()
400+
XCTAssertNotNil(userFromKeychain.createdAt)
401+
XCTAssertNotNil(userFromKeychain.updatedAt)
402+
XCTAssertNotNil(userFromKeychain.email)
403+
XCTAssertNotNil(userFromKeychain.username)
404+
XCTAssertNil(userFromKeychain.password)
405+
XCTAssertNotNil(userFromKeychain.objectId)
406+
XCTAssertNil(userFromKeychain.ACL)
407+
} catch {
408+
XCTFail(error.localizedDescription)
409+
}
410+
DispatchQueue.main.async {
411+
expectation2.fulfill()
412+
}
413+
}
414+
})
415+
publisher.store(in: &subscriptions)
416+
wait(for: [expectation1], timeout: 20.0)
417+
}
418+
352419
func testLogout() async throws {
353420
try await login()
354421
MockURLProtocol.removeAll()

Tests/ParseSwiftTests/ParseUserTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,53 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length
551551
XCTAssertNil(userFromKeychain.ACL)
552552
}
553553

554+
@MainActor
555+
func testBecomeTypeMethod() async throws {
556+
try await login()
557+
MockURLProtocol.removeAll()
558+
559+
let user = try await User.current()
560+
561+
var serverResponse = LoginSignupResponse()
562+
serverResponse.updatedAt = user.updatedAt?.addingTimeInterval(+300)
563+
serverResponse.sessionToken = "newValue"
564+
serverResponse.username = "stop"
565+
566+
MockURLProtocol.mockRequests { _ in
567+
do {
568+
let encoded = try serverResponse.getEncoder().encode(serverResponse, skipKeys: .none)
569+
return MockURLResponse(data: encoded, statusCode: 200)
570+
} catch {
571+
return nil
572+
}
573+
}
574+
575+
guard let sessionToken = serverResponse.sessionToken else {
576+
XCTFail("Should have unwrapped")
577+
return
578+
}
579+
let signedUp = try await User.become(sessionToken: sessionToken)
580+
XCTAssertNotNil(signedUp)
581+
XCTAssertNotNil(signedUp.updatedAt)
582+
XCTAssertNotNil(signedUp.email)
583+
XCTAssertNotNil(signedUp.username)
584+
XCTAssertNil(signedUp.password)
585+
XCTAssertNotNil(signedUp.objectId)
586+
XCTAssertNotNil(signedUp.customKey)
587+
XCTAssertNil(signedUp.ACL)
588+
589+
let userFromKeychain = try await BaseParseUser.current()
590+
591+
XCTAssertNotNil(userFromKeychain.createdAt)
592+
XCTAssertNotNil(userFromKeychain.updatedAt)
593+
XCTAssertNotNil(userFromKeychain.email)
594+
XCTAssertNotNil(userFromKeychain.username)
595+
XCTAssertNil(userFromKeychain.password)
596+
XCTAssertNotNil(userFromKeychain.objectId)
597+
_ = try await BaseParseUser.sessionToken()
598+
XCTAssertNil(userFromKeychain.ACL)
599+
}
600+
554601
@MainActor
555602
func testLogutCommand() async throws {
556603
let command = User.logoutCommand()

0 commit comments

Comments
 (0)