from: github.com/remko/age-plugin-se
This commit is contained in:
79
Tests/Base64Tests.swift
Normal file
79
Tests/Base64Tests.swift
Normal file
@@ -0,0 +1,79 @@
|
||||
import XCTest
|
||||
|
||||
@testable import age_plugin_se
|
||||
|
||||
final class Base64Tests: XCTestCase {
|
||||
func testDataInitBase64RawEncoded_NeedsNoPad() throws {
|
||||
XCTAssertEqual(
|
||||
Data([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]),
|
||||
Data(base64RawEncoded: "AQIDBAUG"))
|
||||
}
|
||||
|
||||
func testDataInitBase64RawEncoded_Needs1Pad() throws {
|
||||
XCTAssertEqual(
|
||||
Data([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]),
|
||||
Data(base64RawEncoded: "AQIDBAUGBwg"))
|
||||
}
|
||||
|
||||
func testDataInitBase64RawEncoded_Needs2Pads() throws {
|
||||
XCTAssertEqual(
|
||||
Data([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]),
|
||||
Data(base64RawEncoded: "AQIDBAUGBw"))
|
||||
}
|
||||
|
||||
func testDataInitBase64RawEncoded_HasPad() throws {
|
||||
XCTAssertEqual(
|
||||
nil,
|
||||
Data(base64RawEncoded: "AQIDBAUGBwg="))
|
||||
}
|
||||
|
||||
func testDataInit_InvalidBase64() throws {
|
||||
XCTAssertEqual(
|
||||
nil,
|
||||
Data(base64RawEncoded: "A_QIDBAUG"))
|
||||
}
|
||||
|
||||
func testDataBase64RawEncodedData() throws {
|
||||
XCTAssertEqual(
|
||||
"AQIDBAUGBw".data(using: .utf8),
|
||||
Data([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]).base64RawEncodedData)
|
||||
}
|
||||
|
||||
func testDataBase64RawEncodedData_Long() throws {
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np
|
||||
bmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFi
|
||||
b3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVu
|
||||
aWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBu
|
||||
aXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0
|
||||
ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxp
|
||||
dCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBF
|
||||
eGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBz
|
||||
dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlk
|
||||
IGVzdCBsYWJvcnVtLg
|
||||
""".data(using: .utf8),
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
||||
.data(using: .utf8)!
|
||||
.base64RawEncodedData)
|
||||
}
|
||||
|
||||
func testDataBase64RawEncodedString_Long() throws {
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np
|
||||
bmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFi
|
||||
b3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVu
|
||||
aWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBu
|
||||
aXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0
|
||||
ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxp
|
||||
dCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBF
|
||||
eGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBz
|
||||
dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlk
|
||||
IGVzdCBsYWJvcnVtLg
|
||||
""",
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
||||
.data(using: .utf8)!
|
||||
.base64RawEncodedString)
|
||||
}
|
||||
}
|
||||
103
Tests/Bech32Tests.swift
Normal file
103
Tests/Bech32Tests.swift
Normal file
@@ -0,0 +1,103 @@
|
||||
import XCTest
|
||||
|
||||
@testable import age_plugin_se
|
||||
|
||||
final class Bech32Tests: XCTestCase {
|
||||
func testEncode() throws {
|
||||
XCTAssertEqual(
|
||||
"age1se1qv9p3zge0tmqxczme5pn3p7g3x80t0uxvlk30s9vevjq0lxuy8rzss09jyq",
|
||||
Bech32().encode(
|
||||
hrp: "age1se",
|
||||
data: Data([
|
||||
0x03, 0x0a, 0x18, 0x89, 0x19, 0x7a, 0xf6, 0x03, 0x60, 0x5b, 0xcd, 0x03, 0x38, 0x87, 0xc8,
|
||||
0x89, 0x8e, 0xf5, 0xbf, 0x86, 0x67, 0xed, 0x17, 0xc0, 0xac, 0xcb, 0x24, 0x07, 0xfc, 0xdc,
|
||||
0x21, 0xc6, 0x28,
|
||||
])))
|
||||
}
|
||||
|
||||
func testEncode_LongUppercase() throws {
|
||||
XCTAssertEqual(
|
||||
"AGE-PLUGIN-SE-1QJPQZ7P3SGQHGVYP75XQYUNTXXQ7UVQTPSPKY6TYQSZDNVLMZYCYSRQRWP6KYPZPQNV20QEQRP3CLMWQALZ8V6TFESK6VDUL30F0D7TC2EXE2RV3Z2TQ5L0ZQFLHJMLY64XS8ESX6KFTL43MN86QVA0W982DTFWL4XMRT7CGXQYQCQMJDDHSYQGQXQRSCQNTWSPQZPPS9CXQYAMTQS5W4LASFLR432Z3658D86JEL8MKGE9XTJLHK4P3ASKWWZ8W6G7RWVLQYSWECSL8XF4RQPCVQF3XXQSPPYCQWRQZDDMQYQGZXQTSCQMTD9JQGYRALY9FHQYLGFET999CZUFGPGLJXQNSCQMJDDKSGGXE56G2EH3Y5V0QPUM8VHADV3FS2TKDR4F2M8266Y444ZFF3FW0VCC85RQZV4JRZAPSWGXQXCTRDSCKKVPFPSPK7CMTXY3RQGQVQD3HQMCVR9ZX2ANFVDJ57AMWV4EYZAT5DPJKUARFVDSHG6T0DCCQJRQYDAJX2MQPQYQNQ2SVQ3HHXEMWXY3RQGQVQD3HQMCVR9ZX2ANFVDJ57AMWV4EYZAT5DPJKUARFVDSHG6T0DCCQWRQZDASSZQGPK9FKDS",
|
||||
Bech32().encode(
|
||||
hrp: "AGE-PLUGIN-SE-",
|
||||
data: Data([
|
||||
0x04, 0x82, 0x01, 0x78, 0x31, 0x82, 0x01, 0x74, 0x30, 0x81, 0xf5, 0x0c, 0x02, 0x72, 0x6b,
|
||||
0x31, 0x81, 0xee, 0x30, 0x0b, 0x0c, 0x03, 0x62, 0x69, 0x64, 0x04, 0x04, 0xd9, 0xb3, 0xfb,
|
||||
0x11, 0x30, 0x48, 0x0c, 0x03, 0x70, 0x75, 0x62, 0x04, 0x41, 0x04, 0xd8, 0xa7, 0x83, 0x20,
|
||||
0x18, 0x63, 0x8f, 0xed, 0xc0, 0xef, 0xc4, 0x76, 0x69, 0x69, 0xcc, 0x2d, 0xa6, 0x37, 0x9f,
|
||||
0x8b, 0xd2, 0xf6, 0xf9, 0x78, 0x56, 0x4d, 0x95, 0x0d, 0x91, 0x12, 0x96, 0x0a, 0x7d, 0xe2,
|
||||
0x02, 0x7f, 0x79, 0x6f, 0xe4, 0xd5, 0x4d, 0x03, 0xe6, 0x06, 0xd5, 0x92, 0xbf, 0xd6, 0x3b,
|
||||
0x99, 0xf4, 0x06, 0x75, 0xee, 0x29, 0xd4, 0xd5, 0xa5, 0xdf, 0xa9, 0xb6, 0x35, 0xfb, 0x08,
|
||||
0x30, 0x08, 0x0c, 0x03, 0x72, 0x6b, 0x6f, 0x02, 0x01, 0x00, 0x30, 0x07, 0x0c, 0x02, 0x6b,
|
||||
0x74, 0x02, 0x01, 0x04, 0x30, 0x2e, 0x0c, 0x02, 0x77, 0x6b, 0x04, 0x28, 0xea, 0xff, 0xb0,
|
||||
0x4f, 0xc7, 0x58, 0xa8, 0x51, 0xd5, 0x0e, 0xd3, 0xea, 0x59, 0xf9, 0xf7, 0x64, 0x64, 0xa6,
|
||||
0x5c, 0xbf, 0x7b, 0x54, 0x31, 0xec, 0x2c, 0xe7, 0x08, 0xee, 0xd2, 0x3c, 0x37, 0x33, 0xe0,
|
||||
0x24, 0x1d, 0x9c, 0x43, 0xe7, 0x32, 0x6a, 0x30, 0x07, 0x0c, 0x02, 0x62, 0x63, 0x02, 0x01,
|
||||
0x09, 0x30, 0x07, 0x0c, 0x02, 0x6b, 0x76, 0x02, 0x01, 0x02, 0x30, 0x17, 0x0c, 0x03, 0x6b,
|
||||
0x69, 0x64, 0x04, 0x10, 0x7d, 0xf9, 0x0a, 0x9b, 0x80, 0x9f, 0x42, 0x72, 0xb2, 0x94, 0xb8,
|
||||
0x17, 0x12, 0x80, 0xa3, 0xf2, 0x30, 0x27, 0x0c, 0x03, 0x72, 0x6b, 0x6d, 0x04, 0x20, 0xd9,
|
||||
0xa6, 0x90, 0xac, 0xde, 0x24, 0xa3, 0x1e, 0x00, 0xf3, 0x67, 0x65, 0xfa, 0xd6, 0x45, 0x30,
|
||||
0x52, 0xec, 0xd1, 0xd5, 0x2a, 0xd9, 0xd5, 0xad, 0x12, 0xb5, 0xa8, 0x92, 0x98, 0xa5, 0xcf,
|
||||
0x66, 0x30, 0x7a, 0x0c, 0x02, 0x65, 0x64, 0x31, 0x74, 0x30, 0x72, 0x0c, 0x03, 0x61, 0x63,
|
||||
0x6c, 0x31, 0x6b, 0x30, 0x29, 0x0c, 0x03, 0x6f, 0x63, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x0c,
|
||||
0x03, 0x63, 0x70, 0x6f, 0x0c, 0x19, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x77, 0x6e,
|
||||
0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x30, 0x09, 0x0c, 0x04, 0x6f, 0x64, 0x65, 0x6c, 0x01, 0x01, 0x01, 0x30, 0x2a, 0x0c,
|
||||
0x04, 0x6f, 0x73, 0x67, 0x6e, 0x31, 0x22, 0x30, 0x20, 0x0c, 0x03, 0x63, 0x70, 0x6f, 0x0c,
|
||||
0x19, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x41, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x07, 0x0c, 0x02,
|
||||
0x6f, 0x61, 0x01, 0x01, 0x01,
|
||||
])))
|
||||
}
|
||||
|
||||
func testDecode() throws {
|
||||
let result = try Bech32().decode(
|
||||
"age1se1qv9p3zge0tmqxczme5pn3p7g3x80t0uxvlk30s9vevjq0lxuy8rzss09jyq")
|
||||
XCTAssertEqual(
|
||||
"age1se", result.hrp)
|
||||
XCTAssertEqual(
|
||||
Data([
|
||||
0x03, 0x0a, 0x18, 0x89, 0x19, 0x7a, 0xf6, 0x03, 0x60, 0x5b, 0xcd, 0x03, 0x38, 0x87, 0xc8,
|
||||
0x89, 0x8e, 0xf5, 0xbf, 0x86, 0x67, 0xed, 0x17, 0xc0, 0xac, 0xcb, 0x24, 0x07, 0xfc, 0xdc,
|
||||
0x21, 0xc6, 0x28,
|
||||
]), result.data)
|
||||
}
|
||||
|
||||
func testDecode_LongUppercase() throws {
|
||||
let result = try Bech32().decode(
|
||||
"AGE-PLUGIN-SE-1QJPQZ7P3SGQHGVYP75XQYUNTXXQ7UVQTPSPKY6TYQSZDNVLMZYCYSRQRWP6KYPZPQNV20QEQRP3CLMWQALZ8V6TFESK6VDUL30F0D7TC2EXE2RV3Z2TQ5L0ZQFLHJMLY64XS8ESX6KFTL43MN86QVA0W982DTFWL4XMRT7CGXQYQCQMJDDHSYQGQXQRSCQNTWSPQZPPS9CXQYAMTQS5W4LASFLR432Z3658D86JEL8MKGE9XTJLHK4P3ASKWWZ8W6G7RWVLQYSWECSL8XF4RQPCVQF3XXQSPPYCQWRQZDDMQYQGZXQTSCQMTD9JQGYRALY9FHQYLGFET999CZUFGPGLJXQNSCQMJDDKSGGXE56G2EH3Y5V0QPUM8VHADV3FS2TKDR4F2M8266Y444ZFF3FW0VCC85RQZV4JRZAPSWGXQXCTRDSCKKVPFPSPK7CMTXY3RQGQVQD3HQMCVR9ZX2ANFVDJ57AMWV4EYZAT5DPJKUARFVDSHG6T0DCCQJRQYDAJX2MQPQYQNQ2SVQ3HHXEMWXY3RQGQVQD3HQMCVR9ZX2ANFVDJ57AMWV4EYZAT5DPJKUARFVDSHG6T0DCCQWRQZDASSZQGPK9FKDS"
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"AGE-PLUGIN-SE-", result.hrp)
|
||||
// print(result.data.map { String(format: "0x%02x", $0) }.joined(separator: ", "))
|
||||
XCTAssertEqual(
|
||||
Data([
|
||||
0x04, 0x82, 0x01, 0x78, 0x31, 0x82, 0x01, 0x74, 0x30, 0x81, 0xf5, 0x0c, 0x02, 0x72, 0x6b,
|
||||
0x31, 0x81, 0xee, 0x30, 0x0b, 0x0c, 0x03, 0x62, 0x69, 0x64, 0x04, 0x04, 0xd9, 0xb3, 0xfb,
|
||||
0x11, 0x30, 0x48, 0x0c, 0x03, 0x70, 0x75, 0x62, 0x04, 0x41, 0x04, 0xd8, 0xa7, 0x83, 0x20,
|
||||
0x18, 0x63, 0x8f, 0xed, 0xc0, 0xef, 0xc4, 0x76, 0x69, 0x69, 0xcc, 0x2d, 0xa6, 0x37, 0x9f,
|
||||
0x8b, 0xd2, 0xf6, 0xf9, 0x78, 0x56, 0x4d, 0x95, 0x0d, 0x91, 0x12, 0x96, 0x0a, 0x7d, 0xe2,
|
||||
0x02, 0x7f, 0x79, 0x6f, 0xe4, 0xd5, 0x4d, 0x03, 0xe6, 0x06, 0xd5, 0x92, 0xbf, 0xd6, 0x3b,
|
||||
0x99, 0xf4, 0x06, 0x75, 0xee, 0x29, 0xd4, 0xd5, 0xa5, 0xdf, 0xa9, 0xb6, 0x35, 0xfb, 0x08,
|
||||
0x30, 0x08, 0x0c, 0x03, 0x72, 0x6b, 0x6f, 0x02, 0x01, 0x00, 0x30, 0x07, 0x0c, 0x02, 0x6b,
|
||||
0x74, 0x02, 0x01, 0x04, 0x30, 0x2e, 0x0c, 0x02, 0x77, 0x6b, 0x04, 0x28, 0xea, 0xff, 0xb0,
|
||||
0x4f, 0xc7, 0x58, 0xa8, 0x51, 0xd5, 0x0e, 0xd3, 0xea, 0x59, 0xf9, 0xf7, 0x64, 0x64, 0xa6,
|
||||
0x5c, 0xbf, 0x7b, 0x54, 0x31, 0xec, 0x2c, 0xe7, 0x08, 0xee, 0xd2, 0x3c, 0x37, 0x33, 0xe0,
|
||||
0x24, 0x1d, 0x9c, 0x43, 0xe7, 0x32, 0x6a, 0x30, 0x07, 0x0c, 0x02, 0x62, 0x63, 0x02, 0x01,
|
||||
0x09, 0x30, 0x07, 0x0c, 0x02, 0x6b, 0x76, 0x02, 0x01, 0x02, 0x30, 0x17, 0x0c, 0x03, 0x6b,
|
||||
0x69, 0x64, 0x04, 0x10, 0x7d, 0xf9, 0x0a, 0x9b, 0x80, 0x9f, 0x42, 0x72, 0xb2, 0x94, 0xb8,
|
||||
0x17, 0x12, 0x80, 0xa3, 0xf2, 0x30, 0x27, 0x0c, 0x03, 0x72, 0x6b, 0x6d, 0x04, 0x20, 0xd9,
|
||||
0xa6, 0x90, 0xac, 0xde, 0x24, 0xa3, 0x1e, 0x00, 0xf3, 0x67, 0x65, 0xfa, 0xd6, 0x45, 0x30,
|
||||
0x52, 0xec, 0xd1, 0xd5, 0x2a, 0xd9, 0xd5, 0xad, 0x12, 0xb5, 0xa8, 0x92, 0x98, 0xa5, 0xcf,
|
||||
0x66, 0x30, 0x7a, 0x0c, 0x02, 0x65, 0x64, 0x31, 0x74, 0x30, 0x72, 0x0c, 0x03, 0x61, 0x63,
|
||||
0x6c, 0x31, 0x6b, 0x30, 0x29, 0x0c, 0x03, 0x6f, 0x63, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x0c,
|
||||
0x03, 0x63, 0x70, 0x6f, 0x0c, 0x19, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x77, 0x6e,
|
||||
0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x30, 0x09, 0x0c, 0x04, 0x6f, 0x64, 0x65, 0x6c, 0x01, 0x01, 0x01, 0x30, 0x2a, 0x0c,
|
||||
0x04, 0x6f, 0x73, 0x67, 0x6e, 0x31, 0x22, 0x30, 0x20, 0x0c, 0x03, 0x63, 0x70, 0x6f, 0x0c,
|
||||
0x19, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x41, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x30, 0x07, 0x0c, 0x02,
|
||||
0x6f, 0x61, 0x01, 0x01, 0x01,
|
||||
]), result.data)
|
||||
}
|
||||
}
|
||||
49
Tests/CLITests.swift
Normal file
49
Tests/CLITests.swift
Normal file
@@ -0,0 +1,49 @@
|
||||
import XCTest
|
||||
|
||||
@testable import age_plugin_se
|
||||
|
||||
final class OptionsTests: XCTestCase {
|
||||
func testParse_NoArguments() throws {
|
||||
let options = try Options.parse(["_"])
|
||||
XCTAssertEqual(.help, options.command)
|
||||
}
|
||||
|
||||
func testParse_CommandWithHelp() throws {
|
||||
let options = try Options.parse(["_", "keygen", "--help"])
|
||||
XCTAssertEqual(.help, options.command)
|
||||
}
|
||||
|
||||
func testParse_CommandWithVersion() throws {
|
||||
let options = try Options.parse(["_", "keygen", "--version"])
|
||||
XCTAssertEqual(.version, options.command)
|
||||
}
|
||||
|
||||
func testParse_Keygen() throws {
|
||||
let options = try Options.parse(["_", "keygen", "--access-control=any-biometry"])
|
||||
XCTAssertEqual(.keygen, options.command)
|
||||
XCTAssertEqual(.anyBiometry, options.accessControl)
|
||||
}
|
||||
|
||||
func testParse_AgePlugin() throws {
|
||||
let options = try Options.parse(["_", "keygen", "--age-plugin=identity-v1"])
|
||||
XCTAssertEqual(.plugin(.identityV1), options.command)
|
||||
}
|
||||
|
||||
func testParse_LongOptionWithEqual() throws {
|
||||
let options = try Options.parse(["_", "keygen", "--output=foo.txt"])
|
||||
XCTAssertEqual(.keygen, options.command)
|
||||
XCTAssertEqual("foo.txt", options.output)
|
||||
}
|
||||
|
||||
func testParse_LongOptionWithoutEqual() throws {
|
||||
let options = try Options.parse(["_", "keygen", "--output", "foo.txt"])
|
||||
XCTAssertEqual(.keygen, options.command)
|
||||
XCTAssertEqual("foo.txt", options.output)
|
||||
}
|
||||
|
||||
func testParse_LongOptionWithoutValue() throws {
|
||||
XCTAssertThrowsError(try Options.parse(["_", "keygen", "--output"])) { error in
|
||||
XCTAssertEqual(Options.Error.missingValue("--output"), error as! Options.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
71
Tests/CryptoTests.swift
Normal file
71
Tests/CryptoTests.swift
Normal file
@@ -0,0 +1,71 @@
|
||||
import XCTest
|
||||
|
||||
@testable import age_plugin_se
|
||||
|
||||
#if !os(Linux) && !os(Windows)
|
||||
import CryptoKit
|
||||
#else
|
||||
import Crypto
|
||||
#endif
|
||||
|
||||
final class CryptoKitCryptoTests: XCTestCase {
|
||||
var crypto = CryptoKitCrypto()
|
||||
|
||||
func testNewEphemeralPrivateKey() throws {
|
||||
let k1 = crypto.newEphemeralPrivateKey()
|
||||
let k2 = crypto.newEphemeralPrivateKey()
|
||||
|
||||
XCTAssertNotEqual(k1.rawRepresentation, k2.rawRepresentation)
|
||||
XCTAssertNotEqual(k1.publicKey.rawRepresentation, k2.publicKey.rawRepresentation)
|
||||
}
|
||||
|
||||
func testNewEphemeralPrivateKey_DifferentCrypto() throws {
|
||||
let k1 = CryptoKitCrypto().newEphemeralPrivateKey()
|
||||
let k2 = CryptoKitCrypto().newEphemeralPrivateKey()
|
||||
|
||||
XCTAssertNotEqual(k1.rawRepresentation, k2.rawRepresentation)
|
||||
XCTAssertNotEqual(k1.publicKey.rawRepresentation, k2.publicKey.rawRepresentation)
|
||||
}
|
||||
|
||||
// A test to validate that CryptoKit / Swift Crypto cannot do any operations with points at infinity
|
||||
func testPointAtInfinity() throws {
|
||||
let sk = P256.KeyAgreement.PrivateKey()
|
||||
|
||||
// base64.b64encode(ECC.generate(curve="p256").export_key(format="DER"))
|
||||
let pk = try P256.KeyAgreement.PublicKey(derRepresentation: Data(base64Encoded: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0Zl262mVCr+1pi9396tEdXC0HIQnENUkWal3nOzLWvX+TYja1xVE++6WzRvunrkBT91380BIJZvB7ZiiEN+Y1A==")!)
|
||||
|
||||
// Test that operations work from a regular DER constructed key
|
||||
let _ = try sk.sharedSecretFromKeyAgreement(with: pk)
|
||||
|
||||
func run() throws {
|
||||
// base64.b64encode(ECC.EccKey(curve = "p256", point = ECC.generate(curve="p256").pointQ.point_at_infinity()).export_key(format="DER"))
|
||||
// Swift Crypto throws at construction time
|
||||
let identityPK = try P256.KeyAgreement.PublicKey(derRepresentation: Data(base64Encoded: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")!)
|
||||
|
||||
// CryptoKit throws at operation time
|
||||
let _ = try sk.sharedSecretFromKeyAgreement(with: identityPK)
|
||||
}
|
||||
|
||||
XCTAssertThrowsError(try run())
|
||||
}
|
||||
}
|
||||
|
||||
final class DummyCryptoTests: XCTestCase {
|
||||
var crypto = DummyCrypto()
|
||||
|
||||
func testNewEphemeralPrivateKey() throws {
|
||||
let k1 = crypto.newEphemeralPrivateKey()
|
||||
let k2 = crypto.newEphemeralPrivateKey()
|
||||
|
||||
XCTAssertNotEqual(k1.rawRepresentation, k2.rawRepresentation)
|
||||
XCTAssertNotEqual(k1.publicKey.rawRepresentation, k2.publicKey.rawRepresentation)
|
||||
}
|
||||
|
||||
func testNewEphemeralPrivateKey_DifferentCrypto() throws {
|
||||
let k1 = DummyCrypto().newEphemeralPrivateKey()
|
||||
let k2 = DummyCrypto().newEphemeralPrivateKey()
|
||||
|
||||
XCTAssertEqual(k1.rawRepresentation, k2.rawRepresentation)
|
||||
XCTAssertEqual(k1.publicKey.rawRepresentation, k2.publicKey.rawRepresentation)
|
||||
}
|
||||
}
|
||||
75
Tests/DummyCrypto.swift
Normal file
75
Tests/DummyCrypto.swift
Normal file
@@ -0,0 +1,75 @@
|
||||
import Foundation
|
||||
|
||||
@testable import age_plugin_se
|
||||
|
||||
#if !os(Linux) && !os(Windows)
|
||||
import CryptoKit
|
||||
#else
|
||||
import Crypto
|
||||
#endif
|
||||
|
||||
class DummyCrypto: Crypto {
|
||||
// If more keys are needed, add them to the front
|
||||
var dummyKeys = [
|
||||
"t8Y0uUHLtBvCtuUz0Hdw2lqbwZf6TgYzYKFWMEEFSs8",
|
||||
"HxEmObcQ6bcAUC8w6kPWrnlUIwBQoi66ZNpQZ0cAXww",
|
||||
"dCDteyAKpkwYd8jCunOz0mvWmy+24zvWV41YBD+Pkeg",
|
||||
"NkkLXSZ+yhx9imKKw9cOsbey4C1XZAPuSDMCgTLENrY",
|
||||
"bQrp04tXb+diJ6x28Kd8EDt9sCmI5diS36Zy3n49DHg",
|
||||
"m8/qMMkYDelvL+ihdUFYyKXBn+7We21fZ5zH/I61y3M",
|
||||
"lQq/Pq0GA2QFGTEiNMQIxZHzBnt+nPRXK5gL3X6nnJY",
|
||||
"VoUn+n/vzkuDzWgMV9n3e1L+tTSIl0Sg7lXSNDR5XqY",
|
||||
"3naom0zZxBZcSZCfoNzyjLVmG6hyRKX8bCU3wukusFI",
|
||||
"N2WRutxd1Ed0l4piqArI2gKYSTG7peE8BYBrLLV7YjQ",
|
||||
].map { Data(base64RawEncoded: $0)! }
|
||||
|
||||
var isSecureEnclaveAvailable = true
|
||||
var failingOperations = false
|
||||
|
||||
func newSecureEnclavePrivateKey(dataRepresentation: Data) throws -> SecureEnclavePrivateKey {
|
||||
return DummySecureEnclavePrivateKey(
|
||||
key: try P256.KeyAgreement.PrivateKey(rawRepresentation: dataRepresentation), crypto: self)
|
||||
}
|
||||
|
||||
func newSecureEnclavePrivateKey(accessControl: SecAccessControl) throws -> SecureEnclavePrivateKey
|
||||
{
|
||||
return DummySecureEnclavePrivateKey(
|
||||
key: try P256.KeyAgreement.PrivateKey(rawRepresentation: dummyKeys.popLast()!), crypto: self)
|
||||
}
|
||||
|
||||
func newEphemeralPrivateKey() -> P256.KeyAgreement.PrivateKey {
|
||||
return try! P256.KeyAgreement.PrivateKey(rawRepresentation: dummyKeys.popLast()!)
|
||||
}
|
||||
}
|
||||
|
||||
struct DummySecureEnclavePrivateKey: SecureEnclavePrivateKey {
|
||||
var key: P256.KeyAgreement.PrivateKey
|
||||
var crypto: DummyCrypto
|
||||
|
||||
var publicKey: P256.KeyAgreement.PublicKey {
|
||||
return key.publicKey
|
||||
}
|
||||
|
||||
var dataRepresentation: Data {
|
||||
return key.rawRepresentation
|
||||
}
|
||||
|
||||
func sharedSecretFromKeyAgreement(with publicKeyShare: P256.KeyAgreement.PublicKey) throws
|
||||
-> SharedSecret
|
||||
{
|
||||
if crypto.failingOperations {
|
||||
throw DummyCryptoError.dummyError
|
||||
}
|
||||
return try key.sharedSecretFromKeyAgreement(with: publicKeyShare)
|
||||
}
|
||||
}
|
||||
|
||||
enum DummyCryptoError: LocalizedError {
|
||||
case dummyError
|
||||
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case .dummyError: return "dummy error"
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Tests/MemoryStream.swift
Normal file
27
Tests/MemoryStream.swift
Normal file
@@ -0,0 +1,27 @@
|
||||
@testable import age_plugin_se
|
||||
|
||||
class MemoryStream: Stream {
|
||||
var inputLines: [String] = []
|
||||
var outputLines: [String] = []
|
||||
|
||||
var output: String {
|
||||
return outputLines.joined(separator: "\n")
|
||||
}
|
||||
|
||||
func add(input: String) {
|
||||
inputLines.append(contentsOf: input.components(separatedBy: "\n"))
|
||||
}
|
||||
|
||||
func readLine() -> String? {
|
||||
if inputLines.isEmpty {
|
||||
return nil
|
||||
}
|
||||
let result = inputLines[0]
|
||||
inputLines.removeFirst()
|
||||
return result
|
||||
}
|
||||
|
||||
func writeLine(_ line: String) {
|
||||
outputLines.append(contentsOf: line.components(separatedBy: "\n"))
|
||||
}
|
||||
}
|
||||
828
Tests/PluginTests.swift
Normal file
828
Tests/PluginTests.swift
Normal file
@@ -0,0 +1,828 @@
|
||||
import XCTest
|
||||
|
||||
@testable import age_plugin_se
|
||||
|
||||
#if !os(Linux) && !os(Windows)
|
||||
import CryptoKit
|
||||
#else
|
||||
import Crypto
|
||||
#endif
|
||||
|
||||
final class PluginTests: XCTestCase {
|
||||
func testCertificateTag() throws {
|
||||
let key = try P256.KeyAgreement.PublicKey(compactRepresentation: Data(count: 32))
|
||||
XCTAssertEqual("Ujulpw", key.tag.base64RawEncodedString)
|
||||
}
|
||||
|
||||
// Test to ensure that age-plugin-yubikey has the same output tag
|
||||
// These values were extracted from a yubikey recipient
|
||||
func testCertificateTag_YubiKeyPlugin() throws {
|
||||
let key = try P256.KeyAgreement.PublicKey(
|
||||
compactRepresentation: Data([
|
||||
182, 32, 36, 98, 119, 204, 123, 231, 20, 203, 102, 119, 81, 232, 194, 196, 140, 194, 55,
|
||||
12, 222, 162, 205, 252, 47, 114, 187, 157, 117, 151, 57, 158,
|
||||
]))
|
||||
XCTAssertEqual(Data([128, 103, 102, 255]), key.tag)
|
||||
XCTAssertEqual("gGdm/w", key.tag.base64RawEncodedString)
|
||||
}
|
||||
}
|
||||
|
||||
final class GenerateTests: XCTestCase {
|
||||
var stream = MemoryStream()
|
||||
var crypto = DummyCrypto()
|
||||
|
||||
override func setUp() {
|
||||
stream = MemoryStream()
|
||||
crypto = DummyCrypto()
|
||||
}
|
||||
|
||||
func testGenerate() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
let result = try plugin.generateKey(
|
||||
accessControl: .anyBiometryOrPasscode, now: Date(timeIntervalSinceReferenceDate: -123456789.0)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
# created: 1997-02-02T02:26:51Z
|
||||
# access control: any biometry or passcode
|
||||
# public key: age1se1qvlvs7x2g83gtaqg0dlstnm3ee8tr49dhtdnxudpfd0sy2gedw20kjmseq4
|
||||
AGE-PLUGIN-SE-1XAJERWKUTH2YWAYH3F32SZKGMGPFSJF3HWJ7Z0Q9SP4JEDTMVG6Q6JD2VG
|
||||
""", result.0)
|
||||
XCTAssertEqual(
|
||||
"age1se1qvlvs7x2g83gtaqg0dlstnm3ee8tr49dhtdnxudpfd0sy2gedw20kjmseq4", result.1)
|
||||
}
|
||||
|
||||
func testGenerate_AnyBiometryAndPasscode() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
let result = try plugin.generateKey(
|
||||
accessControl: .anyBiometryAndPasscode,
|
||||
now: Date(timeIntervalSinceReferenceDate: -123456789.0))
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
# created: 1997-02-02T02:26:51Z
|
||||
# access control: any biometry and passcode
|
||||
# public key: age1se1qvlvs7x2g83gtaqg0dlstnm3ee8tr49dhtdnxudpfd0sy2gedw20kjmseq4
|
||||
AGE-PLUGIN-SE-1XAJERWKUTH2YWAYH3F32SZKGMGPFSJF3HWJ7Z0Q9SP4JEDTMVG6Q6JD2VG
|
||||
""", result.0)
|
||||
XCTAssertEqual(
|
||||
"age1se1qvlvs7x2g83gtaqg0dlstnm3ee8tr49dhtdnxudpfd0sy2gedw20kjmseq4", result.1)
|
||||
}
|
||||
|
||||
func testGenerate_CurrentBiometry() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
let result = try plugin.generateKey(
|
||||
accessControl: .currentBiometry, now: Date(timeIntervalSinceReferenceDate: -123456789.0))
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
# created: 1997-02-02T02:26:51Z
|
||||
# access control: current biometry
|
||||
# public key: age1se1qvlvs7x2g83gtaqg0dlstnm3ee8tr49dhtdnxudpfd0sy2gedw20kjmseq4
|
||||
AGE-PLUGIN-SE-1XAJERWKUTH2YWAYH3F32SZKGMGPFSJF3HWJ7Z0Q9SP4JEDTMVG6Q6JD2VG
|
||||
""", result.0)
|
||||
XCTAssertEqual(
|
||||
"age1se1qvlvs7x2g83gtaqg0dlstnm3ee8tr49dhtdnxudpfd0sy2gedw20kjmseq4", result.1)
|
||||
}
|
||||
|
||||
func testGenerate_NoSecureEnclaveSupport() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
crypto.isSecureEnclaveAvailable = false
|
||||
XCTAssertThrowsError(
|
||||
try plugin.generateKey(
|
||||
accessControl: .anyBiometryOrPasscode,
|
||||
now: Date(timeIntervalSinceReferenceDate: -123456789.0))
|
||||
) { error in
|
||||
XCTAssertEqual(Plugin.Error.seUnsupported, error as! Plugin.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class RecipientV1Tests: XCTestCase {
|
||||
var stream = MemoryStream()
|
||||
var crypto = DummyCrypto()
|
||||
|
||||
override func setUp() {
|
||||
stream = MemoryStream()
|
||||
crypto = DummyCrypto()
|
||||
}
|
||||
|
||||
// Just a test to get the identities of the test keys used in this test
|
||||
func testKeys() throws {
|
||||
let key1 = try! crypto.newSecureEnclavePrivateKey(
|
||||
dataRepresentation: Data(base64RawEncoded: "OSe+zDK18qF0UrjxYVkmwvxyEdxZHp9F69rElj8bKS8")!)
|
||||
XCTAssertEqual(
|
||||
"AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG",
|
||||
key1.ageIdentity)
|
||||
XCTAssertEqual(
|
||||
"age1se1qf0l9gks6x65ha077wq3w3u8fy02tpg3cd9w5j0jlgpfgqkcut2lw6hta9l",
|
||||
key1.publicKey.ageRecipient)
|
||||
|
||||
let key2 = try! crypto.newSecureEnclavePrivateKey(
|
||||
dataRepresentation: Data(base64RawEncoded: "kBuQrPyfvCqBXJ5G4YBkqNER201niIeOmlXsRS2gxN0")!)
|
||||
XCTAssertEqual(
|
||||
"AGE-PLUGIN-SE-1JQDEPT8UN77Z4Q2UNERWRQRY4RG3RK6DV7YG0R562HKY2TDQCNWSREKAW7",
|
||||
key2.ageIdentity)
|
||||
XCTAssertEqual(
|
||||
"age1se1q0mm28s88km3d8fvwve26xg4tt26cqamhxm79g9xvmw0f2erawj752upj6l",
|
||||
key2.publicKey.ageRecipient)
|
||||
}
|
||||
|
||||
func testNothing() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(input: "-> done\n")
|
||||
plugin.runRecipientV1()
|
||||
XCTAssertEqual("-> done\n", stream.output)
|
||||
}
|
||||
|
||||
func testRecipient() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-recipient age1se1qf0l9gks6x65ha077wq3w3u8fy02tpg3cd9w5j0jlgpfgqkcut2lw6hta9l
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testIdentity() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testMultipleRecipients() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-recipient age1se1qf0l9gks6x65ha077wq3w3u8fy02tpg3cd9w5j0jlgpfgqkcut2lw6hta9l
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> add-recipient age1se1q0mm28s88km3d8fvwve26xg4tt26cqamhxm79g9xvmw0f2erawj752upj6l
|
||||
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> recipient-stanza 0 piv-p256 1mgwOA A1x2nUpw2wo/7z0JR5puskK6NuvW5XkQBwkun/T3WC80
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testMultipleRecipientsMultipleKeys() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-recipient age1se1qf0l9gks6x65ha077wq3w3u8fy02tpg3cd9w5j0jlgpfgqkcut2lw6hta9l
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAg
|
||||
-> add-recipient age1se1q0mm28s88km3d8fvwve26xg4tt26cqamhxm79g9xvmw0f2erawj752upj6l
|
||||
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> recipient-stanza 0 piv-p256 1mgwOA A1x2nUpw2wo/7z0JR5puskK6NuvW5XkQBwkun/T3WC80
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> recipient-stanza 1 piv-p256 14yi6A AvEp8Oz0cMnXhpXnWM6cwer4nEDHus/AvNp3kYnUH0Qs
|
||||
L3ig8s2AqjusH/0lW6ZueSEYhpeV2ofrQpaKP06WI9g
|
||||
-> recipient-stanza 1 piv-p256 1mgwOA AoIMpSYaKzGl5IBFaM9AFJXmrseGzTzcQjS9R4kRcjRi
|
||||
vm8flaP+4W08S6LwFENwnEKLlpzZ5YqZ3NdpKFo7Vg8
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientError() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-recipient age1se1qf0l9gks6x65ha077wq3w3u8fy02tpg3cd9w5j0jlgpfgqkcut2lw6hta9l
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> add-recipient age1invalid1q0mm28s88km3d8fvwve26xg4tt26cqamhxm79g9xvmw0f2erawj75hkckfk
|
||||
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error recipient 1
|
||||
Q2hlY2tzdW0gZG9lc24ndCBtYXRjaA
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testIdentityError() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> add-identity AGE-PLUGIN-INVALID-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHS2FM3SW
|
||||
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error identity 1
|
||||
Q2hlY2tzdW0gZG9lc24ndCBtYXRjaA
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testInvalidRecipientHRP() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-recipient age1vld7p2khw44ds8t00vcfmjdf35zxqvn2trjccd35h4s22faj94vsjhn620
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error recipient 0
|
||||
dW5rbm93biBIUlA6IGFnZQ
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
// func testFailingCryptoOperations() throws {
|
||||
// let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
// stream.add(
|
||||
// input:
|
||||
// """
|
||||
// -> add-recipient age1se1qf0l9gks6x65ha077wq3w3u8fy02tpg3cd9w5j0jlgpfgqkcut2lw6hta9l
|
||||
|
||||
// -> wrap-file-key
|
||||
// AAAAAAAAAAAAAAAAAAAAAQ
|
||||
// -> done
|
||||
|
||||
// -> ok
|
||||
|
||||
// """)
|
||||
// crypto.failingOperations = true
|
||||
// plugin.runRecipientV1()
|
||||
|
||||
// XCTAssertEqual(
|
||||
// """
|
||||
// -> error internal
|
||||
// ZHVtbXkgZXJyb3I
|
||||
// -> done
|
||||
|
||||
// """, stream.output)
|
||||
// }
|
||||
|
||||
func testUnknownStanzaTypes() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-recipient age1se1qf0l9gks6x65ha077wq3w3u8fy02tpg3cd9w5j0jlgpfgqkcut2lw6hta9l
|
||||
|
||||
-> unknown-stanza 1 2 3
|
||||
|
||||
-> wrap-file-key
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> anotherunknownstanza
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runRecipientV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
}
|
||||
|
||||
final class IdentityV1Tests: XCTestCase {
|
||||
var stream = MemoryStream()
|
||||
var crypto = DummyCrypto()
|
||||
|
||||
override func setUp() {
|
||||
stream = MemoryStream()
|
||||
crypto = DummyCrypto()
|
||||
}
|
||||
|
||||
func testNothing() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(input: "-> done\n")
|
||||
plugin.runIdentityV1()
|
||||
XCTAssertEqual("-> done\n", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanza() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> file-key 0
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaMultipleFiles() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> recipient-stanza 1 piv-p256 14yi6A AvEp8Oz0cMnXhpXnWM6cwer4nEDHus/AvNp3kYnUH0Qs
|
||||
L3ig8s2AqjusH/0lW6ZueSEYhpeV2ofrQpaKP06WI9g
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> file-key 0
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> file-key 1
|
||||
AAAAAAAAAAAAAAAAAAAAAg
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaMultipleFilesMultipleIdentities() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> add-identity AGE-PLUGIN-SE-1JQDEPT8UN77Z4Q2UNERWRQRY4RG3RK6DV7YG0R562HKY2TDQCNWSREKAW7
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> recipient-stanza 0 piv-p256 1mgwOA A1x2nUpw2wo/7z0JR5puskK6NuvW5XkQBwkun/T3WC80
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> recipient-stanza 1 piv-p256 14yi6A AvEp8Oz0cMnXhpXnWM6cwer4nEDHus/AvNp3kYnUH0Qs
|
||||
L3ig8s2AqjusH/0lW6ZueSEYhpeV2ofrQpaKP06WI9g
|
||||
-> recipient-stanza 1 piv-p256 1mgwOA AoIMpSYaKzGl5IBFaM9AFJXmrseGzTzcQjS9R4kRcjRi
|
||||
vm8flaP+4W08S6LwFENwnEKLlpzZ5YqZ3NdpKFo7Vg8
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> file-key 0
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> file-key 1
|
||||
AAAAAAAAAAAAAAAAAAAAAg
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaMultipleStanzasMissingIdentity() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-1JQDEPT8UN77Z4Q2UNERWRQRY4RG3RK6DV7YG0R562HKY2TDQCNWSREKAW7
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> recipient-stanza 0 piv-p256 1mgwOA A1x2nUpw2wo/7z0JR5puskK6NuvW5XkQBwkun/T3WC80
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> file-key 0
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanza_UnknownType() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> recipient-stanza 0 X25519 A1x2nUpw2wo/7z0JR5puskK6NuvW5XkQBwkun/T3WC80
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> file-key 0
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testIdentityError() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> add-identity AGE-PLUGIN-INVALID-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHS2FM3SW
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error identity 1
|
||||
Q2hlY2tzdW0gZG9lc24ndCBtYXRjaA
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testUnknownIdentityHRP() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> add-identity AGE-SECRET-KEY-1MCFVWZK6PK625PWMWVYPZDQM4N7AS3VA754JHCC60ZT7WJ79TQQSQDYVGF
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error identity 1
|
||||
dW5rbm93biBIUlA6IEFHRS1TRUNSRVQtS0VZLQ
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaMultipleFilesStructurallyInvalidFile() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> add-identity AGE-PLUGIN-SE-1JQDEPT8UN77Z4Q2UNERWRQRY4RG3RK6DV7YG0R562HKY2TDQCNWSREKAW7
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> recipient-stanza 0 piv-p256 1mgwOA
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> recipient-stanza 1 piv-p256 14yi6A AvEp8Oz0cMnXhpXnWM6cwer4nEDHus/AvNp3kYnUH0Qs
|
||||
L3ig8s2AqjusH/0lW6ZueSEYhpeV2ofrQpaKP06WI9g
|
||||
-> recipient-stanza 1 piv-p256 1mgwOA AoIMpSYaKzGl5IBFaM9AFJXmrseGzTzcQjS9R4kRcjRi
|
||||
vm8flaP+4W08S6LwFENwnEKLlpzZ5YqZ3NdpKFo7Vg8
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error stanza 0
|
||||
aW5jb3JyZWN0IGFyZ3VtZW50IGNvdW50
|
||||
-> file-key 1
|
||||
AAAAAAAAAAAAAAAAAAAAAg
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaInvalidStructure_ArgumentCount() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> recipient-stanza 0 piv-p256 1mgwOA
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error stanza 0
|
||||
aW5jb3JyZWN0IGFyZ3VtZW50IGNvdW50
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaInvalidTag() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error stanza 0
|
||||
aW52YWxpZCB0YWc
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaInvalidShare() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5Q
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error stanza 0
|
||||
aW52YWxpZCBzaGFyZQ
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testRecipientStanzaInvalidBody() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
AAAAAAAAAAAAAAAAAAAAARIiJq2e9+1E+xK92Pvdtw
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> error stanza 0
|
||||
aW52YWxpZCBib2R5
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testFailingCryptoOperations() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> add-identity AGE-PLUGIN-SE-1JQDEPT8UN77Z4Q2UNERWRQRY4RG3RK6DV7YG0R562HKY2TDQCNWSREKAW7
|
||||
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> recipient-stanza 0 piv-p256 1mgwOA A1x2nUpw2wo/7z0JR5puskK6NuvW5XkQBwkun/T3WC80
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
crypto.failingOperations = true
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> msg
|
||||
ZHVtbXkgZXJyb3I
|
||||
-> msg
|
||||
ZHVtbXkgZXJyb3I
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testUnknownStanzas() throws {
|
||||
let plugin = Plugin(crypto: crypto, stream: stream)
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> unknown-stanza-1 a bbb c
|
||||
|
||||
-> add-identity AGE-PLUGIN-SE-18YNMANPJKHE2ZAZJHRCKZKFXCT78YYWUTY0F730TMTZFV0CM9YHSRP8GPG
|
||||
|
||||
-> unknown-stanza-2
|
||||
9NGkkBZykDMgw6dndbbjnn7DQBalVV4sVIurWku030Y
|
||||
-> recipient-stanza 0 piv-p256 14yi6A Az7IeMpB4oX0CHt/Bc9xzk6x1K262zNxoUtfAikZa5T7
|
||||
SLgnrcnHLaJHCx+fwSEWWoflDgL91oDGCGNwb2YaT+4
|
||||
-> done
|
||||
|
||||
-> ok
|
||||
|
||||
""")
|
||||
plugin.runIdentityV1()
|
||||
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> file-key 0
|
||||
AAAAAAAAAAAAAAAAAAAAAQ
|
||||
-> done
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
}
|
||||
208
Tests/StanzaTests.swift
Normal file
208
Tests/StanzaTests.swift
Normal file
@@ -0,0 +1,208 @@
|
||||
import XCTest
|
||||
|
||||
@testable import age_plugin_se
|
||||
|
||||
final class StanzaTests: XCTestCase {
|
||||
var stream = MemoryStream()
|
||||
|
||||
override func setUp() {
|
||||
stream = MemoryStream()
|
||||
}
|
||||
|
||||
func testReadFrom() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> mytype MyArgument1 MyArgument2
|
||||
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np
|
||||
bmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFi
|
||||
b3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVu
|
||||
aWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBu
|
||||
aXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0
|
||||
ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxp
|
||||
dCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBF
|
||||
eGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBz
|
||||
dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlk
|
||||
IGVzdCBsYWJvcnVtLg
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
Stanza(
|
||||
type: "mytype",
|
||||
args: ["MyArgument1", "MyArgument2"],
|
||||
body:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
||||
.data(using: .utf8)!
|
||||
), try Stanza.readFrom(stream: stream))
|
||||
}
|
||||
|
||||
func testReadFrom_EmptyBody() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> mytype
|
||||
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
Stanza(
|
||||
type: "mytype",
|
||||
args: [],
|
||||
body: Data()
|
||||
), try Stanza.readFrom(stream: stream))
|
||||
}
|
||||
|
||||
func testReadFrom_EmptyLastLine() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> mystanza
|
||||
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np
|
||||
|
||||
""")
|
||||
XCTAssertEqual(
|
||||
Stanza(
|
||||
type: "mystanza",
|
||||
args: [],
|
||||
body:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipisci"
|
||||
.data(using: .utf8)!
|
||||
), try Stanza.readFrom(stream: stream))
|
||||
}
|
||||
|
||||
func testReadFrom_MissingType() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
->
|
||||
IGVzdCBsYWJvcnVtLg
|
||||
""")
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.invalidStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testReadFrom_InvalidPrefix() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
=> mystanza
|
||||
IGVzdCBsYWJvcnVtLg
|
||||
""")
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.invalidStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testReadFrom_BodyTooLong() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> mystanza
|
||||
dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg
|
||||
""")
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.invalidStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testReadFrom_BodyInvalid() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> mystanza
|
||||
_dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg
|
||||
""")
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.invalidStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testReadFrom_BodyIncomplete() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> mystanza
|
||||
dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlk
|
||||
""")
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.incompleteStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testReadFrom_BodyMissing() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
-> mystanza
|
||||
""")
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.incompleteStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testReadFrom_BodyHasPadding() throws {
|
||||
stream.add(
|
||||
input:
|
||||
"""
|
||||
=> mystanza
|
||||
IGVzdCBsYWJvcnVtLg==
|
||||
""")
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.invalidStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testReadFrom_NoInput() throws {
|
||||
XCTAssertThrowsError(try Stanza.readFrom(stream: stream)) { error in
|
||||
XCTAssertEqual(error as! Plugin.Error, Plugin.Error.incompleteStanza)
|
||||
}
|
||||
}
|
||||
|
||||
func testWriteTo() throws {
|
||||
Stanza(
|
||||
type: "mytype",
|
||||
args: ["MyArgument1", "MyArgument2"],
|
||||
body:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
||||
.data(using: .utf8)!
|
||||
).writeTo(stream: stream)
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> mytype MyArgument1 MyArgument2
|
||||
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np
|
||||
bmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFi
|
||||
b3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVu
|
||||
aWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBu
|
||||
aXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0
|
||||
ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxp
|
||||
dCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBF
|
||||
eGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBz
|
||||
dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlk
|
||||
IGVzdCBsYWJvcnVtLg
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testWriteTo_NoArguments() throws {
|
||||
Stanza(
|
||||
type: "mytype",
|
||||
body: "Lorem ipsum".data(using: .utf8)!
|
||||
).writeTo(stream: stream)
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> mytype
|
||||
TG9yZW0gaXBzdW0
|
||||
""", stream.output)
|
||||
}
|
||||
|
||||
func testWriteTo_EmptyBody() throws {
|
||||
Stanza(
|
||||
type: "mytype",
|
||||
args: [],
|
||||
body: Data()
|
||||
).writeTo(stream: stream)
|
||||
XCTAssertEqual(
|
||||
"""
|
||||
-> mytype
|
||||
|
||||
""", stream.output)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user