import Flutter import UIKit import XCTest @testable import nexo_messaging // Unit tests for the iOS portion of the nexo messaging plugin bridge. // // These cover the minimum iOS method contract and stream handler. They are // deterministic and credential-free; APNs registration, Firebase token // refresh, notification center delegate, ACK, dismiss, and inline reply remain // future smoke/implementation work. // // See https://developer.apple.com/documentation/xctest for more information about using XCTest. class RunnerTests: XCTestCase { private let deviceTokenKey = "nexo.messaging.deviceToken" override func tearDown() { UserDefaults.standard.removeObject(forKey: deviceTokenKey) super.tearDown() } func testGetPlatformVersion() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion) resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testDebugSendNativeEventForwardsPayloadToEventSink() { let plugin = NexoMessagingPlugin() var forwarded: Any? _ = plugin.onListen(withArguments: nil, eventSink: { event in forwarded = event }) let call = FlutterMethodCall(methodName: "debugSendNativeEvent", arguments: [ "type": "opened", "channel_id": "channel-ios", ]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertNil(result) resultExpectation.fulfill() } waitForExpectations(timeout: 1) XCTAssertEqual((forwarded as? [String: Any])?["channel_id"] as? String, "channel-ios") } func testDebugSendNativeEventWithNullPayloadReturnsInvalidArg() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "debugSendNativeEvent", arguments: nil) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertEqual((result as? FlutterError)?.code, "INVALID_ARG") resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testSaveAndGetDeviceToken() { let plugin = NexoMessagingPlugin() let saveCall = FlutterMethodCall(methodName: "saveDeviceToken", arguments: [ "token": "apple_rn-v2:smoke-token", ]) let saveExpectation = expectation(description: "save result block must be called.") plugin.handle(saveCall) { result in XCTAssertNil(result) saveExpectation.fulfill() } let getCall = FlutterMethodCall(methodName: "getDeviceToken", arguments: nil) let getExpectation = expectation(description: "get result block must be called.") plugin.handle(getCall) { result in XCTAssertEqual(result as? String, "apple_rn-v2:smoke-token") getExpectation.fulfill() } waitForExpectations(timeout: 1) } func testSaveDeviceTokenWithNullTokenReturnsInvalidArg() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "saveDeviceToken", arguments: [:]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertEqual((result as? FlutterError)?.code, "INVALID_ARG") resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testSetAuthTokenSuccessNoOp() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "setAuthToken", arguments: [ "serverUrl": "https://smoke.example", "token": "auth-token", ]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertNil(result) resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testSetAuthTokenMissingArgReturnsInvalidArg() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "setAuthToken", arguments: [ "serverUrl": "https://smoke.example", ]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertEqual((result as? FlutterError)?.code, "INVALID_ARG") resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testSetSigningKeySuccessNoOp() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "setSigningKey", arguments: [ "serverUrl": "https://smoke.example", "signingKey": "signing-key", ]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertNil(result) resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testSetSigningKeyMissingArgReturnsInvalidArg() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "setSigningKey", arguments: [ "serverUrl": "https://smoke.example", ]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertEqual((result as? FlutterError)?.code, "INVALID_ARG") resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testClearAuthTokenSuccessNoOp() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "clearAuthToken", arguments: [ "serverUrl": "https://smoke.example", ]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertNil(result) resultExpectation.fulfill() } waitForExpectations(timeout: 1) } func testClearAuthTokenMissingArgReturnsInvalidArg() { let plugin = NexoMessagingPlugin() let call = FlutterMethodCall(methodName: "clearAuthToken", arguments: [:]) let resultExpectation = expectation(description: "result block must be called.") plugin.handle(call) { result in XCTAssertEqual((result as? FlutterError)?.code, "INVALID_ARG") resultExpectation.fulfill() } waitForExpectations(timeout: 1) } }