Skip to content

Commit

Permalink
Test Suite: HTTPURLResponse allHeaderFields is now case-sensitive
Browse files Browse the repository at this point in the history
Swift Regression https://bugs.swift.org/browse/SR-2429

That's why sometimes some tests were failing because the server responded differently: X-Ably-Errorcode or X-Ably-errorcode, etc.
  • Loading branch information
ricardopereira committed Apr 6, 2019
1 parent a22f9ab commit e9e5c22
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Source/ARTConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@

#import "ARTConstants.h"

NSString *const ARTHttpHeaderFieldErrorCodeKey = @"X-Ably-Errorcode";
NSString *const ARTHttpHeaderFieldErrorMessageKey = @"X-Ably-Errormessage";
NSString *const ARTHttpHeaderFieldErrorCodeKey = @"x-ably-errorcode";
NSString *const ARTHttpHeaderFieldErrorMessageKey = @"x-ably-errormessage";
4 changes: 4 additions & 0 deletions Source/ARTHTTPPaginatedResponse+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@

#import <Ably/ARTHTTPPaginatedResponse.h>

#import <Ably/ARTPaginatedResult+Private.h>

@class ARTRest;

NS_ASSUME_NONNULL_BEGIN

@interface ARTHTTPPaginatedResponse ()

@property (nonatomic, strong) NSHTTPURLResponse *response;

+ (void)executePaginated:(ARTRest *)rest withRequest:(NSMutableURLRequest *)request andResponseProcessor:(ARTPaginatedResultResponseProcessor)responseProcessor callback:(void (^)(ARTPaginatedResult * _Nullable, ARTErrorInfo * _Nullable))callback UNAVAILABLE_ATTRIBUTE;

+ (void)executePaginated:(ARTRest *)rest withRequest:(NSMutableURLRequest *)request callback:(void (^)(ARTHTTPPaginatedResponse *_Nullable result, ARTErrorInfo *_Nullable error))callback;
Expand Down
4 changes: 2 additions & 2 deletions Source/ARTHTTPPaginatedResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ NS_ASSUME_NONNULL_BEGIN
/// Returns true when the HTTP status code indicates success i.e. 200 <= statusCode < 300
@property (nonatomic, readonly) BOOL success;

/// Returns the error code if the X-Ably-Errorcode HTTP header is sent in the response
/// Returns the error code if the X-Ably-ErrorCode HTTP header is sent in the response
@property (nonatomic, readonly) NSInteger errorCode;

/// Returns error message if the X-Ably-Errormessage HTTP header is sent in the response
/// Returns error message if the X-Ably-ErrorMessage HTTP header is sent in the response
@property (nullable, nonatomic, readonly) NSString *errorMessage;

/// Returns a dictionary containing all the HTTP header fields of the response header.
Expand Down
6 changes: 2 additions & 4 deletions Source/ARTHTTPPaginatedResponse.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Copyright © 2018 Ably. All rights reserved.
//

#import "ARTHTTPPaginatedResponse.h"
#import "ARTHTTPPaginatedResponse+Private.h"

#import "ARTHttp.h"
#import "ARTAuth.h"
Expand All @@ -17,9 +17,7 @@
#import "ARTEncoder.h"
#import "ARTConstants.h"

@implementation ARTHTTPPaginatedResponse {
NSHTTPURLResponse *_response;
}
@implementation ARTHTTPPaginatedResponse

- (instancetype)initWithResponse:(NSHTTPURLResponse *)response
items:(NSArray *)items
Expand Down
14 changes: 7 additions & 7 deletions Spec/RestClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ class RestClient: QuickSpec {
expect(error).to(beNil())
expect(result).toNot(beNil())

guard let headerErrorCode = testHTTPExecutor.responses.first?.allHeaderFields["X-Ably-Errorcode"] as? String else {
guard let headerErrorCode = testHTTPExecutor.responses.first?.objc_allHeaderFields["X-Ably-Errorcode"] as? String else {
fail("X-Ably-Errorcode not found"); done();
return
}
Expand Down Expand Up @@ -454,7 +454,7 @@ class RestClient: QuickSpec {
expect(errorCode).to(equal(40160))
expect(result).to(beNil())

guard let headerErrorCode = testHTTPExecutor.responses.first?.allHeaderFields["X-Ably-Errorcode"] as? String else {
guard let headerErrorCode = testHTTPExecutor.responses.first?.objc_allHeaderFields["X-Ably-Errorcode"] as? String else {
fail("X-Ably-Errorcode not found"); done();
return
}
Expand Down Expand Up @@ -549,7 +549,7 @@ class RestClient: QuickSpec {
delay(TimeInterval(truncating: tokenParams.ttl!)) {
// [40140, 40150) - token expired and will not recover because authUrl is invalid
publishTestMessage(rest) { error in
guard let errorCode = testHTTPExecutor.responses.first?.allHeaderFields["X-Ably-Errorcode"] as? String else {
guard let errorCode = testHTTPExecutor.responses.first?.objc_allHeaderFields["X-Ably-Errorcode"] as? String else {
fail("expected X-Ably-Errorcode header in request")
return
}
Expand Down Expand Up @@ -598,7 +598,7 @@ class RestClient: QuickSpec {
delay(TimeInterval(truncating: tokenParams.ttl!)) {
// [40140, 40150) - token expired and will not recover because authUrl is invalid
publishTestMessage(rest) { error in
guard let errorCode = testHTTPExecutor.responses.first?.allHeaderFields["X-Ably-Errorcode"] as? String else {
guard let errorCode = testHTTPExecutor.responses.first?.objc_allHeaderFields["X-Ably-Errorcode"] as? String else {
fail("expected X-Ably-Errorcode header in request")
return
}
Expand Down Expand Up @@ -1617,7 +1617,7 @@ class RestClient: QuickSpec {
}

expect(response.statusCode) == httpPaginatedResponse.statusCode
expect(response.allHeaderFields as? [String: String]) == httpPaginatedResponse.headers
expect(response.allHeaderFields as NSDictionary) == httpPaginatedResponse.headers
}

it("should handle response failures") {
Expand Down Expand Up @@ -1649,7 +1649,7 @@ class RestClient: QuickSpec {
expect(paginatedResponse.errorCode) == 40400
expect(paginatedResponse.errorMessage).to(contain("Could not find path"))
expect(paginatedResponse.headers).toNot(beEmpty())
expect(paginatedResponse.headers["X-Ably-Errorcode"]).to(equal("40400"))
expect(paginatedResponse.headers["X-Ably-Errorcode"] as? String).to(equal("40400"))
done()
}
}
Expand All @@ -1665,7 +1665,7 @@ class RestClient: QuickSpec {
}

expect(response.statusCode) == 404
expect(response.allHeaderFields["X-Ably-Errorcode"] as? String).to(equal("40400"))
expect(response.objc_allHeaderFields["X-Ably-Errorcode"] as? String).to(equal("40400"))
}
}

Expand Down
26 changes: 26 additions & 0 deletions Spec/TestUtilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1434,3 +1434,29 @@ extension String {
}
}
}

extension HTTPURLResponse {

/*!
@abstract Returns a dictionary containing all the HTTP header fields
of the receiver.
@discussion This is broken since Swift 3. The access is now case-sensitive.
Regression: HTTPURLResponse allHeaderFields is now case-sensitive
https://bugs.swift.org/browse/SR-2429
@result A dictionary containing all the HTTP header fields of the
receiver.
*/
var objc_allHeaderFields: NSDictionary {
// Disables bridging and calls the Objective-C implementation of the private NSDictionary subclass in CFNetwork directly
return allHeaderFields as NSDictionary
}

}

extension ARTHTTPPaginatedResponse {

var headers: NSDictionary {
return response.objc_allHeaderFields
}

}

0 comments on commit e9e5c22

Please sign in to comment.