2
0

ParameterEncodingTests.swift 25 KB

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