ParameterEncodingTests.swift 24 KB

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