Skip to content

Commit efdc3a8

Browse files
committed
ChatView tests
1 parent 42715c1 commit efdc3a8

File tree

1 file changed

+244
-0
lines changed

1 file changed

+244
-0
lines changed

webview-ui/src/components/chat/__tests__/ChatView.test.tsx

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,3 +547,247 @@ describe('ChatView - Auto Approval Tests', () => {
547547
})
548548
})
549549
})
550+
551+
describe('ChatView - Sound Playing Tests', () => {
552+
beforeEach(() => {
553+
jest.clearAllMocks()
554+
})
555+
556+
it('does not play sound for auto-approved browser actions', async () => {
557+
render(
558+
<ExtensionStateContextProvider>
559+
<ChatView
560+
isHidden={false}
561+
showAnnouncement={false}
562+
hideAnnouncement={() => {}}
563+
showHistoryView={() => {}}
564+
/>
565+
</ExtensionStateContextProvider>
566+
)
567+
568+
// First hydrate state with initial task and streaming
569+
mockPostMessage({
570+
alwaysAllowBrowser: true,
571+
clineMessages: [
572+
{
573+
type: 'say',
574+
say: 'task',
575+
ts: Date.now() - 2000,
576+
text: 'Initial task'
577+
},
578+
{
579+
type: 'say',
580+
say: 'api_req_started',
581+
ts: Date.now() - 1000,
582+
text: JSON.stringify({}),
583+
partial: true
584+
}
585+
]
586+
})
587+
588+
// Then send the browser action ask message (streaming finished)
589+
mockPostMessage({
590+
alwaysAllowBrowser: true,
591+
clineMessages: [
592+
{
593+
type: 'say',
594+
say: 'task',
595+
ts: Date.now() - 2000,
596+
text: 'Initial task'
597+
},
598+
{
599+
type: 'ask',
600+
ask: 'browser_action_launch',
601+
ts: Date.now(),
602+
text: JSON.stringify({ action: 'launch', url: 'http://example.com' }),
603+
partial: false
604+
}
605+
]
606+
})
607+
608+
// Verify no sound was played
609+
expect(vscode.postMessage).not.toHaveBeenCalledWith({
610+
type: 'playSound',
611+
audioType: expect.any(String)
612+
})
613+
})
614+
615+
it('plays notification sound for non-auto-approved browser actions', async () => {
616+
render(
617+
<ExtensionStateContextProvider>
618+
<ChatView
619+
isHidden={false}
620+
showAnnouncement={false}
621+
hideAnnouncement={() => {}}
622+
showHistoryView={() => {}}
623+
/>
624+
</ExtensionStateContextProvider>
625+
)
626+
627+
// First hydrate state with initial task and streaming
628+
mockPostMessage({
629+
alwaysAllowBrowser: false,
630+
clineMessages: [
631+
{
632+
type: 'say',
633+
say: 'task',
634+
ts: Date.now() - 2000,
635+
text: 'Initial task'
636+
},
637+
{
638+
type: 'say',
639+
say: 'api_req_started',
640+
ts: Date.now() - 1000,
641+
text: JSON.stringify({}),
642+
partial: true
643+
}
644+
]
645+
})
646+
647+
// Then send the browser action ask message (streaming finished)
648+
mockPostMessage({
649+
alwaysAllowBrowser: false,
650+
clineMessages: [
651+
{
652+
type: 'say',
653+
say: 'task',
654+
ts: Date.now() - 2000,
655+
text: 'Initial task'
656+
},
657+
{
658+
type: 'ask',
659+
ask: 'browser_action_launch',
660+
ts: Date.now(),
661+
text: JSON.stringify({ action: 'launch', url: 'http://example.com' }),
662+
partial: false
663+
}
664+
]
665+
})
666+
667+
// Verify notification sound was played
668+
await waitFor(() => {
669+
expect(vscode.postMessage).toHaveBeenCalledWith({
670+
type: 'playSound',
671+
audioType: 'notification'
672+
})
673+
})
674+
})
675+
676+
it('plays celebration sound for completion results', async () => {
677+
render(
678+
<ExtensionStateContextProvider>
679+
<ChatView
680+
isHidden={false}
681+
showAnnouncement={false}
682+
hideAnnouncement={() => {}}
683+
showHistoryView={() => {}}
684+
/>
685+
</ExtensionStateContextProvider>
686+
)
687+
688+
// First hydrate state with initial task and streaming
689+
mockPostMessage({
690+
clineMessages: [
691+
{
692+
type: 'say',
693+
say: 'task',
694+
ts: Date.now() - 2000,
695+
text: 'Initial task'
696+
},
697+
{
698+
type: 'say',
699+
say: 'api_req_started',
700+
ts: Date.now() - 1000,
701+
text: JSON.stringify({}),
702+
partial: true
703+
}
704+
]
705+
})
706+
707+
// Then send the completion result message (streaming finished)
708+
mockPostMessage({
709+
clineMessages: [
710+
{
711+
type: 'say',
712+
say: 'task',
713+
ts: Date.now() - 2000,
714+
text: 'Initial task'
715+
},
716+
{
717+
type: 'ask',
718+
ask: 'completion_result',
719+
ts: Date.now(),
720+
text: 'Task completed successfully',
721+
partial: false
722+
}
723+
]
724+
})
725+
726+
// Verify celebration sound was played
727+
await waitFor(() => {
728+
expect(vscode.postMessage).toHaveBeenCalledWith({
729+
type: 'playSound',
730+
audioType: 'celebration'
731+
})
732+
})
733+
})
734+
735+
it('plays progress_loop sound for api failures', async () => {
736+
render(
737+
<ExtensionStateContextProvider>
738+
<ChatView
739+
isHidden={false}
740+
showAnnouncement={false}
741+
hideAnnouncement={() => {}}
742+
showHistoryView={() => {}}
743+
/>
744+
</ExtensionStateContextProvider>
745+
)
746+
747+
// First hydrate state with initial task and streaming
748+
mockPostMessage({
749+
clineMessages: [
750+
{
751+
type: 'say',
752+
say: 'task',
753+
ts: Date.now() - 2000,
754+
text: 'Initial task'
755+
},
756+
{
757+
type: 'say',
758+
say: 'api_req_started',
759+
ts: Date.now() - 1000,
760+
text: JSON.stringify({}),
761+
partial: true
762+
}
763+
]
764+
})
765+
766+
// Then send the api failure message (streaming finished)
767+
mockPostMessage({
768+
clineMessages: [
769+
{
770+
type: 'say',
771+
say: 'task',
772+
ts: Date.now() - 2000,
773+
text: 'Initial task'
774+
},
775+
{
776+
type: 'ask',
777+
ask: 'api_req_failed',
778+
ts: Date.now(),
779+
text: 'API request failed',
780+
partial: false
781+
}
782+
]
783+
})
784+
785+
// Verify progress_loop sound was played
786+
await waitFor(() => {
787+
expect(vscode.postMessage).toHaveBeenCalledWith({
788+
type: 'playSound',
789+
audioType: 'progress_loop'
790+
})
791+
})
792+
})
793+
})

0 commit comments

Comments
 (0)