test fixes

This commit is contained in:
Peter Steinberger 2025-06-23 06:21:35 +02:00
parent ed8c5b70cf
commit ae4c8f5f1c
4 changed files with 47 additions and 13 deletions

View file

@ -22,7 +22,7 @@ enum Theme {
static let terminalForeground = Color(light: Color(hex: "24292E"), dark: Color(hex: "B3B1AD")) static let terminalForeground = Color(light: Color(hex: "24292E"), dark: Color(hex: "B3B1AD"))
// Accent colors (same for both modes) // 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 secondaryAccent = Color(hex: "59C2FF")
static let successAccent = Color(hex: "AAD94C") static let successAccent = Color(hex: "AAD94C")
static let warningAccent = Color(hex: "FFB454") static let warningAccent = Color(hex: "FFB454")

View file

@ -35,7 +35,7 @@ struct SessionCardView: View {
VStack(alignment: .leading, spacing: Theme.Spacing.medium) { VStack(alignment: .leading, spacing: Theme.Spacing.medium) {
// Header with session ID/name and kill button // Header with session ID/name and kill button
HStack { HStack {
Text(session.name) Text(session.displayName)
.font(Theme.Typography.terminalSystem(size: 14)) .font(Theme.Typography.terminalSystem(size: 14))
.fontWeight(.medium) .fontWeight(.medium)
.foregroundColor(Theme.Colors.primaryAccent) .foregroundColor(Theme.Colors.primaryAccent)

View file

@ -29,7 +29,7 @@ struct SessionListView: View {
return sessions.filter { session in return sessions.filter { session in
// Search in session name // Search in session name
if session.name.localizedCaseInsensitiveContains(searchText) { if let name = session.name, name.localizedCaseInsensitiveContains(searchText) {
return true return true
} }
// Search in command // Search in command
@ -275,6 +275,11 @@ struct SessionListView: View {
Task { Task {
await viewModel.killAllSessions() await viewModel.killAllSessions()
} }
},
onCleanupAll: {
Task {
await viewModel.cleanupAllExited()
}
} }
) )
.padding(.horizontal) .padding(.horizontal)
@ -290,13 +295,6 @@ struct SessionListView: View {
GridItem(.flexible(), spacing: Theme.Spacing.medium), GridItem(.flexible(), spacing: Theme.Spacing.medium),
GridItem(.flexible(), spacing: Theme.Spacing.medium) GridItem(.flexible(), spacing: Theme.Spacing.medium)
], spacing: Theme.Spacing.medium) { ], spacing: Theme.Spacing.medium) {
if showExitedSessions && filteredSessions.contains(where: { !$0.isRunning }) {
CleanupAllButton {
Task {
await viewModel.cleanupAllExited()
}
}
}
ForEach(filteredSessions) { session in ForEach(filteredSessions) { session in
SessionCardView(session: session) { SessionCardView(session: session) {
@ -383,11 +381,11 @@ struct ErrorBanner: View {
var body: some View { var body: some View {
HStack { HStack {
Image(systemName: isOffline ? "wifi.slash" : "exclamationmark.triangle") Image(systemName: isOffline ? "wifi.slash" : "exclamationmark.triangle")
.foregroundColor(.white) .foregroundColor(Theme.Colors.terminalBackground)
Text(message) Text(message)
.font(Theme.Typography.terminalSystem(size: 14)) .font(Theme.Typography.terminalSystem(size: 14))
.foregroundColor(.white) .foregroundColor(Theme.Colors.terminalBackground)
.lineLimit(2) .lineLimit(2)
Spacer() Spacer()
@ -493,6 +491,7 @@ struct SessionHeaderView: View {
let sessions: [Session] let sessions: [Session]
@Binding var showExitedSessions: Bool @Binding var showExitedSessions: Bool
let onKillAll: () -> Void let onKillAll: () -> Void
let onCleanupAll: () -> Void
private var runningCount: Int { sessions.count(where: { $0.isRunning }) } private var runningCount: Int { sessions.count(where: { $0.isRunning }) }
private var exitedCount: Int { sessions.count(where: { !$0.isRunning }) } private var exitedCount: Int { sessions.count(where: { !$0.isRunning }) }
@ -524,6 +523,10 @@ struct SessionHeaderView: View {
Spacer() Spacer()
if showExitedSessions && sessions.contains(where: { !$0.isRunning }) {
CleanupAllHeaderButton(onCleanup: onCleanupAll)
}
if sessions.contains(where: \.isRunning) { if sessions.contains(where: \.isRunning) {
KillAllButton(onKillAll: onKillAll) KillAllButton(onKillAll: onKillAll)
} }
@ -600,7 +603,7 @@ struct KillAllButton: View {
.fontWeight(.medium) .fontWeight(.medium)
} }
.font(Theme.Typography.terminalSystem(size: 14)) .font(Theme.Typography.terminalSystem(size: 14))
.foregroundColor(.white) .foregroundColor(Theme.Colors.terminalBackground)
.padding(.horizontal, Theme.Spacing.medium) .padding(.horizontal, Theme.Spacing.medium)
.padding(.vertical, Theme.Spacing.small) .padding(.vertical, Theme.Spacing.small)
.background( .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 /// Wrapper for cast file URL to make it Identifiable
struct CastFileItem: Identifiable { struct CastFileItem: Identifiable {
let id = UUID() let id = UUID()

View file

@ -198,6 +198,7 @@ struct APIClientTests {
// MARK: - Error Handling Tests // MARK: - Error Handling Tests
@Test("Handles 404 error correctly") @Test("Handles 404 error correctly")
@MainActor
func handle404Error() async throws { func handle404Error() async throws {
// Arrange // Arrange
MockURLProtocol.requestHandler = { request in MockURLProtocol.requestHandler = { request in