From fc471993e7c140aa37353f0defbc2aae8524deca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fontana?= Date: Fri, 19 Jan 2024 09:42:03 +0100 Subject: [PATCH] fix(#88): query params array encoding --- .../Client/HTTPRequest/HTTPRequest.swift | 4 +--- .../URLParametersData/URLParametersData.swift | 21 ++++++++++++++++++ Tests/RealHTTPTests/Requests+Tests.swift | 22 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/Sources/RealHTTP/Client/HTTPRequest/HTTPRequest.swift b/Sources/RealHTTP/Client/HTTPRequest/HTTPRequest.swift index 168337b..70e582d 100644 --- a/Sources/RealHTTP/Client/HTTPRequest/HTTPRequest.swift +++ b/Sources/RealHTTP/Client/HTTPRequest/HTTPRequest.swift @@ -397,9 +397,7 @@ public extension HTTPRequest { let paramsData = HTTPBody.URLParametersData(parameters, boolEncoding: boolEncoding, arrayEncoding: arrayEncoding) - paramsData.encodedParametersToDictionary().forEach { item in - add(queryItem: URLQueryItem(name: item.key, value: item.value)) - } + add(queryItems: paramsData.encodedParametersToURLQueryItems()) } } diff --git a/Sources/RealHTTP/Client/Internal/HTTPBody/URLParametersData/URLParametersData.swift b/Sources/RealHTTP/Client/Internal/HTTPBody/URLParametersData/URLParametersData.swift index 1b478c6..4f50f25 100644 --- a/Sources/RealHTTP/Client/Internal/HTTPBody/URLParametersData/URLParametersData.swift +++ b/Sources/RealHTTP/Client/Internal/HTTPBody/URLParametersData/URLParametersData.swift @@ -102,6 +102,27 @@ extension HTTPBody { return components } + /// Creates an array of `URLQueryItem` from the contained parameters. + /// + /// - Returns: [URLQueryItem] + internal func encodedParametersToURLQueryItems() -> [URLQueryItem] { + guard let parameters = self.parameters, parameters.isEmpty == false else { + return [] + } + + var queryItems = [URLQueryItem]() + + for key in parameters.keys.sorted(by: <) { + let value = parameters[key]! + let results = encodeKey(key, withValue: value) + for result in results { + queryItems.append(URLQueryItem(name: result.0, value: result.1)) + } + } + + return queryItems + } + /// Encode a single object according to settings. /// /// - Parameters: diff --git a/Tests/RealHTTPTests/Requests+Tests.swift b/Tests/RealHTTPTests/Requests+Tests.swift index b7237b5..3135bad 100644 --- a/Tests/RealHTTPTests/Requests+Tests.swift +++ b/Tests/RealHTTPTests/Requests+Tests.swift @@ -322,6 +322,28 @@ class RequestsTests: XCTestCase { XCTAssert(parsedParams.params("p4").count == 2, "Failed to encode array") } + func test_queryParametersArrayEncoding() { + let req = HTTPRequest { + $0.path = "/some" + $0.add(parameters: ["param": [1, 2]], arrayEncoding: .withBrackets) + $0.add(parameters: ["anotherParam": [1, 2]], arrayEncoding: .noBrackets) + } + + guard let queryItems = req.query else { + return XCTFail("Query Items not found") + } + + XCTAssertEqual(queryItems.count, 4) + XCTAssertEqual(queryItems[0].name, "param[]".queryEscaped) + XCTAssertEqual(queryItems[0].value, "1") + XCTAssertEqual(queryItems[1].name, "param[]".queryEscaped) + XCTAssertEqual(queryItems[1].value, "2") + XCTAssertEqual(queryItems[2].name, "anotherParam".queryEscaped) + XCTAssertEqual(queryItems[2].value, "1") + XCTAssertEqual(queryItems[3].name, "anotherParam".queryEscaped) + XCTAssertEqual(queryItems[3].value, "2") + } + func test_streamUpload() async throws { setupStubber(echo: true) defer { stopStubber() }