Files
WRNexus-Mobile-SDKs/Tests/WRNexusInboxTests/TransportTests.swift
T

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)
}
}