7
7
//
8
8
9
9
#import < XCTest/XCTest.h>
10
+ #import < Foundation/Foundation.h>
11
+ #import " CCPackageDownload.h"
12
+ #import " CCPackage.h"
13
+ #import " CCPackageDownloadDelegate.h"
10
14
11
- @interface CCPackageDownloadTests : XCTestCase
15
+ static NSUInteger __fileDownloadSize = 0 ;
16
+ static BOOL __support_range_request = YES ;
17
+
18
+ @interface CCPackageDownloadTestURLProtocol : NSURLProtocol @end
19
+
20
+ @implementation CCPackageDownloadTestURLProtocol
21
+
22
+ + (BOOL )canInitWithRequest : (NSURLRequest *)theRequest
23
+ {
24
+ return [theRequest.URL.scheme caseInsensitiveCompare: @" http" ] == NSOrderedSame;
25
+ }
26
+
27
+ + (NSURLRequest *)canonicalRequestForRequest : (NSURLRequest *)theRequest
28
+ {
29
+ return theRequest;
30
+ }
31
+
32
+ - (NSUInteger )parseRangeHeaderValue : (NSString *)string
33
+ {
34
+ if (!string)
35
+ {
36
+ return 0 ;
37
+ }
38
+
39
+ NSError *error;
40
+ NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern: @" bytes=(\\ d+)-"
41
+ options: NSRegularExpressionCaseInsensitive
42
+ error: &error];
43
+
44
+ NSTextCheckingResult *match = [regex firstMatchInString: string
45
+ options: NSMatchingAnchored
46
+ range: NSMakeRange (0 , string.length)];
47
+
48
+ if (match.numberOfRanges == 2 )
49
+ {
50
+ NSString *byteStr = [string substringWithRange: [match rangeAtIndex: 1 ]];
51
+ return (NSUInteger ) [byteStr integerValue ];
52
+ }
53
+
54
+ return 0 ;
55
+ }
56
+
57
+ - (void )startLoading
58
+ {
59
+ NSMutableDictionary *headers = [NSMutableDictionary dictionary ];
60
+
61
+
62
+ NSFileManager *fileManager = [NSFileManager defaultManager ];
63
+ NSString *fileName = [self .request.URL lastPathComponent ];
64
+ NSString *pathToPackage = [[NSBundle mainBundle ] pathForResource: [NSString stringWithFormat: @" Resources-shared/Packages/%@ " , fileName] ofType: nil ];
65
+ NSDictionary *attribs = [fileManager attributesOfItemAtPath: pathToPackage error: nil ];
66
+ NSUInteger fileSize = [attribs[NSFileSize ] unsignedIntegerValue ];
67
+
68
+ NSUInteger byteRangeStart = 0 ;
69
+ if (__support_range_request)
70
+ {
71
+ byteRangeStart = [self parseRangeHeaderValue: self .request.allHTTPHeaderFields[@" Range" ]];
72
+ headers[@" Accept-Ranges" ] = @" bytes" ;
73
+ headers[@" Content-Range" ] = [NSString stringWithFormat: @" bytes %u -%u /%u " , byteRangeStart, fileSize - 1 , fileSize];
74
+ }
75
+
76
+ NSData *data = [[NSData dataWithContentsOfFile: pathToPackage] subdataWithRange: NSMakeRange (byteRangeStart, fileSize - byteRangeStart)];
77
+
78
+ __fileDownloadSize = fileSize;
79
+
80
+ NSHTTPURLResponse *response;
81
+ if (pathToPackage)
82
+ {
83
+ headers[@" Content-Length" ] = [NSString stringWithFormat: @" %u " , [data length ]];
84
+ response = [[NSHTTPURLResponse alloc ] initWithURL: self .request.URL
85
+ statusCode: 200
86
+ HTTPVersion: @" HTTP/1.1"
87
+ headerFields: headers];
88
+ }
89
+ else
90
+ {
91
+ response = [[NSHTTPURLResponse alloc ] initWithURL: self .request.URL
92
+ statusCode: 404
93
+ HTTPVersion: @" HTTP/1.1"
94
+ headerFields: nil ];
95
+ }
96
+
97
+ id <NSURLProtocolClient > client = [self client ];
98
+ [client URLProtocol: self didReceiveResponse: response cacheStoragePolicy: NSURLCacheStorageNotAllowed];
99
+ [client URLProtocol: self didLoadData: data];
100
+ [client URLProtocolDidFinishLoading: self ];
101
+ }
102
+
103
+ - (void )stopLoading
104
+ {
105
+ // Nothing to do
106
+ }
107
+
108
+ @end
109
+
110
+
111
+ #pragma mark - test
112
+
113
+
114
+ @interface CCPackageDownloadTests : XCTestCase <CCPackageDownloadDelegate>
115
+
116
+ @property (nonatomic , strong ) CCPackageDownload *download;
117
+ @property (nonatomic , strong ) CCPackage *package;
118
+ @property (nonatomic , copy ) NSString *downloadPath;
119
+ @property (nonatomic ) BOOL downloadReturned;
120
+ @property (nonatomic ) BOOL downloadSuccessful;
121
+ @property (nonatomic , strong ) NSError *downloadError;
122
+ @property (nonatomic , copy ) NSURL *localURL;
12
123
13
124
@end
14
125
@@ -17,18 +128,137 @@ @implementation CCPackageDownloadTests
17
128
- (void )setUp
18
129
{
19
130
[super setUp ];
20
- // Put setup code here. This method is called before the invocation of each test method in the class.
131
+
132
+ [NSURLProtocol registerClass: [CCPackageDownloadTestURLProtocol class ]];
133
+
134
+ self.downloadPath = [NSTemporaryDirectory () stringByAppendingPathComponent: @" Downloads" ];
135
+
136
+ [self deleteDownloadFolder ];
137
+ [self createDownloadFolder ];
138
+
139
+ self.downloadReturned = NO ;
140
+ self.downloadError = nil ;
141
+ self.downloadSuccessful = NO ;
142
+
143
+
144
+ self.package = [[CCPackage alloc ] initWithName: @" testpackage"
145
+ resolution: @" phonehd"
146
+ os: @" iOS"
147
+ remoteURL: [NSURL URLWithString: @" http://package.request.fake/testpackage-iOS-phonehd.zip" ]];
148
+
149
+ self.localURL = [[NSURL fileURLWithPath: _downloadPath] URLByAppendingPathComponent: @" testdownload.zip" ];
150
+ self.download = [[CCPackageDownload alloc ] initWithPackage: _package localURL: _localURL];
151
+ _download.delegate = self;
21
152
}
22
153
23
154
- (void )tearDown
24
155
{
25
- // Put teardown code here. This method is called after the invocation of each test method in the class.
156
+ [NSURLProtocol unregisterClass: [CCPackageDownloadTestURLProtocol class ]];
157
+
26
158
[super tearDown ];
27
159
}
28
160
29
- - (void )testExample
161
+ - (void )deleteDownloadFolder
162
+ {
163
+ NSFileManager *fileManager = [NSFileManager defaultManager ];
164
+ NSError *error;
165
+ if (![fileManager removeItemAtPath: _downloadPath error: &error])
166
+ {
167
+ NSLog (@" %@ " ,error);
168
+ }
169
+ }
170
+
171
+ - (void )createDownloadFolder
172
+ {
173
+ NSError *error;
174
+ NSFileManager *fileManager = [NSFileManager defaultManager ];
175
+ if (![fileManager createDirectoryAtURL: [NSURL fileURLWithPath: _downloadPath]
176
+ withIntermediateDirectories: YES
177
+ attributes: nil
178
+ error: &error])
179
+ {
180
+ NSLog (@" %@ " , error);
181
+ }
182
+ }
183
+
184
+
185
+ #pragma mark - tests
186
+
187
+ - (void )testDownloadPackage
188
+ {
189
+ [self startDownloadAndWaitForDelegateToReturn ];
190
+
191
+ NSFileManager *fileManager = [NSFileManager defaultManager ];
192
+ NSDictionary *attribs = [fileManager attributesOfItemAtPath: _localURL.path error: nil ];
193
+
194
+ XCTAssertTrue ([fileManager fileExistsAtPath: _localURL.path]);
195
+ XCTAssertEqual ([attribs[NSFileSize ] unsignedIntegerValue ], __fileDownloadSize);
196
+ }
197
+
198
+ - (void )startDownloadAndWaitForDelegateToReturn
199
+ {
200
+ [_download start ];
201
+
202
+ while (!_downloadReturned)
203
+ {
204
+ [[NSRunLoop currentRunLoop ] runMode: NSDefaultRunLoopMode beforeDate: [NSDate distantFuture ]];
205
+ }
206
+ }
207
+
208
+ - (void )testRangeRequest
209
+ {
210
+ // Setting up partial download on disk
211
+ NSString *fileName = [_package.remoteURL lastPathComponent ];
212
+ NSString *pathToPackage = [[NSBundle mainBundle ] pathForResource: [NSString stringWithFormat: @" Resources-shared/Packages/%@ " , fileName] ofType: nil ];
213
+ NSData *data = [[NSData dataWithContentsOfFile: pathToPackage] subdataWithRange: NSMakeRange (0 , 5000 )];
214
+ NSString *tempName = [_download performSelector: @selector (createTempName )];
215
+ [data writeToFile: [[_localURL.path stringByDeletingLastPathComponent ] stringByAppendingPathComponent: tempName] atomically: YES ];
216
+
217
+ [self startDownloadAndWaitForDelegateToReturn ];
218
+
219
+ NSFileManager *fileManager = [NSFileManager defaultManager ];
220
+ NSDictionary *attribs = [fileManager attributesOfItemAtPath: _localURL.path error: nil ];
221
+ XCTAssertTrue ([fileManager fileExistsAtPath: _localURL.path]);
222
+ XCTAssertEqual ([attribs[NSFileSize ] unsignedIntegerValue ], __fileDownloadSize);
223
+ }
224
+
225
+ /*
226
+ - (void)testResumeDownloadedPackage
227
+ {
228
+
229
+ }
230
+
231
+ - (void)testPauseDownload
232
+ {
233
+
234
+ }
235
+
236
+
237
+ - (void)testDownloadWith404Response
238
+ {
239
+
240
+ }
241
+ */
242
+
243
+
244
+ #pragma mark - CCPackageDownloadDelegate
245
+
246
+ - (void )downloadFinished : (CCPackageDownload *)download
247
+ {
248
+ self.downloadReturned = YES ;
249
+ self.downloadSuccessful = YES ;
250
+ }
251
+
252
+ - (void )downloadFailed : (CCPackageDownload *)download error : (NSError *)error
253
+ {
254
+ self.downloadReturned = YES ;
255
+ self.downloadError = error;
256
+ self.downloadSuccessful = NO ;
257
+ }
258
+
259
+ - (BOOL )shouldResumeDownload : (CCPackageDownload *)download
30
260
{
31
- XCTFail ( @" No implementation for \" %s \" " , __PRETTY_FUNCTION__) ;
261
+ return YES ;
32
262
}
33
263
34
264
@end
0 commit comments