Files
multi-simadmin/apps/ios/Tests/MultiSimAdminTests/InstanceRepositoryTests.swift
T
chick eb880e0d14 release(ios): 0.2.2 移除分组改用标签归类并完成石墨配色重构
- 删除分组实体:分组视图/编辑器/仓储与 groupId 全部移除,升级首启清理
  instance-groups.json 与 fleet.groupMode
- 新增批量标签表:三态覆盖度(未贴 / N/M / 全部),整批加减与新建标签
- 配色重构,全应用零蓝色:石墨墨色承担主操作与选中态,颜色只留给状态语义;
  浅色改中性冷灰,深色改低明度石墨三层
- 选中态改实心主色 + onPrimary,替换不可读的低透明度色雾(主题块、图例胶囊)
- 应用图标重做为扁平石墨底 + 黄铜 SIM 面板,参数化光栅化脚本与参考稿
- 运行概览:检测进度并入副标题,读数栅格固定八格两行并保留不可用占位
- 实例详情:仪表改两列发丝线栅格,缺数据留轨道,修掉头部高度回弹;
  补齐设备名称/存储总量/可用存储/使用率四个字段名
- 版本号显示去掉括号,设置页只显示 0.2.2
- 文档:新增 docs/ios-native-0.2.2.md,同步 ios-native.md 与两处 README
2026-09-15 02:23:24 +08:00

106 lines
4.0 KiB
Swift

import XCTest
@testable import MultiSimAdmin
final class InstanceRepositoryTests: XCTestCase {
private var location: URL!
override func setUp() {
super.setUp()
location = FileManager.default.temporaryDirectory
.appendingPathComponent("multi-simadmin-\(UUID().uuidString).json")
}
override func tearDown() {
try? FileManager.default.removeItem(at: location)
super.tearDown()
}
func testCreateListUpdateAndDeleteInstance() async throws {
let repository = FileInstanceRepository(location: location)
let input = InstanceInput(
name: "Lab Alpha",
origin: URL(string: "http://192.168.3.55:3000/")!,
tags: ["primary", "lab"],
password: "secret"
)
let created = try await repository.create(input)
XCTAssertEqual(created.name, "Lab Alpha")
XCTAssertEqual(created.origin.absoluteString, "http://192.168.3.55:3000")
XCTAssertEqual(created.tags, ["primary", "lab"])
XCTAssertEqual(created.configRevision, 1)
XCTAssertTrue(created.credentialConfigured)
let patch = InstancePatch(name: "Alpha", tags: ["lab"])
let updated = try await repository.update(created.id, expectedRevision: 1, patch)
XCTAssertEqual(updated.name, "Alpha")
XCTAssertEqual(updated.tags, ["lab"])
XCTAssertEqual(updated.configRevision, 2)
XCTAssertTrue(updated.credentialConfigured)
try await repository.delete(updated.id, expectedRevision: 2)
let afterDelete = try await repository.list(InstanceQuery())
XCTAssertTrue(afterDelete.isEmpty)
}
func testRejectsInvalidOriginDuplicateOriginAndStaleRevision() async throws {
let repository = FileInstanceRepository(location: location)
let origin = URL(string: "http://192.168.1.20:3000")!
let input = InstanceInput(name: "One", origin: origin, tags: [], password: nil)
let first = try await repository.create(input)
do {
let nested = InstanceInput(
name: "Nested",
origin: URL(string: "http://192.168.1.20:3000/admin")!,
tags: [],
password: nil
)
_ = try await repository.create(nested)
XCTFail("Expected nested path rejection")
} catch let error as RepositoryError {
XCTAssertEqual(error, .invalidOrigin)
}
do {
_ = try await repository.create(input)
XCTFail("Expected duplicate-origin failure")
} catch let error as RepositoryError {
XCTAssertEqual(error, .duplicateOrigin)
}
do {
_ = try await repository.update(first.id, expectedRevision: 99, InstancePatch(name: "New"))
XCTFail("Expected stale-revision failure")
} catch let error as RepositoryError {
XCTAssertEqual(error, .revisionConflict)
}
}
func testListFiltersBySearchAndTag() async throws {
let repository = FileInstanceRepository(location: location)
_ = try await repository.create(InstanceInput(
name: "Lab Alpha",
origin: URL(string: "http://192.168.1.10:3000")!,
tags: ["production"],
password: nil
))
_ = try await repository.create(InstanceInput(
name: "Home Beta",
origin: URL(string: "http://192.168.1.20:3000")!,
tags: ["lab"],
password: nil
))
let search = try await repository.list(InstanceQuery(search: "alpha"))
XCTAssertEqual(search.map(\.name), ["Lab Alpha"])
let tagged = try await repository.list(InstanceQuery(tags: ["lab"]))
XCTAssertEqual(tagged.map(\.name), ["Home Beta"])
let production = try await repository.list(InstanceQuery(tags: ["production"]))
XCTAssertEqual(production.map(\.name), ["Lab Alpha"])
let sorted = try await repository.list(InstanceQuery())
XCTAssertEqual(sorted.map(\.name), ["Home Beta", "Lab Alpha"])
}
}