Files

90 lines
3.5 KiB
Swift

import XCTest
@testable import ShadowsocksX_NG2
/// SettingsWorkflow 与真实 ProxyRuntimeController 的监听设置提交集成。
@MainActor
final class SettingsWorkflowTests: XCTestCase {
private var runtime: ProxyRuntimeFixture.TemporaryRuntime!
private var catalogFileURL: URL!
private var activationFileURL: URL!
private var agent: ProxyRuntimeFixture.FakeLaunchAgent!
private var systemProxy: ProxyRuntimeFixture.FakeSystemProxy!
private var listeningStore: InMemorySettingsStore!
override func setUp() async throws {
try await super.setUp()
runtime = ProxyRuntimeFixture.makeTemporaryRuntime()
catalogFileURL = runtime.directory.appendingPathComponent("catalog.json")
activationFileURL = runtime.directory.appendingPathComponent("activation.json")
agent = ProxyRuntimeFixture.FakeLaunchAgent()
systemProxy = ProxyRuntimeFixture.FakeSystemProxy()
listeningStore = InMemorySettingsStore()
}
override func tearDown() async throws {
try? FileManager.default.removeItem(at: runtime.directory)
try await super.tearDown()
}
func testListenerModeSavePersistsWithoutStartingAnOffAgent() async throws {
let pair = makePair()
var draft = pair.workflow.beginLANListeningEditing()
draft.isEnabled = true
draft.mode = .allIPv4AndIPv6Interfaces
let outcome = await pair.workflow.saveLANListening(draft)
XCTAssertEqual(outcome, .persisted)
XCTAssertEqual(pair.controller.settings.listen.listenerMode, .allIPv4AndIPv6Interfaces)
XCTAssertEqual(listeningStore.saved?.listenerMode, .allIPv4AndIPv6Interfaces)
XCTAssertEqual(pair.controller.state, .off)
XCTAssertEqual(agent.registerCount, 0)
}
private func makePair() -> (controller: ProxyRuntimeController, workflow: SettingsWorkflow) {
let catalogSnapshotReader = CatalogCommitCoordinator.bootstrap(
fileStore: makeTestCatalogStore(fileURL: catalogFileURL)
).catalogSnapshotReader
let runtimeFileStore = RuntimeFileStore(fileURL: runtime.contract)
agent.onRegister = { [runtimeFileStore] in
try? runtimeFileStore.writePublishedRuntimeReceipt(processID: 42)
}
let controller = ProxyRuntimeController(
controlPreferences: makeTestProxyControlPreferences(),
catalogSnapshotReader: catalogSnapshotReader,
activationFileStore: ActivationStateFileStore(fileURL: activationFileURL),
runtimeFileStore: runtimeFileStore,
plugins: ActivationFixture.plugins,
listeningStore: listeningStore,
appBundle: AppArtifact.bundle,
settingsRestore: RestoredProxyRuntimeSettings(
settings: ProxyRuntimeSettings(listen: ActivationFixture.listen), unreadableError: nil),
agent: agent,
probe: ProxyRuntimeFixture.FakeProbe.reachable(),
systemProxy: systemProxy,
systemProxyHelper: ProxyRuntimeFixture.FakeSystemProxyHelperService(),
firewallExecutableURLs: [URL(fileURLWithPath: "/bundle/Helpers/sslocal")],
firewallPollIntervalNanoseconds: 1_000_000,
launchHealthTimeoutSeconds: 0.05,
sendSignal: { _, _ in 0 },
processIsAlive: { $0 == 42 })
let workflow = SettingsWorkflow(
committing: controller, occupancyProbe: FakeOccupancyProbe())
return (controller, workflow)
}
final class InMemorySettingsStore: ProxyListeningStoring {
var saved: ProxyListeningConfiguration?
func load() throws -> ProxyListeningConfiguration {
saved ?? ProxyListeningConfiguration()
}
func save(_ settings: ProxyListeningConfiguration) throws {
saved = settings
}
}
}