Skip to content

Disable auto-retry for 403 #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion PubNub/Data/Managers/PNSubscriber.m
Original file line number Diff line number Diff line change
Expand Up @@ -1330,7 +1330,8 @@ - (void)handleFailedSubscriptionStatus:(PNSubscribeStatus *)status {
statusCategory == PNTLSConnectionFailedCategory) {

__weak __typeof(self) weakSelf = self;
((PNStatus *)status).automaticallyRetry = (statusCategory != PNMalformedFilterExpressionCategory &&
((PNStatus *)status).automaticallyRetry = (statusCategory != PNAccessDeniedCategory &&
statusCategory != PNMalformedFilterExpressionCategory &&
statusCategory != PNRequestURITooLongCategory);
PNSubscriberState subscriberState = PNAccessRightsErrorSubscriberState;
((PNStatus *)status).retryCancelBlock = ^{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@ @implementation PNSubscribeContractTestSteps
- (void)setup {
[self startCucumberHookEventsListening];

Given(@"the crypto keyset", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
self.configuration.cipherKey = @"enigma";
});

Given(@"the invalid-crypto keyset", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
self.configuration.cipherKey = @"secret";
});

When(@"I subscribe", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
self.testedFeatureType = PNSubscribeOperation;

Expand Down Expand Up @@ -55,6 +47,12 @@ - (void)setup {

[self pauseMainQueueFor:0.5f];
});

Match(@[@"*"], @"I don't auto-retry subscribe", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
self.allowsPendingRequests = YES;
// Delay execution to ensure that there is no automated retry.
[self pauseMainQueueFor:2.f];
});
}

#pragma mark -
Expand Down
7 changes: 7 additions & 0 deletions Tests/Tests/Helpers/PNContractTestCase.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, assign) PNOperationType testedFeatureType;

/**
* @brief Whether at the end of the test on expectation check it is allowed to have pending requests
* or not.
*/
@property (nonatomic, assign, class) BOOL allowsPendingRequests;
@property (nonatomic, assign) BOOL allowsPendingRequests;


#pragma mark - Initialization & Configuration

Expand Down
72 changes: 68 additions & 4 deletions Tests/Tests/Helpers/PNContractTestCase.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#pragma mark Types & Constants

static BOOL _allowsPendingRequests = NO;

/**
* @brief Origin which should be used to reach mock server for contract testing.
*/
Expand Down Expand Up @@ -159,6 +161,22 @@ @implementation PNContractTestCase

#pragma mark - Information

+ (BOOL)allowsPendingRequests {
return _allowsPendingRequests;
}

+ (void)setAllowsPendingRequests:(BOOL)allowsPendingRequests {
_allowsPendingRequests = allowsPendingRequests;
}

- (BOOL)allowsPendingRequests {
return [PNContractTestCase class].allowsPendingRequests;
}

- (void)setAllowsPendingRequests:(BOOL)allowsPendingRequests {
[PNContractTestCase class].allowsPendingRequests = allowsPendingRequests;
}

- (PNConfiguration *)configuration {
if (!self.currentConfiguration) {
self.currentConfiguration = [PNConfiguration configurationWithPublishKey:kPNDefaultPublishKey
Expand Down Expand Up @@ -245,8 +263,12 @@ - (void)setup {
error:nil];

NSArray<NSString *> *pendingExpectation = [response valueForKeyPath:@"expectations.pending"];
if (pendingExpectation.count) {
XCTAssertTrue(false, @"Expectations not met: %@", [pendingExpectation componentsJoinedByString:@", "]);
NSArray<NSString *> *failedExpectation = [response valueForKeyPath:@"expectations.failed"];
if (pendingExpectation.count && !self.allowsPendingRequests) {
XCTAssertTrue(false, @"Expectations not met (pending): %@", [pendingExpectation componentsJoinedByString:@", "]);
}
if (failedExpectation.count) {
XCTAssertTrue(false, @"Expectations not met (failed): %@", [failedExpectation componentsJoinedByString:@", "]);
}
}

Expand All @@ -262,6 +284,26 @@ - (void)setup {
// Nothing to do. Mock server will simulate proper error here.
});

Given(@"the crypto keyset", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
self.configuration.cipherKey = @"enigma";
});

Given(@"the invalid-crypto keyset", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
self.configuration.cipherKey = @"secret";
});

Given(@"auth key", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
self.configuration.authKey = @"test-auth-key";
});

Given(@"no auth key", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
// Nothing to do. By default PubNub client doesn't have configured authKey.
});

Given(@"token", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
[self.client setAuthToken:@"my-test-token"];
});

Then(@"I receive successful response", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
PNStatus *status = [self lastStatus];
PNResult *result = [self lastResult];
Expand Down Expand Up @@ -291,6 +333,24 @@ - (void)setup {
}
});

Then(@"I receive access denied status", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
PNStatus *status = [self lastStatus];

XCTAssertNotNil(status, @"Last API call should fail");
XCTAssertTrue(status.isError, @"Last API call should report error");
XCTAssertEqual(status.category, PNAccessDeniedCategory);
XCTAssertEqual([self lastStatus].statusCode, 403);
});

Match(@[@"*"], @"I receive access denied status", ^(NSArray<NSString *> *args, NSDictionary *userInfo) {
PNStatus *status = [self lastStatus];

XCTAssertNotNil(status, @"Last API call should fail");
XCTAssertTrue(status.isError, @"Last API call should report error");
XCTAssertEqual(status.category, PNAccessDeniedCategory);
XCTAssertEqual([self lastStatus].statusCode, 403);
});

// Complete known contract steps configuration.
[[PNAccessContractTestSteps new] setup];
[[PNFilesContractTestSteps new] setup];
Expand All @@ -317,7 +377,10 @@ - (void)subscribeClient:(PubNub *)client
client = client ?: self.client;

[_statusHandlers addObject:^void(PubNub *receiver, PNStatus *status) {
if (status.operation == PNSubscribeOperation && status.category == PNConnectedCategory) {
if (status.operation == PNSubscribeOperation &&
(status.category == PNConnectedCategory || status.category == PNAccessDeniedCategory)) {
[self storeRequestStatus:status];

subscribeCompletedInTime = YES;
dispatch_semaphore_signal(semaphore);
}
Expand Down Expand Up @@ -379,7 +442,8 @@ - (void)unsubscribeClient:(PubNub *)client
NSString *clientIdentifier = receiver.currentConfiguration.uuid;

if ([client.currentConfiguration.uuid isEqualToString:clientIdentifier]) {
receivedRequiredCount = messagesCount >= [weakSelf messagesCountForClient:receiver onChannel:channel];
NSUInteger messagesCountForClient = [weakSelf messagesCountForClient:receiver onChannel:channel];
receivedRequiredCount = messagesCountForClient > 0 && messagesCount >= messagesCountForClient;
}

if (receivedRequiredCount) {
Expand Down
57 changes: 2 additions & 55 deletions Tests/Tests/Integration/PNSubscribeIntegrationTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,7 @@ - (void)testItShouldNotSubscribeToChannelAndReceiveAccessDeniedEventWhenPAMKeysU
withBlock:^(PubNub *client, PNSubscribeStatus *status, BOOL *remove) {

if (status.operation == PNSubscribeOperation && status.category == PNAccessDeniedCategory) {
XCTAssertTrue(status.willAutomaticallyRetry);
[status cancelAutomaticRetry];
XCTAssertFalse(status.willAutomaticallyRetry);

*remove = YES;

Expand All @@ -426,32 +425,6 @@ - (void)testItShouldNotSubscribeToChannelAndReceiveAccessDeniedEventWhenPAMKeysU
}];
}

- (void)testItShouldNotSubscribeToChannelAndRetryWhenReceiveAccessDeniedEvent {
NSString *channel = [self channelWithName:@"test-channel1"];
__block NSUInteger retriedCount = 0;


[self waitToCompleteIn:self.testCompletionDelay codeBlock:^(dispatch_block_t handler) {
[self addStatusHandlerForClient:self.client
withBlock:^(PubNub *client, PNSubscribeStatus *status, BOOL *remove) {

if (status.operation == PNSubscribeOperation && status.category == PNAccessDeniedCategory) {
XCTAssertTrue(status.willAutomaticallyRetry);

if (retriedCount == 1) {
[status cancelAutomaticRetry];
*remove = YES;
handler();
} else {
retriedCount++;
}
}
}];

[self.client subscribeToChannels:@[channel] withPresence:NO];
}];
}


#pragma mark - Tests :: Subscribe to channel group

Expand Down Expand Up @@ -791,8 +764,7 @@ - (void)testItShouldNotSubscribeToChannelGroupAndReceiveAccessDeniedEventWhenPAM
withBlock:^(PubNub *client, PNSubscribeStatus *status, BOOL *remove) {

if (status.operation == PNSubscribeOperation && status.category == PNAccessDeniedCategory) {
XCTAssertTrue(status.willAutomaticallyRetry);
[status cancelAutomaticRetry];
XCTAssertFalse(status.willAutomaticallyRetry);

*remove = YES;

Expand All @@ -804,31 +776,6 @@ - (void)testItShouldNotSubscribeToChannelGroupAndReceiveAccessDeniedEventWhenPAM
}];
}

- (void)testItShouldNotSubscribeToChannelGroupAndRetryWhenReceiveAccessDeniedEvent {
NSString *channelGroup = [self channelGroupWithName:@"test-channel-group1"];
__block NSUInteger retriedCount = 0;


[self waitToCompleteIn:self.testCompletionDelay codeBlock:^(dispatch_block_t handler) {
[self addStatusHandlerForClient:self.client
withBlock:^(PubNub *client, PNSubscribeStatus *status, BOOL *remove) {

if (status.operation == PNSubscribeOperation && status.category == PNAccessDeniedCategory) {
XCTAssertTrue(status.willAutomaticallyRetry);

if (retriedCount == 1) {
[status cancelAutomaticRetry];
*remove = YES;
handler();
} else {
retriedCount++;
}
}
}];

[self.client subscribeToChannelGroups:@[channelGroup] withPresence:NO];
}];
}


#pragma mark - Tests :: Builder pattern-based subscribe
Expand Down