fix(ios): improve fleet overview and app identity

- Show stable group health in a fixed 2x2 metric grid
- Add link-chain state to fleet cards and parse hardware/control/SIM/cellular
- Replace the wrapped icon with a full-bleed app icon
- Bump the IPA build number
This commit is contained in:
chick
2026-09-13 00:46:26 +08:00
parent 409345cba3
commit 2ff23d1fb0
23 changed files with 3600 additions and 269 deletions
@@ -22,6 +22,28 @@ final class DeviceServiceTests: XCTestCase {
XCTAssertEqual(snapshot.sections[5].values["state"], "connected")
}
func testBuildsRunningSummaryFromUpstreamSections() async throws {
let store = InstanceSessionStore()
let client = DeviceTestClient()
let service = DeviceService(client: client, sessions: store)
let instance = Self.instance()
await store.set(instance.id, origin: instance.origin, cookie: "simadmin_session=token")
let summary = try await service.summary(instance)
XCTAssertEqual(summary.deviceName, "SIMBox 8")
XCTAssertEqual(summary.phoneNumber, "13800138000")
XCTAssertEqual(summary.operatorName, "中国移动")
XCTAssertEqual(summary.connectivity, "connected")
XCTAssertEqual(summary.firmwareVersion, "2.4.1")
XCTAssertEqual(summary.totalStorageBytes, 1024)
XCTAssertEqual(summary.availableStorageBytes, 512)
XCTAssertEqual(summary.downloadRateBytesPerSecond, 128)
XCTAssertEqual(summary.uploadRateBytesPerSecond, 64)
XCTAssertEqual(summary.messagesToday, 12)
XCTAssertEqual(summary.uptimeSeconds, 86400)
}
private static func instance() -> Instance {
Instance(
id: UUID(),
@@ -43,12 +65,12 @@ private final class DeviceTestClient: SimAdminClientProtocol, @unchecked Sendabl
throw UpstreamError.unauthorized
}
let payload: [UpstreamRoute: String] = [
.device: #"{"data":{"model":"SIMBox 8","online":true}}"#,
.device: #"{"data":{"model":"SIMBox 8","online":true,"firmware_version":"2.4.1"}}"#,
.sim: #"{"data":{"phone_numbers":["13800138000"],"iccid":"123"}}"#,
.network: #"{"data":{"operator_name":"中国移动","registration_status":"registered"}}"#,
.stats: #"{"data":{"uptime":{"uptime_seconds":86400}}}"#,
.stats: #"{"data":{"uptime":{"uptime_seconds":86400},"disk_total_bytes":1024,"disk_available_bytes":512}}"#,
.statsCpu: #"{"data":{"core_count":4,"model_name":"ARM CPU"}}"#,
.connectivity: #"{"data":{"state":"connected","latency_ms":21}}"#
.connectivity: #"{"data":{"state":"connected","latency_ms":21,"download":128,"upload":64,"messages_today":12}}"#
]
guard let json = payload[route] else {
throw UpstreamError.notSupported