From ae4c8f5f1c393dd2f2c4ee29c062d316c6de3bf2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 23 Jun 2025 06:21:35 +0200 Subject: [PATCH] test fixes --- ios/VibeTunnel/Utils/Theme.swift | 2 +- .../Views/Sessions/SessionCardView.swift | 2 +- .../Views/Sessions/SessionListView.swift | 55 +++++++++++++++---- .../Services/APIClientTests.swift | 1 + 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/ios/VibeTunnel/Utils/Theme.swift b/ios/VibeTunnel/Utils/Theme.swift index 45cb65c3..a5f764ab 100644 --- a/ios/VibeTunnel/Utils/Theme.swift +++ b/ios/VibeTunnel/Utils/Theme.swift @@ -22,7 +22,7 @@ enum Theme { static let terminalForeground = Color(light: Color(hex: "24292E"), dark: Color(hex: "B3B1AD")) // Accent colors (same for both modes) - static let primaryAccent = Color(hex: "00FF88") // Green accent matching web + static let primaryAccent = Color(light: Color(hex: "22C55E"), dark: Color(hex: "00FF88")) // Darker green for light mode static let secondaryAccent = Color(hex: "59C2FF") static let successAccent = Color(hex: "AAD94C") static let warningAccent = Color(hex: "FFB454") diff --git a/ios/VibeTunnel/Views/Sessions/SessionCardView.swift b/ios/VibeTunnel/Views/Sessions/SessionCardView.swift index 4d60bb2c..ced22b3b 100644 --- a/ios/VibeTunnel/Views/Sessions/SessionCardView.swift +++ b/ios/VibeTunnel/Views/Sessions/SessionCardView.swift @@ -35,7 +35,7 @@ struct SessionCardView: View { VStack(alignment: .leading, spacing: Theme.Spacing.medium) { // Header with session ID/name and kill button HStack { - Text(session.name) + Text(session.displayName) .font(Theme.Typography.terminalSystem(size: 14)) .fontWeight(.medium) .foregroundColor(Theme.Colors.primaryAccent) diff --git a/ios/VibeTunnel/Views/Sessions/SessionListView.swift b/ios/VibeTunnel/Views/Sessions/SessionListView.swift index b5c9dadd..8f8a22bb 100644 --- a/ios/VibeTunnel/Views/Sessions/SessionListView.swift +++ b/ios/VibeTunnel/Views/Sessions/SessionListView.swift @@ -29,7 +29,7 @@ struct SessionListView: View { return sessions.filter { session in // Search in session name - if session.name.localizedCaseInsensitiveContains(searchText) { + if let name = session.name, name.localizedCaseInsensitiveContains(searchText) { return true } // Search in command @@ -275,6 +275,11 @@ struct SessionListView: View { Task { await viewModel.killAllSessions() } + }, + onCleanupAll: { + Task { + await viewModel.cleanupAllExited() + } } ) .padding(.horizontal) @@ -290,13 +295,6 @@ struct SessionListView: View { GridItem(.flexible(), spacing: Theme.Spacing.medium), GridItem(.flexible(), spacing: Theme.Spacing.medium) ], spacing: Theme.Spacing.medium) { - if showExitedSessions && filteredSessions.contains(where: { !$0.isRunning }) { - CleanupAllButton { - Task { - await viewModel.cleanupAllExited() - } - } - } ForEach(filteredSessions) { session in SessionCardView(session: session) { @@ -383,11 +381,11 @@ struct ErrorBanner: View { var body: some View { HStack { Image(systemName: isOffline ? "wifi.slash" : "exclamationmark.triangle") - .foregroundColor(.white) + .foregroundColor(Theme.Colors.terminalBackground) Text(message) .font(Theme.Typography.terminalSystem(size: 14)) - .foregroundColor(.white) + .foregroundColor(Theme.Colors.terminalBackground) .lineLimit(2) Spacer() @@ -493,6 +491,7 @@ struct SessionHeaderView: View { let sessions: [Session] @Binding var showExitedSessions: Bool let onKillAll: () -> Void + let onCleanupAll: () -> Void private var runningCount: Int { sessions.count(where: { $0.isRunning }) } private var exitedCount: Int { sessions.count(where: { !$0.isRunning }) } @@ -524,6 +523,10 @@ struct SessionHeaderView: View { Spacer() + if showExitedSessions && sessions.contains(where: { !$0.isRunning }) { + CleanupAllHeaderButton(onCleanup: onCleanupAll) + } + if sessions.contains(where: \.isRunning) { KillAllButton(onKillAll: onKillAll) } @@ -600,7 +603,7 @@ struct KillAllButton: View { .fontWeight(.medium) } .font(Theme.Typography.terminalSystem(size: 14)) - .foregroundColor(.white) + .foregroundColor(Theme.Colors.terminalBackground) .padding(.horizontal, Theme.Spacing.medium) .padding(.vertical, Theme.Spacing.small) .background( @@ -645,6 +648,36 @@ struct CleanupAllButton: View { } } +struct CleanupAllHeaderButton: View { + let onCleanup: () -> Void + + var body: some View { + Button(action: { + HapticFeedback.impact(.medium) + onCleanup() + }, label: { + HStack(spacing: 6) { + Image(systemName: "trash") + .font(.system(size: 14)) + Text("Clean Up All Exited") + .font(Theme.Typography.terminalSystem(size: 14)) + } + .foregroundColor(Theme.Colors.warningAccent) + .padding(.horizontal, Theme.Spacing.medium) + .padding(.vertical, Theme.Spacing.small) + .background( + RoundedRectangle(cornerRadius: Theme.CornerRadius.medium) + .fill(Theme.Colors.warningAccent.opacity(0.1)) + .overlay( + RoundedRectangle(cornerRadius: Theme.CornerRadius.medium) + .stroke(Theme.Colors.warningAccent.opacity(0.2), lineWidth: 1) + ) + ) + }) + .buttonStyle(PlainButtonStyle()) + } +} + /// Wrapper for cast file URL to make it Identifiable struct CastFileItem: Identifiable { let id = UUID() diff --git a/ios/VibeTunnelTests/Services/APIClientTests.swift b/ios/VibeTunnelTests/Services/APIClientTests.swift index a3cb43cd..1d6ac3dd 100644 --- a/ios/VibeTunnelTests/Services/APIClientTests.swift +++ b/ios/VibeTunnelTests/Services/APIClientTests.swift @@ -198,6 +198,7 @@ struct APIClientTests { // MARK: - Error Handling Tests @Test("Handles 404 error correctly") + @MainActor func handle404Error() async throws { // Arrange MockURLProtocol.requestHandler = { request in