Skip to content

Commit cd99083

Browse files
authored
Merge pull request #20 from ipinfo/fix-tests
Fix failing resproxy tests caused by data change
2 parents 85efb33 + fea04d4 commit cd99083

3 files changed

Lines changed: 71 additions & 7 deletions

File tree

Package.resolved

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/ipinfoKit/API/API.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,30 +37,34 @@ extension Service.Router {
3737
// MARK: - Service
3838

3939
@MainActor
40-
class Service {
40+
public class Service {
4141

4242
// MARK: Lifecycle
4343

4444
private init() { }
4545

4646
// MARK: Internal
4747

48-
static let shared = Service()
48+
public static let shared = Service()
4949

5050
var ipInfoURL = "https://ipinfo.io"
5151
let headers: HTTPHeaders = [
5252
"Authorization": "Bearer \(Constants.ACCESS_TOKEN)",
5353
"User-Agent": "IPinfoClient/Swift/\(Constants.SDK_VERSION)",
5454
]
5555

56+
/// Custom session for testing. When nil, uses default AF session.
57+
public var session: Session?
58+
5659
@MainActor
5760
func requestAPI(
5861
URL: Service.Router,
5962
method: HTTPMethod,
6063
params: Parameters? = nil,
6164
completion: @escaping (_ status: Response,_ data: Data,_ msg: String) -> Void) {
6265

63-
AF.request(URL.endPoint , method: method, parameters: params , encoding: JSONEncoding.default, headers: headers)
66+
let requestSession = session ?? AF
67+
requestSession.request(URL.endPoint , method: method, parameters: params , encoding: JSONEncoding.default, headers: headers)
6468
.response { response in
6569
DispatchQueue.main.async {
6670
switch response.result {

Tests/ipinfoKitTests/ResproxyTests.swift

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,53 @@
1+
import Alamofire
12
import Foundation
23
import Testing
34
import ipinfoKit
45

6+
/// Custom URLProtocol that only mocks specific URLs for resproxy tests
7+
private class ResproxyMockURLProtocol: URLProtocol {
8+
nonisolated(unsafe) static var mockResponses: [String: Data] = [:]
9+
10+
override class func canInit(with request: URLRequest) -> Bool {
11+
guard let url = request.url?.absoluteString else { return false }
12+
return mockResponses.keys.contains(url)
13+
}
14+
15+
override class func canonicalRequest(for request: URLRequest) -> URLRequest {
16+
return request
17+
}
18+
19+
override func startLoading() {
20+
guard let url = request.url?.absoluteString,
21+
let data = ResproxyMockURLProtocol.mockResponses[url] else {
22+
client?.urlProtocol(self, didFailWithError: NSError(domain: "ResproxyMockURLProtocol", code: 404))
23+
return
24+
}
25+
26+
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: ["Content-Type": "application/json"])!
27+
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
28+
client?.urlProtocol(self, didLoad: data)
29+
client?.urlProtocolDidFinishLoading(self)
30+
}
31+
32+
override func stopLoading() {}
33+
}
34+
535
@MainActor
636
struct ResproxyTests {
37+
738
@Test func resproxyTest() async throws {
39+
// Set up mock response
40+
let mockData = """
41+
{"ip":"175.107.211.204","last_seen":"2025-01-20","percent_days_seen":0.85,"service":"example_service"}
42+
""".data(using: .utf8)!
43+
ResproxyMockURLProtocol.mockResponses["https://ipinfo.io/resproxy/175.107.211.204"] = mockData
44+
45+
// Configure mock session for this test
46+
let configuration = URLSessionConfiguration.ephemeral
47+
configuration.protocolClasses = [ResproxyMockURLProtocol.self]
48+
let mockSession = Session(configuration: configuration)
49+
Service.shared.session = mockSession
50+
851
let response = try await withCheckedThrowingContinuation { continuation in
952
IPINFO.shared.getResproxy(ip: "175.107.211.204") { status, response, msg in
1053
switch status {
@@ -26,13 +69,26 @@ struct ResproxyTests {
2669
}
2770
}
2871

72+
Service.shared.session = nil
73+
ResproxyMockURLProtocol.mockResponses.removeAll()
74+
2975
#expect(response.ip == "175.107.211.204")
30-
#expect(response.lastSeen != nil)
31-
#expect(response.percentDaysSeen != nil)
32-
#expect(response.service != nil)
76+
#expect(response.lastSeen == "2025-01-20")
77+
#expect(response.percentDaysSeen == 0.85)
78+
#expect(response.service == "example_service")
3379
}
3480

3581
@Test func resproxyEmptyTest() async throws {
82+
// Set up mock response for empty result
83+
let mockData = "{}".data(using: .utf8)!
84+
ResproxyMockURLProtocol.mockResponses["https://ipinfo.io/resproxy/8.8.8.8"] = mockData
85+
86+
// Configure mock session for this test
87+
let configuration = URLSessionConfiguration.ephemeral
88+
configuration.protocolClasses = [ResproxyMockURLProtocol.self]
89+
let mockSession = Session(configuration: configuration)
90+
Service.shared.session = mockSession
91+
3692
let response = try await withCheckedThrowingContinuation { continuation in
3793
IPINFO.shared.getResproxy(ip: "8.8.8.8") { status, response, msg in
3894
switch status {
@@ -54,6 +110,9 @@ struct ResproxyTests {
54110
}
55111
}
56112

113+
Service.shared.session = nil
114+
ResproxyMockURLProtocol.mockResponses.removeAll()
115+
57116
#expect(response.ip == nil)
58117
#expect(response.lastSeen == nil)
59118
#expect(response.percentDaysSeen == nil)

0 commit comments

Comments
 (0)