ActiveResourceKit  v1.2 (498.0)
 All Classes Files Functions Variables Typedefs Enumerator Properties Macros Pages
ConnectionTests.m
Go to the documentation of this file.
1 // ActiveResourceKitTests ConnectionTests.m
2 //
3 // Copyright © 2012, Roy Ratcliffe, Pioneering Software, United Kingdom
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the “Software”), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND, EITHER
16 // EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO
18 // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
19 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
22 //
23 //------------------------------------------------------------------------------
24 
25 #import "ConnectionTests.h"
26 
27 // import the monolithic header at its installed location
29 
30 @implementation ConnectionTests
31 
33 {
34  NSError *(^errorForResponse)(NSInteger code) = ^(NSInteger code) {
35  return [ARConnection errorForResponse:[[ARHTTPResponse alloc] initWithHTTPURLResponse:[[NSHTTPURLResponse alloc] initWithURL:ActiveResourceKitTestsBaseURL() statusCode:code HTTPVersion:@"HTTP/1.1" headerFields:nil] body:nil]];
36  };
37  // valid responses: 2xx and 3xx
38  for (NSNumber *code in [NSArray arrayWithObjects:[NSNumber numberWithInt:200], [NSNumber numberWithInt:299], [NSNumber numberWithInt:300], [NSNumber numberWithInt:399], nil])
39  {
40  STAssertNil(errorForResponse([code integerValue]), nil);
41  }
42  // redirection
43  NSArray *redirectCodes = [NSArray arrayWithObjects:[NSNumber numberWithInt:301], [NSNumber numberWithInt:302], [NSNumber numberWithInt:303], [NSNumber numberWithInt:307], nil];
44  NSArray *redirectDescriptions = [NSArray arrayWithObjects:@"moved permanently", @"found", @"see other", @"temporarily redirected", nil];
45  NSDictionary *redirectDescriptionForCode = [NSDictionary dictionaryWithObjects:redirectDescriptions forKeys:redirectCodes];
46  for (NSNumber *code in redirectCodes)
47  {
48  NSError *error = errorForResponse([code integerValue]);
49  STAssertNotNil(error, nil);
50  STAssertEquals([error code], (NSInteger)ARRedirectionErrorCode, nil);
51  STAssertEqualObjects([[error userInfo] objectForKey:NSLocalizedDescriptionKey], [redirectDescriptionForCode objectForKey:code], nil);
52  }
53  // client errors: 4xx
54  struct
55  {
56  NSInteger statusCode;
57  NSInteger errorCode;
58  }
59  clientCodesAndErrors[] =
60  {
61  { 400, (NSInteger)ARBadRequestErrorCode },
62  { 401, (NSInteger)ARUnauthorizedAccessErrorCode },
63  { 403, (NSInteger)ARForbiddenAccessErrorCode },
64  { 404, (NSInteger)ARResourceNotFoundErrorCode },
65  { 405, (NSInteger)ARMethodNotAllowedErrorCode },
66  { 409, (NSInteger)ARResourceConflictErrorCode },
67  { 410, (NSInteger)ARResourceGoneErrorCode },
68  { 422, (NSInteger)ARResourceInvalidErrorCode },
69  };
70  for (NSUInteger i = 0; i < ARDimOf(clientCodesAndErrors); i++)
71  {
72  STAssertEquals([errorForResponse(clientCodesAndErrors[i].statusCode) code], clientCodesAndErrors[i].errorCode, nil);
73  }
74  for (NSInteger statusCode = 402; statusCode <= 499; statusCode++)
75  {
76  NSUInteger i;
77  for (i = 0; i < ARDimOf(clientCodesAndErrors) && statusCode != clientCodesAndErrors[i].statusCode; i++);
78  if (i == ARDimOf(clientCodesAndErrors))
79  {
80  STAssertEquals([errorForResponse(statusCode) code], (NSInteger)ARClientErrorCode, nil);
81  }
82  }
83  // server errors: 5xx
84  for (NSInteger statusCode = 500; statusCode <= 599; statusCode++)
85  {
86  STAssertEquals([errorForResponse(statusCode) code], (NSInteger)ARServerErrorCode, nil);
87  }
88 }
89 
90 - (void)testGet
91 {
92  ARSynchronousLoadingURLConnection *connection = [[ARSynchronousLoadingURLConnection alloc] initWithSite:ActiveResourceKitTestsBaseURL()];
93  NSHTTPURLResponse *__autoreleasing response = nil;
94  NSError *__autoreleasing error = nil;
95  NSMutableURLRequest *request = [connection requestForHTTPMethod:ARHTTPGetMethod path:@"/people/1.json" headers:nil];
96  NSData *data = [connection sendRequest:request returningResponse:&response error:&error];
97  NSDictionary *matz = [[connection format] decode:data error:&error];
98  STAssertEqualObjects(@"Matz", [matz valueForKey:@"name"], nil);
99 }
100 
101 - (void)testHead
102 {
103  // Test against the same path as above in testGet, same headers, only the
104  // HTTP request method differs: HEAD rather than GET. In response, the
105  // server should answer with an empty body and response code 200.
106  NSHTTPURLResponse *response = nil;
107  ARSynchronousLoadingURLConnection *connection = [[ARSynchronousLoadingURLConnection alloc] initWithSite:ActiveResourceKitTestsBaseURL()];
108  NSMutableURLRequest *request = [connection requestForHTTPMethod:ARHTTPHeadMethod path:@"/people/1.json" headers:nil];
109  NSData *data = [connection sendRequest:request returningResponse:&response error:NULL];
110  STAssertEquals([data length], (NSUInteger)0, nil);
111  STAssertEquals([response statusCode], (NSInteger)200, nil);
112 }
113 
115 {
116  ARSynchronousLoadingURLConnection *connection = [[ARSynchronousLoadingURLConnection alloc] initWithSite:ActiveResourceKitTestsBaseURL()];
117  NSHTTPURLResponse *response = nil;
118  NSDictionary *headers = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"];
119  NSMutableURLRequest *request = [connection requestForHTTPMethod:ARHTTPGetMethod path:@"/people/2.json" headers:headers];
120  NSData *data = [connection sendRequest:request returningResponse:&response error:NULL];
121  // This is not a real test of GET with headers. The test cannot assert
122  // anything about headers being successfully sent along with the GET
123  // request; the server does not echo the headers. However, if you check the
124  // server log at log/thin.log, you should see traces of a GET request
125  // containing, amongst other bits and pieces, the following:
126  //
127  // GET /people/2.json HTTP/1.1
128  // Host: localhost:3000
129  // Accept: application/json
130  // key: value
131  // Accept-Language: en-gb
132  // Accept-Encoding: gzip, deflate
133  // Connection: keep-alive
134  //
135  NSDictionary *david = [[connection format] decode:data error:NULL];
136  STAssertEqualObjects(@"David", [david valueForKey:@"name"], nil);
137 }
138 
139 - (void)testPost
140 {
141  NSHTTPURLResponse *response = nil;
142  ARSynchronousLoadingURLConnection *connection = [[ARSynchronousLoadingURLConnection alloc] initWithSite:ActiveResourceKitTestsBaseURL()];
143  NSMutableURLRequest *request = [connection requestForHTTPMethod:ARHTTPPostMethod path:@"/people.json" headers:nil];
144  [connection sendRequest:request returningResponse:&response error:NULL];
145  STAssertNotNil([[response allHeaderFields] objectForKey:@"Location"], nil);
146 }
147 
148 @end