1+ import Crypto
12import Foundation
23import Testing
34import WalletPasses
5+ import Zip
46
57@Suite ( " WalletPasses Tests " )
68struct WalletPassesTests {
9+ let decoder = JSONDecoder ( )
10+ let pass = TestPass ( )
11+
12+ init ( ) {
13+ Zip . addCustomFileExtension ( " pkpass " )
14+ }
15+
716 @Test ( " Build Pass " )
817 func build( ) throws {
918 let builder = PassBuilder (
@@ -13,11 +22,11 @@ struct WalletPassesTests {
1322 )
1423
1524 let bundle = try builder. build (
16- pass: TestPass ( ) ,
25+ pass: pass ,
1726 sourceFilesDirectoryPath: " \( FileManager . default. currentDirectoryPath) /Tests/WalletPassesTests/SourceFiles "
1827 )
1928
20- #expect ( bundle != nil )
29+ try testRoundTripped ( bundle)
2130 }
2231
2332 @Test ( " Build Pass with Encrypted Key " )
@@ -30,11 +39,11 @@ struct WalletPassesTests {
3039 )
3140
3241 let bundle = try builder. build (
33- pass: TestPass ( ) ,
42+ pass: pass ,
3443 sourceFilesDirectoryPath: " \( FileManager . default. currentDirectoryPath) /Tests/WalletPassesTests/SourceFiles "
3544 )
3645
37- #expect ( bundle != nil )
46+ try testRoundTripped ( bundle)
3847 }
3948
4049 @Test ( " Build Pass with Personalization " )
@@ -54,12 +63,12 @@ struct WalletPassesTests {
5463 )
5564
5665 let bundle = try builder. build (
57- pass: TestPass ( ) ,
66+ pass: pass ,
5867 sourceFilesDirectoryPath: " \( FileManager . default. currentDirectoryPath) /Tests/WalletPassesTests/SourceFiles " ,
5968 personalization: testPersonalization
6069 )
6170
62- #expect ( bundle != nil )
71+ try testRoundTripped ( bundle, with : testPersonalization )
6372 }
6473
6574 @Test ( " Build Pass without Source Files " )
@@ -72,7 +81,7 @@ struct WalletPassesTests {
7281
7382 #expect( throws: WalletPassesError . noSourceFiles) {
7483 try builder. build (
75- pass: TestPass ( ) ,
84+ pass: pass ,
7685 sourceFilesDirectoryPath: " \( FileManager . default. currentDirectoryPath) /Tests/WalletPassesTests/NoSourceFiles "
7786 )
7887 }
@@ -90,9 +99,45 @@ struct WalletPassesTests {
9099
91100 #expect( throws: WalletPassesError . noOpenSSLExecutable) {
92101 try builder. build (
93- pass: TestPass ( ) ,
102+ pass: pass ,
94103 sourceFilesDirectoryPath: " \( FileManager . default. currentDirectoryPath) /Tests/WalletPassesTests/SourceFiles "
95104 )
96105 }
97106 }
107+
108+ private func testRoundTripped( _ bundle: Data , with personalization: PersonalizationJSON ? = nil ) throws {
109+ let passURL = FileManager . default. temporaryDirectory. appendingPathComponent ( " \( UUID ( ) . uuidString) .pkpass " )
110+ try bundle. write ( to: passURL)
111+ let passFolder = FileManager . default. temporaryDirectory. appendingPathComponent ( UUID ( ) . uuidString, isDirectory: true )
112+ try Zip . unzipFile ( passURL, destination: passFolder)
113+
114+ #expect( FileManager . default. fileExists ( atPath: passFolder. path. appending ( " /signature " ) ) )
115+
116+ #expect( FileManager . default. fileExists ( atPath: passFolder. path. appending ( " /logo.png " ) ) )
117+ #expect( FileManager . default. fileExists ( atPath: passFolder. path. appending ( " /personalizationLogo.png " ) ) )
118+ #expect( FileManager . default. fileExists ( atPath: passFolder. path. appending ( " /it-IT.lproj/logo.png " ) ) )
119+ #expect( FileManager . default. fileExists ( atPath: passFolder. path. appending ( " /it-IT.lproj/personalizationLogo.png " ) ) )
120+
121+ #expect( FileManager . default. fileExists ( atPath: passFolder. path. appending ( " /pass.json " ) ) )
122+ let passData = try String ( contentsOfFile: passFolder. path. appending ( " /pass.json " ) ) . data ( using: . utf8) !
123+ let roundTrippedPass = try decoder. decode ( TestPass . self, from: passData)
124+ #expect( roundTrippedPass. authenticationToken == pass. authenticationToken)
125+ #expect( roundTrippedPass. serialNumber == pass. serialNumber)
126+ #expect( roundTrippedPass. description == pass. description)
127+
128+ if let personalization {
129+ let personalizationJSONData = try String ( contentsOfFile: passFolder. path. appending ( " /personalization.json " ) ) . data ( using: . utf8)
130+ let personalizationJSON = try decoder. decode ( PersonalizationJSON . self, from: personalizationJSONData!)
131+ #expect( personalizationJSON. description == personalization. description)
132+ }
133+
134+ let manifestJSONData = try String ( contentsOfFile: passFolder. path. appending ( " /manifest.json " ) ) . data ( using: . utf8) !
135+ let manifestJSON = try decoder. decode ( [ String : String ] . self, from: manifestJSONData)
136+ let iconData = try Data ( contentsOf: passFolder. appendingPathComponent ( " /icon.png " ) )
137+ #expect( manifestJSON [ " icon.png " ] == Insecure . SHA1. hash ( data: iconData) . map { " 0 \( String ( $0, radix: 16 ) ) " . suffix ( 2 ) } . joined ( ) )
138+ #expect( manifestJSON [ " logo.png " ] != nil )
139+ #expect( manifestJSON [ " personalizationLogo.png " ] != nil )
140+ #expect( manifestJSON [ " it-IT.lproj/logo.png " ] != nil )
141+ #expect( manifestJSON [ " it-IT.lproj/personalizationLogo.png " ] != nil )
142+ }
98143}
0 commit comments