Skip to content

Commit

Permalink
REFACTOR: Migrate Adapter tests to Swift Testing (#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamayoung authored Sep 16, 2024
1 parent 5e14f08 commit f553fb5
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 86 deletions.
156 changes: 70 additions & 86 deletions Tests/TMDbTests/Adapters/URLSessionHTTPClientAdapterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,144 +17,128 @@
// limitations under the License.
//

import Foundation
import Testing
@testable import TMDb
import XCTest
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

final class URLSessionHTTPClientAdapterTests: XCTestCase {
@Suite(
.serialized,
.tags(.adapter)
)
final class URLSessionHTTPClientAdapterTests {

var httpClient: URLSessionHTTPClientAdapter!
var baseURL: URL!
var urlSession: URLSession!

override func setUpWithError() throws {
try super.setUpWithError()
baseURL = try XCTUnwrap(URL(string: "https://some.domain.com/path"))
init() throws {
self.baseURL = try #require(URL(string: "https://some.domain.com/path"))

let configuration = URLSessionConfiguration.default
configuration.protocolClasses = [MockURLProtocol.self]
urlSession = URLSession(configuration: configuration)
httpClient = URLSessionHTTPClientAdapter(urlSession: urlSession)
self.urlSession = URLSession(configuration: configuration)
self.httpClient = URLSessionHTTPClientAdapter(urlSession: urlSession)
}

override func tearDown() async throws {
deinit {
httpClient = nil
urlSession = nil
baseURL = nil
await MockURLProtocol.reset()
try await super.tearDown()
Task {
await MockURLProtocol.reset()
}
}

@Test("perform when response status code is 401 returns unauthorised error")
@MainActor
func testPerformWhenResponseStatusCodeIs401ReturnsUnauthorisedError() async throws {
func performWhenResponseStatusCodeIs401ReturnsUnauthorisedError() async throws {
MockURLProtocol.responseStatusCode = 401
let url = try XCTUnwrap(URL(string: "/error"))
let url = try #require(URL(string: "/error"))
let request = HTTPRequest(url: url)

let response: HTTPResponse
do {
response = try await httpClient.perform(request: request)
} catch {
XCTFail("Unexpected error thrown")
return
}
let response = try await httpClient.perform(request: request)

XCTAssertEqual(response.statusCode, 401)
#expect(response.statusCode == 401)
}

@Test("perform when response status code is 404 returns not found error")
@MainActor
func testPerformWhenResponseStatusCodeIs404ReturnsNotFoundError() async throws {
func performWhenResponseStatusCodeIs404ReturnsNotFoundError() async throws {
MockURLProtocol.responseStatusCode = 404
let url = try XCTUnwrap(URL(string: "/error"))
let url = try #require(URL(string: "/error"))
let request = HTTPRequest(url: url)

let response: HTTPResponse
do {
response = try await httpClient.perform(request: request)
} catch {
XCTFail("Unexpected error thrown")
return
}
let response = try await httpClient.perform(request: request)

XCTAssertEqual(response.statusCode, 404)
#expect(response.statusCode == 404)
}

@Test("perform when response status code is 404 and has status message error throws not found error with message")
@MainActor
func testPerformWhenResponseStatusCodeIs404AndHasStatusMessageErrorThrowsNotFoundErrorWithMessage() async throws {
func performWhenResponseStatusCodeIs404AndHasStatusMessageErrorThrowsNotFoundErrorWithMessage() async throws {
MockURLProtocol.responseStatusCode = 404
let expectedData = try Data(fromResource: "error-status-response", withExtension: "json")
MockURLProtocol.data = expectedData
let url = try XCTUnwrap(URL(string: "/error"))
let url = try #require(URL(string: "/error"))
let request = HTTPRequest(url: url)

let response: HTTPResponse
do {
response = try await httpClient.perform(request: request)
} catch {
XCTFail("Unexpected error thrown")
return
}
let response = try await httpClient.perform(request: request)

XCTAssertEqual(response.statusCode, 404)
XCTAssertEqual(response.data, expectedData)
#expect(response.statusCode == 404)
#expect(response.data == expectedData)
}

@Test("perform when response has valid data returns decoded object")
@MainActor
func testGetWhenResponseHasValidDataReturnsDecodedObject() async throws {
func performWhenResponseHasValidDataReturnsDecodedObject() async throws {
let expectedStatusCode = 200
let expectedData = Data("abc".utf8)
MockURLProtocol.data = expectedData
let url = try XCTUnwrap(URL(string: "/object"))
let url = try #require(URL(string: "/object"))
let request = HTTPRequest(url: url)

let response = try await httpClient.perform(request: request)

XCTAssertEqual(response.statusCode, expectedStatusCode)
XCTAssertEqual(response.data, expectedData)
#expect(response.statusCode == expectedStatusCode)
#expect(response.data == expectedData)
}

}

#if !canImport(FoundationNetworking)
extension URLSessionHTTPClientAdapterTests {

@MainActor
func testPerformURLRequestHasCorrectURL() async throws {
let path = "/object?key1=value1&key2=value2"
let expectedURL = try XCTUnwrap(URL(string: path))
let request = HTTPRequest(url: expectedURL)
@Test("perform URL request has correct URL")
@MainActor
func performURLRequestHasCorrectURL() async throws {
let path = "/object?key1=value1&key2=value2"
let expectedURL = try #require(URL(string: path))
let request = HTTPRequest(url: expectedURL)

_ = try? await httpClient.perform(request: request)
_ = try? await httpClient.perform(request: request)

let result = MockURLProtocol.lastRequest?.url
let result = MockURLProtocol.lastRequest?.url

XCTAssertEqual(result, expectedURL)
}

@MainActor
func testPerformWhenHeaderSetShouldBePresentInURLRequest() async throws {
let url = try XCTUnwrap(URL(string: "/object"))
let header1Name = "Accept"
let header1Value = "application/json"
let header2Name = "Content-Type"
let header2Value = "text/html"
let headers = [
header1Name: header1Value,
header2Name: header2Value
]
let request = HTTPRequest(url: url, headers: headers)

_ = try? await httpClient.perform(request: request)

let lastURLRequest = try XCTUnwrap(MockURLProtocol.lastRequest)
let result1 = lastURLRequest.value(forHTTPHeaderField: header1Name)
let result2 = lastURLRequest.value(forHTTPHeaderField: header2Name)

XCTAssertEqual(result1, header1Value)
XCTAssertEqual(result2, header2Value)
}
#expect(result == expectedURL)
}

@Test("perform when header set should be present in URL request")
@MainActor
func performWhenHeaderSetShouldBePresentInURLRequest() async throws {
let url = try #require(URL(string: "/object"))
let header1Name = "Accept"
let header1Value = "application/json"
let header2Name = "Content-Type"
let header2Value = "text/html"
let headers = [
header1Name: header1Value,
header2Name: header2Value
]
let request = HTTPRequest(url: url, headers: headers)

_ = try? await httpClient.perform(request: request)

let lastURLRequest = try #require(MockURLProtocol.lastRequest)
let result1 = lastURLRequest.value(forHTTPHeaderField: header1Name)
let result2 = lastURLRequest.value(forHTTPHeaderField: header2Name)

#expect(result1 == header1Value)
#expect(result2 == header2Value)
}
#endif

}
1 change: 1 addition & 0 deletions Tests/TMDbTests/TestUtils/Tags.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Testing

extension Tag {

@Tag static var adapter: Self
@Tag static var domain: Self
@Tag static var networking: Self

Expand Down

0 comments on commit f553fb5

Please sign in to comment.