From 3852a93ed00e532c6214086700fb98e5eb4bd03f Mon Sep 17 00:00:00 2001 From: Corey Date: Fri, 2 Apr 2021 08:42:23 -0400 Subject: [PATCH] Recreate new installation after deletion from keychain (#112) * Create new installation automatically after it's removed from keychain * Add changelog * Make sure installationId's aren't nil --- CHANGELOG.md | 3 +- .../Objects/ParseInstallation.swift | 4 + .../ParseUserCombineTests.swift | 59 ++++++++----- Tests/ParseSwiftTests/ParseUserTests.swift | 85 +++++++++++++------ 4 files changed, 100 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86683026d..f095679d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ [Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.2.5...1.2.6) __Fixes__ -- Crash when linking auth types due to server not sending sessionToken ([#109](https://github.com/parse-community/Parse-Swift/pull/109)), thanks to [Corey Baker](https://github.com/cbaker6). +- Recreate installation automatically after deletion from Keychain ([#112](https://github.com/parse-community/Parse-Swift/pull/112)), thanks to [Corey Baker](https://github.com/cbaker6). +- Error when linking auth types due to server not sending sessionToken ([#109](https://github.com/parse-community/Parse-Swift/pull/109)), thanks to [Corey Baker](https://github.com/cbaker6). ### 1.2.5 [Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.2.4...1.2.5) diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index d14a4407c..9c03b422f 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -187,6 +187,10 @@ extension ParseInstallation { #if !os(Linux) && !os(Android) try? KeychainStore.shared.delete(valueFor: ParseStorage.Keys.currentInstallation) #endif + //Prepare new installation + DispatchQueue.main.async { + _ = BaseParseInstallation() + } } /** diff --git a/Tests/ParseSwiftTests/ParseUserCombineTests.swift b/Tests/ParseSwiftTests/ParseUserCombineTests.swift index 9ea577e56..5a37c000f 100644 --- a/Tests/ParseSwiftTests/ParseUserCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseUserCombineTests.swift @@ -293,32 +293,47 @@ class ParseUserCombineTests: XCTestCase { // swiftlint:disable:this type_body_le } let expectation1 = XCTestExpectation(description: "Logout user1") - let publisher = User.logoutPublisher() - .sink(receiveCompletion: { result in - - if case let .failure(error) = result { - XCTFail(error.localizedDescription) - } + DispatchQueue.main.async { + guard let oldInstallationId = BaseParseInstallation.current?.installationId else { + XCTFail("Should have unwrapped") expectation1.fulfill() - - }, receiveValue: { _ in - if let userFromKeychain = BaseParseUser.current { - XCTFail("\(userFromKeychain) wasn't deleted from Keychain during logout") + return } + let publisher = User.logoutPublisher() + .sink(receiveCompletion: { result in - if let installationFromMemory: CurrentInstallationContainer - = try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { - XCTFail("\(installationFromMemory) wasn't deleted from memory during logout") - } + if case let .failure(error) = result { + XCTFail(error.localizedDescription) + } + expectation1.fulfill() - #if !os(Linux) && !os(Android) - if let installationFromKeychain: CurrentInstallationContainer - = try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { - XCTFail("\(installationFromKeychain) wasn't deleted from Keychain during logout") - } - #endif - }) - publisher.store(in: &subscriptions) + }, receiveValue: { _ in + if let userFromKeychain = BaseParseUser.current { + XCTFail("\(userFromKeychain) wasn't deleted from Keychain during logout") + } + DispatchQueue.main.async { + if let installationFromMemory: CurrentInstallationContainer + = try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { + if installationFromMemory.installationId == oldInstallationId + && installationFromMemory.installationId != nil { + XCTFail("\(installationFromMemory) wasn't deleted and recreated in memory during logout") + } + } + + #if !os(Linux) && !os(Android) + if let installationFromKeychain: CurrentInstallationContainer + = try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { + if installationFromKeychain.installationId == oldInstallationId + && installationFromKeychain.installationId != nil { + // swiftlint:disable:next line_length + XCTFail("\(installationFromKeychain) wasn't deleted and recreated in Keychain during logout") + } + } + #endif + } + }) + publisher.store(in: &subscriptions) + } wait(for: [expectation1], timeout: 20.0) } diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index 638febb3b..10a885d74 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -1094,48 +1094,77 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length return nil } } - do { - try User.logout() - if let userFromKeychain = BaseParseUser.current { - XCTFail("\(userFromKeychain) wasn't deleted from Keychain during logout") - } - if let installationFromKeychain = BaseParseInstallation.current { - XCTFail("\(installationFromKeychain) wasn't deleted from Keychain during logout") + DispatchQueue.main.async { + guard let oldInstallationId = BaseParseInstallation.current?.installationId else { + XCTFail("Should have unwrapped") + return + } + do { + try User.logout() + if let userFromKeychain = BaseParseUser.current { + XCTFail("\(userFromKeychain) wasn't deleted from Keychain during logout") + } + DispatchQueue.main.async { + if let installationFromKeychain = BaseParseInstallation.current { + if installationFromKeychain.installationId == oldInstallationId + && installationFromKeychain.installationId != nil { + XCTFail("\(installationFromKeychain) wasn't deleted then created in Keychain during logout") + } + } + } + } catch { + XCTFail(error.localizedDescription) } - } catch { - XCTFail(error.localizedDescription) } } func logoutAsync(callbackQueue: DispatchQueue) { let expectation1 = XCTestExpectation(description: "Logout user1") - User.logout(callbackQueue: callbackQueue) { result in - switch result { + DispatchQueue.main.async { + guard let oldInstallationId = BaseParseInstallation.current?.installationId else { + XCTFail("Should have unwrapped") + expectation1.fulfill() + return + } - case .success: - if let userFromKeychain = BaseParseUser.current { - XCTFail("\(userFromKeychain) wasn't deleted from Keychain during logout") - } + User.logout(callbackQueue: callbackQueue) { result in - if let installationFromMemory: CurrentInstallationContainer - = try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { - XCTFail("\(installationFromMemory) wasn't deleted from memory during logout") - } + switch result { - #if !os(Linux) && !os(Android) - if let installationFromKeychain: CurrentInstallationContainer - = try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { - XCTFail("\(installationFromKeychain) wasn't deleted from Keychain during logout") - } - #endif + case .success: + if let userFromKeychain = BaseParseUser.current { + XCTFail("\(userFromKeychain) wasn't deleted from Keychain during logout") + } + DispatchQueue.main.async { + if let installationFromMemory: CurrentInstallationContainer + = try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { + if installationFromMemory.installationId == oldInstallationId + && installationFromMemory.installationId != nil { + // swiftlint:disable:next line_length + XCTFail("\(installationFromMemory) wasn't deleted and recreated in memory during logout") + } + } - case .failure(let error): - XCTFail(error.localizedDescription) + #if !os(Linux) && !os(Android) + if let installationFromKeychain: CurrentInstallationContainer + = try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentInstallation) { + if installationFromKeychain.installationId == oldInstallationId + && installationFromKeychain.installationId != nil { + // swiftlint:disable:next line_length + XCTFail("\(installationFromKeychain) wasn't deleted and recreated in Keychain during logout") + } + } + #endif + } + + case .failure(let error): + XCTFail(error.localizedDescription) + } + expectation1.fulfill() } - expectation1.fulfill() } wait(for: [expectation1], timeout: 20.0) }