ParameterEncodingTests.swift 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. //
  2. // ParameterEncodingTests.swift
  3. //
  4. // Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. import Alamofire
  25. import Foundation
  26. import XCTest
  27. class ParameterEncodingTestCase: BaseTestCase {
  28. let URLRequest = NSURLRequest(URL: NSURL(string: "https://example.com/")!)
  29. }
  30. // MARK: -
  31. class URLParameterEncodingTestCase: ParameterEncodingTestCase {
  32. let encoding: ParameterEncoding = .URL
  33. // MARK: Tests - Parameter Types
  34. func testURLParameterEncodeNilParameters() {
  35. // Given
  36. // When
  37. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: nil)
  38. // Then
  39. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  40. }
  41. func testURLParameterEncodeEmptyDictionaryParameter() {
  42. // Given
  43. let parameters: [String: AnyObject] = [:]
  44. // When
  45. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  46. // Then
  47. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  48. }
  49. func testURLParameterEncodeOneStringKeyStringValueParameter() {
  50. // Given
  51. let parameters = ["foo": "bar"]
  52. // When
  53. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  54. // Then
  55. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=bar", "query is incorrect")
  56. }
  57. func testURLParameterEncodeOneStringKeyStringValueParameterAppendedToQuery() {
  58. // Given
  59. let mutableURLRequest = self.URLRequest.URLRequest
  60. let URLComponents = NSURLComponents(URL: mutableURLRequest.URL!, resolvingAgainstBaseURL: false)!
  61. URLComponents.query = "baz=qux"
  62. mutableURLRequest.URL = URLComponents.URL
  63. let parameters = ["foo": "bar"]
  64. // When
  65. let (URLRequest, _) = encoding.encode(mutableURLRequest, parameters: parameters)
  66. // Then
  67. XCTAssertEqual(URLRequest.URL?.query ?? "", "baz=qux&foo=bar", "query is incorrect")
  68. }
  69. func testURLParameterEncodeTwoStringKeyStringValueParameters() {
  70. // Given
  71. let parameters = ["foo": "bar", "baz": "qux"]
  72. // When
  73. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  74. // Then
  75. XCTAssertEqual(URLRequest.URL?.query ?? "", "baz=qux&foo=bar", "query is incorrect")
  76. }
  77. func testURLParameterEncodeStringKeyIntegerValueParameter() {
  78. // Given
  79. let parameters = ["foo": 1]
  80. // When
  81. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  82. // Then
  83. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=1", "query is incorrect")
  84. }
  85. func testURLParameterEncodeStringKeyDoubleValueParameter() {
  86. // Given
  87. let parameters = ["foo": 1.1]
  88. // When
  89. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  90. // Then
  91. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=1.1", "query is incorrect")
  92. }
  93. func testURLParameterEncodeStringKeyBoolValueParameter() {
  94. // Given
  95. let parameters = ["foo": true]
  96. // When
  97. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  98. // Then
  99. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=1", "query is incorrect")
  100. }
  101. func testURLParameterEncodeStringKeyArrayValueParameter() {
  102. // Given
  103. let parameters = ["foo": ["a", 1, true]]
  104. // When
  105. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  106. // Then
  107. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5B%5D=a&foo%5B%5D=1&foo%5B%5D=1", "query is incorrect")
  108. }
  109. func testURLParameterEncodeStringKeyDictionaryValueParameter() {
  110. // Given
  111. let parameters = ["foo": ["bar": 1]]
  112. // When
  113. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  114. // Then
  115. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5Bbar%5D=1", "query is incorrect")
  116. }
  117. func testURLParameterEncodeStringKeyNestedDictionaryValueParameter() {
  118. // Given
  119. let parameters = ["foo": ["bar": ["baz": 1]]]
  120. // When
  121. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  122. // Then
  123. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5Bbar%5D%5Bbaz%5D=1", "query is incorrect")
  124. }
  125. func testURLParameterEncodeStringKeyNestedDictionaryArrayValueParameter() {
  126. // Given
  127. let parameters = ["foo": ["bar": ["baz": ["a", 1, true]]]]
  128. // When
  129. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  130. // Then
  131. let expectedQuery = "foo%5Bbar%5D%5Bbaz%5D%5B%5D=a&foo%5Bbar%5D%5Bbaz%5D%5B%5D=1&foo%5Bbar%5D%5Bbaz%5D%5B%5D=1"
  132. XCTAssertEqual(URLRequest.URL?.query ?? "", expectedQuery, "query is incorrect")
  133. }
  134. // MARK: Tests - All Reserved / Unreserved / Illegal Characters According to RFC 3986
  135. func testThatReservedCharactersArePercentEscapedMinusQuestionMarkAndForwardSlash() {
  136. // Given
  137. let generalDelimiters = ":#[]@"
  138. let subDelimiters = "!$&'()*+,;="
  139. let parameters = ["reserved": "\(generalDelimiters)\(subDelimiters)"]
  140. // When
  141. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  142. // Then
  143. let expectedQuery = "reserved=%3A%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D"
  144. XCTAssertEqual(URLRequest.URL?.query ?? "", expectedQuery, "query is incorrect")
  145. }
  146. func testThatReservedCharactersQuestionMarkAndForwardSlashAreNotPercentEscaped() {
  147. // Given
  148. let parameters = ["reserved": "?/"]
  149. // When
  150. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  151. // Then
  152. XCTAssertEqual(URLRequest.URL?.query ?? "", "reserved=?/", "query is incorrect")
  153. }
  154. func testThatUnreservedNumericCharactersAreNotPercentEscaped() {
  155. // Given
  156. let parameters = ["numbers": "0123456789"]
  157. // When
  158. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  159. // Then
  160. XCTAssertEqual(URLRequest.URL?.query ?? "", "numbers=0123456789", "query is incorrect")
  161. }
  162. func testThatUnreservedLowercaseCharactersAreNotPercentEscaped() {
  163. // Given
  164. let parameters = ["lowercase": "abcdefghijklmnopqrstuvwxyz"]
  165. // When
  166. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  167. // Then
  168. XCTAssertEqual(URLRequest.URL?.query ?? "", "lowercase=abcdefghijklmnopqrstuvwxyz", "query is incorrect")
  169. }
  170. func testThatUnreservedUppercaseCharactersAreNotPercentEscaped() {
  171. // Given
  172. let parameters = ["uppercase": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
  173. // When
  174. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  175. // Then
  176. XCTAssertEqual(URLRequest.URL?.query ?? "", "uppercase=ABCDEFGHIJKLMNOPQRSTUVWXYZ", "query is incorrect")
  177. }
  178. func testThatIllegalASCIICharactersArePercentEscaped() {
  179. // Given
  180. let parameters = ["illegal": " \"#%<>[]\\^`{}|"]
  181. // When
  182. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  183. // Then
  184. let expectedQuery = "illegal=%20%22%23%25%3C%3E%5B%5D%5C%5E%60%7B%7D%7C"
  185. XCTAssertEqual(URLRequest.URL?.query ?? "", expectedQuery, "query is incorrect")
  186. }
  187. // MARK: Tests - Special Character Queries
  188. func testURLParameterEncodeStringWithAmpersandKeyStringWithAmpersandValueParameter() {
  189. // Given
  190. let parameters = ["foo&bar": "baz&qux", "foobar": "bazqux"]
  191. // When
  192. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  193. // Then
  194. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%26bar=baz%26qux&foobar=bazqux", "query is incorrect")
  195. }
  196. func testURLParameterEncodeStringWithQuestionMarkKeyStringWithQuestionMarkValueParameter() {
  197. // Given
  198. let parameters = ["?foo?": "?bar?"]
  199. // When
  200. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  201. // Then
  202. XCTAssertEqual(URLRequest.URL?.query ?? "", "?foo?=?bar?", "query is incorrect")
  203. }
  204. func testURLParameterEncodeStringWithSlashKeyStringWithQuestionMarkValueParameter() {
  205. // Given
  206. let parameters = ["foo": "/bar/baz/qux"]
  207. // When
  208. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  209. // Then
  210. XCTAssertEqual(URLRequest.URL?.query ?? "", "foo=/bar/baz/qux", "query is incorrect")
  211. }
  212. func testURLParameterEncodeStringWithSpaceKeyStringWithSpaceValueParameter() {
  213. // Given
  214. let parameters = [" foo ": " bar "]
  215. // When
  216. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  217. // Then
  218. XCTAssertEqual(URLRequest.URL?.query ?? "", "%20foo%20=%20bar%20", "query is incorrect")
  219. }
  220. func testURLParameterEncodeStringWithPlusKeyStringWithPlusValueParameter() {
  221. // Given
  222. let parameters = ["+foo+": "+bar+"]
  223. // When
  224. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  225. // Then
  226. XCTAssertEqual(URLRequest.URL?.query ?? "", "%2Bfoo%2B=%2Bbar%2B", "query is incorrect")
  227. }
  228. func testURLParameterEncodeStringKeyPercentEncodedStringValueParameter() {
  229. // Given
  230. let parameters = ["percent": "%25"]
  231. // When
  232. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  233. // Then
  234. XCTAssertEqual(URLRequest.URL?.query ?? "", "percent=%2525", "query is incorrect")
  235. }
  236. func testURLParameterEncodeStringKeyNonLatinStringValueParameter() {
  237. // Given
  238. let parameters = [
  239. "french": "français",
  240. "japanese": "日本語",
  241. "arabic": "العربية",
  242. "emoji": "😃"
  243. ]
  244. // When
  245. let (URLRequest, _) = encoding.encode(self.URLRequest, parameters: parameters)
  246. // Then
  247. let expectedParameterValues = [
  248. "arabic=%D8%A7%D9%84%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9",
  249. "emoji=%F0%9F%98%83",
  250. "french=fran%C3%A7ais",
  251. "japanese=%E6%97%A5%E6%9C%AC%E8%AA%9E"
  252. ]
  253. let expectedQuery = expectedParameterValues.joinWithSeparator("&")
  254. XCTAssertEqual(URLRequest.URL?.query ?? "", expectedQuery, "query is incorrect")
  255. }
  256. func testURLParameterEncodeStringForRequestWithPrecomposedQuery() {
  257. // Given
  258. let URL = NSURL(string: "https://example.com/movies?hd=[1]")!
  259. let parameters = ["page": "0"]
  260. // When
  261. let (URLRequest, _) = encoding.encode(NSURLRequest(URL: URL), parameters: parameters)
  262. // Then
  263. XCTAssertEqual(URLRequest.URL?.query ?? "", "hd=%5B1%5D&page=0", "query is incorrect")
  264. }
  265. func testURLParameterEncodeStringWithPlusKeyStringWithPlusValueParameterForRequestWithPrecomposedQuery() {
  266. // Given
  267. let URL = NSURL(string: "https://example.com/movie?hd=[1]")!
  268. let parameters = ["+foo+": "+bar+"]
  269. // When
  270. let (URLRequest, _) = encoding.encode(NSURLRequest(URL: URL), parameters: parameters)
  271. // Then
  272. XCTAssertEqual(URLRequest.URL?.query ?? "", "hd=%5B1%5D&%2Bfoo%2B=%2Bbar%2B", "query is incorrect")
  273. }
  274. func testURLParameterEncodeStringWithThousandsOfChineseCharacters() {
  275. // Given
  276. let repeatedCount = 2_000
  277. let URL = NSURL(string: "https://example.com/movies")!
  278. let parameters = ["chinese": String(count: repeatedCount, repeatedString: "一二三四五六七八九十")]
  279. // When
  280. let (URLRequest, _) = encoding.encode(NSURLRequest(URL: URL), parameters: parameters)
  281. // Then
  282. var expected = "chinese="
  283. for _ in 0..<repeatedCount {
  284. expected += "%E4%B8%80%E4%BA%8C%E4%B8%89%E5%9B%9B%E4%BA%94%E5%85%AD%E4%B8%83%E5%85%AB%E4%B9%9D%E5%8D%81"
  285. }
  286. XCTAssertEqual(URLRequest.URL?.query ?? "", expected, "query is incorrect")
  287. }
  288. // MARK: Tests - Varying HTTP Methods
  289. func testThatURLParameterEncodingEncodesGETParametersInURL() {
  290. // Given
  291. let mutableURLRequest = self.URLRequest.URLRequest
  292. mutableURLRequest.HTTPMethod = Method.GET.rawValue
  293. let parameters = ["foo": 1, "bar": 2]
  294. // When
  295. let (URLRequest, _) = encoding.encode(mutableURLRequest, parameters: parameters)
  296. // Then
  297. XCTAssertEqual(URLRequest.URL?.query ?? "", "bar=2&foo=1", "query is incorrect")
  298. XCTAssertNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should be nil")
  299. XCTAssertNil(URLRequest.HTTPBody, "HTTPBody should be nil")
  300. }
  301. func testThatURLParameterEncodingEncodesPOSTParametersInHTTPBody() {
  302. // Given
  303. let mutableURLRequest = self.URLRequest.URLRequest
  304. mutableURLRequest.HTTPMethod = Method.POST.rawValue
  305. let parameters = ["foo": 1, "bar": 2]
  306. // When
  307. let (URLRequest, _) = encoding.encode(mutableURLRequest, parameters: parameters)
  308. // Then
  309. XCTAssertEqual(
  310. URLRequest.valueForHTTPHeaderField("Content-Type") ?? "",
  311. "application/x-www-form-urlencoded; charset=utf-8",
  312. "Content-Type should be application/x-www-form-urlencoded"
  313. )
  314. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  315. if let
  316. HTTPBody = URLRequest.HTTPBody,
  317. decodedHTTPBody = String(data: HTTPBody, encoding: NSUTF8StringEncoding)
  318. {
  319. XCTAssertEqual(decodedHTTPBody, "bar=2&foo=1", "HTTPBody is incorrect")
  320. } else {
  321. XCTFail("decoded http body should not be nil")
  322. }
  323. }
  324. func testThatURLEncodedInURLParameterEncodingEncodesPOSTParametersInURL() {
  325. // Given
  326. let mutableURLRequest = self.URLRequest.URLRequest
  327. mutableURLRequest.HTTPMethod = Method.POST.rawValue
  328. let parameters = ["foo": 1, "bar": 2]
  329. // When
  330. let (URLRequest, _) = ParameterEncoding.URLEncodedInURL.encode(mutableURLRequest, parameters: parameters)
  331. // Then
  332. XCTAssertEqual(URLRequest.URL?.query ?? "", "bar=2&foo=1", "query is incorrect")
  333. XCTAssertNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should be nil")
  334. XCTAssertNil(URLRequest.HTTPBody, "HTTPBody should be nil")
  335. }
  336. }
  337. // MARK: -
  338. class JSONParameterEncodingTestCase: ParameterEncodingTestCase {
  339. // MARK: Properties
  340. let encoding: ParameterEncoding = .JSON
  341. // MARK: Tests
  342. func testJSONParameterEncodeNilParameters() {
  343. // Given
  344. // When
  345. let (URLRequest, error) = encoding.encode(self.URLRequest, parameters: nil)
  346. // Then
  347. XCTAssertNil(error, "error should be nil")
  348. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  349. XCTAssertNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should be nil")
  350. XCTAssertNil(URLRequest.HTTPBody, "HTTPBody should be nil")
  351. }
  352. func testJSONParameterEncodeComplexParameters() {
  353. // Given
  354. let parameters = [
  355. "foo": "bar",
  356. "baz": ["a", 1, true],
  357. "qux": [
  358. "a": 1,
  359. "b": [2, 2],
  360. "c": [3, 3, 3]
  361. ]
  362. ]
  363. // When
  364. let (URLRequest, error) = encoding.encode(self.URLRequest, parameters: parameters)
  365. // Then
  366. XCTAssertNil(error, "error should be nil")
  367. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  368. XCTAssertNotNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should not be nil")
  369. XCTAssertEqual(
  370. URLRequest.valueForHTTPHeaderField("Content-Type") ?? "",
  371. "application/json",
  372. "Content-Type should be application/json"
  373. )
  374. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  375. if let HTTPBody = URLRequest.HTTPBody {
  376. do {
  377. let JSON = try NSJSONSerialization.JSONObjectWithData(HTTPBody, options: .AllowFragments)
  378. if let JSON = JSON as? NSObject {
  379. XCTAssertEqual(JSON, parameters as NSObject, "HTTPBody JSON does not equal parameters")
  380. } else {
  381. XCTFail("JSON should be an NSObject")
  382. }
  383. } catch {
  384. XCTFail("JSON should not be nil")
  385. }
  386. } else {
  387. XCTFail("JSON should not be nil")
  388. }
  389. }
  390. func testJSONParameterEncodeParametersRetainsCustomContentType() {
  391. // Given
  392. let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: "https://example.com/")!)
  393. mutableURLRequest.setValue("application/custom-json-type+json", forHTTPHeaderField: "Content-Type")
  394. let parameters = ["foo": "bar"]
  395. // When
  396. let (URLRequest, error) = encoding.encode(mutableURLRequest, parameters: parameters)
  397. // Then
  398. XCTAssertNil(error)
  399. XCTAssertNil(URLRequest.URL?.query)
  400. XCTAssertEqual(URLRequest.valueForHTTPHeaderField("Content-Type"), "application/custom-json-type+json")
  401. }
  402. }
  403. // MARK: -
  404. class PropertyListParameterEncodingTestCase: ParameterEncodingTestCase {
  405. // MARK: Properties
  406. let encoding: ParameterEncoding = .PropertyList(.XMLFormat_v1_0, 0)
  407. // MARK: Tests
  408. func testPropertyListParameterEncodeNilParameters() {
  409. // Given
  410. // When
  411. let (URLRequest, error) = encoding.encode(self.URLRequest, parameters: nil)
  412. // Then
  413. XCTAssertNil(error, "error should be nil")
  414. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  415. XCTAssertNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should be nil")
  416. XCTAssertNil(URLRequest.HTTPBody, "HTTPBody should be nil")
  417. }
  418. func testPropertyListParameterEncodeComplexParameters() {
  419. // Given
  420. let parameters = [
  421. "foo": "bar",
  422. "baz": ["a", 1, true],
  423. "qux": [
  424. "a": 1,
  425. "b": [2, 2],
  426. "c": [3, 3, 3]
  427. ]
  428. ]
  429. // When
  430. let (URLRequest, error) = encoding.encode(self.URLRequest, parameters: parameters)
  431. // Then
  432. XCTAssertNil(error, "error should be nil")
  433. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  434. XCTAssertNotNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should not be nil")
  435. XCTAssertEqual(
  436. URLRequest.valueForHTTPHeaderField("Content-Type") ?? "",
  437. "application/x-plist",
  438. "Content-Type should be application/x-plist"
  439. )
  440. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  441. if let HTTPBody = URLRequest.HTTPBody {
  442. do {
  443. let plist = try NSPropertyListSerialization.propertyListWithData(
  444. HTTPBody,
  445. options: NSPropertyListReadOptions.Immutable,
  446. format: nil
  447. )
  448. if let plist = plist as? NSObject {
  449. XCTAssertEqual(plist, parameters as NSObject, "HTTPBody plist does not equal parameters")
  450. } else {
  451. XCTFail("plist should be an NSObject")
  452. }
  453. } catch {
  454. XCTFail("plist should not be nil")
  455. }
  456. }
  457. }
  458. func testPropertyListParameterEncodeDateAndDataParameters() {
  459. // Given
  460. let date: NSDate = NSDate()
  461. let data: NSData = "data".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
  462. let parameters = [
  463. "date": date,
  464. "data": data
  465. ]
  466. // When
  467. let (URLRequest, error) = encoding.encode(self.URLRequest, parameters: parameters)
  468. // Then
  469. XCTAssertNil(error, "error should be nil")
  470. XCTAssertNil(URLRequest.URL?.query, "query should be nil")
  471. XCTAssertNotNil(URLRequest.valueForHTTPHeaderField("Content-Type"), "Content-Type should not be nil")
  472. XCTAssertEqual(
  473. URLRequest.valueForHTTPHeaderField("Content-Type") ?? "",
  474. "application/x-plist",
  475. "Content-Type should be application/x-plist"
  476. )
  477. XCTAssertNotNil(URLRequest.HTTPBody, "HTTPBody should not be nil")
  478. if let HTTPBody = URLRequest.HTTPBody {
  479. do {
  480. let plist = try NSPropertyListSerialization.propertyListWithData(
  481. HTTPBody,
  482. options: NSPropertyListReadOptions.Immutable,
  483. format: nil
  484. )
  485. XCTAssertTrue(plist.valueForKey("date") is NSDate, "date is not NSDate")
  486. XCTAssertTrue(plist.valueForKey("data") is NSData, "data is not NSData")
  487. } catch {
  488. XCTFail("plist should not be nil")
  489. }
  490. } else {
  491. XCTFail("HTTPBody should not be nil")
  492. }
  493. }
  494. func testPropertyListParameterEncodeParametersRetainsCustomContentType() {
  495. // Given
  496. let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: "https://example.com/")!)
  497. mutableURLRequest.setValue("application/custom-plist-type+plist", forHTTPHeaderField: "Content-Type")
  498. let parameters = ["foo": "bar"]
  499. // When
  500. let (URLRequest, error) = encoding.encode(mutableURLRequest, parameters: parameters)
  501. // Then
  502. XCTAssertNil(error)
  503. XCTAssertNil(URLRequest.URL?.query)
  504. XCTAssertEqual(URLRequest.valueForHTTPHeaderField("Content-Type"), "application/custom-plist-type+plist")
  505. }
  506. }
  507. // MARK: -
  508. class CustomParameterEncodingTestCase: ParameterEncodingTestCase {
  509. // MARK: Tests
  510. func testCustomParameterEncode() {
  511. // Given
  512. let encodingClosure: (URLRequestConvertible, [String: AnyObject]?) -> (NSMutableURLRequest, NSError?) = { URLRequest, parameters in
  513. guard let parameters = parameters else { return (URLRequest.URLRequest, nil) }
  514. var URLString = URLRequest.URLRequest.URLString + "?"
  515. parameters.forEach { URLString += "\($0)=\($1)" }
  516. let mutableURLRequest = URLRequest.URLRequest
  517. mutableURLRequest.URL = NSURL(string: URLString)!
  518. return (mutableURLRequest, nil)
  519. }
  520. // When
  521. let encoding: ParameterEncoding = .Custom(encodingClosure)
  522. // Then
  523. let URL = NSURL(string: "https://example.com")!
  524. let URLRequest = NSURLRequest(URL: URL)
  525. let parameters: [String: AnyObject] = ["foo": "bar"]
  526. XCTAssertEqual(
  527. encoding.encode(URLRequest, parameters: parameters).0.URLString,
  528. "https://example.com?foo=bar",
  529. "the encoded URL should match the expected value"
  530. )
  531. }
  532. }