Add unit tests for "key: value" syntax in Password class

This commit is contained in:
Danny Moesch 2018-06-17 16:41:14 +02:00 committed by Bob Sun
parent b7a0cbaef6
commit 213234f57e
2 changed files with 275 additions and 0 deletions

View file

@ -10,6 +10,7 @@
18F19A67B0C07F13C17169E0 /* Pods_pass.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A5620D17DF5E86B61761D0E /* Pods_pass.framework */; }; 18F19A67B0C07F13C17169E0 /* Pods_pass.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A5620D17DF5E86B61761D0E /* Pods_pass.framework */; };
23B82F0228254275DBA609E7 /* Pods_passExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B975797E0F0B7476CADD6A7D /* Pods_passExtension.framework */; }; 23B82F0228254275DBA609E7 /* Pods_passExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B975797E0F0B7476CADD6A7D /* Pods_passExtension.framework */; };
3012B06D2039D6E400BE1793 /* Yams.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3012B06C2039D6E400BE1793 /* Yams.framework */; }; 3012B06D2039D6E400BE1793 /* Yams.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3012B06C2039D6E400BE1793 /* Yams.framework */; };
30B04860209A5141001013CA /* PasswordTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B0485F209A5141001013CA /* PasswordTests.swift */; };
61326CDA7A73757FB68DCB04 /* Pods_passKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAB3F5541E51ADC8C6B56642 /* Pods_passKit.framework */; }; 61326CDA7A73757FB68DCB04 /* Pods_passKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAB3F5541E51ADC8C6B56642 /* Pods_passKit.framework */; };
A20691F41F2A3D0E0096483D /* SecurePasteboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20691F31F2A3D0E0096483D /* SecurePasteboard.swift */; }; A20691F41F2A3D0E0096483D /* SecurePasteboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20691F31F2A3D0E0096483D /* SecurePasteboard.swift */; };
A2168A7F1EFD40D5005EA873 /* OnePasswordExtensionConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2168A7E1EFD40D5005EA873 /* OnePasswordExtensionConstants.swift */; }; A2168A7F1EFD40D5005EA873 /* OnePasswordExtensionConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2168A7E1EFD40D5005EA873 /* OnePasswordExtensionConstants.swift */; };
@ -160,6 +161,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
3012B06C2039D6E400BE1793 /* Yams.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Yams.framework; path = Carthage/Build/iOS/Yams.framework; sourceTree = "<group>"; }; 3012B06C2039D6E400BE1793 /* Yams.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Yams.framework; path = Carthage/Build/iOS/Yams.framework; sourceTree = "<group>"; };
30B0485F209A5141001013CA /* PasswordTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordTests.swift; sourceTree = "<group>"; };
31C3033E8868D05B2C55C8B1 /* Pods-passExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-passExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-passExtension/Pods-passExtension.debug.xcconfig"; sourceTree = "<group>"; }; 31C3033E8868D05B2C55C8B1 /* Pods-passExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-passExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-passExtension/Pods-passExtension.debug.xcconfig"; sourceTree = "<group>"; };
3A5620D17DF5E86B61761D0E /* Pods_pass.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pass.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3A5620D17DF5E86B61761D0E /* Pods_pass.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pass.framework; sourceTree = BUILT_PRODUCTS_DIR; };
666769E0B255666D02945C15 /* Pods-passKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-passKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-passKitTests/Pods-passKitTests.release.xcconfig"; sourceTree = "<group>"; }; 666769E0B255666D02945C15 /* Pods-passKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-passKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-passKitTests/Pods-passKitTests.release.xcconfig"; sourceTree = "<group>"; };
@ -364,6 +366,7 @@
children = ( children = (
A26075871EEC6F34005DB03E /* passKitTests.swift */, A26075871EEC6F34005DB03E /* passKitTests.swift */,
A26075891EEC6F34005DB03E /* Info.plist */, A26075891EEC6F34005DB03E /* Info.plist */,
30B0485F209A5141001013CA /* PasswordTests.swift */,
); );
path = passKitTests; path = passKitTests;
sourceTree = "<group>"; sourceTree = "<group>";
@ -993,6 +996,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
30B04860209A5141001013CA /* PasswordTests.swift in Sources */,
A26075881EEC6F34005DB03E /* passKitTests.swift in Sources */, A26075881EEC6F34005DB03E /* passKitTests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View file

@ -0,0 +1,271 @@
//
// PasswordTests.swift
// passKitTests
//
// Created by Danny Mösch on 02.05.18.
// Copyright © 2018 Bob Sun. All rights reserved.
//
import XCTest
@testable import passKit
class PasswordTest: XCTestCase {
static let EMPTY_STRING = ""
static let PASSWORD_NAME = "password"
static let PASSWORD_PATH = "/path/to/\(PASSWORD_NAME)"
static let PASSWORD_URL = URL(fileURLWithPath: PASSWORD_PATH)
static let PASSWORD_STRING = "abcd1234"
static let OTP_TOKEN = "otpauth://totp/email@email.com?secret=abcd1234"
static let SECURE_URL_FIELD = AdditionField(title: "url", content: "https://secure.com")
static let INSECURE_URL_FIELD = AdditionField(title: "url", content: "http://insecure.com")
static let LOGIN_FIELD = AdditionField(title: "login", content: "login name")
static let USERNAME_FIELD = AdditionField(title: "username", content: "some username")
static let NOTE_FIELD = AdditionField(title: "note", content: "A NOTE")
func testUrl() {
let password1 = getPasswordObjectWith(content: PasswordTest.EMPTY_STRING)
XCTAssertEqual(password1.namePath, PasswordTest.PASSWORD_PATH)
let password2 = getPasswordObjectWith(content: PasswordTest.EMPTY_STRING, url: nil)
XCTAssertEqual(password2.namePath, PasswordTest.EMPTY_STRING)
}
func testLooksLikeOTP() {
XCTAssertTrue(Password.LooksLikeOTP(line: PasswordTest.OTP_TOKEN))
XCTAssertFalse(Password.LooksLikeOTP(line: "no_auth://totp/blabla"))
}
func testEmptyFile() {
let fileContent = PasswordTest.EMPTY_STRING
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, PasswordTest.EMPTY_STRING)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), PasswordTest.EMPTY_STRING)
XCTAssertTrue(password.getFilteredAdditions().isEmpty)
XCTAssertNil(password.getUsername())
XCTAssertNil(password.getURLString())
XCTAssertNil(password.getLogin())
}
func testOneEmptyLine() {
let fileContent = """
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, PasswordTest.EMPTY_STRING)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), PasswordTest.EMPTY_STRING)
XCTAssertTrue(password.getFilteredAdditions().isEmpty)
XCTAssertNil(password.getUsername())
XCTAssertNil(password.getURLString())
XCTAssertNil(password.getLogin())
}
func testSimplePasswordFile() {
let passwordString = PasswordTest.PASSWORD_STRING
let urlField = PasswordTest.SECURE_URL_FIELD
let loginField = PasswordTest.LOGIN_FIELD
let usernameField = PasswordTest.USERNAME_FIELD
let noteField = PasswordTest.NOTE_FIELD
let fileContent = """
\(passwordString)
\(urlField.asString)
\(loginField.asString)
\(usernameField.asString)
\(noteField.asString)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, passwordString)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), asPlainText(urlField, loginField, usernameField, noteField))
XCTAssertTrue(does(password: password, contain: urlField))
XCTAssertFalse(does(password: password, contain: loginField))
XCTAssertFalse(does(password: password, contain: usernameField))
XCTAssertTrue(does(password: password, contain: noteField))
XCTAssertEqual(password.getURLString(), urlField.content)
XCTAssertEqual(password.getLogin(), loginField.content)
XCTAssertEqual(password.getUsername(), usernameField.content)
}
func testTwoPasswords() {
let firstPasswordString = PasswordTest.PASSWORD_STRING
let secondPasswordString = "efgh5678"
let urlField = PasswordTest.INSECURE_URL_FIELD
let fileContent = """
\(firstPasswordString)
\(secondPasswordString)
\(urlField.asString)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, firstPasswordString)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), asPlainText(secondPasswordString, urlField.asString))
XCTAssertTrue(does(password: password, contain: urlField))
XCTAssertTrue(does(password: password, contain: AdditionField(title: "unknown 1", content: secondPasswordString)))
XCTAssertNil(password.getUsername())
XCTAssertEqual(password.getURLString(), urlField.content)
XCTAssertNil(password.getLogin())
}
func testNoPassword() {
let urlField = PasswordTest.SECURE_URL_FIELD
let noteField = PasswordTest.NOTE_FIELD
let fileContent = """
\(urlField.asString)
\(noteField.asString)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, urlField.asString)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), asPlainText(noteField))
XCTAssertTrue(does(password: password, contain: noteField))
XCTAssertNil(password.getUsername())
XCTAssertNil(password.getURLString())
XCTAssertNil(password.getLogin())
}
func testDuplicateKeys() {
let passwordString = PasswordTest.PASSWORD_STRING
let urlField1 = PasswordTest.SECURE_URL_FIELD
let urlField2 = PasswordTest.INSECURE_URL_FIELD
let fileContent = """
\(passwordString)
\(urlField1.asString)
\(urlField2.asString)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, passwordString)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), asPlainText(urlField1, urlField2))
XCTAssertTrue(does(password: password, contain: urlField1))
XCTAssertTrue(does(password: password, contain: urlField2))
XCTAssertNil(password.getUsername())
XCTAssertEqual(password.getURLString(), urlField1.content)
XCTAssertNil(password.getLogin())
}
func testUnknownKeys() {
let passwordString = PasswordTest.PASSWORD_STRING
let value1 = "value 1"
let value2 = "value 2"
let value3 = "value 3"
let value4 = "value 4"
let noteField = PasswordTest.NOTE_FIELD
let urlField = PasswordTest.SECURE_URL_FIELD
let fileContent = """
\(passwordString)
\(value1)
\(noteField.asString)
\(value2)
\(value3)
\(urlField.asString)
\(value4)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, passwordString)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), asPlainText(value1, noteField.asString, value2, value3, urlField.asString, value4))
XCTAssertTrue(does(password: password, contain: AdditionField(title: "unknown 1", content: value1)))
XCTAssertTrue(does(password: password, contain: noteField))
XCTAssertTrue(does(password: password, contain: AdditionField(title: "unknown 2", content: value2)))
XCTAssertTrue(does(password: password, contain: AdditionField(title: "unknown 3", content: value3)))
XCTAssertTrue(does(password: password, contain: urlField))
XCTAssertTrue(does(password: password, contain: AdditionField(title: "unknown 4", content: value4)))
XCTAssertNil(password.getUsername())
XCTAssertEqual(password.getURLString(), urlField.content)
XCTAssertNil(password.getLogin())
}
func testPasswordFileWithOtpToken() {
let passwordString = PasswordTest.PASSWORD_STRING
let noteField = PasswordTest.NOTE_FIELD
let otpToken = PasswordTest.OTP_TOKEN
let fileContent = """
\(passwordString)
\(noteField.asString)
\(otpToken)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, passwordString)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), asPlainText(noteField.asString, otpToken))
XCTAssertEqual(password.otpType, Password.OtpType.totp)
XCTAssertNotNil(password.getOtp())
}
func testFirstLineIsOtpToken() {
let otpToken = PasswordTest.OTP_TOKEN
let fileContent = """
\(otpToken)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, otpToken)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), PasswordTest.EMPTY_STRING)
XCTAssertNil(password.getUsername())
XCTAssertNil(password.getURLString())
XCTAssertNil(password.getLogin())
XCTAssertEqual(password.otpType, Password.OtpType.totp)
XCTAssertNotNil(password.getOtp())
}
func testWrongOtpToken() {
let otpToken = "otpauth://htop/blabla"
let fileContent = """
\(otpToken)
"""
let password = getPasswordObjectWith(content: fileContent)
XCTAssertEqual(password.password, otpToken)
XCTAssertEqual(password.getPlainData(), fileContent.data(using: .utf8))
XCTAssertEqual(password.getAdditionsPlainText(), PasswordTest.EMPTY_STRING)
XCTAssertEqual(password.otpType, Password.OtpType.none)
XCTAssertNil(password.getOtp())
}
private func getPasswordObjectWith(content: String, url: URL? = PasswordTest.PASSWORD_URL) -> Password {
return Password(name: PasswordTest.PASSWORD_NAME, url: url, plainText: content)
}
private func does(password: Password, contain field: AdditionField) -> Bool {
return password.getFilteredAdditions().contains(field)
}
private func asPlainText(_ strings: String...) -> String {
return strings.joined(separator: "\n")
}
private func asPlainText(_ fields: AdditionField...) -> String {
return fields.map { $0.asString }.joined(separator: "\n")
}
}