ParameterEncodingTests.swift 25 KB

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