@@ -36,8 +36,7 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
3636
3737 /// Verifies the generator receives exactly the caller supplied custom headers and the upload identifier for correlation.
3838 func testGenerateHeadersReceivesOnlyCallerSuppliedHeaders( ) throws {
39- let configuration = URLSessionConfiguration . default
40- configuration. protocolClasses = [ MockURLProtocol . self]
39+ let configuration = makeConfiguration ( )
4140
4241 let expectedHeaders = [
4342 " Authorization " : " Bearer token " ,
@@ -47,19 +46,12 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
4746 var receivedRequestID : UUID ?
4847 let generatorCalled = expectation ( description: " Header generator called " )
4948
50- client = try TUSClient (
51- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
52- sessionIdentifier: " TEST " ,
53- sessionConfiguration: configuration,
54- storageDirectory: relativeStoragePath,
55- supportedExtensions: [ . creation] ,
56- generateHeaders: { requestID, headers, onHeadersGenerated in
57- receivedRequestID = requestID
58- receivedHeaders = headers
59- onHeadersGenerated ( headers)
60- generatorCalled. fulfill ( )
61- }
62- )
49+ client = try makeClient ( configuration: configuration) { requestID, headers, onHeadersGenerated in
50+ receivedRequestID = requestID
51+ receivedHeaders = headers
52+ onHeadersGenerated ( headers)
53+ generatorCalled. fulfill ( )
54+ }
6355 client. delegate = tusDelegate
6456
6557 let uploadID = try client. upload ( data: data, customHeaders: expectedHeaders)
@@ -71,23 +63,15 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
7163
7264 /// Verifies we don't bother clients when there are no custom headers to override.
7365 func testGenerateHeadersNotCalledWhenNoCustomHeaders( ) throws {
74- let configuration = URLSessionConfiguration . default
75- configuration. protocolClasses = [ MockURLProtocol . self]
66+ let configuration = makeConfiguration ( )
7667
7768 let generatorNotCalled = expectation ( description: " Header generator should not be invoked " )
7869 generatorNotCalled. isInverted = true
7970
80- client = try TUSClient (
81- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
82- sessionIdentifier: " TEST " ,
83- sessionConfiguration: configuration,
84- storageDirectory: relativeStoragePath,
85- supportedExtensions: [ . creation] ,
86- generateHeaders: { _, _, onHeadersGenerated in
87- generatorNotCalled. fulfill ( )
88- onHeadersGenerated ( [ : ] )
89- }
90- )
71+ client = try makeClient ( configuration: configuration) { _, _, onHeadersGenerated in
72+ generatorNotCalled. fulfill ( )
73+ onHeadersGenerated ( [ : ] )
74+ }
9175 client. delegate = tusDelegate
9276
9377 XCTAssertNoThrow ( try client. upload ( data: data) )
@@ -96,8 +80,7 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
9680
9781 /// Ensures the generator receives the headers that were actually used on the previous request when retrying.
9882 func testGenerateHeadersReceivesLastAppliedValuesOnAutomaticRetry( ) throws {
99- let configuration = URLSessionConfiguration . default
100- configuration. protocolClasses = [ MockURLProtocol . self]
83+ let configuration = makeConfiguration ( )
10184
10285 prepareNetworkForSuccesfulUploads ( data: data)
10386 prepareNetworkForFailingUploads ( )
@@ -110,23 +93,16 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
11093 let uploadFailed = expectation ( description: " Upload should fail after retries " )
11194 tusDelegate. uploadFailedExpectation = uploadFailed
11295
113- client = try TUSClient (
114- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
115- sessionIdentifier: " TEST " ,
116- sessionConfiguration: configuration,
117- storageDirectory: relativeStoragePath,
118- supportedExtensions: [ . creation] ,
119- generateHeaders: { _, headers, onHeadersGenerated in
120- let current = headers [ " Authorization " ] ?? " "
121- receivedAuthorizationHeaders. append ( current)
122- let nextValue = current. isEmpty ? " Bearer mutated \( receivedAuthorizationHeaders. count) " : " \( current) -mutated \( receivedAuthorizationHeaders. count - 1 ) "
123- onHeadersGenerated ( [ " Authorization " : nextValue] )
124- if trackedCalls < 2 {
125- generatorCalledTwice. fulfill ( )
126- }
127- trackedCalls += 1
96+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
97+ let current = headers [ " Authorization " ] ?? " "
98+ receivedAuthorizationHeaders. append ( current)
99+ let nextValue = current. isEmpty ? " Bearer mutated \( receivedAuthorizationHeaders. count) " : " \( current) -mutated \( receivedAuthorizationHeaders. count - 1 ) "
100+ onHeadersGenerated ( [ " Authorization " : nextValue] )
101+ if trackedCalls < 2 {
102+ generatorCalledTwice. fulfill ( )
128103 }
129- )
104+ trackedCalls += 1
105+ }
130106 client. delegate = tusDelegate
131107
132108 _ = try client. upload ( data: data, customHeaders: [ " Authorization " : " Bearer original " ] )
@@ -139,8 +115,7 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
139115
140116 /// Ensures resuming an upload reuses the previously applied headers.
141117 func testGenerateHeadersCalledWhenResumingUpload( ) throws {
142- let configuration = URLSessionConfiguration . default
143- configuration. protocolClasses = [ MockURLProtocol . self]
118+ let configuration = makeConfiguration ( )
144119
145120 prepareNetworkForSuccesfulUploads ( data: data)
146121
@@ -149,20 +124,13 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
149124 tusDelegate. startUploadExpectation = uploadStarted
150125
151126 var firstFulfilled = false
152- client = try TUSClient (
153- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
154- sessionIdentifier: " TEST " ,
155- sessionConfiguration: configuration,
156- storageDirectory: relativeStoragePath,
157- supportedExtensions: [ . creation] ,
158- generateHeaders: { _, headers, onHeadersGenerated in
159- onHeadersGenerated ( [ " Authorization " : " Bearer resume-mutated " ] )
160- if !firstFulfilled {
161- firstFulfilled = true
162- firstGeneratorCalled. fulfill ( )
163- }
127+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
128+ onHeadersGenerated ( [ " Authorization " : " Bearer resume-mutated " ] )
129+ if !firstFulfilled {
130+ firstFulfilled = true
131+ firstGeneratorCalled. fulfill ( )
164132 }
165- )
133+ }
166134 client. delegate = tusDelegate
167135
168136 let uploadID = try client. upload ( data: data, customHeaders: [ " Authorization " : " Bearer resume " ] )
@@ -178,17 +146,10 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
178146 tusDelegate. finishUploadExpectation = finishExpectation
179147
180148 var resumedHeaders : [ String ] = [ ]
181- client = try TUSClient (
182- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
183- sessionIdentifier: " TEST " ,
184- sessionConfiguration: configuration,
185- storageDirectory: relativeStoragePath,
186- supportedExtensions: [ . creation] ,
187- generateHeaders: { _, headers, onHeadersGenerated in
188- resumedHeaders. append ( headers [ " Authorization " ] ?? " " )
189- onHeadersGenerated ( headers)
190- }
191- )
149+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
150+ resumedHeaders. append ( headers [ " Authorization " ] ?? " " )
151+ onHeadersGenerated ( headers)
152+ }
192153 client. delegate = tusDelegate
193154
194155 let resumedUploads = client. start ( ) . map ( \. 0 )
@@ -200,28 +161,20 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
200161
201162 /// Ensures uploads wait for asynchronous header generation before proceeding.
202163 func testGenerateHeadersSupportsAsynchronousCompletion( ) throws {
203- let configuration = URLSessionConfiguration . default
204- configuration. protocolClasses = [ MockURLProtocol . self]
164+ let configuration = makeConfiguration ( )
205165 prepareNetworkForSuccesfulUploads ( data: data)
206166
207167 let asyncExpectation = expectation ( description: " Async header generator invoked " )
208168 asyncExpectation. expectedFulfillmentCount = 2
209169 let finishExpectation = expectation ( description: " Upload finished " )
210170 tusDelegate. finishUploadExpectation = finishExpectation
211171
212- client = try TUSClient (
213- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
214- sessionIdentifier: " TEST " ,
215- sessionConfiguration: configuration,
216- storageDirectory: relativeStoragePath,
217- supportedExtensions: [ . creation] ,
218- generateHeaders: { _, headers, onHeadersGenerated in
219- DispatchQueue . global ( ) . asyncAfter ( deadline: . now( ) + 0.2 ) {
220- asyncExpectation. fulfill ( )
221- onHeadersGenerated ( headers. merging ( [ " Authorization " : " Bearer async " ] ) { _, new in new } )
222- }
172+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
173+ DispatchQueue . global ( ) . asyncAfter ( deadline: . now( ) + 0.2 ) {
174+ asyncExpectation. fulfill ( )
175+ onHeadersGenerated ( headers. merging ( [ " Authorization " : " Bearer async " ] ) { _, new in new } )
223176 }
224- )
177+ }
225178 client. delegate = tusDelegate
226179
227180 _ = try client. upload ( data: data, customHeaders: [ " Authorization " : " Bearer original " ] )
@@ -230,30 +183,22 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
230183
231184 /// Ensures the generator only receives caller-supplied headers during upload creation.
232185 func testGenerateHeadersReceivesOnlyCustomHeadersDuringCreate( ) throws {
233- let configuration = URLSessionConfiguration . default
234- configuration. protocolClasses = [ MockURLProtocol . self]
186+ let configuration = makeConfiguration ( )
235187 prepareNetworkForSuccesfulUploads ( data: data)
236188
237189 let customHeaders = [ " Authorization " : " Bearer foo " , " X-Trace " : " 123 " ]
238190 var observedHeaders : [ [ String : String ] ] = [ ]
239191 let createGeneratorCalled = expectation ( description: " Header generator called during create " )
240192
241193 var createInvocationRecorded = false
242- client = try TUSClient (
243- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
244- sessionIdentifier: " TEST " ,
245- sessionConfiguration: configuration,
246- storageDirectory: relativeStoragePath,
247- supportedExtensions: [ . creation] ,
248- generateHeaders: { _, headers, onHeadersGenerated in
249- if !createInvocationRecorded {
250- observedHeaders. append ( headers)
251- createInvocationRecorded = true
252- createGeneratorCalled. fulfill ( )
253- }
254- onHeadersGenerated ( headers)
194+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
195+ if !createInvocationRecorded {
196+ observedHeaders. append ( headers)
197+ createInvocationRecorded = true
198+ createGeneratorCalled. fulfill ( )
255199 }
256- )
200+ onHeadersGenerated ( headers)
201+ }
257202 tusDelegate. finishUploadExpectation = expectation ( description: " Upload finished " )
258203 client. delegate = tusDelegate
259204
@@ -265,23 +210,15 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
265210
266211 /// Ensures the generator only receives caller-supplied headers when a status check runs.
267212 func testGenerateHeadersReceivesOnlyCustomHeadersDuringStatus( ) throws {
268- let configuration = URLSessionConfiguration . default
269- configuration. protocolClasses = [ MockURLProtocol . self]
213+ let configuration = makeConfiguration ( )
270214 prepareNetworkForSuccesfulUploads ( data: data)
271215
272216 let customHeaders = [ " Authorization " : " Bearer bar " , " X-Trace " : " resume-123 " ]
273217 tusDelegate. startUploadExpectation = expectation ( description: " Upload started " )
274218
275- client = try TUSClient (
276- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
277- sessionIdentifier: " TEST " ,
278- sessionConfiguration: configuration,
279- storageDirectory: relativeStoragePath,
280- supportedExtensions: [ . creation] ,
281- generateHeaders: { _, headers, onHeadersGenerated in
282- onHeadersGenerated ( headers)
283- }
284- )
219+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
220+ onHeadersGenerated ( headers)
221+ }
285222 client. delegate = tusDelegate
286223
287224 let uploadID = try client. upload ( data: data, customHeaders: customHeaders)
@@ -298,20 +235,13 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
298235 tusDelegate. finishUploadExpectation = finishExpectation
299236
300237 var observedHeaders : [ [ String : String ] ] = [ ]
301- client = try TUSClient (
302- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
303- sessionIdentifier: " TEST " ,
304- sessionConfiguration: configuration,
305- storageDirectory: relativeStoragePath,
306- supportedExtensions: [ . creation] ,
307- generateHeaders: { _, headers, onHeadersGenerated in
308- observedHeaders. append ( headers)
309- onHeadersGenerated ( headers)
310- if observedHeaders. count == 1 {
311- statusGeneratorCalled. fulfill ( )
312- }
238+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
239+ observedHeaders. append ( headers)
240+ onHeadersGenerated ( headers)
241+ if observedHeaders. count == 1 {
242+ statusGeneratorCalled. fulfill ( )
313243 }
314- )
244+ }
315245 client. delegate = tusDelegate
316246
317247 let resumedUploads = client. start ( ) . map ( \. 0 )
@@ -322,25 +252,17 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
322252
323253 /// Ensures the generator only receives caller-supplied headers during the upload (PATCH) step.
324254 func testGenerateHeadersReceivesOnlyCustomHeadersDuringUpload( ) throws {
325- let configuration = URLSessionConfiguration . default
326- configuration. protocolClasses = [ MockURLProtocol . self]
255+ let configuration = makeConfiguration ( )
327256 prepareNetworkForSuccesfulUploads ( data: data)
328257
329258 let customHeaders = [ " Authorization " : " Bearer data " , " X-Trace " : " upload-step " ]
330259 tusDelegate. finishUploadExpectation = expectation ( description: " Upload finished " )
331260
332261 var uploadHeaders : [ [ String : String ] ] = [ ]
333- client = try TUSClient (
334- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
335- sessionIdentifier: " TEST " ,
336- sessionConfiguration: configuration,
337- storageDirectory: relativeStoragePath,
338- supportedExtensions: [ . creation] ,
339- generateHeaders: { _, headers, onHeadersGenerated in
340- uploadHeaders. append ( headers)
341- onHeadersGenerated ( headers)
342- }
343- )
262+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
263+ uploadHeaders. append ( headers)
264+ onHeadersGenerated ( headers)
265+ }
344266 client. delegate = tusDelegate
345267
346268 _ = try client. upload ( data: data, customHeaders: customHeaders)
@@ -351,27 +273,19 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
351273
352274 /// Ensures the generator cannot override headers that TUSClient manages itself.
353275 func testGenerateHeadersCannotOverrideReservedHeaders( ) throws {
354- let configuration = URLSessionConfiguration . default
355- configuration. protocolClasses = [ MockURLProtocol . self]
276+ let configuration = makeConfiguration ( )
356277 MockURLProtocol . reset ( )
357278 prepareNetworkForSuccesfulUploads ( data: data)
358279
359280 let customHeaders = [ " Authorization " : " Bearer original " ]
360281 tusDelegate. finishUploadExpectation = expectation ( description: " Upload finished " )
361282
362- client = try TUSClient (
363- server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
364- sessionIdentifier: " TEST " ,
365- sessionConfiguration: configuration,
366- storageDirectory: relativeStoragePath,
367- supportedExtensions: [ . creation] ,
368- generateHeaders: { _, headers, onHeadersGenerated in
369- var newHeaders = headers
370- newHeaders [ " Authorization " ] = " Bearer mutated "
371- newHeaders [ " Upload-Offset " ] = " 999 "
372- onHeadersGenerated ( newHeaders)
373- }
374- )
283+ client = try makeClient ( configuration: configuration) { _, headers, onHeadersGenerated in
284+ var newHeaders = headers
285+ newHeaders [ " Authorization " ] = " Bearer mutated "
286+ newHeaders [ " Upload-Offset " ] = " 999 "
287+ onHeadersGenerated ( newHeaders)
288+ }
375289 client. delegate = tusDelegate
376290
377291 _ = try client. upload ( data: data, customHeaders: customHeaders)
@@ -386,4 +300,23 @@ final class TUSClient_HeaderGenerationTests: XCTestCase {
386300 XCTAssertEqual ( patchHeaders [ " Authorization " ] , " Bearer mutated " )
387301 XCTAssertNotEqual ( patchHeaders [ " Upload-Offset " ] , " 999 " )
388302 }
303+
304+ private func makeConfiguration( ) -> URLSessionConfiguration {
305+ let configuration = URLSessionConfiguration . default
306+ configuration. protocolClasses = [ MockURLProtocol . self]
307+ return configuration
308+ }
309+
310+ private func makeClient( configuration: URLSessionConfiguration ? = nil ,
311+ generateHeaders: HeaderGenerationHandler ? = nil ) throws -> TUSClient {
312+ let configuration = configuration ?? makeConfiguration ( )
313+ return try TUSClient (
314+ server: URL ( string: " https://tusd.tusdemo.net/files " ) !,
315+ sessionIdentifier: " TEST " ,
316+ sessionConfiguration: configuration,
317+ storageDirectory: relativeStoragePath,
318+ supportedExtensions: [ . creation] ,
319+ generateHeaders: generateHeaders
320+ )
321+ }
389322}
0 commit comments