Skip to content

Commit cf13549

Browse files
committed
Ensure fetcher authorization delays support stop callbacks.
1 parent 295c3f6 commit cf13549

File tree

2 files changed

+36
-20
lines changed

2 files changed

+36
-20
lines changed

Sources/Core/GTMSessionFetcher.m

+22-4
Original file line numberDiff line numberDiff line change
@@ -1827,13 +1827,26 @@ - (void)authorizer:(nullable id __unused)auth
18271827
finishedWithError:(nullable NSError *)error {
18281828
GTMSessionCheckNotSynchronized(self);
18291829

1830+
@synchronized(self) {
1831+
// If `stopFetching` was called, do nothing, since the fetch was in a delay state
1832+
// any needed callback already happened.
1833+
if (_userStoppedFetching) {
1834+
return;
1835+
}
1836+
// If it wasn't called, clear the `_delayState`, so a call after this point will
1837+
// trigger a callback as needed. This also ensure if this is going to error below
1838+
// a cancel callback couldn't also trigger.
1839+
_delayState = kDelayStateNotDelayed;
1840+
1841+
if (error == nil) {
1842+
_request = authorizedRequest;
1843+
}
1844+
}
1845+
18301846
if (error != nil) {
18311847
// We can't fetch without authorization
18321848
[self failToBeginFetchWithError:(NSError *_Nonnull)error];
18331849
} else {
1834-
@synchronized(self) {
1835-
_request = authorizedRequest;
1836-
}
18371850
[self beginFetchMayDelay:NO mayAuthorize:NO mayDecorate:YES];
18381851
}
18391852
}
@@ -2080,7 +2093,12 @@ - (void)stopFetching {
20802093
// `stopFetchReleasingCallbacks:` will dequeue it if there is a sevice throttled
20812094
// delay, so the canceled callback needs to be directly triggered since the serivce
20822095
// won't attempt to restart it.
2083-
triggerCallback = _delayState == kDelayStateServiceDelayed && self.stopFetchingTriggersCompletionHandler;
2096+
//
2097+
// And the authorization delay assumes all stop notifications needed will be done from
2098+
// from here.
2099+
triggerCallback =
2100+
(_delayState == kDelayStateServiceDelayed || _delayState == kDelayStateAuthorizing) &&
2101+
self.stopFetchingTriggersCompletionHandler;
20842102
} // @synchronized(self)
20852103

20862104
if (triggerCallback) {

UnitTests/GTMSessionFetcherFetchingTest.m

+14-16
Original file line numberDiff line numberDiff line change
@@ -1585,57 +1585,47 @@ - (void)testDelayedSyncAuthCancelFetchWithCallback_WithoutFetcherService {
15851585
}
15861586

15871587
- (void)testImmediateSyncAuthCancelFetchWithCallback {
1588-
XCTSkip(@"Has failed on CI, but not locally, needs investigation.");
15891588
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer syncAuthorizer]];
15901589
}
15911590

15921591
- (void)testImmediateSyncAuthCancelFetchWithCallback_WithoutFetcherService {
15931592
_fetcherService = nil;
1594-
XCTSkip(@"Has failed on CI, but not locally, needs investigation.");
15951593
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer syncAuthorizer]];
15961594
}
15971595

15981596
- (void)testDelayedAsyncAuthCancelFetchWithCallback {
1599-
XCTSkip(@"Currently fails, needs fixing.");
16001597
[self internalCancelFetchWithCallback:1 authorizer:[TestAuthorizer asyncAuthorizer]];
16011598
}
16021599

16031600
- (void)testDelayedAsyncAuthCancelFetchWithCallback_WithoutFetcherService {
16041601
_fetcherService = nil;
1605-
XCTSkip(@"Currently fails, needs fixing.");
16061602
[self internalCancelFetchWithCallback:1 authorizer:[TestAuthorizer asyncAuthorizer]];
16071603
}
16081604

16091605
- (void)testImmediateAsyncAuthCancelFetchWithCallback {
1610-
XCTSkip(@"Currently fails, needs fixing.");
16111606
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer asyncAuthorizer]];
16121607
}
16131608

16141609
- (void)testImmediateAsyncAuthCancelFetchWithCallback_WithoutFetcherService {
16151610
_fetcherService = nil;
1616-
XCTSkip(@"Currently fails, needs fixing.");
16171611
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer asyncAuthorizer]];
16181612
}
16191613

16201614
- (void)testDelayedAsyncDelayedAuthCancelFetchWithCallback {
1621-
XCTSkip(@"Currently fails, needs fixing.");
16221615
[self internalCancelFetchWithCallback:1 authorizer:[TestAuthorizer asyncAuthorizerDelayed:2]];
16231616
}
16241617

16251618
- (void)testDelayedAsyncDelayedAuthCancelFetchWithCallback_WithoutFetcherService {
16261619
_fetcherService = nil;
1627-
XCTSkip(@"Currently fails, needs fixing.");
16281620
[self internalCancelFetchWithCallback:1 authorizer:[TestAuthorizer asyncAuthorizerDelayed:2]];
16291621
}
16301622

16311623
- (void)testImmediateAsyncDelayedAuthCancelFetchWithCallback {
1632-
XCTSkip(@"Currently fails, needs fixing.");
16331624
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer asyncAuthorizerDelayed:1]];
16341625
}
16351626

16361627
- (void)testImmediateAsyncDelayedAuthCancelFetchWithCallback_WithoutFetcherService {
16371628
_fetcherService = nil;
1638-
XCTSkip(@"Currently fails, needs fixing.");
16391629
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer asyncAuthorizerDelayed:1]];
16401630
}
16411631

@@ -1649,7 +1639,17 @@ - (void)internalCancelFetchWithCallback:(unsigned int)sleepTime
16491639
#pragma clang diagnostic pop
16501640
if (!_isServerRunning) return;
16511641

1652-
CREATE_START_STOP_NOTIFICATION_EXPECTATIONS(1, 1);
1642+
// If the authorizer is async, then the fetch won't fully begin, and there won't ever be
1643+
// a start notification (and thus stop notification).
1644+
int expectedNotifications = ((TestAuthorizer*)authorizer).isAsync ? 0 : 1;
1645+
XCTestExpectation *fetcherStartedExpectation = nil;
1646+
XCTestExpectation *fetcherStoppedExpectation = nil;
1647+
if (expectedNotifications) {
1648+
fetcherStartedExpectation =
1649+
[[XCTNSNotificationExpectation alloc] initWithName:kGTMSessionFetcherStartedNotification];
1650+
fetcherStoppedExpectation =
1651+
[[XCTNSNotificationExpectation alloc] initWithName:kGTMSessionFetcherStoppedNotification];
1652+
}
16531653

16541654
FetcherNotificationsCounter *fnctr = [[FetcherNotificationsCounter alloc] init];
16551655

@@ -1674,19 +1674,17 @@ - (void)internalCancelFetchWithCallback:(unsigned int)sleepTime
16741674
}
16751675
[fetcher stopFetching];
16761676

1677-
WAIT_FOR_START_STOP_NOTIFICATION_EXPECTATIONS();
1678-
16791677
[self waitForExpectationsWithTimeout:_timeoutInterval handler:nil];
16801678

16811679
[self assertCallbacksReleasedForFetcher:fetcher];
16821680

16831681
// Check the notifications.
1684-
XCTAssertEqual(fnctr.fetchStarted, 1, @"%@", fnctr.fetchersStartedDescriptions);
1685-
XCTAssertEqual(fnctr.fetchStopped, 1, @"%@", fnctr.fetchersStoppedDescriptions);
1682+
XCTAssertEqual(fnctr.fetchStarted, expectedNotifications, @"%@", fnctr.fetchersStartedDescriptions);
1683+
XCTAssertEqual(fnctr.fetchStopped, fnctr.fetchStarted, @"%@", fnctr.fetchersStoppedDescriptions);
16861684
XCTAssertEqual(fnctr.fetchCompletionInvoked, 1);
16871685
#if GTM_BACKGROUND_TASK_FETCHING
16881686
[self waitForBackgroundTaskEndedNotifications:fnctr];
1689-
XCTAssertEqual(fnctr.backgroundTasksStarted.count, (NSUInteger)1);
1687+
XCTAssertEqual(fnctr.backgroundTasksStarted.count, (NSUInteger)expectedNotifications);
16901688
XCTAssertEqualObjects(fnctr.backgroundTasksStarted, fnctr.backgroundTasksEnded);
16911689
#endif
16921690
}

0 commit comments

Comments
 (0)