spb/poche Public
Agent personnel 100 % on-device — SwiftUI + Apple Foundation Models + EventKit + SwiftData. Aucune API, aucun serveur.
Swift 100%
1//2// NetworkIsolationTests.swift3// PocheTests4//5// Author: Simon-Pierre Boucher6// Contact: contact@spboucher.ai7//89import Foundation10import SwiftData11import Testing12@testable import Poche1314/// CLAUDE.md §7: no network request of any kind in the agent path. This15/// tripwire registers a URLProtocol spy on the default URL loading system16/// and fails if anything in the exercised path issues a request.17/// (It cannot see custom-configuration sessions — but Poche must not18/// create any URLSession at all, so any hit here is already a breach.)19final class NetworkSpyProtocol: URLProtocol {20 // Test-serial access only.21 nonisolated(unsafe) static var requestCount = 02223 override class func canInit(with request: URLRequest) -> Bool {24 requestCount += 125 return false26 }2728 override class func canonicalRequest(for request: URLRequest) -> URLRequest {29 request30 }31}3233@MainActor34struct NetworkIsolationTests {35 @Test func agentToolPathMakesNoNetworkRequest() async throws {36 NetworkSpyProtocol.requestCount = 037 URLProtocol.registerClass(NetworkSpyProtocol.self)38 defer { URLProtocol.unregisterClass(NetworkSpyProtocol.self) }3940 let container = try ModelContainer(41 for: Note.self, TaskItem.self, ConversationRecord.self, TurnRecord.self,42 configurations: ModelConfiguration(isStoredInMemoryOnly: true)43 )44 let store = PocheStore(container: container)45 let index = SemanticIndex()46 let executor = ActionExecutor(bridge: EventKitBridge(), store: store)47 let confirm = ConfirmCenter(executor: executor)4849 // Exercise validation, proposal, store writes and semantic search.50 let reminderTool = CreateReminderTool(confirm: confirm)51 _ = try await reminderTool.call(52 arguments: .init(title: "Test réseau", dueDate: "2030-06-01T10:00:00", list: nil)53 )5455 store.addNote(title: "Idée", content: "Comparer les embeddings locaux")56 let searchTool = SearchMyDataTool(store: store, index: index)57 _ = try await searchTool.call(arguments: .init(query: "embeddings"))5859 #expect(NetworkSpyProtocol.requestCount == 0)60 }61}62