feat(ios): add cross-instance notification center
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import XCTest
|
||||
|
||||
@testable import MultiSimAdmin
|
||||
|
||||
@MainActor
|
||||
final class NotificationsViewModelTests: XCTestCase {
|
||||
func testRefreshLoadsInstancesAndAggregatedOverview() async throws {
|
||||
let repository = MemoryInstanceRepository()
|
||||
let client = NotificationViewModelClient()
|
||||
let service = NotificationService(client: client, sessions: InstanceSessionStore())
|
||||
let model = NotificationsViewModel(repository: repository, service: service)
|
||||
_ = try await repository.create(InstanceInput(
|
||||
name: "Notification Node",
|
||||
origin: URL(string: "http://192.168.1.20:3000")!,
|
||||
tags: [],
|
||||
password: nil
|
||||
))
|
||||
|
||||
await model.refresh()
|
||||
|
||||
XCTAssertEqual(model.instances.count, 1)
|
||||
XCTAssertEqual(model.overview?.devices.first?.state, .ready)
|
||||
XCTAssertEqual(model.overview?.queue.items.first?.id, "queue-1")
|
||||
XCTAssertNil(model.errorMessage)
|
||||
}
|
||||
|
||||
func testRetryQueueTargetsOwningInstance() async throws {
|
||||
let repository = MemoryInstanceRepository()
|
||||
let client = NotificationViewModelClient()
|
||||
let service = NotificationService(client: client, sessions: InstanceSessionStore())
|
||||
let model = NotificationsViewModel(repository: repository, service: service)
|
||||
_ = try await repository.create(InstanceInput(
|
||||
name: "Notification Node",
|
||||
origin: URL(string: "http://192.168.1.20:3000")!,
|
||||
tags: [],
|
||||
password: nil
|
||||
))
|
||||
await model.refresh()
|
||||
let item = try XCTUnwrap(model.overview?.queue.items.first)
|
||||
|
||||
await model.retryQueue(item)
|
||||
|
||||
XCTAssertEqual(client.routes.last, .notificationRetryQueue(id: "queue-1"))
|
||||
}
|
||||
|
||||
func testRetryAllTargetsEveryInstance() async throws {
|
||||
let repository = MemoryInstanceRepository()
|
||||
let client = NotificationViewModelClient()
|
||||
let service = NotificationService(client: client, sessions: InstanceSessionStore())
|
||||
let model = NotificationsViewModel(repository: repository, service: service)
|
||||
_ = try await repository.create(InstanceInput(
|
||||
name: "First",
|
||||
origin: URL(string: "http://192.168.1.20:3000")!,
|
||||
tags: [],
|
||||
password: nil
|
||||
))
|
||||
_ = try await repository.create(InstanceInput(
|
||||
name: "Second",
|
||||
origin: URL(string: "http://192.168.1.21:3000")!,
|
||||
tags: [],
|
||||
password: nil
|
||||
))
|
||||
await model.refresh()
|
||||
|
||||
await model.retryAll()
|
||||
|
||||
XCTAssertEqual(client.routes.filter { $0 == .notificationRetryAllQueue }.count, 2)
|
||||
}
|
||||
}
|
||||
|
||||
private final class NotificationViewModelClient: SimAdminClientProtocol, @unchecked Sendable {
|
||||
var routes: [UpstreamRoute] = []
|
||||
|
||||
func send(_ route: UpstreamRoute, baseURL: URL, cookie: String?) async throws -> UpstreamResponse {
|
||||
routes.append(route)
|
||||
switch route {
|
||||
case .notificationConfig:
|
||||
return Self.response(#"{"status":"ok","data":{"channels":[{"type":"webhook","enabled":true}]}}"#)
|
||||
case .notificationLogs:
|
||||
return Self.response(#"{"status":"ok","data":{"total":1,"logs":[{"id":"log-1","event_type":"system","status":"success","created_at":"2026-09-08T10:00:00Z"}]}}"#)
|
||||
case .notificationQueue:
|
||||
return Self.response(#"{"status":"ok","data":{"total":1,"items":[{"id":"queue-1","event_type":"system","status":"failed","created_at":"2026-09-08T10:00:00Z"}]}}"#)
|
||||
default:
|
||||
return Self.response(#"{"status":"ok"}"#)
|
||||
}
|
||||
}
|
||||
|
||||
private static func response(_ json: String) -> UpstreamResponse {
|
||||
UpstreamResponse(status: 200, data: Data(json.utf8))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user