diff --git a/Source/BugsnagConfiguration.h b/Source/BugsnagConfiguration.h index dae31ff7c..86388335f 100644 --- a/Source/BugsnagConfiguration.h +++ b/Source/BugsnagConfiguration.h @@ -145,6 +145,12 @@ typedef NSDictionary *_Nullable (^BugsnagBeforeNotifyHook)( */ - (void)addBeforeSendBlock:(BugsnagBeforeSendBlock _Nonnull)block; + +/** + * Clear all callbacks + */ +- (void)clearBeforeSendBlocks; + /** * Whether reports shoould be sent, based on release stage options * diff --git a/Source/BugsnagConfiguration.m b/Source/BugsnagConfiguration.m index bfae933e6..515e2eb62 100644 --- a/Source/BugsnagConfiguration.m +++ b/Source/BugsnagConfiguration.m @@ -38,7 +38,7 @@ + (BugsnagNotifier*)notifier; @interface BugsnagConfiguration () @property(nonatomic, readwrite, strong) NSMutableArray *beforeNotifyHooks; -@property(nonatomic, readwrite, strong) NSMutableArray *BugsnagBeforeSendBlock; +@property(nonatomic, readwrite, strong) NSMutableArray *beforeSendBlocks; @end @implementation BugsnagConfiguration @@ -51,7 +51,7 @@ - (id)init { _autoNotify = YES; _notifyURL = [NSURL URLWithString:@"https://notify.bugsnag.com/"]; _beforeNotifyHooks = [NSMutableArray new]; - _BugsnagBeforeSendBlock = [NSMutableArray new]; + _beforeSendBlocks = [NSMutableArray new]; _notifyReleaseStages = nil; _breadcrumbs = [BugsnagBreadcrumbs new]; _automaticallyCollectBreadcrumbs = YES; @@ -83,6 +83,10 @@ - (void)addBeforeSendBlock:(BugsnagBeforeSendBlock)block { [(NSMutableArray *)self.beforeSendBlocks addObject:[block copy]]; } +- (void)clearBeforeSendBlocks { + [(NSMutableArray *)self.beforeSendBlocks removeAllObjects]; +} + - (void)addBeforeNotifyHook:(BugsnagBeforeNotifyHook)hook { [(NSMutableArray *)self.beforeNotifyHooks addObject:[hook copy]]; } diff --git a/Tests/BugsnagSpec.m b/Tests/BugsnagSpec.m index 09bb3b1af..c567b813a 100644 --- a/Tests/BugsnagSpec.m +++ b/Tests/BugsnagSpec.m @@ -42,6 +42,7 @@ @implementation BugsnagTestError }; beforeEach(^{ + request = nil; BugsnagSink *sink = [[KSCrash sharedInstance] valueForKeyPath:@"sink"]; NSURLSession *session = [sink valueForKeyPath:@"session"]; [session stub:@selector(uploadTaskWithRequest:fromData:completionHandler:) withBlock:^id(NSArray *params) { @@ -56,6 +57,7 @@ @implementation BugsnagTestError afterEach(^{ request = nil; httpBody = nil; + [[Bugsnag configuration] clearBeforeSendBlocks]; }); describe(@"notify:", ^{ @@ -87,6 +89,46 @@ @implementation BugsnagTestError }); }); + describe(@"updating a report via notify: with beforeSend block", ^{ + __block NSException *exception; + __block BOOL called; + beforeEach(^{ + called = NO; + exception = [NSException exceptionWithName:@"failure to launch" + reason:@"no fuel" userInfo:nil]; + [[Bugsnag configuration] addBeforeSendBlock:^bool(NSDictionary * _Nonnull rawEventData, BugsnagCrashReport * _Nonnull report) { + report.errorClass = @"FatalException"; + called = YES; + return YES; + }]; + [Bugsnag notify:exception]; + }); + + it(@"invokes the block", ^{ + [[expectFutureValue(@(called)) shouldSoon] equal:@YES]; + }); + + it(@"updates report data", ^{ + [[expectFutureValue(requestExceptionValue(@"errorClass")) shouldSoon] equal:@"FatalException"]; + }); + }); + + describe(@"cancelling a report via notify: with beforeSend block", ^{ + __block NSException *exception; + beforeEach(^{ + exception = [NSException exceptionWithName:@"failure to launch" + reason:@"no fuel" userInfo:nil]; + [[Bugsnag configuration] addBeforeSendBlock:^bool(NSDictionary * _Nonnull rawEventData, BugsnagCrashReport * _Nonnull report) { + return NO; + }]; + [Bugsnag notify:exception]; + }); + + it(@"cancels the report", ^{ + [[expectFutureValue(request) shouldAfterWait] beNil]; + }); + }); + describe(@"notify:block:", ^{ __block NSException *exception;