Refactor core data classes (#671)
This commit is contained in:
parent
ab453580ad
commit
d1de81d919
24 changed files with 605 additions and 433 deletions
31
passKitTests/CoreData/CoreDataTestCase.swift
Normal file
31
passKitTests/CoreData/CoreDataTestCase.swift
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// CoreDataTestCase.swift
|
||||
// pass
|
||||
//
|
||||
// Created by Mingshen Sun on 1/4/25.
|
||||
// Copyright © 2025 Bob Sun. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable import passKit
|
||||
|
||||
// swiftlint:disable:next final_test_case
|
||||
class CoreDataTestCase: XCTestCase {
|
||||
// swiftlint:disable:next test_case_accessibility
|
||||
private(set) var controller: PersistenceController!
|
||||
|
||||
override func setUpWithError() throws {
|
||||
try super.setUpWithError()
|
||||
|
||||
controller = PersistenceController(isUnitTest: true)
|
||||
controller.setup()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
controller = nil
|
||||
}
|
||||
}
|
||||
88
passKitTests/CoreData/PasswordEntityTest.swift
Normal file
88
passKitTests/CoreData/PasswordEntityTest.swift
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
//
|
||||
// PasswordEntityTest.swift
|
||||
// pass
|
||||
//
|
||||
// Created by Mingshen Sun on 1/4/25.
|
||||
// Copyright © 2025 Bob Sun. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable import passKit
|
||||
|
||||
final class PasswordEntityTest: CoreDataTestCase {
|
||||
func testFetchAll() throws {
|
||||
let context = controller.viewContext()
|
||||
let expectedCount = 5
|
||||
(0 ..< expectedCount).forEach { index in
|
||||
let name = String(format: "Generated %05d", index)
|
||||
let path = String(format: "/%05d", index)
|
||||
PasswordEntity.insert(name: name, path: path, isDir: false, into: context)
|
||||
}
|
||||
let count = PasswordEntity.fetchAllPassword(in: context).count
|
||||
XCTAssertEqual(expectedCount, count)
|
||||
PasswordEntity.deleteAll(in: context)
|
||||
}
|
||||
|
||||
func testTotalNumber() throws {
|
||||
let context = controller.viewContext()
|
||||
PasswordEntity.insert(name: "1", path: "path1", isDir: false, into: context)
|
||||
PasswordEntity.insert(name: "2", path: "path2", isDir: false, into: context)
|
||||
PasswordEntity.insert(name: "3", path: "path3", isDir: true, into: context)
|
||||
XCTAssertEqual(2, PasswordEntity.totalNumber(in: context))
|
||||
PasswordEntity.deleteAll(in: context)
|
||||
}
|
||||
|
||||
func testFetchUnsynced() throws {
|
||||
let context = controller.viewContext()
|
||||
let syncedPasswordEntity = PasswordEntity.insert(name: "1", path: "path", isDir: false, into: context)
|
||||
syncedPasswordEntity.isSynced = true
|
||||
|
||||
let expectedCount = 5
|
||||
(0 ..< expectedCount).forEach { index in
|
||||
let name = String(format: "Generated %05d", index)
|
||||
let path = String(format: "/%05d", index)
|
||||
PasswordEntity.insert(name: name, path: path, isDir: false, into: context)
|
||||
}
|
||||
let count = PasswordEntity.fetchUnsynced(in: context).count
|
||||
XCTAssertEqual(expectedCount, count)
|
||||
PasswordEntity.deleteAll(in: context)
|
||||
}
|
||||
|
||||
func testFetchByPath() throws {
|
||||
let context = controller.viewContext()
|
||||
PasswordEntity.insert(name: "1", path: "path1", isDir: false, into: context)
|
||||
PasswordEntity.insert(name: "2", path: "path2", isDir: true, into: context)
|
||||
let passwordEntity = PasswordEntity.fetch(by: "path1", in: context)!
|
||||
XCTAssertEqual(passwordEntity.path, "path1")
|
||||
XCTAssertEqual(passwordEntity.name, "1")
|
||||
}
|
||||
|
||||
func testFetchByParent() throws {
|
||||
let context = controller.viewContext()
|
||||
let parent = PasswordEntity.insert(name: "parent", path: "path1", isDir: true, into: context)
|
||||
let child1 = PasswordEntity.insert(name: "child1", path: "path2", isDir: false, into: context)
|
||||
let child2 = PasswordEntity.insert(name: "child2", path: "path3", isDir: true, into: context)
|
||||
let child3 = PasswordEntity.insert(name: "child3", path: "path4", isDir: false, into: context)
|
||||
parent.children = [child1, child2]
|
||||
child2.children = [child3]
|
||||
let childern = PasswordEntity.fetch(by: parent, in: context)
|
||||
XCTAssertEqual(childern.count, 2)
|
||||
}
|
||||
|
||||
func testDeleteRecursively() throws {
|
||||
let context = controller.viewContext()
|
||||
|
||||
let parent = PasswordEntity.insert(name: "parent", path: "path1", isDir: true, into: context)
|
||||
let child1 = PasswordEntity.insert(name: "child1", path: "path2", isDir: true, into: context)
|
||||
let child2 = PasswordEntity.insert(name: "child2", path: "path3", isDir: false, into: context)
|
||||
let child3 = PasswordEntity.insert(name: "child3", path: "path4", isDir: false, into: context)
|
||||
parent.children = [child1, child2]
|
||||
child1.children = [child3]
|
||||
PasswordEntity.deleteRecursively(entity: child2, in: context)
|
||||
PasswordEntity.deleteRecursively(entity: child3, in: context)
|
||||
|
||||
XCTAssertEqual(PasswordEntity.fetchAll(in: context).count, 0)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,8 @@ final class PasswordStoreTest: XCTestCase {
|
|||
private let remoteRepoURL = URL(string: "https://github.com/mssun/passforios-password-store.git")!
|
||||
|
||||
func testCloneAndDecryptMultiKeys() throws {
|
||||
let url = URL(fileURLWithPath: "\(Globals.repositoryPath)-test")
|
||||
let url = Globals.sharedContainerURL.appendingPathComponent("Library/password-store-test/")
|
||||
|
||||
Defaults.isEnableGPGIDOn = true
|
||||
let passwordStore = PasswordStore(url: url)
|
||||
try passwordStore.cloneRepository(remoteRepoURL: remoteRepoURL, branchName: "master")
|
||||
|
|
@ -42,7 +43,7 @@ final class PasswordStoreTest: XCTestCase {
|
|||
let work = try decrypt(passwordStore: passwordStore, path: "work/github.com.gpg", passphrase: "passforios")
|
||||
XCTAssertEqual(work.plainText, "passwordforwork\n")
|
||||
|
||||
let testPassword = Password(name: "test", url: URL(string: "test.gpg")!, plainText: "testpassword")
|
||||
let testPassword = Password(name: "test", path: "test.gpg", plainText: "testpassword")
|
||||
let testPasswordEntity = try passwordStore.add(password: testPassword)!
|
||||
let testPasswordPlain = try passwordStore.decrypt(passwordEntity: testPasswordEntity, requestPGPKeyPassphrase: requestPGPKeyPassphrase)
|
||||
XCTAssertEqual(testPasswordPlain.plainText, "testpassword")
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ final class PasswordTest: XCTestCase {
|
|||
func testURL() {
|
||||
let password = getPasswordObjectWith(content: "")
|
||||
|
||||
XCTAssertEqual(password.url, PASSWORD_URL)
|
||||
XCTAssertEqual(password.path, PASSWORD_PATH)
|
||||
XCTAssertEqual(password.namePath, PASSWORD_PATH)
|
||||
}
|
||||
|
||||
|
|
@ -242,11 +242,17 @@ final class PasswordTest: XCTestCase {
|
|||
}
|
||||
|
||||
func testUsernameInPath() {
|
||||
let password = getPasswordObjectWith(content: "", url: URL(fileURLWithPath: "exampleservice/exampleusername.pgp"))
|
||||
let password = getPasswordObjectWith(content: "", path: "exampleservice/exampleusername.pgp")
|
||||
|
||||
XCTAssertEqual(password.nameFromPath, "exampleusername")
|
||||
}
|
||||
|
||||
func testDotInFilename() {
|
||||
let password = getPasswordObjectWith(content: "", path: "exampleservice/..pgp")
|
||||
|
||||
XCTAssertEqual(password.nameFromPath, ".")
|
||||
}
|
||||
|
||||
func testMultilineValues() {
|
||||
let lineBreakField = "with line breaks" => "|\n This is \n text spread over \n multiple lines! "
|
||||
let noLineBreakField = "without line breaks" => " > \n This is \n text spread over\n multiple lines!"
|
||||
|
|
@ -283,16 +289,16 @@ final class PasswordTest: XCTestCase {
|
|||
let password = getPasswordObjectWith(content: "")
|
||||
XCTAssertEqual(password.changed, 0)
|
||||
|
||||
password.updatePassword(name: "password", url: PASSWORD_URL, plainText: "")
|
||||
password.updatePassword(name: "password", path: PASSWORD_PATH, plainText: "")
|
||||
XCTAssertEqual(password.changed, 0)
|
||||
|
||||
password.updatePassword(name: "", url: PASSWORD_URL, plainText: "a")
|
||||
password.updatePassword(name: "", path: PASSWORD_PATH, plainText: "a")
|
||||
XCTAssertEqual(password.changed, 2)
|
||||
|
||||
password.updatePassword(name: "", url: URL(fileURLWithPath: "/some/path/"), plainText: "a")
|
||||
password.updatePassword(name: "", path: "/some/path/", plainText: "a")
|
||||
XCTAssertEqual(password.changed, 3)
|
||||
|
||||
password.updatePassword(name: "", url: PASSWORD_URL, plainText: "")
|
||||
password.updatePassword(name: "", path: PASSWORD_PATH, plainText: "")
|
||||
XCTAssertEqual(password.changed, 3)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import XCTest
|
|||
@testable import passKit
|
||||
|
||||
let PASSWORD_PATH = "/path/to/password"
|
||||
let PASSWORD_URL = URL(fileURLWithPath: "/path/to/password")
|
||||
let PASSWORD_STRING = "abcd1234"
|
||||
let TOTP_URL = "otpauth://totp/email@email.com?secret=abcd1234"
|
||||
let STEAM_TOTP_URL = "otpauth://totp/username?secret=12345678901234567890&issuer=Steam&algorithm=SHA1&digits=5&period=30&representation=steamguard"
|
||||
|
|
@ -30,8 +29,8 @@ let TOTP_URL_FIELD = "otpauth" => "//totp/email@email.com?secret=abcd1234"
|
|||
let MULTILINE_BLOCK_START = "multiline block" => "|"
|
||||
let MULTILINE_LINE_START = "multiline line" => ">"
|
||||
|
||||
func getPasswordObjectWith(content: String, url: URL? = nil) -> Password {
|
||||
Password(name: "password", url: url ?? PASSWORD_URL, plainText: content)
|
||||
func getPasswordObjectWith(content: String, path: String? = nil) -> Password {
|
||||
Password(name: "password", path: path ?? PASSWORD_PATH, plainText: content)
|
||||
}
|
||||
|
||||
func assertDefaults(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue