50 lines
4.3 KiB
Swift
50 lines
4.3 KiB
Swift
import XCTest
|
|
@testable import WRNexusInbox
|
|
import Foundation
|
|
#if canImport(FoundationNetworking)
|
|
import FoundationNetworking
|
|
#endif
|
|
private final class StubProtocol: URLProtocol {
|
|
static var handler: ((URLRequest) -> (Int,String))!
|
|
override class func canInit(with request:URLRequest)->Bool {true}
|
|
override class func canonicalRequest(for request:URLRequest)->URLRequest {request}
|
|
override func startLoading() {
|
|
let (status,text)=Self.handler(request)
|
|
client?.urlProtocol(self,didReceive:HTTPURLResponse(url:request.url!,statusCode:status,httpVersion:nil,headerFields:["Content-Type":"application/json"])!,cacheStoragePolicy:.notAllowed)
|
|
client?.urlProtocol(self,didLoad:Data(text.utf8));client?.urlProtocolDidFinishLoading(self)
|
|
}
|
|
override func stopLoading() {}
|
|
}
|
|
private final class Counter: @unchecked Sendable {let lock=NSLock();var count=0;func next()->String{lock.lock();defer{lock.unlock()};count+=1;return "recipient-\(count)"}}
|
|
final class TransportTests:XCTestCase {
|
|
func testAllRecipientOperationsAndTokenRefresh() async throws {
|
|
let config=URLSessionConfiguration.ephemeral;config.protocolClasses=[StubProtocol.self];let session=URLSession(configuration:config);defer{session.invalidateAndCancel()}
|
|
var requests=[URLRequest]();let counter=Counter()
|
|
StubProtocol.handler={request in
|
|
requests.append(request)
|
|
if request.httpMethod=="GET",request.url!.path.hasSuffix("messages") {return (200,#"{"messages":[],"unreadCount":2}"#)}
|
|
if request.httpMethod=="GET",request.url!.path.hasSuffix("preferences") {return (200,##"{"branding":{"displayName":"Acme","brandColor":"#123456","brandTextColor":"#ffffff","logoUrl":null},"deliveryRules":{"timezone":"UTC","quietHours":null,"marketingDailyLimit":null},"preferences":[{"category":"*","in_app_enabled":1,"marketing_enabled":0}],"channelPreferences":[]}"##)}
|
|
if request.httpMethod=="GET",request.url!.path.hasSuffix("devices") {return (200,#"{"devices":[],"mobileDevices":[],"connections":[],"mobileConnections":[]}"#)}
|
|
return (200,#"{"ok":true,"id":"d","revision":2,"replayed":false}"#)
|
|
}
|
|
let c=try InboxClient(endpoint:URL(string:"http://localhost")!,session:session,token:{counter.next()})
|
|
let snapshot=try await c.messages(limit:20);XCTAssertEqual(snapshot.unreadCount,2)
|
|
_=try await c.markRead("m");_=try await c.archive("m")
|
|
let preferences=try await c.preferences();XCTAssertEqual(preferences.preferences[0].inAppEnabled,1);XCTAssertEqual(preferences.branding?.displayName,"Acme")
|
|
try await c.savePreferences(PreferenceInput(category:"*",inAppEnabled:true,marketingEnabled:false,deliveryRules:DeliveryRules(timezone:"UTC")))
|
|
_=try await c.devices();let device=try await c.registerMobilePush(MobileRegistration(connectionId:"c",installationId:"i",name:"Phone",token:"rotated"));XCTAssertEqual(device.revision,2)
|
|
_=try await c.unregisterMobilePush("d");_=try await c.unregisterWebPush("w")
|
|
XCTAssertEqual(requests.count,9);XCTAssertEqual(requests[0].url?.query,"limit=20")
|
|
for (i,r) in requests.enumerated(){XCTAssertEqual(r.value(forHTTPHeaderField:"Authorization"),"Bearer recipient-\(i+1)")}
|
|
let encoded=try JSONSerialization.jsonObject(with:requests[4].httpBody!) as! [String:Any];let rules=encoded["deliveryRules"] as! [String:Any];XCTAssertTrue(rules["quietHours"] is NSNull);XCTAssertNil(encoded["externalChannels"])
|
|
let registration=try JSONSerialization.jsonObject(with:requests[6].httpBody!) as! [String:Any];XCTAssertEqual(registration["action"] as? String,"register-mobile");XCTAssertEqual(registration["installationId"] as? String,"i")
|
|
c.close()
|
|
}
|
|
func testErrorHasCodeAndNoWriteRetry() async throws {
|
|
var requests=0;StubProtocol.handler={_ in requests+=1;return (401,#"{"error":{"code":"recipient-token-invalid","message":"Expired"}}"#)}
|
|
let config=URLSessionConfiguration.ephemeral;config.protocolClasses=[StubProtocol.self];let session=URLSession(configuration:config);defer{session.invalidateAndCancel()}
|
|
let c=try InboxClient(session:session,token:{"expired"});defer{c.close()}
|
|
do {_=try await c.archive("m");XCTFail()} catch let e as InboxError {XCTAssertEqual(e.status,401);XCTAssertEqual(e.code,"recipient-token-invalid")};XCTAssertEqual(requests,1)
|
|
}
|
|
}
|