-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ability to transform values on migrate #228
Conversation
@@ -708,7 +708,7 @@ class ValetIntegrationTests: XCTestCase | |||
} | |||
} | |||
|
|||
func test_migrateObjectsMatching_withAccountNameAsData_doesNotRaiseException() throws |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test name was incorrect.
Codecov Report
@@ Coverage Diff @@
## master #228 +/- ##
==========================================
+ Coverage 85.68% 86.74% +1.06%
==========================================
Files 15 16 +1
Lines 992 1049 +57
==========================================
+ Hits 850 910 +60
+ Misses 142 139 -3
|
for keychainEntry in retrievedItemsToMigrateWithData { | ||
guard let key = keychainEntry[kSecAttrAccount as String] as? String, key != Keychain.canaryKey else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll force the key
to be a String
later on as part of the compactMap
. For now, we just want to make sure we have a key.
fddf1ce
to
9ed7cd6
Compare
@@ -167,6 +172,271 @@ - (void)test_iCloudValetWithSharedAccessGroupIdentifier_accessibility_returnsNil | |||
XCTAssertNil(valet); | |||
} | |||
|
|||
- (void)test_containsObjectForKey_returnsTrueWhenObjectExistsInKeychain; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized while I was here that I didn’t have an explicit objective-c test for this wrapper method, so I wrote a couple
@@ -45,6 +45,11 @@ - (NSString *)sharedAccessGroupIdentifier; | |||
#endif | |||
} | |||
|
|||
- (BOOL)testEnvironmentIsSigned; | |||
{ | |||
return NSBundle.mainBundle.bundleIdentifier != nil && ![NSBundle.mainBundle.bundleIdentifier isEqualToString:@"com.apple.dt.xctest.tool"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is the same logic used in the swift tests
@@ -732,7 +732,130 @@ class ValetIntegrationTests: XCTestCase | |||
XCTAssertEqual(error as? MigrationError, .keyToMigrateInvalid) | |||
} | |||
} | |||
|
|||
|
|||
func test_migrateObjectsMatchingCompactMap_successfullyMigratesTransformedValue() throws { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also add a test that transforms the key
? (Same for the Valet -> Valet equivalent below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call! Will add
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mostly looked at the public API 😉
import Foundation | ||
|
||
/// A struct that represented a key:value pair that can be migrated. | ||
public struct MigratableKeyValuePair<KeyType: Hashable>: Hashable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe?
public struct MigratableKeyValuePair<KeyType: Hashable>: Hashable { | |
public struct MigratableKeyValuePair<Key: Hashable>: Hashable { |
https://swift.org/documentation/api-design-guidelines#name-according-to-roles
|
||
/// A sentinal `ObjectiveCCompatibilityMigratableKeyValuePairOutput` that conveys that the migration should be prevented. | ||
@objc | ||
public static func preventMigration() -> ObjectiveCCompatibilityMigratableKeyValuePairOutput { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method sounds to me more than its actually doing the action to prevent migration on an instance rather than creating an instance that prevents the migration.
Maybe migrationDisabled
/ migrationPrevented
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the tough thing here is it isn't super clear that we're doing this work before the migration has started. This is why I wanted to use a future tense. A past-tense phrase here might make it read as if returning it prevented/disabled the migration of just this pair (or future pairs).
In the context where it's used, I hope this method reads well:
Valet/Tests/ValetObjectiveCBridgeTests/VALValetTests.m
Lines 475 to 484 in c7cec75
[otherValet migrateObjectsMatching:@{ | |
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, | |
(__bridge id)kSecAttrService : @"VAL_VALValet_initWithIdentifier:accessibility:_identifier_AccessibleWhenUnlocked", | |
} compactMap:^VALMigratableKeyValuePairOutput * _Nullable(VALMigratableKeyValuePairInput * _Nonnull input) { | |
if ([input.key isEqualToString:key1]) { | |
return [[VALMigratableKeyValuePairOutput alloc] initWithKey:input.key value:input.value];; | |
} else { | |
return VALMigratableKeyValuePairOutput.preventMigration; | |
} | |
} error:nil]; |
The documentation on the migrateObjectsMatching
Objective-C method also makes it clear how to use this method:
Valet/Sources/Valet/Valet.swift
Lines 661 to 668 in c7cec75
/// Migrates objects matching the input query into the receiving Valet instance. | |
/// - Parameters: | |
/// - query: The query with which to retrieve existing keychain data via a call to SecItemCopyMatching. | |
/// - compactMap: A closure that transforms a key:value pair from the raw pair currently in the keychain into a key:value pair we'll insert into the destination Valet. Returning `nil` from this closure will cause that key:value pair not to be migrated. Returning `VALMigratableKeyValuePairOutput.preventMigration` will prevent migrating any key:value pairs. | |
/// - error: An error of type `KeychainError` or `MigrationError`. | |
@available(swift, obsoleted: 1.0) | |
@objc(migrateObjectsMatching:compactMap:error:) | |
public func 🚫swift_migrateObjects(matching query: [String : AnyHashable], compactMap: (ObjectiveCCompatibilityMigratableKeyValuePairInput) -> ObjectiveCCompatibilityMigratableKeyValuePairOutput?) throws { |
While I agree that reading this method by itself is a bit confusing, I think within the context it's supposed to be used it makes sense? Let me know if not @fdiaz.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, I should make this method available only to Objective-C
Co-authored-by: Nick Entin <[email protected]>
093d029
to
abb6d42
Compare
Force push had no functional changes. Only change was branch history after merging |
This PR resolves #226 by adding the ability to
compactMap
over key:value pairs as they are being migrated.I do not intend to merge this PR prior to the release of Valet 4.0.