// // MemoTests.swift // ZcashLightClientKit-Unit-Tests // // Created by Francisco Gindre on 4/23/20. // import XCTest @testable import ZcashLightClientKit // swiftlint:disable force_unwrapping print_function_usage class MemoTests: XCTestCase { /** Non-utf8 memos are properly ignored */ func testNonUnicodeMemos() throws { XCTAssertNil(Self.randomMemoData()!.asZcashTransactionMemo()) } /** Memo length is correct, padding characters are ignored */ func testMemoLength() throws { XCTAssertEqual(validMemoData.count, 512) XCTAssertEqual(validMemoData.asZcashTransactionMemo()!.trimmingCharacters(in: .controlCharacters).count, Self.validMemoDataExpectedString.count) } /** Verify support for common unicode characters */ func testUnicodeCharacters() throws { let memo = validMemoData.asZcashTransactionMemo()!.trimmingCharacters(in: .controlCharacters) XCTAssertNotNil(memo) XCTAssertEqual(memo, Self.validMemoDataExpectedString) } func testEmojiUnicodeCharacters() throws { let memo = Self.emojiMemoData.asZcashTransactionMemo()!.trimmingCharacters(in: .controlCharacters) XCTAssertNotNil(memo) XCTAssertEqual(memo, Self.expectedEmojiMemoString) } /** Blank memos are ignored */ func testBlankMemos() throws { // This is an example of a functional test case. XCTAssertEqual(emptyMemoData.asZcashTransactionMemo(), String(data: emptyMemoData, encoding: .utf8)) } /** test canonical memos */ func testCanonicalBlankMemos() throws { XCTAssertNil(Self.canonicalEmptyMemo().asZcashTransactionMemo()) } /** ******* * mocked memos * ****** */ /** Real text: "Here's gift from the Zec Fairy @ ECC!" */ static let validMemoDataExpectedString = "Here's gift from the Zec Fairy @ ECC!" static let validMemoDataBase64 = // swiftlint:disable:next line_length "SGVyZSdzIGdpZnQgZnJvbSB0aGUgWmVjIEZhaXJ5IEAgRUNDIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" let validMemoData = Data(base64Encoded: validMemoDataBase64)! let emptyMemoData = Data([UInt8](repeating: 0, count: 512)) let totallyRandomDataMemo = randomMemoData()! static let emojiDataBase64 = // swiftlint:disable:next line_length "8J+SlfCfkpXwn5KV8J+mk/CfppPwn6aT8J+bofCfm6Hwn5uhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" static let emojiMemoData = Data(base64Encoded: emojiDataBase64)! static let expectedEmojiMemoString = "💕💕💕🦓🦓🦓🛡🛡🛡" static func canonicalEmptyMemo() -> Data { var bytes = [UInt8](repeating: 0, count: 512) bytes[0] = UInt8(0xF6) return Data(bytes: &bytes, count: 512) } static func randomMemoData() -> Data? { let length: Int = 512 var keyData = Data(count: length) let result = keyData.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, length, $0.baseAddress!) } if result == errSecSuccess { return keyData } else { print("Problem generating random bytes") return nil } } }