Archived
feat: center square Hope presence and guide secure certificate setup
This commit is contained in:
1 parent
6f2659421c
commit
15c6389ffb
12 files changed
+252
-129
No files matched your search
@@ -28,6 +28,14 @@ struct AuthTests {
|
||||
config.protocolClasses = [AuthURLProtocol.self]
|
||||
return URLSession(configuration: config)
|
||||
}
|
||||
@Test func certificateFailureHasSafeRecovery() throws {
|
||||
let url = URL(string: "https://192.168.86.2:9178")!
|
||||
let message = ConnectionFailure.message(URLError(.serverCertificateUntrusted), server: url)
|
||||
#expect(message.contains("192.168.86.2"))
|
||||
#expect(message.contains("Certificate Trust Settings"))
|
||||
#expect(!message.contains("disable"))
|
||||
#expect(ConnectionFailure.message(AuthError.status(401), server: url).contains("username and password"))
|
||||
}
|
||||
@Test func canonicalOriginsAndSecureIPv6() throws {
|
||||
let parsed = try config(" HTTPS://EXAMPLE.COM:443/path ")
|
||||
#expect(parsed.baseURL.absoluteString == "https://example.com")
|
||||
|
||||
@@ -85,6 +85,39 @@ struct ConversationStateTests {
|
||||
#expect(!model.isThinkingChipVisible)
|
||||
}
|
||||
|
||||
@Test("square LED presence responds to input and emphasizes assistant output")
|
||||
func ledPresenceAudioResponse() {
|
||||
let quiet = LightwellView.dot(row: 10, column: 10, phase: .listening(level: 0), time: 0, reduceMotion: false)
|
||||
let listening = LightwellView.dot(row: 10, column: 10, phase: .listening(level: 0.8), time: 0, reduceMotion: false)
|
||||
let speaking = LightwellView.dot(row: 10, column: 10, phase: .speaking(level: 0.8), time: 0, reduceMotion: false)
|
||||
#expect(listening.opacity > quiet.opacity)
|
||||
#expect(listening.scale > quiet.scale)
|
||||
#expect(speaking.opacity > listening.opacity)
|
||||
#expect(speaking.scale > listening.scale)
|
||||
}
|
||||
|
||||
@Test("LED reduce motion freezes audio geometry and pending waves")
|
||||
func ledReduceMotion() {
|
||||
for phase: LightwellView.Phase in [.connecting, .thinking, .speaking(level: 0.8)] {
|
||||
#expect(LightwellView.dot(row: 8, column: 9, phase: phase, time: 0, reduceMotion: true)
|
||||
== LightwellView.dot(row: 8, column: 9, phase: phase, time: 7, reduceMotion: true))
|
||||
}
|
||||
#expect(LightwellView.dot(row: 10, column: 10, phase: .listening(level: 0), time: 0, reduceMotion: true)
|
||||
== LightwellView.dot(row: 10, column: 10, phase: .listening(level: 1), time: 0, reduceMotion: true))
|
||||
}
|
||||
|
||||
@Test("LED state patterns are distinct and invalid signal levels remain bounded")
|
||||
func ledStatePatterns() {
|
||||
let dormant = LightwellView.dot(row: 10, column: 10, phase: .idle, time: 0, reduceMotion: false)
|
||||
let thinking = LightwellView.dot(row: 10, column: 10, phase: .thinking, time: 0, reduceMotion: true)
|
||||
#expect(thinking.opacity > dormant.opacity)
|
||||
for level in [Double.nan, Double.infinity, -1, 10] {
|
||||
let dot = LightwellView.dot(row: 10, column: 10, phase: .speaking(level: level), time: 0, reduceMotion: false)
|
||||
#expect(dot.opacity.isFinite && (0...1).contains(dot.opacity))
|
||||
#expect(dot.scale.isFinite && dot.scale >= 1)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Interruption begin mute decision (Iteration 08 Item 1)
|
||||
|
||||
/// Pure decision seam test: verifies that the interruption-begin mute
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import Voice
|
||||
|
||||
/// Explicit opt-in native CFNetwork probe; no account credentials or bodies.
|
||||
struct TLSLiveTests {
|
||||
@Test func pinnedLANHTTPS() async throws {
|
||||
guard ProcessInfo.processInfo.environment["HOPE_TLS_LIVE"] == "1" else {
|
||||
print("HOPE_TLS_PROBE skipped: explicit live opt-in absent")
|
||||
return
|
||||
}
|
||||
print("HOPE_TLS_PROBE native HTTPS validation started")
|
||||
let (data, response) = try await TLSPinning.session().data(from: URL(string: "https://192.168.86.2:9178/api/auth/me")!)
|
||||
#expect((response as? HTTPURLResponse)?.statusCode == 401)
|
||||
#expect(!data.isEmpty)
|
||||
}
|
||||
|
||||
@Test func nativeAccountLogin() async throws {
|
||||
let env = ProcessInfo.processInfo.environment
|
||||
guard env["HOPE_TLS_LIVE"] == "1", let username = env["HOPE_TEST_USERNAME"],
|
||||
let password = env["HOPE_TEST_PASSWORD"] else { return }
|
||||
print("HOPE_TLS_PROBE native account login started")
|
||||
let config = try ServerConfig.parse("https://192.168.86.2:9178").get()
|
||||
let client = AuthClient(config: config)
|
||||
let login = try await client.login(username: username, password: password)
|
||||
#expect(login.user.username == username)
|
||||
#expect(try await client.me(token: login.token).id == login.user.id)
|
||||
try await client.logout(token: login.token)
|
||||
print("HOPE_TLS_PROBE native login/me/logout completed")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user