ParameterEncodingTests.swift 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. // ParameterEncodingTests.swift
  2. //
  3. // Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
  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, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. import Alamofire
  23. import Foundation
  24. import XCTest
  25. class ParameterEncodingTestCase: BaseTestCase {
  26. let URLRequest = NSURLRequest(URL: NSURL(string: "http://example.com/")!)
  27. }
  28. // MARK: -
  29. class URLParameterEncodingTestCase: ParameterEncodingTestCase {
  30. // MARK: Properties
  31. let encoding: ParameterEncoding = .URL
  32. // MARK: Tests
  33. func testURLParameterEncodeNilParameters() {
  34. // Given
  35. // When
  36. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: nil)
  37. // Then
  38. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  39. }
  40. func testURLParameterEncodeOneStringKeyStringValueParameter() {
  41. // Given
  42. let parameters = ["foo": "bar"]
  43. // When
  44. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  45. // Then
  46. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=bar", "query is incorrect")
  47. }
  48. func testURLParameterEncodeOneStringKeyStringValueParameterAppendedToQuery() {
  49. // Given
  50. var mutableURLRequest = self.URLRequest.mutableCopy() as! NSMutableURLRequest
  51. let URLComponents = NSURLComponents(URL: mutableURLRequest.URL!, resolvingAgainstBaseURL: false)!
  52. URLComponents.query = "baz=qux"
  53. mutableURLRequest.URL = URLComponents.URL
  54. let parameters = ["foo": "bar"]
  55. // When
  56. let (URLRequest, error) = self.encoding.encode(mutableURLRequest, parameters: parameters)
  57. // Then
  58. XCTAssertEqual(URLRequest.URL?.query ?? "", "baz=qux&foo=bar", "query is incorrect")
  59. }
  60. func testURLParameterEncodeTwoStringKeyStringValueParameters() {
  61. // Given
  62. let parameters = ["foo": "bar", "baz": "qux"]
  63. // When
  64. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  65. // Then
  66. XCTAssertEqual(URLRequest.URL?.query ?? "", "baz=qux&foo=bar", "query is incorrect")
  67. }
  68. func testURLParameterEncodeStringKeyIntegerValueParameter() {
  69. // Given
  70. let parameters = ["foo": 1]
  71. // When
  72. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  73. // Then
  74. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=1", "query is incorrect")
  75. }
  76. func testURLParameterEncodeStringKeyDoubleValueParameter() {
  77. // Given
  78. let parameters = ["foo": 1.1]
  79. // When
  80. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  81. // Then
  82. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=1.1", "query is incorrect")
  83. }
  84. func testURLParameterEncodeStringKeyBoolValueParameter() {
  85. // Given
  86. let parameters = ["foo": true]
  87. // When
  88. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  89. // Then
  90. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=1", "query is incorrect")
  91. }
  92. func testURLParameterEncodeStringKeyArrayValueParameter() {
  93. // Given
  94. let parameters = ["foo": ["a", 1, true]]
  95. // When
  96. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  97. // Then
  98. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5B%5D=a&foo%5B%5D=1&foo%5B%5D=1", "query is incorrect")
  99. }
  100. func testURLParameterEncodeStringKeyDictionaryValueParameter() {
  101. // Given
  102. let parameters = ["foo": ["bar": 1]]
  103. // When
  104. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  105. // Then
  106. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5Bbar%5D=1", "query is incorrect")
  107. }
  108. func testURLParameterEncodeStringKeyNestedDictionaryValueParameter() {
  109. // Given
  110. let parameters = ["foo": ["bar": ["baz": 1]]]
  111. // When
  112. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  113. // Then
  114. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5Bbar%5D%5Bbaz%5D=1", "query is incorrect")
  115. }
  116. func testURLParameterEncodeStringKeyNestedDictionaryArrayValueParameter() {
  117. // Given
  118. let parameters = ["foo": ["bar": ["baz": ["a", 1, true]]]]
  119. // When
  120. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  121. // Then
  122. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5Bbar%5D%5Bbaz%5D%5B%5D=a&foo%5Bbar%5D%5Bbaz%5D%5B%5D=1&foo%5Bbar%5D%5Bbaz%5D%5B%5D=1", "query is incorrect")
  123. }
  124. func testURLParameterEncodeStringWithAmpersandKeyStringWithAmpersandValueParameter() {
  125. // Given
  126. let parameters = ["foo&bar": "baz&qux", "foobar": "bazqux"]
  127. // When
  128. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  129. // Then
  130. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%26bar=baz%26qux&foobar=bazqux", "query is incorrect")
  131. }
  132. func testURLParameterEncodeStringWithQuestionMarkKeyStringWithQuestionMarkValueParameter() {
  133. // Given
  134. let parameters = ["?foo?": "?bar?"]
  135. // When
  136. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  137. // Then
  138. XCTAssertEqual(URLRequest.URL?.query ?? "", "?foo?=?bar?", "query is incorrect")
  139. }
  140. func testURLParameterEncodeStringWithSlashKeyStringWithQuestionMarkValueParameter() {
  141. // Given
  142. let parameters = ["foo": "/bar/baz/qux"]
  143. // When
  144. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  145. // Then
  146. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=/bar/baz/qux", "query is incorrect")
  147. }
  148. func testURLParameterEncodeStringWithSpaceKeyStringWithSpaceValueParameter() {
  149. // Given
  150. let parameters = [" foo ": " bar "]
  151. // When
  152. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  153. // Then
  154. XCTAssertEqual(URLRequest.URL?.query ?? "", "%20foo%20=%20bar%20", "query is incorrect")
  155. }
  156. func testURLParameterEncodeStringWithPlusKeyStringWithPlusValueParameter() {
  157. // Given
  158. let parameters = ["+foo+": "+bar+"]
  159. // When
  160. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  161. // Then
  162. XCTAssertEqual(URLRequest.URL?.query ?? "", "%2Bfoo%2B=%2Bbar%2B", "query is incorrect")
  163. }
  164. func testURLParameterEncodeStringKeyAllowedCharactersStringValueParameter() {
  165. // Given
  166. let parameters = ["allowed": " =\"#%<>@\\^`{}[]|&"]
  167. // When
  168. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  169. // Then
  170. XCTAssertEqual(URLRequest.URL?.query ?? "", "allowed=%20%3D%22%23%25%3C%3E%40%5C%5E%60%7B%7D%5B%5D%7C%26", "query is incorrect")
  171. }
  172. func testURLParameterEncodeStringKeyPercentEncodedStringValueParameter() {
  173. // Given
  174. let parameters = ["percent": "%25"]
  175. // When
  176. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  177. // Then
  178. XCTAssertEqual(URLRequest.URL?.query ?? "", "percent=%2525", "query is incorrect")
  179. }
  180. func testURLParameterEncodeStringKeyNonLatinStringValueParameter() {
  181. // Given
  182. let parameters = [
  183. "french": "français",
  184. "japanese": "日本語",
  185. "arabic": "العربية",
  186. "emoji": "😃"
  187. ]
  188. // When
  189. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  190. // Then
  191. XCTAssertEqual(URLRequest.URL?.query ?? "", "arabic=%D8%A7%D9%84%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9&emoji=%F0%9F%98%83&french=fran%C3%A7ais&japanese=%E6%97%A5%E6%9C%AC%E8%AA%9E", "query is incorrect")
  192. }
  193. func testURLParameterEncodeStringForRequestWithPrecomposedQuery() {
  194. // Given
  195. let URL = NSURL(string: "http://example.com/movies?hd=[1]")!
  196. let parameters = ["page": "0"]
  197. // When
  198. let (URLRequest, error) = self.encoding.encode(NSURLRequest(URL: URL), parameters: parameters)
  199. // Then
  200. XCTAssertEqual(URLRequest.URL?.query ?? "", "hd=%5B1%5D&page=0", "query is incorrect")
  201. }
  202. func testURLParameterEncodeStringWithPlusKeyStringWithPlusValueParameterForRequestWithPrecomposedQuery() {
  203. // Given
  204. let URL = NSURL(string: "http://example.com/movie?hd=[1]")!
  205. let parameters = ["+foo+": "+bar+"]
  206. // When
  207. let (URLRequest, error) = self.encoding.encode(NSURLRequest(URL: URL), parameters: parameters)
  208. // Then
  209. XCTAssertEqual(URLRequest.URL?.query ?? "", "hd=%5B1%5D&%2Bfoo%2B=%2Bbar%2B", "query is incorrect")
  210. }
  211. func testURLParameterEncodeGETParametersInURL() {
  212. // Given
  213. var mutableURLRequest = self.URLRequest.mutableCopy() as! NSMutableURLRequest
  214. mutableURLRequest.HTTPMethod = Method.GET.rawValue
  215. let parameters = ["foo": 1, "bar": 2]
  216. // When
  217. let (URLRequest, error) = self.encoding.encode(mutableURLRequest, parameters: parameters)
  218. // Then
  219. XCTAssertEqual(URLRequest.URL?.query ?? "", "bar=2&foo=1", "query is incorrect")
  220. XCTAssertNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should be nil")
  221. XCTAssertNil(URLRequest.HTTPBody, "HTTPBody should be nil")
  222. }
  223. func testURLParameterEncodePOSTParametersInHTTPBody() {
  224. // Given
  225. var mutableURLRequest = self.URLRequest.mutableCopy() as! NSMutableURLRequest
  226. mutableURLRequest.HTTPMethod = Method.POST.rawValue
  227. let parameters = ["foo": 1, "bar": 2]
  228. // When
  229. let (URLRequest, error) = self.encoding.encode(mutableURLRequest, parameters: parameters)
  230. // Then
  231. XCTAssertEqual(URLRequest.valueForHTTPHeaderField("Content-Type") ?? "", "application/x-www-form-urlencoded", "Content-Type should be application/x-www-form-urlencoded")
  232. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  233. if let HTTPBody = URLRequest.HTTPBody,
  234. decodedHTTPBody = NSString(data: HTTPBody, encoding: NSUTF8StringEncoding)
  235. {
  236. XCTAssertEqual(decodedHTTPBody, "bar=2&foo=1", "HTTPBody is incorrect")
  237. } else {
  238. XCTFail("decoded http body should not be nil")
  239. }
  240. }
  241. }
  242. // MARK: -
  243. class JSONParameterEncodingTestCase: ParameterEncodingTestCase {
  244. // MARK: Properties
  245. let encoding: ParameterEncoding = .JSON
  246. // MARK: Tests
  247. func testJSONParameterEncodeNilParameters() {
  248. // Given
  249. // When
  250. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: nil)
  251. // Then
  252. XCTAssertNil(error, "error should be nil")
  253. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  254. XCTAssertNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should be nil")
  255. XCTAssertNil(URLRequest.HTTPBody, "HTTPBody should be nil")
  256. }
  257. func testJSONParameterEncodeComplexParameters() {
  258. // Given
  259. let parameters = [
  260. "foo": "bar",
  261. "baz": ["a", 1, true],
  262. "qux": [
  263. "a": 1,
  264. "b": [2, 2],
  265. "c": [3, 3, 3]
  266. ]
  267. ]
  268. // When
  269. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  270. // Then
  271. XCTAssertNil(error, "error should be nil")
  272. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  273. XCTAssertNotNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should not be nil")
  274. XCTAssertEqual(URLRequest.valueForHTTPHeaderField("Content-Type") ?? "", "application/json", "Content-Type should be application/json")
  275. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  276. if let HTTPBody = URLRequest.HTTPBody,
  277. JSON = NSJSONSerialization.JSONObjectWithData(HTTPBody, options: .AllowFragments, error: nil) as? NSObject
  278. {
  279. XCTAssertEqual(JSON, parameters as NSObject, "HTTPBody JSON does not equal parameters")
  280. } else {
  281. XCTFail("JSON should not be nil")
  282. }
  283. }
  284. }
  285. // MARK: -
  286. class PropertyListParameterEncodingTestCase: ParameterEncodingTestCase {
  287. // MARK: Properties
  288. let encoding: ParameterEncoding = .PropertyList(.XMLFormat_v1_0, 0)
  289. // MARK: Tests
  290. func testPropertyListParameterEncodeNilParameters() {
  291. // Given
  292. // When
  293. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: nil)
  294. // Then
  295. XCTAssertNil(error, "error should be nil")
  296. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  297. XCTAssertNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should be nil")
  298. XCTAssertNil(URLRequest.HTTPBody, "HTTPBody should be nil")
  299. }
  300. func testPropertyListParameterEncodeComplexParameters() {
  301. // Given
  302. let parameters = [
  303. "foo": "bar",
  304. "baz": ["a", 1, true],
  305. "qux": [
  306. "a": 1,
  307. "b": [2, 2],
  308. "c": [3, 3, 3]
  309. ]
  310. ]
  311. // When
  312. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  313. // Then
  314. XCTAssertNil(error, "error should be nil")
  315. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  316. XCTAssertNotNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should not be nil")
  317. XCTAssertEqual(URLRequest.valueForHTTPHeaderField("Content-Type") ?? "", "application/x-plist", "Content-Type should be application/x-plist")
  318. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  319. if let HTTPBody = URLRequest.HTTPBody,
  320. let plist = NSPropertyListSerialization.propertyListWithData(HTTPBody, options: 0, format: nil, error: nil) as? NSObject
  321. {
  322. XCTAssertEqual(plist, parameters as NSObject, "HTTPBody plist does not equal parameters")
  323. } else {
  324. XCTFail("plist should not be nil")
  325. }
  326. }
  327. func testPropertyListParameterEncodeDateAndDataParameters() {
  328. // Given
  329. let date: NSDate = NSDate()
  330. let data: NSData = "data".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
  331. let parameters = [
  332. "date": date,
  333. "data": data
  334. ]
  335. // When
  336. let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
  337. // Then
  338. XCTAssertNil(error, "error should be nil")
  339. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  340. XCTAssertNotNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should not be nil")
  341. XCTAssertEqual(URLRequest.valueForHTTPHeaderField("Content-Type") ?? "", "application/x-plist", "Content-Type should be application/x-plist")
  342. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  343. if let HTTPBody = URLRequest.HTTPBody,
  344. let plist = NSPropertyListSerialization.propertyListWithData(HTTPBody, options: 0, format: nil, error: nil) as? NSObject
  345. {
  346. XCTAssertTrue(plist.valueForKey("date") is NSDate, "date is not NSDate")
  347. XCTAssertTrue(plist.valueForKey("data") is NSData, "data is not NSData")
  348. } else {
  349. XCTFail("plist should not be nil")
  350. }
  351. }
  352. }
  353. // MARK: -
  354. class CustomParameterEncodingTestCase: ParameterEncodingTestCase {
  355. // MARK: Tests
  356. func testCustomParameterEncode() {
  357. // Given
  358. let encodingClosure: (URLRequestConvertible, [String: AnyObject]?) -> (NSURLRequest, NSError?) = { URLRequest, parameters in
  359. let mutableURLRequest = URLRequest.URLRequest.mutableCopy() as! NSMutableURLRequest
  360. mutableURLRequest.setValue("Xcode", forHTTPHeaderField: "User-Agent")
  361. return (mutableURLRequest, nil)
  362. }
  363. // When
  364. let encoding: ParameterEncoding = .Custom(encodingClosure)
  365. // Then
  366. let URL = NSURL(string: "http://example.com")!
  367. let URLRequest = NSURLRequest(URL: URL)
  368. let parameters: [String: AnyObject] = [:]
  369. XCTAssertEqual(encoding.encode(URLRequest, parameters: parameters).0, encodingClosure(URLRequest, parameters).0, "URLRequest should be equal")
  370. }
  371. }