Buckets:
localhost1978/localhost / LOCALHOST1978 /Modules /SSK_Foundation /Tests /SSK_FoundationTests /EncryptedFileVaultManagerTests.swift
| import XCTest | |
| import CryptoKit | |
| import SSK_Abstractions | |
| @testable import SSK_Foundation | |
| final class EncryptedFileVaultManagerTests: XCTestCase { | |
| var vaultManager: EncryptedFileVaultManager! | |
| var tempURL: URL! | |
| override func setUpWithError() throws { | |
| let keyManager = VaultKeyManager() | |
| vaultManager = EncryptedFileVaultManager(keyManager: keyManager) | |
| let tempDirectory = FileManager.default.temporaryDirectory | |
| tempURL = tempDirectory.appendingPathComponent(UUID().uuidString) | |
| } | |
| override func tearDownWithError() throws { | |
| if FileManager.default.fileExists(atPath: tempURL.path) { | |
| try FileManager.default.removeItem(at: tempURL) | |
| } | |
| vaultManager = nil | |
| } | |
| func testVaultCreationAndMetadataEncryption() async throws { | |
| // Create the vault | |
| try await vaultManager.createVault(at: tempURL) | |
| // Verify directory is created | |
| XCTAssertTrue(FileManager.default.fileExists(atPath: tempURL.path), "Vault directory should be created.") | |
| // Verify encrypted metadata file exists | |
| let metadataURL = tempURL.appendingPathComponent("vault_metadata.enc") | |
| XCTAssertTrue(FileManager.default.fileExists(atPath: metadataURL.path), "Encrypted metadata should be created to verify security.") | |
| } | |
| func testVaultMountSuccess() async throws { | |
| // Create the vault | |
| try await vaultManager.createVault(at: tempURL) | |
| // Attempt to mount | |
| try await vaultManager.mount(volume: tempURL) | |
| // Verify mount path is set and isMounted is true | |
| XCTAssertTrue(vaultManager.isMounted) | |
| XCTAssertEqual(vaultManager.currentMountPath, tempURL) | |
| } | |
| func testVaultUnmountSuccess() async throws { | |
| // Create and mount the vault | |
| try await vaultManager.createVault(at: tempURL) | |
| try await vaultManager.mount(volume: tempURL) | |
| XCTAssertTrue(vaultManager.isMounted) | |
| // Unmount | |
| try await vaultManager.unmount() | |
| // Verify unmounted | |
| XCTAssertFalse(vaultManager.isMounted) | |
| XCTAssertNil(vaultManager.currentMountPath) | |
| } | |
| func testMountNonExistentVaultFails() async { | |
| do { | |
| try await vaultManager.mount(volume: tempURL) | |
| XCTFail("Mounting a non-existent vault should throw an error.") | |
| } catch let error as EncryptedVaultError { | |
| XCTAssertEqual(error, .vaultNotFound, "Expected .vaultNotFound error.") | |
| } catch { | |
| XCTFail("Unexpected error thrown: \(error)") | |
| } | |
| } | |
| func testMountWithIncorrectPasskeyFails() async throws { | |
| // Create the vault using the normal key manager | |
| try await vaultManager.createVault(at: tempURL) | |
| // Save the correct key by creating a new manager with the same keychain context, but we will mock it | |
| // to return a bad key for the test. We can just replace the key manager in the vaultManager. | |
| // Actually, to mock it properly without a full mock class, we can corrupt the metadata file | |
| // or clear the keychain and generate a NEW key. | |
| try await vaultManager.unmount() | |
| // Scrub keys and clear keychain so a new different key is generated | |
| let lockQuery: [String: Any] = [ | |
| kSecClass as String: kSecClassGenericPassword, | |
| kSecAttrService as String: KeychainConstants.Services.vault, | |
| kSecAttrAccount as String: KeychainConstants.Accounts.vaultKey | |
| ] | |
| SecItemDelete(lockQuery as CFDictionary) | |
| let newKeyManager = VaultKeyManager() | |
| let badVaultManager = EncryptedFileVaultManager(keyManager: newKeyManager) | |
| do { | |
| try await badVaultManager.mount(volume: tempURL) | |
| XCTFail("Mounting with an incorrect passkey should throw an error.") | |
| } catch { | |
| // Depending on the CryptoKit error when AES GCM open fails, we expect it to fail decryption. | |
| // CryptoKit throws CryptoKitError.authenticationFailure when GCM authentication tag mismatches | |
| // We just ensure it throws. | |
| XCTAssertTrue(error is CryptoKitError, "Expected a CryptoKitError.authenticationFailure or similar.") | |
| } | |
| } | |
| func testConcurrentMountAndUnmount() async throws { | |
| try await vaultManager.createVault(at: tempURL) | |
| let localVaultManager = self.vaultManager! | |
| let localTempURL = self.tempURL! | |
| await withTaskGroup(of: Void.self) { group in | |
| for _ in 0..<100 { | |
| group.addTask { | |
| try? await localVaultManager.mount(volume: localTempURL) | |
| } | |
| group.addTask { | |
| try? await localVaultManager.unmount() | |
| } | |
| } | |
| } | |
| // Just asserting that no data races crashed the process | |
| // State could be either mounted or unmounted depending on the last operation. | |
| XCTAssertNotNil(vaultManager) | |
| } | |
| } | |
Xet Storage Details
- Size:
- 5.13 kB
- Xet hash:
- 6ebd7618e92e1dae8009bf32a207dbda65c6500bf827f6529c3b3114c75bb239
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.