10
10
11
11
import XCTest
12
12
13
- import Basics
13
+ @ testable import Basics
14
14
import TSCBasic
15
15
import TSCTestSupport
16
16
17
17
final class AuthorizationProviderTests : XCTestCase {
18
18
func testBasicAPIs( ) {
19
19
struct TestProvider : AuthorizationProvider {
20
- private var map = [ URL: ( user: String, password: String) ] ( )
21
-
22
- mutating func addOrUpdate( for url: Foundation . URL , user: String , password: String , callback: @escaping ( Result < Void , Error > ) -> Void ) {
23
- self . map [ url] = ( user, password)
24
- callback ( . success( ( ) ) )
25
- }
20
+ let map : [ URL : ( user: String , password: String ) ]
26
21
27
22
func authentication( for url: URL ) -> ( user: String , password: String ) ? {
28
23
return self . map [ url]
29
24
}
30
25
}
31
26
32
- var provider = TestProvider ( )
33
- self . run ( for: & provider)
27
+ let url = URL ( string: " http:// \( UUID ( ) . uuidString) " ) !
28
+ let user = UUID ( ) . uuidString
29
+ let password = UUID ( ) . uuidString
30
+
31
+ let provider = TestProvider ( map: [ url: ( user: user, password: password) ] )
32
+ self . assertAuthentication ( provider, for: url, expected: ( user, password) )
34
33
}
35
34
36
35
func testNetrc( ) throws {
37
36
try testWithTemporaryDirectory { tmpPath in
38
37
let netrcPath = tmpPath. appending ( component: " .netrc " )
39
38
40
39
var provider = try NetrcAuthorizationProvider ( path: netrcPath, fileSystem: localFileSystem)
41
- self . run ( for: & provider)
40
+
41
+ let user = UUID ( ) . uuidString
42
+
43
+ let url = URL ( string: " http:// \( UUID ( ) . uuidString) " ) !
44
+ let password = UUID ( ) . uuidString
45
+
46
+ let otherURL = URL ( string: " https:// \( UUID ( ) . uuidString) " ) !
47
+ let otherPassword = UUID ( ) . uuidString
48
+
49
+ // Add
50
+ XCTAssertNoThrow ( try tsc_await { callback in provider. addOrUpdate ( for: url, user: user, password: password, callback: callback) } )
51
+ XCTAssertNoThrow ( try tsc_await { callback in provider. addOrUpdate ( for: otherURL, user: user, password: otherPassword, callback: callback) } )
52
+
53
+ self . assertAuthentication ( provider, for: url, expected: ( user, password) )
54
+
55
+ // Update - the new password is appended to the end of file
56
+ let newPassword = UUID ( ) . uuidString
57
+ XCTAssertNoThrow ( try tsc_await { callback in provider. addOrUpdate ( for: url, user: user, password: newPassword, callback: callback) } )
58
+
59
+ // .netrc file now contains two entries for `url`: one with `password` and the other with `newPassword`.
60
+ // `NetrcAuthorizationProvider` returns the first entry it finds.
61
+ self . assertAuthentication ( provider, for: url, expected: ( user, password) )
62
+
63
+ // Make sure the new entry is saved
64
+ XCTAssertNotNil ( provider. machines. first ( where: { $0. name == url. host!. lowercased ( ) && $0. login == user && $0. password == newPassword } ) )
65
+
66
+ self . assertAuthentication ( provider, for: otherURL, expected: ( user, otherPassword) )
42
67
}
43
68
}
44
69
45
70
func testKeychain( ) throws {
46
71
#if !canImport(Security) || !ENABLE_KEYCHAIN_TEST
47
72
try XCTSkipIf ( true )
48
73
#else
49
- var provider = KeychainAuthorizationProvider ( )
50
- self . run ( for: & provider)
51
- #endif
52
- }
53
-
54
- private func run< Provider> ( for provider: inout Provider ) where Provider: AuthorizationProvider {
74
+ let provider = KeychainAuthorizationProvider ( )
75
+
55
76
let user = UUID ( ) . uuidString
56
77
57
78
let url = URL ( string: " http:// \( UUID ( ) . uuidString) " ) !
@@ -63,23 +84,24 @@ final class AuthorizationProviderTests: XCTestCase {
63
84
// Add
64
85
XCTAssertNoThrow ( try tsc_await { callback in provider. addOrUpdate ( for: url, user: user, password: password, callback: callback) } )
65
86
XCTAssertNoThrow ( try tsc_await { callback in provider. addOrUpdate ( for: otherURL, user: user, password: otherPassword, callback: callback) } )
66
-
67
- let auth = provider. authentication ( for: url)
68
- XCTAssertEqual ( auth? . user, user)
69
- XCTAssertEqual ( auth? . password, password)
70
- XCTAssertEqual ( provider. httpAuthorizationHeader ( for: url) , " Basic " + " \( user) : \( password) " . data ( using: . utf8) !. base64EncodedString ( ) )
87
+
88
+ self . assertAuthentication ( provider, for: url, expected: ( user, password) )
71
89
72
90
// Update
73
91
let newPassword = UUID ( ) . uuidString
74
92
XCTAssertNoThrow ( try tsc_await { callback in provider. addOrUpdate ( for: url, user: user, password: newPassword, callback: callback) } )
75
93
76
- let updatedAuth = provider. authentication ( for: url)
77
- XCTAssertEqual ( updatedAuth? . user, user)
78
- XCTAssertEqual ( updatedAuth? . password, newPassword)
79
- XCTAssertEqual ( provider. httpAuthorizationHeader ( for: url) , " Basic " + " \( user) : \( newPassword) " . data ( using: . utf8) !. base64EncodedString ( ) )
94
+ // Existing password is updated
95
+ self . assertAuthentication ( provider, for: url, expected: ( user, newPassword) )
80
96
81
- let otherAuth = provider. authentication ( for: otherURL)
82
- XCTAssertEqual ( otherAuth? . user, user)
83
- XCTAssertEqual ( otherAuth? . password, otherPassword)
97
+ self . assertAuthentication ( provider, for: otherURL, expected: ( user, otherPassword) )
98
+ #endif
99
+ }
100
+
101
+ private func assertAuthentication( _ provider: AuthorizationProvider , for url: Foundation . URL , expected: ( user: String , password: String ) ) {
102
+ let authentication = provider. authentication ( for: url)
103
+ XCTAssertEqual ( authentication? . user, expected. user)
104
+ XCTAssertEqual ( authentication? . password, expected. password)
105
+ XCTAssertEqual ( provider. httpAuthorizationHeader ( for: url) , " Basic " + " \( expected. user) : \( expected. password) " . data ( using: . utf8) !. base64EncodedString ( ) )
84
106
}
85
107
}
0 commit comments