mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-11 22:55:59 +05:45
- Failing unit tests - which need to be looked into https://github.com/firebase/firebase-ios-sdk/pull/16546
1213 lines
59 KiB
Objective-C
1213 lines
59 KiB
Objective-C
// Copyright 2020 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#pragma mark - Unswizzle based tests
|
|
|
|
#ifndef SWIFT_PACKAGE
|
|
|
|
#import "FirebasePerformance/Tests/Unit/Instruments/FPRNSURLSessionInstrumentTestDelegates.h"
|
|
|
|
#import <XCTest/XCTest.h>
|
|
#import <objc/runtime.h>
|
|
|
|
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations+Private.h"
|
|
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
|
|
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
|
|
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNSURLSessionInstrument.h"
|
|
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNSURLSessionInstrument_Private.h"
|
|
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
|
|
|
|
#import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
|
|
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
|
|
#import "FirebasePerformance/Tests/Unit/Server/FPRHermeticTestServer.h"
|
|
|
|
/** This class is used to wrap an NSURLSession object during testing. */
|
|
@interface FPRNSURLSessionProxy : NSProxy {
|
|
// The wrapped session object.
|
|
id _session;
|
|
}
|
|
|
|
/** @return an instance of the session proxy. */
|
|
- (instancetype)initWithSession:(id)session;
|
|
|
|
@end
|
|
|
|
@implementation FPRNSURLSessionProxy
|
|
|
|
- (instancetype)initWithSession:(id)session {
|
|
if (self) {
|
|
_session = session;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
|
|
return [_session methodSignatureForSelector:selector];
|
|
}
|
|
|
|
- (void)forwardInvocation:(NSInvocation *)invocation {
|
|
[invocation invokeWithTarget:_session];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface FPRNSURLSessionDelegateProxy : NSProxy {
|
|
// The wrapped delegate object.
|
|
id _delegate;
|
|
}
|
|
|
|
/** @return an instance of the delegate proxy. */
|
|
- (instancetype)initWithDelegate:(id)delegate;
|
|
|
|
/** @return the wrapped delegate object. */
|
|
- (id)delegate;
|
|
|
|
@end
|
|
|
|
@implementation FPRNSURLSessionDelegateProxy
|
|
|
|
- (instancetype)initWithDelegate:(id)delegate {
|
|
if (self) {
|
|
_delegate = delegate;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (Class)class {
|
|
return [self.delegate class];
|
|
}
|
|
|
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
|
|
return [_delegate methodSignatureForSelector:selector];
|
|
}
|
|
|
|
- (BOOL)respondsToSelector:(SEL)aSelector {
|
|
return [_delegate respondsToSelector:aSelector];
|
|
}
|
|
|
|
- (id)delegate {
|
|
return _delegate;
|
|
}
|
|
|
|
- (void)forwardInvocation:(NSInvocation *)invocation {
|
|
[invocation invokeWithTarget:_delegate];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface FPRNSURLSessionDelegateWeakProxy : NSProxy {
|
|
// The wrapped delegate object.
|
|
__weak id _delegate;
|
|
}
|
|
|
|
/** @return an instance of the delegate proxy. */
|
|
- (instancetype)initWithDelegate:(id)delegate;
|
|
|
|
@end
|
|
|
|
@implementation FPRNSURLSessionDelegateWeakProxy
|
|
|
|
- (instancetype)initWithDelegate:(id)delegate {
|
|
if (self) {
|
|
_delegate = delegate;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (Class)class {
|
|
return [self->_delegate class];
|
|
}
|
|
|
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
|
|
return [_delegate methodSignatureForSelector:selector];
|
|
}
|
|
|
|
- (BOOL)respondsToSelector:(SEL)aSelector {
|
|
return [_delegate respondsToSelector:aSelector];
|
|
}
|
|
|
|
- (void)forwardInvocation:(NSInvocation *)invocation {
|
|
[invocation invokeWithTarget:_delegate];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface FPRNSURLSessionInstrumentTest : FPRTestCase
|
|
|
|
/** Test server to create connections to. */
|
|
@property(nonatomic) FPRHermeticTestServer *testServer;
|
|
|
|
@end
|
|
|
|
@implementation FPRNSURLSessionInstrumentTest
|
|
|
|
- (void)setUp {
|
|
[super setUp];
|
|
FIRPerformance *performance = [FIRPerformance sharedInstance];
|
|
[performance setDataCollectionEnabled:YES];
|
|
XCTAssertFalse(self.testServer.isRunning);
|
|
self.testServer = [[FPRHermeticTestServer alloc] init];
|
|
[self.testServer registerTestPaths];
|
|
[self.testServer start];
|
|
}
|
|
|
|
- (void)tearDown {
|
|
[super tearDown];
|
|
FIRPerformance *performance = [FIRPerformance sharedInstance];
|
|
[performance setDataCollectionEnabled:NO];
|
|
[self.testServer stop];
|
|
[FPRConfigurations reset];
|
|
}
|
|
|
|
/** Waits for the server connection to finish by giving a block to run just before a response is
|
|
* sent.
|
|
*
|
|
* @param block A block to run just after the server response is sent.
|
|
*/
|
|
- (void)waitAndRunBlockAfterResponse:(void (^)(id self,
|
|
GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response))block {
|
|
__block BOOL loopingMainThread = YES;
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
__weak id weakSelf = self;
|
|
self.testServer.responseCompletedBlock =
|
|
^(GCDWebServerRequest *_Nonnull request, GCDWebServerResponse *_Nonnull response) {
|
|
block(weakSelf, request, response);
|
|
dispatch_semaphore_signal(sema);
|
|
};
|
|
XCTAssertEqual(
|
|
dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC)), 0);
|
|
loopingMainThread = NO;
|
|
});
|
|
// This is necessary because the FPRHermeticTestServer callbacks occur on the main thread.
|
|
while (loopingMainThread) {
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Testing infrastructure and subclass instrumenting
|
|
|
|
/** Tests initing of FPRNSURLSessionInstrument also inits NSURLSessionDelegate instrument. */
|
|
- (void)testInit {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
self.testServer.responseCompletedBlock =
|
|
^(GCDWebServerRequest *_Nonnull request, GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssert(instrument);
|
|
XCTAssert(instrument.delegateInstrument);
|
|
};
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that creating a shared session returns a non-nil object. */
|
|
- (void)testSharedSession {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
XCTAssertNotNil(session);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that a method that returns an NSURLSession subclass registers that subclass. */
|
|
- (void)testSubclassRegistration {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
XCTAssertNotNil(session);
|
|
XCTAssertEqual(instrument.classInstrumentors.count, 2);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that a discovered subclass isn't registered more than once. */
|
|
- (void)testSubclassIsNotRegisteredMoreThanOnce {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURLSession *session2 = [NSURLSession sharedSession];
|
|
XCTAssertNotNil(session);
|
|
XCTAssertNotNil(session2);
|
|
XCTAssertEqual(instrument.classInstrumentors.count, 2);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests sessionWithConfiguration: with the default configuration returns a non-nil object. */
|
|
- (void)testSessionWithDefaultSessionConfiguration {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
|
|
XCTAssertNotNil(session);
|
|
XCTAssertEqual(instrument.classInstrumentors.count, 2);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests sessionWithConfiguration: with an ephemeral configuration returns a non-nil object. */
|
|
- (void)testSessionWithEphemeralSessionConfiguration {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration ephemeralSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
|
|
XCTAssertNotNil(session);
|
|
XCTAssertEqual(instrument.classInstrumentors.count, 2);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests sessionWithConfiguration: with a background configuration returns a non-nil object. */
|
|
- (void)testSessionWithBackgroundSessionConfiguration {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"madeUpID"];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
|
|
XCTAssertNotNil(session);
|
|
XCTAssertEqual(instrument.classInstrumentors.count, 2);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests instrumenting an NSProxy wrapped NSURLSession object works. */
|
|
- (void)testProxyWrappedSharedSession {
|
|
Method method = class_getClassMethod([NSURLSession class], @selector(sharedSession));
|
|
IMP originalImp = method_getImplementation(method);
|
|
IMP swizzledImp = imp_implementationWithBlock(^(id session) {
|
|
typedef NSURLSession *(*OriginalImp)(id, SEL);
|
|
NSURLSession *originalSession = ((OriginalImp)originalImp)(session, @selector(sharedSession));
|
|
return [[FPRNSURLSessionProxy alloc] initWithSession:originalSession];
|
|
});
|
|
method_setImplementation(method, swizzledImp);
|
|
XCTAssertEqual([[NSURLSession sharedSession] class], [FPRNSURLSessionProxy class]);
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session;
|
|
XCTAssertNoThrow(session = [NSURLSession sharedSession]);
|
|
NSURL *url = self.testServer.serverURL;
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler"];
|
|
NSURLSessionDownloadTask *task =
|
|
[session downloadTaskWithURL:url
|
|
completionHandler:^(NSURL *_Nullable location, NSURLResponse *_Nullable response,
|
|
NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
}];
|
|
[task resume];
|
|
XCTAssertNotNil(task);
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
method_setImplementation(method, originalImp);
|
|
XCTAssertNotEqual([[NSURLSession sharedSession] class], [FPRNSURLSessionProxy class]);
|
|
}
|
|
|
|
/** Tests instrumenting an NSProxy wrapped NSURLSession object works. */
|
|
- (void)testProxyWrappedSessionWithConfiguration {
|
|
Method method = class_getClassMethod([NSURLSession class], @selector(sessionWithConfiguration:));
|
|
IMP originalImp = method_getImplementation(method);
|
|
IMP swizzledImp =
|
|
imp_implementationWithBlock(^(id session, NSURLSessionConfiguration *configuration) {
|
|
typedef NSURLSession *(*OriginalImp)(id, SEL, NSURLSessionConfiguration *);
|
|
NSURLSession *originalSession = ((OriginalImp)originalImp)(
|
|
session, @selector(sessionWithConfiguration:), configuration);
|
|
return [[FPRNSURLSessionProxy alloc] initWithSession:originalSession];
|
|
});
|
|
method_setImplementation(method, swizzledImp);
|
|
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
|
XCTAssertEqual([[NSURLSession sessionWithConfiguration:config] class],
|
|
[FPRNSURLSessionProxy class]);
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session;
|
|
XCTAssertNoThrow(session = [NSURLSession sessionWithConfiguration:config]);
|
|
NSURL *url = self.testServer.serverURL;
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler"];
|
|
NSURLSessionDownloadTask *task =
|
|
[session downloadTaskWithURL:url
|
|
completionHandler:^(NSURL *_Nullable location, NSURLResponse *_Nullable response,
|
|
NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
}];
|
|
XCTAssertNotNil(task);
|
|
[task resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
method_setImplementation(method, originalImp);
|
|
XCTAssertNotEqual([[NSURLSession sharedSession] class], [FPRNSURLSessionProxy class]);
|
|
}
|
|
|
|
/** Tests instrumenting an NSProxy wrapped NSURLSession object works. */
|
|
- (void)testProxyWrappedSessionWithConfigurationDelegateDelegateQueue {
|
|
SEL selector = @selector(sessionWithConfiguration:delegate:delegateQueue:);
|
|
Method method = class_getClassMethod([NSURLSession class], selector);
|
|
IMP originalImp = method_getImplementation(method);
|
|
IMP swizzledImp = imp_implementationWithBlock(
|
|
^(id session, NSURLSessionConfiguration *configuration, id<NSURLSessionDelegate> *delegate,
|
|
NSOperationQueue *delegateQueue) {
|
|
typedef NSURLSession *(*OriginalImp)(id, SEL, NSURLSessionConfiguration *,
|
|
id<NSURLSessionDelegate> *, NSOperationQueue *);
|
|
NSURLSession *originalSession =
|
|
((OriginalImp)originalImp)(session, selector, configuration, delegate, delegateQueue);
|
|
return [[FPRNSURLSessionProxy alloc] initWithSession:originalSession];
|
|
});
|
|
method_setImplementation(method, swizzledImp);
|
|
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
|
XCTAssertEqual([[NSURLSession sessionWithConfiguration:config delegate:nil
|
|
delegateQueue:nil] class],
|
|
[FPRNSURLSessionProxy class]);
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session;
|
|
XCTAssertNoThrow(session = [NSURLSession sessionWithConfiguration:config
|
|
delegate:nil
|
|
delegateQueue:nil]);
|
|
NSURL *url = self.testServer.serverURL;
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler"];
|
|
NSURLSessionDownloadTask *task =
|
|
[session downloadTaskWithURL:url
|
|
completionHandler:^(NSURL *_Nullable location, NSURLResponse *_Nullable response,
|
|
NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
}];
|
|
XCTAssertNotNil(task);
|
|
[task resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
method_setImplementation(method, originalImp);
|
|
}
|
|
|
|
#pragma mark - Testing delegate method wrapping
|
|
|
|
/** Tests using a nil delegate still results in tracking responses. */
|
|
- (void)testSessionWithConfigurationDelegateDelegateQueueWithNilDelegate {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:nil
|
|
delegateQueue:nil];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.testServer.serverURL];
|
|
NSURLSessionTask *task;
|
|
@autoreleasepool {
|
|
task = [session dataTaskWithRequest:request];
|
|
XCTAssertNotNil(task);
|
|
[task resume];
|
|
XCTAssertNotNil(session.delegate); // Not sure this is the desired behavior.
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
}];
|
|
}
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the delegate class isn't instrumented more than once. */
|
|
- (void)testDelegateClassOnlyRegisteredOnce {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
[NSURLSession sessionWithConfiguration:configuration delegate:delegate delegateQueue:nil];
|
|
[NSURLSession sessionWithConfiguration:configuration delegate:delegate delegateQueue:nil];
|
|
XCTAssertEqual(instrument.delegateInstrument.classInstrumentors.count, 1);
|
|
XCTAssertEqual(instrument.delegateInstrument.instrumentedClasses.count, 1);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testDelegateURLSessionTaskDidCompleteWithError {
|
|
[self.testServer stop];
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
// This request needs to fail.
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://nonurl"]];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURLSessionTask *task;
|
|
@autoreleasepool {
|
|
task = [session dataTaskWithRequest:request];
|
|
[task resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];
|
|
}
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
XCTAssertTrue(delegate.URLSessionTaskDidCompleteWithErrorCalled);
|
|
[instrument deregisterInstrumentors];
|
|
[self.testServer start];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testDelegateURLSessionTaskDidSendBodyDataTotalBytesSentTotalBytesExpectedToSend {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
|
|
request.HTTPMethod = @"POST";
|
|
|
|
NSBundle *bundle = [FPRTestUtils getBundle];
|
|
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileURL];
|
|
[uploadTask resume];
|
|
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
FPRNetworkTrace *networkTrace = [FPRNetworkTrace networkTraceFromObject:uploadTask];
|
|
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionTaskDidSendBodyDataTotalBytesSentTotalBytesExpectedCalled);
|
|
XCTAssert(networkTrace.requestSize > 0);
|
|
XCTAssert(
|
|
[networkTrace
|
|
timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
|
|
andState:FPRNetworkTraceCheckpointStateRequestCompleted] > 0);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testDelegateURLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testRedirect"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURLSessionTask *task = [session dataTaskWithRequest:request];
|
|
[task resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(
|
|
delegate.URLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandlerCalled);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testDelegateURLSessionDataTaskDidReceiveData {
|
|
FPRNSURLSessionInstrument *instrument;
|
|
NSURLSessionDataTask *dataTask;
|
|
@autoreleasepool {
|
|
instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
|
|
dataTask = [session dataTaskWithURL:URL];
|
|
[dataTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDataTaskDidReceiveDataCalled);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
}];
|
|
}
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testDelegateURLSessionDownloadTaskDidFinishDownloadingToURL {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testDownload"];
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:URL];
|
|
[downloadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDownloadTaskDidFinishDownloadingToURLCalled);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testDelegateURLSessionDownloadDidReceiveResponseCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument;
|
|
NSURLSessionDataTask *dataTask;
|
|
@autoreleasepool {
|
|
instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
|
|
dataTask = [session dataTaskWithURL:URL];
|
|
[dataTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDataTaskDidReceiveResponseCompletionHandlerCalled);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
}];
|
|
}
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through.
|
|
* The delegate cancels the download from didWriteData and resumes with resume data, which
|
|
* triggers didResumeAtOffset:expectedTotalBytes: on the same delegate.
|
|
*/
|
|
- (void)testDelegateURLSessionDownloadTaskDidResumeAtOffsetExpectedTotalBytes {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionTestDownloadDelegate *delegate =
|
|
[[FPRNSURLSessionTestDownloadDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:URL];
|
|
[downloadTask resume];
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
XCTAssertTrue(delegate.URLSessionDownloadTaskDidResumeAtOffsetExpectedTotalBytesCalled);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testDelegateURLSessionDownloadTaskDidWriteDataTotalBytesWrittenTotalBytesExpectedToWrite {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:URL];
|
|
[downloadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDownloadTaskDidWriteDataTotalBytesWrittenTotalBytesCalled);
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that even if a delegate doesn't implement a method, we add it to the delegate class. */
|
|
- (void)testDelegateUnimplementedURLSessionTaskDidCompleteWithError {
|
|
FPRNSURLSessionTestDelegate *delegate = [[FPRNSURLSessionTestDelegate alloc] init];
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
XCTAssertFalse([delegate respondsToSelector:@selector(URLSession:task:didCompleteWithError:)]);
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:delegate
|
|
delegateQueue:nil];
|
|
XCTAssertTrue([delegate respondsToSelector:@selector(URLSession:task:didCompleteWithError:)]);
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:self.testServer.serverURL];
|
|
[downloadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
#pragma mark - Testing proxy delegate method wrapping
|
|
|
|
/** Tests that the delegate class is instrumented once when its wrapped with NSProxy. */
|
|
- (void)testProxyDelegateSwizzlesDelegateOnce {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
[NSURLSession sessionWithConfiguration:configuration delegate:proxyDelegate delegateQueue:nil];
|
|
[NSURLSession sessionWithConfiguration:configuration delegate:proxyDelegate delegateQueue:nil];
|
|
XCTAssertEqual(instrument.delegateInstrument.classInstrumentors.count, 1);
|
|
XCTAssertEqual(instrument.delegateInstrument.instrumentedClasses.count, 1);
|
|
XCTAssertTrue(
|
|
[instrument.delegateInstrument.instrumentedClasses containsObject:[delegate class]]);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the delegate class is not instrumented in an NSProxy if it is weak. */
|
|
- (void)testWeakProxyDelegateSkipsSwizzlingDelegate {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateWeakProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateWeakProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
[NSURLSession sessionWithConfiguration:configuration delegate:proxyDelegate delegateQueue:nil];
|
|
[NSURLSession sessionWithConfiguration:configuration delegate:proxyDelegate delegateQueue:nil];
|
|
XCTAssertEqual(instrument.delegateInstrument.classInstrumentors.count, 0);
|
|
XCTAssertEqual(instrument.delegateInstrument.instrumentedClasses.count, 0);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testProxyDelegateURLSessionTaskDidCompleteWithError {
|
|
[self.testServer stop];
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://nonurl"]];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
NSURLSessionTask *task;
|
|
@autoreleasepool {
|
|
task = [session dataTaskWithRequest:request];
|
|
[task resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];
|
|
}
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
XCTAssertTrue(delegate.URLSessionTaskDidCompleteWithErrorCalled);
|
|
[instrument deregisterInstrumentors];
|
|
[self.testServer start];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testProxyDelegateURLSessionTaskDidSendBodyDataTotalBytesSentTotalBytesExpectedToSend {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
|
|
request.HTTPMethod = @"POST";
|
|
NSBundle *bundle = [FPRTestUtils getBundle];
|
|
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileURL];
|
|
[uploadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
FPRNetworkTrace *networkTrace = [FPRNetworkTrace networkTraceFromObject:uploadTask];
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionTaskDidSendBodyDataTotalBytesSentTotalBytesExpectedCalled);
|
|
XCTAssert(networkTrace.requestSize > 0);
|
|
XCTAssert(
|
|
[networkTrace
|
|
timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
|
|
andState:FPRNetworkTraceCheckpointStateRequestCompleted] > 0);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testProxyDelegateURLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testRedirect"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
NSURLSessionTask *task = [session dataTaskWithRequest:request];
|
|
[task resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:task]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(
|
|
delegate.URLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandlerCalled);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testProxyDelegateURLSessionDataTaskDidReceiveData {
|
|
FPRNSURLSessionInstrument *instrument;
|
|
NSURLSessionDataTask *dataTask;
|
|
@autoreleasepool {
|
|
instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
|
|
dataTask = [session dataTaskWithURL:URL];
|
|
[dataTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDataTaskDidReceiveDataCalled);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
}];
|
|
}
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testProxyDelegateURLSessionDownloadTaskDidFinishDownloadingToURL {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testDownload"];
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:URL];
|
|
[downloadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDownloadTaskDidFinishDownloadingToURLCalled);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)testProxyDelegateURLSessionDownloadDidReceiveResponseCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument;
|
|
NSURLSessionDataTask *dataTask;
|
|
@autoreleasepool {
|
|
instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
|
|
dataTask = [session dataTaskWithURL:URL];
|
|
[dataTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDataTaskDidReceiveResponseCompletionHandlerCalled);
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
}];
|
|
}
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that the called delegate selector is wrapped and calls through. */
|
|
- (void)
|
|
testProxyDelegateURLSessionDownloadTaskDidWriteDataTotalBytesWrittenTotalBytesExpectedToWrite {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
FPRNSURLSessionCompleteTestDelegate *delegate =
|
|
[[FPRNSURLSessionCompleteTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:URL];
|
|
[downloadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertTrue(delegate.URLSessionDownloadTaskDidWriteDataTotalBytesWrittenTotalBytesCalled);
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that even if a delegate doesn't implement a method, we add it to the delegate class. */
|
|
- (void)testProxyDelegateUnimplementedURLSessionTaskDidCompleteWithError {
|
|
FPRNSURLSessionTestDelegate *delegate = [[FPRNSURLSessionTestDelegate alloc] init];
|
|
FPRNSURLSessionDelegateProxy *proxyDelegate =
|
|
[[FPRNSURLSessionDelegateProxy alloc] initWithDelegate:delegate];
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSessionConfiguration *configuration =
|
|
[NSURLSessionConfiguration defaultSessionConfiguration];
|
|
XCTAssertFalse([delegate respondsToSelector:@selector(URLSession:task:didCompleteWithError:)]);
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
|
|
delegate:proxyDelegate
|
|
delegateQueue:nil];
|
|
XCTAssertTrue([delegate respondsToSelector:@selector(URLSession:task:didCompleteWithError:)]);
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:self.testServer.serverURL];
|
|
[downloadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
}];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
#pragma mark - Testing instance method wrapping
|
|
|
|
/** Tests that dataTaskWithRequest: returns a non-nil object. */
|
|
- (void)testDataTaskWithRequest {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"test"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
|
|
XCTAssertNotNil(dataTask);
|
|
[dataTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that dataTaskWithRequest:completionHandler: returns a non-nil object. */
|
|
- (void)testDataTaskWithRequestAndCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"test"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
|
|
void (^completionHandler)(NSData *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
|
|
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
};
|
|
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
|
|
completionHandler:completionHandler];
|
|
XCTAssertNotNil(dataTask);
|
|
[dataTask resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that dataTaskWithRequest:completionHandler: for a POST request returns a non-nil object
|
|
* and collects request size. */
|
|
- (void)testDataTaskWithPostRequestAndCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"test"];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
|
|
request.HTTPMethod = @"POST";
|
|
request.HTTPBody = [@"sampleData" dataUsingEncoding:NSUTF8StringEncoding];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
|
|
|
|
void (^completionHandler)(NSData *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
|
|
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
};
|
|
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
|
|
completionHandler:completionHandler];
|
|
XCTAssertNotNil(dataTask);
|
|
[dataTask resume];
|
|
FPRNetworkTrace *trace = [FPRNetworkTrace networkTraceFromObject:dataTask];
|
|
XCTAssertEqual(trace.requestSize, 10);
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that dataTaskWithUrl:completionHandler: returns a non-nil object. */
|
|
- (void)testDataTaskWithUrlAndCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"test"];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
|
|
|
|
NSURLSessionDataTask *dataTask = nil;
|
|
void (^completionHandler)(NSData *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
|
|
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[expectation fulfill];
|
|
};
|
|
dataTask = [session dataTaskWithURL:URL completionHandler:completionHandler];
|
|
XCTAssertNotNil(dataTask);
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[dataTask resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that uploadTaskWithRequest:fromFile: returns a non-nil object. */
|
|
- (void)testUploadTaskWithRequestFromFile {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
|
|
NSBundle *bundle = [FPRTestUtils getBundle];
|
|
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileURL];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
XCTAssertNotNil(uploadTask);
|
|
[uploadTask resume];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that uploadTaskWithRequest:fromFile:completionHandler returns a non-nil object. */
|
|
- (void)testUploadTaskWithRequestFromFileCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
|
|
NSBundle *bundle = [FPRTestUtils getBundle];
|
|
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
|
|
void (^completionHandler)(NSData *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
|
|
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
};
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
|
|
fromFile:fileURL
|
|
completionHandler:completionHandler];
|
|
XCTAssertNotNil(uploadTask);
|
|
[uploadTask resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that uploadTaskWithRequest:fromData: returns a non-nil object. */
|
|
- (void)testUploadTaskWithRequestFromData {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
|
|
request.HTTPMethod = @"POST";
|
|
NSData *data = [[NSData alloc] init];
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:data];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
XCTAssertNotNil(uploadTask);
|
|
[uploadTask resume];
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertEqual(response.statusCode, 200);
|
|
[instrument deregisterInstrumentors];
|
|
}];
|
|
}
|
|
|
|
/** Tests that uploadTaskWithRequest:fromData:completionHandler: returns a non-nil object. */
|
|
- (void)testUploadTaskWithRequestFromDataCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
|
|
void (^completionHandler)(NSData *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
|
|
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
};
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
|
|
fromData:[[NSData alloc] init]
|
|
completionHandler:completionHandler];
|
|
XCTAssertNotNil(uploadTask);
|
|
[uploadTask resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that uploadTaskWithStreamedRequest: returns a non-nil object. */
|
|
- (void)testUploadTaskWithStreamedRequest {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithStreamedRequest:request];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
XCTAssertNotNil(uploadTask);
|
|
[uploadTask resume];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that downloadTaskWithRequest: returns a non-nil object. */
|
|
- (void)testDownloadTaskWithRequest {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testDownload"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
XCTAssertNotNil(downloadTask);
|
|
[downloadTask resume];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that downloadTaskWithRequest:completionHandler: returns a non-nil object. */
|
|
- (void)testDownloadTaskWithRequestCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testDownload"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
|
|
void (^completionHandler)(NSURL *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
|
|
^(NSURL *_Nullable location, NSURLResponse *_Nullable response, NSError *_Nullable error) {
|
|
[expectation fulfill];
|
|
};
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request
|
|
completionHandler:completionHandler];
|
|
XCTAssertNotNil(downloadTask);
|
|
[downloadTask resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Tests that downloadTaskWithUrl:completionHandler: returns a non-nil object. */
|
|
- (void)testDownloadTaskWithURLCompletionHandler {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURLSession *session = [NSURLSession sharedSession];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"test"];
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
|
|
|
|
NSURLSessionDownloadTask *downloadTask = nil;
|
|
void (^completionHandler)(NSURL *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
|
|
^(NSURL *_Nullable location, NSURLResponse *_Nullable response, NSError *_Nullable error) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[expectation fulfill];
|
|
};
|
|
downloadTask = [session downloadTaskWithURL:URL completionHandler:completionHandler];
|
|
XCTAssertNotNil(downloadTask);
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[downloadTask resume];
|
|
[self waitForExpectationsWithTimeout:10.0 handler:nil];
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
/** Validate that it works with NSMutableURLRequest URLs across data, upload, and download. */
|
|
- (void)testMutableRequestURLs {
|
|
FPRNSURLSessionInstrument *instrument = [[FPRNSURLSessionInstrument alloc] init];
|
|
[instrument registerInstrumentors];
|
|
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testDownload"];
|
|
NSMutableURLRequest *URLRequest = [NSMutableURLRequest requestWithURL:URL];
|
|
NSURLSession *session = [NSURLSession
|
|
sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
|
|
|
|
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:URLRequest];
|
|
[dataTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:dataTask]);
|
|
}];
|
|
|
|
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:URLRequest];
|
|
[downloadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
|
|
}];
|
|
|
|
URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
|
|
URLRequest.URL = URL;
|
|
URLRequest.HTTPMethod = @"POST";
|
|
NSData *uploadData = [[NSData alloc] init];
|
|
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:URLRequest
|
|
fromData:uploadData];
|
|
[uploadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
}];
|
|
|
|
NSBundle *bundle = [FPRTestUtils getBundle];
|
|
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
|
|
uploadTask = [session uploadTaskWithRequest:URLRequest fromFile:fileURL];
|
|
[uploadTask resume];
|
|
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
[self waitAndRunBlockAfterResponse:^(id self, GCDWebServerRequest *_Nonnull request,
|
|
GCDWebServerResponse *_Nonnull response) {
|
|
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
|
|
}];
|
|
|
|
[instrument deregisterInstrumentors];
|
|
}
|
|
|
|
@end
|
|
|
|
#endif // SWIFT_PACKAGE
|