test(apple): CoreGateway seam, XCTest suite, and CI

- Introduce a CoreGateway protocol so feature models depend on a seam
  (CoreRepository conforms); enables faking the core in tests
- Add a VniDropTests target with 42 tests mirroring the KMP suites:
  approval coordinator, send/receive/settings/app models, preferences,
  file previews, invitation decode, message queue, error mapping
- Add a fake gateway/file-system/device-info and fixtures
- Add .github/workflows/apple.yml: build the Rust core, generate the
  project, and run the tests on an iOS Simulator
This commit is contained in:
2026-07-19 23:48:11 +02:00
parent e35c8c840a
commit 17099d32f2
23 changed files with 771 additions and 20 deletions

View File

@@ -0,0 +1,41 @@
import XCTest
@testable import VniDrop
/// Ports app-level assertions: core initialization on launch, destination
/// selection guard, and theme following preferences.
@MainActor
final class AppModelTests: XCTestCase {
private func makeModel(_ core: FakeCoreGateway, preferences: AppPreferencesRepository) -> AppModel {
AppModel(
environment: PlatformEnvironment(name: "Test", appVersion: "0.1.0", defaultCoreDataDir: NSTemporaryDirectory()),
repository: core,
preferences: preferences,
messages: UiMessageController()
)
}
func testInitializesCoreOnLaunch() async {
let core = FakeCoreGateway()
_ = makeModel(core, preferences: Fixtures.preferences())
await waitUntil { core.state.isInitialized }
XCTAssertTrue(core.state.isInitialized)
}
func testSelectDestination() {
let model = makeModel(FakeCoreGateway(), preferences: Fixtures.preferences())
XCTAssertEqual(model.destination, .send)
model.selectDestination(.settings)
XCTAssertEqual(model.destination, .settings)
model.selectDestination(.settings) // no-op guard
XCTAssertEqual(model.destination, .settings)
}
func testThemeModeFollowsPreferences() async {
let prefs = Fixtures.preferences()
let model = makeModel(FakeCoreGateway(), preferences: prefs)
prefs.setThemeMode(.dark)
await waitUntil { model.themeMode == .dark }
XCTAssertEqual(model.themeMode, .dark)
}
}