Skip to content

Commit

Permalink
Fix faking with pattern (#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
3lvis authored Jul 15, 2023
1 parent 17f55bd commit 042aa2d
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 47 deletions.
85 changes: 39 additions & 46 deletions Sources/Networking/FakeRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,54 @@ struct FakeRequest {

static func find(ofType type: Networking.RequestType, forPath path: String, in collection: [Networking.RequestType: [String: FakeRequest]]) throws -> FakeRequest? {
guard let requests = collection[type] else { return nil }

guard path.count > 0 else { return nil }
var evaluatedPath = path
evaluatedPath.removeFirstLetterIfDash()
evaluatedPath.removeLastLetterIfDash()
let lookupPathParts = evaluatedPath.components(separatedBy: "/")

for (originalFakedPath, fakeRequest) in requests {
switch fakeRequest.responseType {
case .data, .image:
if originalFakedPath == path {
return fakeRequest
} else {
continue
}
case .json:
if let response = fakeRequest.response {
var fakedPath = originalFakedPath
fakedPath.removeFirstLetterIfDash()
fakedPath.removeLastLetterIfDash()
let fakePathParts = fakedPath.components(separatedBy: "/")
guard lookupPathParts.count == fakePathParts.count else { continue }
guard lookupPathParts.first == fakePathParts.first else { continue }
guard lookupPathParts.count != 1 && fakePathParts.count != 1 else { return requests[originalFakedPath] }
if let result = requests[path] {
return result
} else {
var evaluatedPath = path
evaluatedPath.removeFirstLetterIfDash()
evaluatedPath.removeLastLetterIfDash()
let lookupPathParts = evaluatedPath.components(separatedBy: "/")

var replacedValues = [String: String]()
for (index, fakePathPart) in fakePathParts.enumerated() {
if fakePathPart.contains("{") {
replacedValues[fakePathPart] = lookupPathParts[index]
}
}
for (originalFakedPath, fakeRequest) in requests {
guard originalFakedPath.contains("{") else { continue }

var fakedPath = originalFakedPath
fakedPath.removeFirstLetterIfDash()
fakedPath.removeLastLetterIfDash()
let fakePathParts = fakedPath.components(separatedBy: "/")

guard lookupPathParts.count == fakePathParts.count else { continue }
guard lookupPathParts.first == fakePathParts.first else { continue }
guard lookupPathParts.count != 1 && fakePathParts.count != 1 else { continue }

if var responseString = String(data: try JSONSerialization.data(withJSONObject: response, options: .prettyPrinted), encoding: .utf8) {
for (key, value) in replacedValues {
responseString = responseString.replacingOccurrences(of: key, with: value)
}
if let stringData = responseString.data(using: .utf8) {
let finalJSON = try JSONSerialization.jsonObject(with: stringData, options: [])
return FakeRequest(response: finalJSON, responseType: fakeRequest.responseType, headerFields: fakeRequest.headerFields, statusCode: fakeRequest.statusCode)
} else {
continue
}
} else {
continue
var replacedValues = [String: String]()
for (index, fakePathPart) in fakePathParts.enumerated() {
if fakePathPart.contains("{") {
replacedValues[fakePathPart] = lookupPathParts[index]
}
} else if originalFakedPath == path {
return fakeRequest
} else {
continue
}

var replacedPath = originalFakedPath
for (key, value) in replacedValues {
replacedPath = replacedPath.replacingOccurrences(of: key, with: value)
}
guard replacedPath == path else { continue }
guard let response = fakeRequest.response else { continue }
guard var responseString = String(data: try JSONSerialization.data(withJSONObject: response, options: .prettyPrinted), encoding: .utf8) else { continue }

for (key, value) in replacedValues {
responseString = responseString.replacingOccurrences(of: key, with: value)
}

guard let stringData = responseString.data(using: .utf8) else { continue }
let finalJSON = try JSONSerialization.jsonObject(with: stringData, options: [])
return FakeRequest(response: finalJSON, responseType: fakeRequest.responseType, headerFields: fakeRequest.headerFields, statusCode: fakeRequest.statusCode)
}
}

let result = requests[path]
return result
return nil
}
}

Expand Down
66 changes: 65 additions & 1 deletion Tests/NetworkingTests/FakeRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ class FakeRequestTests: XCTestCase {
XCTAssertEqual(result?.response as? NSDictionary, expected as NSDictionary)
}

func testOneLevelFindFailureBecauseOfDictionary() throws {
let json = [
"name": "Name {userID}"
]
let request = FakeRequest(response: json, responseType: .json, headerFields: nil, statusCode: 200)
let existingRequests = [
Networking.RequestType.get: [
"/users/ados": request,
"/users/bedos": request,
"/users/cedos": request,
"/users/tedos": request,
"/users/melos": request,
"/users/{userID}": request
]
]
let result = try FakeRequest.find(ofType: .get, forPath: "/users/10", in: existingRequests)

let expected = [
"name": "Name 10"
]

XCTAssertEqual(result?.response as? NSDictionary, expected as NSDictionary)
}

func testTwoLevelFind() throws {
let json = [
"user": "User {userID}",
Expand All @@ -80,7 +104,16 @@ class FakeRequestTests: XCTestCase {
"product": "Product {productID}"
]
let request = FakeRequest(response: json, responseType: .json, headerFields: nil, statusCode: 200)
let existingRequests = [Networking.RequestType.get: ["/users/{userID}/companies/{companyID}/products/{productID}": request]]
let existingRequests = [Networking.RequestType.get: [
"/users/{userID}/companies/{companyID}/products/a": request,
"/users/{userID}/companies/{companyID}/products/b": request,
"/users/{userID}/companies/{companyID}/products/c": request,
"/users/{userID}/companies/{companyID}/products/d": request,
"/users/{userID}/companies/{companyID}/products/{productID}": request,
"/users/{userID}/companies/{companyID}/products/e": request,
"/users/{userID}/companies/{companyID}/products/f": request,
"/users/{userID}/companies/{companyID}/products/g": request,
]]
let result = try FakeRequest.find(ofType: .get, forPath: "/users/10/companies/20/products/30", in: existingRequests)

let expected = [
Expand Down Expand Up @@ -197,6 +230,12 @@ extension FakeRequestTests {
let json = [
"name": "Name {userID}"
]

networking.fakeGET("/users/ados", response: json, statusCode: 200)
networking.fakeGET("/users/bedos", response: json, statusCode: 200)
networking.fakeGET("/users/cedos", response: json, statusCode: 200)
networking.fakeGET("/users/tedos", response: json, statusCode: 200)
networking.fakeGET("/users/melos", response: json, statusCode: 200)
networking.fakeGET("/users/{userID}", response: json, statusCode: 200)

let result = try await networking.get("/users/10")
Expand Down Expand Up @@ -299,6 +338,31 @@ extension FakeRequestTests {
XCTFail(response.error.localizedDescription)
}
}

func testFakePOSTMultiple() async throws {
let networking = Networking(baseURL: baseURL)

networking.fakeGET("/g/1/1", response: ["id":"2"])
networking.fakeGET("/g/2/2", response: ["id":"2"])
networking.fakePOST("/g/1/e", response: ["id":"2"])
networking.fakePOST("/g/1/b", response: ["id":"5"])
networking.fakePOST("/g/5/f", response: nil)
networking.fakePUT("/g/2/2", response: ["id":"2"])
networking.fakePOST("/g/x/o", response: ["id":"3"])
networking.fakePOST("/g/1/b", response: ["id":"4"])
networking.fakeDELETE("/g/2/2", response: nil)
networking.fakePOST("/g/1/b", response: ["id":"1"])

let result = try await networking.post("/g/1/b", parameters: ["ignored": true])
switch result {
case let .success(response):
let json = response.dictionaryBody
let value = json["id"] as! String
XCTAssertEqual(value, "1")
case let .failure(response):
XCTFail(response.error.localizedDescription)
}
}
}

// PUT tests
Expand Down

0 comments on commit 042aa2d

Please sign in to comment.