Fixes logic for displaying CloudNotificationBanner and adjusts tests

This commit is contained in:
Bruno Bergher 2025-08-05 21:59:41 +01:00
parent 5871cce9d3
commit ea43c87f7f
3 changed files with 44 additions and 11 deletions

View file

@ -1,6 +1,7 @@
import { useTranslation } from "react-i18next"
import { Lightbulb, X } from "lucide-react"
import { cn } from "@src/lib/utils"
import { vscode } from "@src/utils/vscode"
interface CloudNotificationBannerProps {
onDismiss: () => void
@ -14,16 +15,20 @@ export const CloudNotificationBanner = ({ onDismiss, className }: CloudNotificat
onDismiss()
}
const handleClick = () => {
const handleNavigate = () => {
vscode.postMessage({ type: "switchTab", tab: "account" })
handleDismiss()
}
return (
<div className={cn("bg-vscode-badge-background relative z-50", className)}>
<div
className={cn("bg-vscode-badge-background relative z-50", className)}
data-testid="cloud-notification-banner">
{/* Main notification container with speech bubble */}
<div
className="relative text-vscode-badge-foreground p-2 rounded-md cursor-pointer transition-colors"
onClick={handleClick}>
onClick={handleNavigate}
data-testid="navigate-button">
{/* Speech bubble triangle */}
<div
className="absolute bg-vscode-badge-background w-3 h-1.5"
@ -46,7 +51,8 @@ export const CloudNotificationBanner = ({ onDismiss, className }: CloudNotificat
handleDismiss()
}}
className="cursor-pointer"
aria-label="Close notification">
aria-label="Close notification"
data-testid="dismiss-button">
<X size={14} className="text-vscode-badge-foreground" />
</button>
</div>

View file

@ -70,12 +70,12 @@ const TaskHeader = ({
// Show notification if task has been running for more than 2 minutes
// and hasn't been dismissed for this task
const shouldShow = duration > threshold && !dismissedCloudNotifications.has(taskId)
const shouldShow = duration > threshold && !dismissedCloudNotifications.has(taskId) && buttonsDisabled
setShowCloudNotification(shouldShow)
}, 1000)
return () => clearInterval(interval)
}, [task.ts, currentTaskItem?.id, dismissedCloudNotifications])
}, [task.ts, currentTaskItem?.id, dismissedCloudNotifications, buttonsDisabled])
const handleDismissCloudNotification = () => {
if (currentTaskItem?.id) {

View file

@ -110,7 +110,7 @@ describe("TaskHeader Cloud Notification", () => {
tokensOut: 50,
totalCost: 0.05,
contextTokens: 1000,
buttonsDisabled: false,
buttonsDisabled: true,
handleCondenseContext: vi.fn(),
}
@ -146,6 +146,7 @@ describe("TaskHeader Cloud Notification", () => {
const taskStartTime = Date.now() - 3 * 60 * 1000 // 3 minutes ago
renderTaskHeader({
task: { type: "say", ts: taskStartTime, text: "Test task", images: [] },
buttonsDisabled: true, // Task is still running
})
// Fast-forward timers to trigger the interval
@ -162,6 +163,7 @@ describe("TaskHeader Cloud Notification", () => {
const taskStartTime = Date.now() - 1 * 60 * 1000 // 1 minute ago
renderTaskHeader({
task: { type: "say", ts: taskStartTime, text: "Test task", images: [] },
buttonsDisabled: true, // Task is still running
})
// Fast-forward timers to trigger the interval
@ -180,6 +182,24 @@ describe("TaskHeader Cloud Notification", () => {
renderTaskHeader({
task: { type: "say", ts: taskStartTime, text: "Test task", images: [] },
buttonsDisabled: true, // Task is still running
})
// Fast-forward timers to trigger the interval
act(() => {
vi.advanceTimersByTime(1000)
})
await waitFor(() => {
expect(screen.queryByTestId("cloud-notification-banner")).not.toBeInTheDocument()
})
})
it("does not show cloud notification for completed tasks (buttonsDisabled: false)", async () => {
const taskStartTime = Date.now() - 3 * 60 * 1000 // 3 minutes ago
renderTaskHeader({
task: { type: "say", ts: taskStartTime, text: "Test task", images: [] },
buttonsDisabled: false, // Task is completed/not running
})
// Fast-forward timers to trigger the interval
@ -196,6 +216,7 @@ describe("TaskHeader Cloud Notification", () => {
const taskStartTime = Date.now() - 3 * 60 * 1000 // 3 minutes ago
renderTaskHeader({
task: { type: "say", ts: taskStartTime, text: "Test task", images: [] },
buttonsDisabled: true, // Task is still running
})
// Expand the task to see TaskActions
@ -219,6 +240,7 @@ describe("TaskHeader Cloud Notification", () => {
const taskStartTime = Date.now() - 3 * 60 * 1000 // 3 minutes ago
renderTaskHeader({
task: { type: "say", ts: taskStartTime, text: "Test task", images: [] },
buttonsDisabled: true, // Task is still running
})
// Fast-forward timers to trigger the interval
@ -244,6 +266,7 @@ describe("TaskHeader Cloud Notification", () => {
const taskStartTime = Date.now() - 3 * 60 * 1000 // 3 minutes ago
renderTaskHeader({
task: { type: "say", ts: taskStartTime, text: "Test task", images: [] },
buttonsDisabled: true, // Task is still running
})
// Fast-forward timers to trigger the interval
@ -279,6 +302,7 @@ describe("TaskHeader Cloud Notification", () => {
it("updates duration tracking when task changes", async () => {
const { rerender } = renderTaskHeader({
task: { type: "say", ts: Date.now() - 1 * 60 * 1000, text: "Test task", images: [] },
buttonsDisabled: true, // Task is still running
})
// Fast-forward timers
@ -292,10 +316,13 @@ describe("TaskHeader Cloud Notification", () => {
// Update task to be older
rerender(
<QueryClientProvider client={queryClient}>
<TaskHeader
{...defaultProps}
task={{ type: "say", ts: Date.now() - 3 * 60 * 1000, text: "Test task", images: [] }}
/>
<TooltipProvider>
<TaskHeader
{...defaultProps}
task={{ type: "say", ts: Date.now() - 3 * 60 * 1000, text: "Test task", images: [] }}
buttonsDisabled={true} // Task is still running
/>
</TooltipProvider>
</QueryClientProvider>,
)