59 lines
2.0 KiB
Swift
59 lines
2.0 KiB
Swift
|
|
import XCTest
|
||
|
|
@testable import LCEssentials
|
||
|
|
|
||
|
|
private struct SamplePayload: Encodable, Sendable {
|
||
|
|
let name: String
|
||
|
|
let age: Int
|
||
|
|
}
|
||
|
|
|
||
|
|
final class HTTPBodyTests: XCTestCase {
|
||
|
|
|
||
|
|
// MARK: - JSONBody
|
||
|
|
|
||
|
|
func testJSONBodyEncodesPayloadAndContentType() throws {
|
||
|
|
let payload = SamplePayload(name: "loverde", age: 3)
|
||
|
|
let (data, contentType) = try JSONBody(payload).encoded()
|
||
|
|
|
||
|
|
XCTAssertEqual(contentType, "application/json; charset=UTF-8")
|
||
|
|
|
||
|
|
let decoded = try JSONDecoder().decode([String: AnyDecodable].self, from: data)
|
||
|
|
XCTAssertEqual(decoded["name"]?.value as? String, "loverde")
|
||
|
|
XCTAssertEqual(decoded["age"]?.value as? Int, 3)
|
||
|
|
}
|
||
|
|
|
||
|
|
func testJSONBodyFactory() throws {
|
||
|
|
let (data, _) = try jsonBody(SamplePayload(name: "x", age: 1)).encoded()
|
||
|
|
XCTAssertFalse(data.isEmpty)
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - FormURLEncodedBody
|
||
|
|
|
||
|
|
func testFormURLEncodedEncodesPairsAndPercentEscapes() throws {
|
||
|
|
let (data, contentType) = try FormURLEncodedBody(["a": "1", "b": "two words"]).encoded()
|
||
|
|
|
||
|
|
XCTAssertEqual(contentType, "application/x-www-form-urlencoded; charset=UTF-8")
|
||
|
|
|
||
|
|
let pairs = Set(String(data: data, encoding: .utf8)!.split(separator: "&").map(String.init))
|
||
|
|
XCTAssertEqual(pairs, ["a=1", "b=two%20words"])
|
||
|
|
}
|
||
|
|
|
||
|
|
func testFormURLEncodedEscapesReservedCharactersInsteadOfDropping() throws {
|
||
|
|
let (data, _) = try FormURLEncodedBody(["q": "a&b=c"]).encoded()
|
||
|
|
let body = String(data: data, encoding: .utf8)!
|
||
|
|
XCTAssertEqual(body, "q=a%26b%3Dc")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Minimal type-erased decoder for asserting JSON shape in tests.
|
||
|
|
struct AnyDecodable: Decodable {
|
||
|
|
let value: Any
|
||
|
|
init(from decoder: Decoder) throws {
|
||
|
|
let c = try decoder.singleValueContainer()
|
||
|
|
if let i = try? c.decode(Int.self) { value = i }
|
||
|
|
else if let s = try? c.decode(String.self) { value = s }
|
||
|
|
else if let b = try? c.decode(Bool.self) { value = b }
|
||
|
|
else if let d = try? c.decode(Double.self) { value = d }
|
||
|
|
else { value = "" }
|
||
|
|
}
|
||
|
|
}
|