@@ -681,6 +681,102 @@ class IterableAPITests: XCTestCase {
681681
682682 wait ( for: [ expectation] , timeout: testExpectationTimeout)
683683 }
684+
685+ @available ( iOS 13 . 0 , * )
686+ func testDisableDeviceForCurrentUserAsyncSuccess( ) async throws {
687+ let oldImplementation = IterableAPI . implementation
688+ defer { IterableAPI . implementation = oldImplementation }
689+
690+ let networkSession = MockNetworkSession ( statusCode: 200 )
691+ let token = try await setUpIterableAPIForAsyncDisableDevice ( networkSession: networkSession)
692+
693+ try await IterableAPI . disableDeviceForCurrentUser ( )
694+
695+ guard let request = networkSession. getRequest ( withEndPoint: Const . Path. disableDevice) else {
696+ return XCTFail ( " Expected disableDevice request " )
697+ }
698+ guard let body = TestUtils . getRequestBody ( request: request) else {
699+ return XCTFail ( " Expected disableDevice request body " )
700+ }
701+
702+ TestUtils . validate ( request: request,
703+ requestType: . post,
704+ apiEndPoint: Endpoint . api,
705+ path: Const . Path. disableDevice,
706+ queryParams: [ ] )
707+ TestUtils . validateElementPresent ( withName: JsonKey . token, andValue: token. hexString ( ) , inDictionary: body)
708+ TestUtils . validateElementPresent ( withName: JsonKey . email, andValue: " user@example.com " , inDictionary: body)
709+ }
710+
711+ @available ( iOS 13 . 0 , * )
712+ func testDisableDeviceForAllUsersAsyncSuccess( ) async throws {
713+ let oldImplementation = IterableAPI . implementation
714+ defer { IterableAPI . implementation = oldImplementation }
715+
716+ let networkSession = MockNetworkSession ( statusCode: 200 )
717+ let token = try await setUpIterableAPIForAsyncDisableDevice ( networkSession: networkSession)
718+
719+ try await IterableAPI . disableDeviceForAllUsers ( )
720+
721+ guard let request = networkSession. getRequest ( withEndPoint: Const . Path. disableDevice) else {
722+ return XCTFail ( " Expected disableDevice request " )
723+ }
724+ guard let body = TestUtils . getRequestBody ( request: request) else {
725+ return XCTFail ( " Expected disableDevice request body " )
726+ }
727+
728+ TestUtils . validate ( request: request,
729+ requestType: . post,
730+ apiEndPoint: Endpoint . api,
731+ path: Const . Path. disableDevice,
732+ queryParams: [ ] )
733+ TestUtils . validateElementPresent ( withName: JsonKey . token, andValue: token. hexString ( ) , inDictionary: body)
734+ TestUtils . validateElementNotPresent ( withName: JsonKey . email, inDictionary: body)
735+ TestUtils . validateElementNotPresent ( withName: JsonKey . userId, inDictionary: body)
736+ }
737+
738+ @available ( iOS 13 . 0 , * )
739+ func testDisableDeviceForCurrentUserAsyncFailureThrowsSendRequestError( ) async throws {
740+ let oldImplementation = IterableAPI . implementation
741+ defer { IterableAPI . implementation = oldImplementation }
742+
743+ let failureReason = " disable failed "
744+ let networkSession = MockNetworkSession ( responseCallback: { url in
745+ if url. absoluteString. contains ( Const . Path. disableDevice) {
746+ return MockNetworkSession . MockResponse ( statusCode: 400 ,
747+ data: [ " msg " : failureReason] . toJsonData ( ) )
748+ }
749+ return MockNetworkSession . MockResponse ( statusCode: 200 )
750+ } )
751+ _ = try await setUpIterableAPIForAsyncDisableDevice ( networkSession: networkSession)
752+
753+ do {
754+ try await IterableAPI . disableDeviceForCurrentUser ( )
755+ XCTFail ( " Expected disableDeviceForCurrentUser async API to throw " )
756+ } catch let error as SendRequestError {
757+ XCTAssertEqual ( error. reason, failureReason)
758+ XCTAssertEqual ( error. data, [ " msg " : failureReason] . toJsonData ( ) )
759+ } catch {
760+ XCTFail ( " Expected SendRequestError, got \( error) " )
761+ }
762+ }
763+
764+ @available ( iOS 13 . 0 , * )
765+ func testDisableDeviceForCurrentUserAsyncNotInitializedThrowsSendRequestError( ) async {
766+ let oldImplementation = IterableAPI . implementation
767+ IterableAPI . implementation = nil
768+ defer { IterableAPI . implementation = oldImplementation }
769+
770+ do {
771+ try await IterableAPI . disableDeviceForCurrentUser ( )
772+ XCTFail ( " Expected disableDeviceForCurrentUser async API to throw " )
773+ } catch let error as SendRequestError {
774+ XCTAssertEqual ( error. reason, " Iterable SDK is not initialized " )
775+ XCTAssertNil ( error. data)
776+ } catch {
777+ XCTFail ( " Expected SendRequestError, got \( error) " )
778+ }
779+ }
684780
685781 func testUpdateCart( ) {
686782 let condition1 = XCTestExpectation ( description: #function)
@@ -1478,4 +1574,54 @@ class IterableAPITests: XCTestCase {
14781574 XCTAssertEqual ( dateFromMilliseconds, testDate)
14791575 }
14801576
1577+ @available ( iOS 13 . 0 , * )
1578+ private func setUpIterableAPIForAsyncDisableDevice( networkSession: MockNetworkSession ) async throws -> Data {
1579+ let config = IterableConfig ( )
1580+ config. pushIntegrationName = " my-push-integration "
1581+
1582+ IterableAPI . initializeForTesting ( apiKey: IterableAPITests . apiKey,
1583+ config: config,
1584+ networkSession: networkSession)
1585+ IterableAPI . email = " user@example.com "
1586+
1587+ let token = " zeeToken " . data ( using: . utf8) !
1588+ try await registerTokenForAsyncDisableDevice ( token)
1589+ return token
1590+ }
1591+
1592+ @available ( iOS 13 . 0 , * )
1593+ private func registerTokenForAsyncDisableDevice( _ token: Data ) async throws {
1594+ try await withCheckedThrowingContinuation { continuation in
1595+ let resumeGuard = TestAsyncContinuationResumeGuard ( )
1596+
1597+ IterableAPI . register ( token: token, onSuccess: { _ in
1598+ resumeGuard. resume {
1599+ continuation. resume ( returning: ( ) )
1600+ }
1601+ } , onFailure: { reason, data in
1602+ resumeGuard. resume {
1603+ continuation. resume ( throwing: SendRequestError ( reason: reason, data: data) )
1604+ }
1605+ } )
1606+ }
1607+ }
1608+
1609+ }
1610+
1611+ private final class TestAsyncContinuationResumeGuard {
1612+ private let lock = NSLock ( )
1613+ private var didResume = false
1614+
1615+ func resume( _ block: ( ) -> Void ) {
1616+ lock. lock ( )
1617+ let shouldResume = !didResume
1618+ if shouldResume {
1619+ didResume = true
1620+ }
1621+ lock. unlock ( )
1622+
1623+ if shouldResume {
1624+ block ( )
1625+ }
1626+ }
14811627}
0 commit comments