ParameterEncodingTests.swift 26 KB

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