1
1
import Foundation
2
- import Swifter
2
+ import Mocker
3
3
import Testing
4
4
@testable import VPNLib
5
5
@@ -14,18 +14,11 @@ struct DownloaderTests {
14
14
@Test
15
15
func downloadFile( ) async throws {
16
16
let destinationURL = FileManager . default. temporaryDirectory. appendingPathComponent ( UUID ( ) . uuidString)
17
-
18
- let server = HttpServer ( )
19
17
let testData = Data ( " foo " . utf8)
20
18
21
- server [ " /test.txt " ] = { _ in
22
- HttpResponse . ok ( . data( testData) )
23
- }
24
-
25
- try server. start ( freePort ( ) )
26
- defer { server. stop ( ) }
19
+ let fileURL = URL ( string: " http://example.com/test1.txt " ) !
20
+ Mock ( url: fileURL, contentType: . html, statusCode: 200 , data: [ . get: testData] ) . register ( )
27
21
28
- let fileURL = try URL ( string: " http://localhost: \( server. port ( ) ) /test.txt " ) !
29
22
try await downloader. download ( src: fileURL, dest: destinationURL)
30
23
31
24
try #require( FileManager . default. fileExists ( atPath: destinationURL. path) )
@@ -37,126 +30,46 @@ struct DownloaderTests {
37
30
38
31
@Test
39
32
func fileNotModified( ) async throws {
40
- let server = HttpServer ( )
41
33
let testData = Data ( " foo bar " . utf8)
34
+ let fileURL = URL ( string: " http://example.com/test2.txt " ) !
42
35
43
36
let destinationURL = FileManager . default. temporaryDirectory. appendingPathComponent ( UUID ( ) . uuidString)
37
+ defer { try ? FileManager . default. removeItem ( at: destinationURL) }
44
38
45
- var notModifiedSent = false
46
- server [ " /test.txt " ] = { req in
47
- let etag = etag ( data: testData)
48
- if let ifNoneMatch = req. headers [ " if-none-match " ] , ifNoneMatch == etag {
49
- notModifiedSent = true
50
- return . raw( 304 , " Not Modified " , nil , nil )
51
- } else {
52
- return . ok( . data( testData) )
53
- }
54
- }
55
-
56
- try server. start ( freePort ( ) )
57
- defer { server. stop ( ) }
58
-
59
- let fileURL = try URL ( string: " http://localhost: \( server. port ( ) ) /test.txt " ) !
60
- try await downloader. download ( src: fileURL, dest: destinationURL)
39
+ Mock ( url: fileURL, contentType: . html, statusCode: 200 , data: [ . get: testData] ) . register ( )
61
40
41
+ try await downloader. download ( src: fileURL, dest: destinationURL)
62
42
try #require( FileManager . default. fileExists ( atPath: destinationURL. path) )
63
- defer { try ? FileManager . default. removeItem ( at: destinationURL) }
64
43
let downloadedData = try Data ( contentsOf: destinationURL)
65
44
#expect( downloadedData == testData)
66
45
46
+ Mock ( url: fileURL, contentType: . html, statusCode: 304 , data: [ . get: Data ( ) ] ) . register ( )
47
+
67
48
try await downloader. download ( src: fileURL, dest: destinationURL)
68
- #expect ( downloadedData == testData )
69
- #expect( notModifiedSent )
49
+ let unchangedData = try Data ( contentsOf : destinationURL )
50
+ #expect( unchangedData == testData )
70
51
}
71
52
72
53
@Test
73
54
func fileUpdated( ) async throws {
74
- let server = HttpServer ( )
75
55
let ogData = Data ( " foo bar " . utf8)
76
56
let newData = Data ( " foo bar qux " . utf8)
77
57
58
+ let fileURL = URL ( string: " http://example.com/test3.txt " ) !
78
59
let destinationURL = FileManager . default. temporaryDirectory. appendingPathComponent ( UUID ( ) . uuidString)
60
+ defer { try ? FileManager . default. removeItem ( at: destinationURL) }
79
61
80
- server [ " /test.txt " ] = { _ in
81
- . ok( . data( ogData) )
82
- }
83
-
84
- try server. start ( freePort ( ) )
85
- defer { server. stop ( ) }
86
-
87
- let fileURL = try URL ( string: " http://localhost: \( server. port ( ) ) /test.txt " ) !
62
+ Mock ( url: fileURL, contentType: . html, statusCode: 200 , data: [ . get: ogData] ) . register ( )
88
63
89
64
try await downloader. download ( src: fileURL, dest: destinationURL)
90
65
try #require( FileManager . default. fileExists ( atPath: destinationURL. path) )
91
- defer { try ? FileManager . default. removeItem ( at: destinationURL) }
92
66
var downloadedData = try Data ( contentsOf: destinationURL)
93
67
#expect( downloadedData == ogData)
94
68
95
- server [ " /test.txt " ] = { _ in
96
- . ok( . data( newData) )
97
- }
69
+ Mock ( url: fileURL, contentType: . html, statusCode: 200 , data: [ . get: newData] ) . register ( )
70
+
98
71
try await downloader. download ( src: fileURL, dest: destinationURL)
99
72
downloadedData = try Data ( contentsOf: destinationURL)
100
73
#expect( downloadedData == newData)
101
74
}
102
75
}
103
-
104
- // From https://stackoverflow.com/questions/65670932/how-to-find-a-free-local-port-using-swift
105
- func freePort( ) -> UInt16 {
106
- var port : UInt16 = 8000
107
-
108
- let socketFD = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP)
109
- if socketFD == - 1 {
110
- return port
111
- }
112
-
113
- var hints = addrinfo (
114
- ai_flags: AI_PASSIVE,
115
- ai_family: AF_INET,
116
- ai_socktype: SOCK_STREAM,
117
- ai_protocol: 0 ,
118
- ai_addrlen: 0 ,
119
- ai_canonname: nil ,
120
- ai_addr: nil ,
121
- ai_next: nil
122
- )
123
-
124
- var addressInfo : UnsafeMutablePointer < addrinfo > ?
125
- var result = getaddrinfo ( nil , " 0 " , & hints, & addressInfo)
126
- if result != 0 {
127
- close ( socketFD)
128
- return port
129
- }
130
-
131
- result = Darwin . bind ( socketFD, addressInfo!. pointee. ai_addr, socklen_t ( addressInfo!. pointee. ai_addrlen) )
132
- if result == - 1 {
133
- close ( socketFD)
134
- return port
135
- }
136
-
137
- result = Darwin . listen ( socketFD, 1 )
138
- if result == - 1 {
139
- close ( socketFD)
140
- return port
141
- }
142
-
143
- var addr_in = sockaddr_in ( )
144
- addr_in. sin_len = UInt8 ( MemoryLayout . size ( ofValue: addr_in) )
145
- addr_in. sin_family = sa_family_t ( AF_INET)
146
-
147
- var len = socklen_t ( addr_in. sin_len)
148
- result = withUnsafeMutablePointer ( to: & addr_in) {
149
- $0. withMemoryRebound ( to: sockaddr. self, capacity: 1 ) {
150
- Darwin . getsockname ( socketFD, $0, & len)
151
- }
152
- }
153
-
154
- if result == 0 {
155
- port = addr_in. sin_port
156
- }
157
-
158
- Darwin . shutdown ( socketFD, SHUT_RDWR)
159
- close ( socketFD)
160
-
161
- return port
162
- }
0 commit comments