OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/bind.h" | |
6 #include "base/run_loop.h" | |
7 #include "base/strings/utf_string_conversions.h" | |
8 #include "chrome/browser/speech/speech_recognition_bubble_controller.h" | |
9 #include "chrome/browser/ui/browser.h" | |
10 #include "chrome/browser/ui/browser_tabstrip.h" | |
11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
12 #include "chrome/test/base/browser_with_test_window_test.h" | |
13 #include "chrome/test/base/testing_profile.h" | |
14 #include "content/public/browser/render_process_host.h" | |
15 #include "content/public/browser/render_view_host.h" | |
16 #include "content/public/test/test_browser_thread.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 #include "ui/gfx/rect.h" | |
19 | |
20 | |
21 using content::BrowserThread; | |
22 using content::WebContents; | |
23 | |
24 namespace speech { | |
25 | |
26 // A mock bubble class which fakes a focus change or recognition cancel by the | |
27 // user and closing of the info bubble. | |
28 class MockSpeechRecognitionBubble : public SpeechRecognitionBubbleBase { | |
29 public: | |
30 enum BubbleType { | |
31 BUBBLE_TEST_FOCUS_CHANGED, | |
32 BUBBLE_TEST_CLICK_CANCEL, | |
33 BUBBLE_TEST_CLICK_TRY_AGAIN, | |
34 }; | |
35 | |
36 MockSpeechRecognitionBubble(int render_process_id, int render_view_id, | |
37 Delegate* delegate, const gfx::Rect&) | |
38 : SpeechRecognitionBubbleBase(render_process_id, render_view_id) { | |
39 VLOG(1) << "MockSpeechRecognitionBubble created"; | |
40 base::MessageLoop::current()->PostTask( | |
41 FROM_HERE, base::Bind(&InvokeDelegate, delegate)); | |
42 } | |
43 | |
44 static void InvokeDelegate(Delegate* delegate) { | |
45 VLOG(1) << "MockSpeechRecognitionBubble invoking delegate for type " | |
46 << type_; | |
47 switch (type_) { | |
48 case BUBBLE_TEST_FOCUS_CHANGED: | |
49 delegate->InfoBubbleFocusChanged(); | |
50 break; | |
51 case BUBBLE_TEST_CLICK_CANCEL: | |
52 delegate->InfoBubbleButtonClicked( | |
53 SpeechRecognitionBubble::BUTTON_CANCEL); | |
54 break; | |
55 case BUBBLE_TEST_CLICK_TRY_AGAIN: | |
56 delegate->InfoBubbleButtonClicked( | |
57 SpeechRecognitionBubble::BUTTON_TRY_AGAIN); | |
58 break; | |
59 } | |
60 } | |
61 | |
62 static void set_type(BubbleType type) { | |
63 type_ = type; | |
64 } | |
65 static BubbleType type() { | |
66 return type_; | |
67 } | |
68 | |
69 virtual void Show() OVERRIDE {} | |
70 virtual void Hide() OVERRIDE {} | |
71 virtual void UpdateLayout() OVERRIDE {} | |
72 virtual void UpdateImage() OVERRIDE {} | |
73 | |
74 private: | |
75 static BubbleType type_; | |
76 }; | |
77 | |
78 // The test fixture. | |
79 class SpeechRecognitionBubbleControllerTest | |
80 : public SpeechRecognitionBubbleControllerDelegate, | |
81 public BrowserWithTestWindowTest { | |
82 public: | |
83 SpeechRecognitionBubbleControllerTest() | |
84 : BrowserWithTestWindowTest(), | |
85 cancel_clicked_(false), | |
86 try_again_clicked_(false), | |
87 focus_changed_(false), | |
88 controller_(new SpeechRecognitionBubbleController(this)) { | |
89 EXPECT_EQ(NULL, test_fixture_); | |
90 test_fixture_ = this; | |
91 } | |
92 | |
93 virtual ~SpeechRecognitionBubbleControllerTest() { | |
94 test_fixture_ = NULL; | |
95 } | |
96 | |
97 // SpeechRecognitionBubbleControllerDelegate methods. | |
98 virtual void InfoBubbleButtonClicked( | |
99 int session_id, | |
100 SpeechRecognitionBubble::Button button) OVERRIDE { | |
101 VLOG(1) << "Received InfoBubbleButtonClicked for button " << button; | |
102 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
103 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { | |
104 cancel_clicked_ = true; | |
105 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { | |
106 try_again_clicked_ = true; | |
107 } | |
108 } | |
109 | |
110 virtual void InfoBubbleFocusChanged(int session_id) OVERRIDE { | |
111 VLOG(1) << "Received InfoBubbleFocusChanged"; | |
112 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
113 focus_changed_ = true; | |
114 } | |
115 | |
116 // testing::Test methods. | |
117 virtual void SetUp() { | |
118 BrowserWithTestWindowTest::SetUp(); | |
119 SpeechRecognitionBubble::set_factory( | |
120 &SpeechRecognitionBubbleControllerTest::CreateBubble); | |
121 } | |
122 | |
123 virtual void TearDown() { | |
124 SpeechRecognitionBubble::set_factory(NULL); | |
125 BrowserWithTestWindowTest::TearDown(); | |
126 } | |
127 | |
128 static void ActivateBubble() { | |
129 if (MockSpeechRecognitionBubble::type() != | |
130 MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED) { | |
131 test_fixture_->controller_->SetBubbleMessage(base::ASCIIToUTF16("Test")); | |
132 } | |
133 } | |
134 | |
135 static SpeechRecognitionBubble* CreateBubble( | |
136 WebContents* web_contents, | |
137 SpeechRecognitionBubble::Delegate* delegate, | |
138 const gfx::Rect& element_rect) { | |
139 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
140 // Set up to activate the bubble soon after it gets created, since we test | |
141 // events sent by the bubble and those are handled only when the bubble is | |
142 // active. | |
143 base::MessageLoop::current()->PostTask(FROM_HERE, | |
144 base::Bind(&ActivateBubble)); | |
145 | |
146 return new MockSpeechRecognitionBubble(0, 0, delegate, element_rect); | |
147 } | |
148 | |
149 protected: | |
150 bool cancel_clicked_; | |
151 bool try_again_clicked_; | |
152 bool focus_changed_; | |
153 scoped_refptr<SpeechRecognitionBubbleController> controller_; | |
154 | |
155 static const int kBubbleSessionId; | |
156 static SpeechRecognitionBubbleControllerTest* test_fixture_; | |
157 }; | |
158 | |
159 SpeechRecognitionBubbleControllerTest* | |
160 SpeechRecognitionBubbleControllerTest::test_fixture_ = NULL; | |
161 | |
162 const int SpeechRecognitionBubbleControllerTest::kBubbleSessionId = 1; | |
163 | |
164 MockSpeechRecognitionBubble::BubbleType MockSpeechRecognitionBubble::type_ = | |
165 MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED; | |
166 | |
167 // Test that the speech bubble UI gets created in the UI thread and that the | |
168 // focus changed callback comes back in the IO thread. | |
169 TEST_F(SpeechRecognitionBubbleControllerTest, TestFocusChanged) { | |
170 MockSpeechRecognitionBubble::set_type( | |
171 MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED); | |
172 | |
173 controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1)); | |
174 base::RunLoop().RunUntilIdle(); | |
175 EXPECT_TRUE(focus_changed_); | |
176 EXPECT_FALSE(cancel_clicked_); | |
177 EXPECT_FALSE(try_again_clicked_); | |
178 controller_->CloseBubble(); | |
179 } | |
180 | |
181 // Test that the speech bubble UI gets created in the UI thread and that the | |
182 // recognition cancelled callback comes back in the IO thread. | |
183 TEST_F(SpeechRecognitionBubbleControllerTest, TestRecognitionCancelled) { | |
184 MockSpeechRecognitionBubble::set_type( | |
185 MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_CANCEL); | |
186 | |
187 controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1)); | |
188 base::RunLoop().RunUntilIdle(); | |
189 EXPECT_TRUE(cancel_clicked_); | |
190 EXPECT_FALSE(try_again_clicked_); | |
191 EXPECT_FALSE(focus_changed_); | |
192 controller_->CloseBubble(); | |
193 } | |
194 | |
195 // Test that the speech bubble UI gets created in the UI thread and that the | |
196 // try-again button click event comes back in the IO thread. | |
197 TEST_F(SpeechRecognitionBubbleControllerTest, TestTryAgainClicked) { | |
198 MockSpeechRecognitionBubble::set_type( | |
199 MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_TRY_AGAIN); | |
200 | |
201 controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1)); | |
202 base::RunLoop().RunUntilIdle(); | |
203 EXPECT_FALSE(cancel_clicked_); | |
204 EXPECT_TRUE(try_again_clicked_); | |
205 EXPECT_FALSE(focus_changed_); | |
206 controller_->CloseBubble(); | |
207 } | |
208 | |
209 } // namespace speech | |
OLD | NEW |