add tests for AppKeychain

This commit is contained in:
Lysann Tranvouez 2026-03-09 13:36:19 +01:00
parent 7a65a27d34
commit b9851eb938
2 changed files with 105 additions and 0 deletions

View file

@ -114,6 +114,7 @@
5F9D7B0D27AF6F7500A8AB22 /* CryptoTokenKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 5F9D7B0D27AF6F7500A8AB22 /* CryptoTokenKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
5F9D7B0E27AF6FCA00A8AB22 /* CryptoTokenKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 5F9D7B0E27AF6FCA00A8AB22 /* CryptoTokenKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
5F9D7B0F27AF6FD200A8AB22 /* CryptoTokenKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 5F9D7B0F27AF6FD200A8AB22 /* CryptoTokenKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
8A4716692F5EF56900C7A64D /* AppKeychainTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A4716682F5EF56900C7A64D /* AppKeychainTest.swift */; };
8AD8EBF32F5E2723007475AB /* Fixtures in Resources */ = {isa = PBXBuildFile; fileRef = 8AD8EBF22F5E268D007475AB /* Fixtures */; }; 8AD8EBF32F5E2723007475AB /* Fixtures in Resources */ = {isa = PBXBuildFile; fileRef = 8AD8EBF22F5E268D007475AB /* Fixtures */; };
9A1D1CE526E5D1CE0052028E /* OneTimePassword in Frameworks */ = {isa = PBXBuildFile; productRef = 9A1D1CE426E5D1CE0052028E /* OneTimePassword */; }; 9A1D1CE526E5D1CE0052028E /* OneTimePassword in Frameworks */ = {isa = PBXBuildFile; productRef = 9A1D1CE426E5D1CE0052028E /* OneTimePassword */; };
9A1D1CE726E5D2230052028E /* OneTimePassword in Frameworks */ = {isa = PBXBuildFile; productRef = 9A1D1CE626E5D2230052028E /* OneTimePassword */; }; 9A1D1CE726E5D2230052028E /* OneTimePassword in Frameworks */ = {isa = PBXBuildFile; productRef = 9A1D1CE626E5D2230052028E /* OneTimePassword */; };
@ -423,6 +424,7 @@
30F6C1B327664C7200BE5AB2 /* SVProgressHUD.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = SVProgressHUD.xcframework; path = Carthage/Build/SVProgressHUD.xcframework; sourceTree = "<group>"; }; 30F6C1B327664C7200BE5AB2 /* SVProgressHUD.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = SVProgressHUD.xcframework; path = Carthage/Build/SVProgressHUD.xcframework; sourceTree = "<group>"; };
30FD2F77214D9E0E005E0A92 /* ParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserTest.swift; sourceTree = "<group>"; }; 30FD2F77214D9E0E005E0A92 /* ParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserTest.swift; sourceTree = "<group>"; };
5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoTokenKit.framework; path = System/Library/Frameworks/CryptoTokenKit.framework; sourceTree = SDKROOT; }; 5F9D7B0C27AF6F7300A8AB22 /* CryptoTokenKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoTokenKit.framework; path = System/Library/Frameworks/CryptoTokenKit.framework; sourceTree = SDKROOT; };
8A4716682F5EF56900C7A64D /* AppKeychainTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppKeychainTest.swift; sourceTree = "<group>"; };
8AD8EBF22F5E268D007475AB /* Fixtures */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Fixtures; sourceTree = "<group>"; }; 8AD8EBF22F5E268D007475AB /* Fixtures */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Fixtures; sourceTree = "<group>"; };
9A1EF0B324C50DD80074FEAC /* passBeta.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = passBeta.entitlements; sourceTree = "<group>"; }; 9A1EF0B324C50DD80074FEAC /* passBeta.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = passBeta.entitlements; sourceTree = "<group>"; };
9A1EF0B424C50E780074FEAC /* passBetaAutoFillExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = passBetaAutoFillExtension.entitlements; sourceTree = "<group>"; }; 9A1EF0B424C50E780074FEAC /* passBetaAutoFillExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = passBetaAutoFillExtension.entitlements; sourceTree = "<group>"; };
@ -626,6 +628,7 @@
301F6464216164670071A4CE /* Helpers */ = { 301F6464216164670071A4CE /* Helpers */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
8A4716682F5EF56900C7A64D /* AppKeychainTest.swift */,
3032328922C9FBA2009EBD9C /* KeyFileManagerTest.swift */, 3032328922C9FBA2009EBD9C /* KeyFileManagerTest.swift */,
); );
path = Helpers; path = Helpers;
@ -1634,6 +1637,7 @@
A2699ACF24027D9500F36323 /* PasswordTableEntryTest.swift in Sources */, A2699ACF24027D9500F36323 /* PasswordTableEntryTest.swift in Sources */,
30FD2F78214D9E0E005E0A92 /* ParserTest.swift in Sources */, 30FD2F78214D9E0E005E0A92 /* ParserTest.swift in Sources */,
A2AA934622DE3A8000D79A00 /* PGPAgentTest.swift in Sources */, A2AA934622DE3A8000D79A00 /* PGPAgentTest.swift in Sources */,
8A4716692F5EF56900C7A64D /* AppKeychainTest.swift in Sources */,
30695E2524FAEF2600C9D46E /* GitCredentialTest.swift in Sources */, 30695E2524FAEF2600C9D46E /* GitCredentialTest.swift in Sources */,
30BAC8C622E3BAAF00438475 /* TestBase.swift in Sources */, 30BAC8C622E3BAAF00438475 /* TestBase.swift in Sources */,
30B04860209A5141001013CA /* PasswordTest.swift in Sources */, 30B04860209A5141001013CA /* PasswordTest.swift in Sources */,

View file

@ -0,0 +1,101 @@
//
// AppKeychainTest.swift
// passKitTests
//
// Created by Lysann Tranvouez on 9/3/26.
// Copyright © 2026 Bob Sun. All rights reserved.
//
import XCTest
@testable import passKit
final class AppKeychainTest: XCTestCase {
private let keychain = AppKeychain.shared
private let testPrefix = "test.AppKeychainTest."
override func tearDown() {
super.tearDown()
keychain.removeAllContent(withPrefix: testPrefix)
}
private func key(_ name: String) -> String {
"\(testPrefix)\(name)"
}
// MARK: - Basic round-trip
func testAddAndGet() {
keychain.add(string: "hello", for: key("addGet"))
XCTAssertEqual(keychain.get(for: key("addGet")), "hello")
}
func testGetMissingKeyReturnsNil() {
XCTAssertNil(keychain.get(for: key("nonexistent")))
}
func testOverwriteValue() {
keychain.add(string: "first", for: key("overwrite"))
keychain.add(string: "second", for: key("overwrite"))
XCTAssertEqual(keychain.get(for: key("overwrite")), "second")
}
func testAddNilRemovesValue() {
keychain.add(string: "value", for: key("addNil"))
keychain.add(string: nil, for: key("addNil"))
XCTAssertNil(keychain.get(for: key("addNil")))
XCTAssertFalse(keychain.contains(key: key("addNil")))
}
// MARK: - contains
func testContainsReturnsTrueForExistingKey() {
keychain.add(string: "value", for: key("exists"))
XCTAssertTrue(keychain.contains(key: key("exists")))
}
func testContainsReturnsFalseForMissingKey() {
XCTAssertFalse(keychain.contains(key: key("missing")))
}
// MARK: - removeContent
func testRemoveContent() {
keychain.add(string: "value", for: key("remove"))
keychain.removeContent(for: key("remove"))
XCTAssertNil(keychain.get(for: key("remove")))
XCTAssertFalse(keychain.contains(key: key("remove")))
}
func testRemoveContentForMissingKeyDoesNotThrow() {
keychain.removeContent(for: key("neverExisted"))
// No assertion needed just verifying it doesn't crash
}
// MARK: - removeAllContent(withPrefix:)
func testRemoveAllContentWithPrefix() {
keychain.add(string: "1", for: key("prefixA.one"))
keychain.add(string: "2", for: key("prefixA.two"))
keychain.add(string: "3", for: key("prefixB.one"))
keychain.removeAllContent(withPrefix: key("prefixA"))
XCTAssertNil(keychain.get(for: key("prefixA.one")))
XCTAssertNil(keychain.get(for: key("prefixA.two")))
XCTAssertEqual(keychain.get(for: key("prefixB.one")), "3")
}
func testRemoveAllContentWithPrefixNoMatches() {
keychain.add(string: "value", for: key("survivor"))
keychain.removeAllContent(withPrefix: key("noMatch"))
XCTAssertEqual(keychain.get(for: key("survivor")), "value")
}
}