Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions Tests/MicroClientTests/Doubles/URLSessionMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,43 @@ import Foundation
@testable import MicroClient

final class URLSessionMock: URLSessionProtocol {
var dataToReturn: Data = Data()
var responseToReturn: URLResponse = URLResponse()
var errorToThrow: Error?
var lastRequest: URLRequest?

// MARK: - Properties

private(set) var lastRequest: URLRequest?
private var stubbedDataToReturn: Data = Data()
private var stubbedResponseToReturn: URLResponse = URLResponse()
private var stubbedErrorToThrow: Error?

// MARK: - Public

func data(
for request: URLRequest,
delegate: URLSessionTaskDelegate? = nil
) async throws -> (Data, URLResponse) {
lastRequest = request

if let error = errorToThrow {
if let error = stubbedErrorToThrow {
throw error
}

return (dataToReturn, responseToReturn)
return (stubbedDataToReturn, stubbedResponseToReturn)
}
}

// MARK: - Stub

extension URLSessionMock {

func stubDataToReturn(
data: Data,
response: URLResponse
) {
stubbedDataToReturn = data
stubbedResponseToReturn = response
}

func stubDataToThrow(error: Error?) {
stubbedErrorToThrow = error
}
}
27 changes: 0 additions & 27 deletions Tests/MicroClientTests/Fixtures/NetworkClientMother.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,33 +40,6 @@ enum NetworkClientMother {
)!
}

static func makeErrorResponse(
for url: URL,
statusCode: Int = 500,
httpVersion: String = "HTTP/1.1",
headerFields: [String: String]? = ["Content-Type": "application/json"]
) -> HTTPURLResponse {
HTTPURLResponse(
url: url,
statusCode: statusCode,
httpVersion: httpVersion,
headerFields: headerFields
)!
}

static func makeNotFoundResponse(
for url: URL,
httpVersion: String = "HTTP/1.1",
headerFields: [String: String]? = ["Content-Type": "application/json"]
) -> HTTPURLResponse {
HTTPURLResponse(
url: url,
statusCode: 404,
httpVersion: httpVersion,
headerFields: headerFields
)!
}

static func makeNetworkConfiguration(
session: URLSessionProtocol = URLSessionMock(),
baseURL: URL = URL(string: "https://api.example.com")!,
Expand Down
38 changes: 0 additions & 38 deletions Tests/MicroClientTests/Fixtures/TestModelMother.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,6 @@ enum TestModelMother {
)
}

static func makeTestResponseModel(
success: Bool = true,
message: String = "Success",
data: TestResponseModel.TestData? = makeTestData()
) -> TestResponseModel {
TestResponseModel(
success: success,
message: message,
data: data
)
}

static func makeSuccessfulResponseModel(
message: String = "Created successfully"
) -> TestResponseModel {
Expand All @@ -109,22 +97,6 @@ enum TestModelMother {
)
}

static func makeFailedResponseModel(
message: String = "Operation failed"
) -> TestResponseModel {
TestResponseModel(
success: false,
message: message,
data: nil
)
}

static func makeTestData(
value: String = "test"
) -> TestResponseModel.TestData {
TestResponseModel.TestData(value: value)
}

// MARK: - NetworkRequest Models

static func makeNetworkRequestTestModel(
Expand All @@ -137,16 +109,6 @@ enum TestModelMother {
)
}

static func makeNetworkRequestResponseModel(
success: Bool = true,
message: String = "Success"
) -> NetworkRequestResponseModel {
NetworkRequestResponseModel(
success: success,
message: message
)
}

// MARK: - Decoding Models

static func makeDecodingTestModel(
Expand Down
7 changes: 5 additions & 2 deletions Tests/MicroClientTests/NetworkClientErrorHandlingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@ struct NetworkClientErrorHandlingTests {
let invalidJSON = Data("{ invalid json".utf8)
let expectedURL = try #require(URL(string: "https://api.example.com/data"))

mockSession.dataToReturn = invalidJSON
mockSession.responseToReturn = try #require(
let response = try #require(
HTTPURLResponse(
url: expectedURL,
statusCode: 200,
httpVersion: "HTTP/1.1",
headerFields: nil
)
)
mockSession.stubDataToReturn(
data: invalidJSON,
response: response
)

let request = NetworkRequest<VoidRequest, TestResponseModel>(
path: "/data",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ struct NetworkClientStatusPublisherTests {
session: mockSession
)

mockSession.dataToReturn = Data()
mockSession.responseToReturn = URLResponse()
mockSession.stubDataToReturn(
data: Data(),
response: URLResponse()
)

var statusUpdates: [NetworkClientStatus] = []

Expand Down Expand Up @@ -56,7 +58,7 @@ struct NetworkClientStatusPublisherTests {
session: mockSession
)

mockSession.errorToThrow = URLError(.networkConnectionLost)
mockSession.stubDataToThrow(error: URLError(.networkConnectionLost))

var statusUpdates: [NetworkClientStatus] = []

Expand Down
47 changes: 29 additions & 18 deletions Tests/MicroClientTests/NetworkClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ struct NetworkClientTests {
)

let expectedURL = try #require(URL(string: "https://api.example.com/ping"))
mockSession.dataToReturn = Data()
mockSession.responseToReturn = NetworkClientMother.makeSuccessResponse(
for: expectedURL

mockSession.stubDataToReturn(
data: Data(),
response: NetworkClientMother.makeSuccessResponse(
for: expectedURL
)
)

let request = NetworkRequest<VoidRequest, VoidResponse>(
Expand All @@ -28,7 +31,7 @@ struct NetworkClientTests {
let response = try await client.run(request)

#expect(
response.value != nil,
type(of: response.value) == VoidResponse.self,
"It should return VoidResponse"
)
#expect(
Expand All @@ -53,10 +56,12 @@ struct NetworkClientTests {
""".utf8)

let expectedURL = try #require(URL(string: "https://api.example.com/users"))
mockSession.dataToReturn = responseData
mockSession.responseToReturn = NetworkClientMother.makeSuccessResponse(
for: expectedURL,
statusCode: 201
mockSession.stubDataToReturn(
data: responseData,
response: NetworkClientMother.makeSuccessResponse(
for: expectedURL,
statusCode: 201
)
)

let requestBody = TestModelMother.makeTestRequestModel()
Expand Down Expand Up @@ -92,7 +97,7 @@ struct NetworkClientTests {
)

let networkError = URLError(.notConnectedToInternet)
mockSession.errorToThrow = networkError
mockSession.stubDataToThrow(error: networkError)

let request = NetworkRequest<VoidRequest, VoidResponse>(
path: "/test",
Expand All @@ -118,9 +123,11 @@ struct NetworkClientTests {
)

let expectedURL = try #require(URL(string: "https://api.example.com/protected"))
mockSession.dataToReturn = Data()
mockSession.responseToReturn = NetworkClientMother.makeSuccessResponse(
for: expectedURL
mockSession.stubDataToReturn(
data: Data(),
response: NetworkClientMother.makeSuccessResponse(
for: expectedURL
)
)

let request = NetworkRequest<VoidRequest, VoidResponse>(
Expand Down Expand Up @@ -152,9 +159,11 @@ struct NetworkClientTests {
)

let expectedURL = try #require(URL(string: "https://api.example.com/search?q=swift&limit=10"))
mockSession.dataToReturn = Data()
mockSession.responseToReturn = NetworkClientMother.makeSuccessResponse(
for: expectedURL
mockSession.stubDataToReturn(
data: Data(),
response: NetworkClientMother.makeSuccessResponse(
for: expectedURL
)
)

let request = NetworkRequest<VoidRequest, VoidResponse>(
Expand Down Expand Up @@ -200,9 +209,11 @@ struct NetworkClientTests {
let client = NetworkClient(configuration: configuration)

let expectedURL = try #require(URL(string: "https://api.example.com/data"))
mockSession.dataToReturn = Data()
mockSession.responseToReturn = NetworkClientMother.makeSuccessResponse(
for: expectedURL
mockSession.stubDataToReturn(
data: Data(),
response: NetworkClientMother.makeSuccessResponse(
for: expectedURL
)
)

let request = NetworkRequest<VoidRequest, VoidResponse>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ struct NetworkResponseComplexModelsTests {
networkResponse.response === httpResponse,
"It should store the HTTPURLResponse"
)

if let httpUrlResponse = networkResponse.response as? HTTPURLResponse {
#expect(
httpUrlResponse.statusCode == 201,
Expand All @@ -44,6 +43,10 @@ struct NetworkResponseComplexModelsTests {
httpUrlResponse.allHeaderFields["Location"] as? String == "/api/complex/\(complexModel.id)",
"It should preserve HTTP headers for complex models"
)
#expect(
httpResponse.location?.absoluteString == "/api/complex/\(complexModel.id)",
"It should preserve HTTP headers for complex models"
)
}
}
}
Loading