1// Copyright 2013 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 "chrome/browser/ui/search/search_model.h"
6
7#include "base/command_line.h"
8#include "chrome/browser/ui/search/search_model_observer.h"
9#include "chrome/browser/ui/search/search_tab_helper.h"
10#include "chrome/common/chrome_switches.h"
11#include "chrome/common/search_types.h"
12#include "chrome/test/base/chrome_render_view_host_test_harness.h"
13
14namespace {
15
16class MockSearchModelObserver : public SearchModelObserver {
17 public:
18  MockSearchModelObserver();
19  virtual ~MockSearchModelObserver();
20
21  virtual void ModelChanged(const SearchModel::State& old_state,
22                            const SearchModel::State& new_state) OVERRIDE;
23
24  void VerifySearchModelStates(const SearchModel::State& expected_old_state,
25                               const SearchModel::State& expected_new_state);
26
27  void VerifyNotificationCount(int expected_count);
28
29 private:
30  // How many times we've seen search model changed notifications.
31  int modelchanged_notification_count_;
32
33  SearchModel::State actual_old_state_;
34  SearchModel::State actual_new_state_;
35
36  DISALLOW_COPY_AND_ASSIGN(MockSearchModelObserver);
37};
38
39MockSearchModelObserver::MockSearchModelObserver()
40    : modelchanged_notification_count_(0) {
41}
42
43MockSearchModelObserver::~MockSearchModelObserver() {
44}
45
46void MockSearchModelObserver::ModelChanged(
47    const SearchModel::State& old_state,
48    const SearchModel::State& new_state) {
49  actual_old_state_ = old_state;
50  actual_new_state_ = new_state;
51  modelchanged_notification_count_++;
52}
53
54void MockSearchModelObserver::VerifySearchModelStates(
55    const SearchModel::State& expected_old_state,
56    const SearchModel::State& expected_new_state) {
57  EXPECT_TRUE(actual_old_state_ == expected_old_state);
58  EXPECT_TRUE(actual_new_state_ == expected_new_state);
59}
60
61void MockSearchModelObserver::VerifyNotificationCount(int expected_count) {
62  EXPECT_EQ(modelchanged_notification_count_, expected_count);
63}
64
65}  // namespace
66
67class SearchModelTest : public ChromeRenderViewHostTestHarness {
68 public:
69  virtual void SetUp() OVERRIDE;
70  virtual void TearDown() OVERRIDE;
71
72  MockSearchModelObserver mock_observer;
73  SearchModel* model;
74};
75
76void SearchModelTest::SetUp() {
77  ChromeRenderViewHostTestHarness::SetUp();
78  SearchTabHelper::CreateForWebContents(web_contents());
79  SearchTabHelper* search_tab_helper =
80      SearchTabHelper::FromWebContents(web_contents());
81  ASSERT_TRUE(search_tab_helper != NULL);
82  model = search_tab_helper->model();
83  model->AddObserver(&mock_observer);
84}
85
86void SearchModelTest::TearDown() {
87  model->RemoveObserver(&mock_observer);
88  ChromeRenderViewHostTestHarness::TearDown();
89}
90
91TEST_F(SearchModelTest, UpdateSearchModelInstantSupport) {
92  mock_observer.VerifyNotificationCount(0);
93  EXPECT_TRUE(model->instant_support() == INSTANT_SUPPORT_UNKNOWN);
94  SearchModel::State expected_old_state = model->state();
95  SearchModel::State expected_new_state(model->state());
96  expected_new_state.instant_support = INSTANT_SUPPORT_YES;
97
98  model->SetInstantSupportState(INSTANT_SUPPORT_YES);
99  mock_observer.VerifySearchModelStates(expected_old_state, expected_new_state);
100  mock_observer.VerifyNotificationCount(1);
101  EXPECT_TRUE(model->instant_support() == INSTANT_SUPPORT_YES);
102
103  expected_old_state = expected_new_state;
104  expected_new_state.instant_support = INSTANT_SUPPORT_NO;
105  model->SetInstantSupportState(INSTANT_SUPPORT_NO);
106  mock_observer.VerifySearchModelStates(expected_old_state, expected_new_state);
107  mock_observer.VerifyNotificationCount(2);
108
109  // Notify the observer only if the search model state is changed.
110  model->SetInstantSupportState(INSTANT_SUPPORT_NO);
111  EXPECT_TRUE(model->state() == expected_new_state);
112  EXPECT_TRUE(model->instant_support() == INSTANT_SUPPORT_NO);
113  mock_observer.VerifyNotificationCount(2);
114}
115
116TEST_F(SearchModelTest, UpdateSearchModelMode) {
117  mock_observer.VerifyNotificationCount(0);
118  SearchMode search_mode(SearchMode::MODE_NTP, SearchMode::ORIGIN_NTP);
119  SearchModel::State expected_old_state = model->state();
120  SearchModel::State expected_new_state(model->state());
121  expected_new_state.mode = search_mode;
122
123  model->SetMode(search_mode);
124  mock_observer.VerifySearchModelStates(expected_old_state, expected_new_state);
125  mock_observer.VerifyNotificationCount(1);
126
127  search_mode.mode = SearchMode::MODE_SEARCH_RESULTS;
128  expected_old_state = expected_new_state;
129  expected_new_state.mode = search_mode;
130  model->SetMode(search_mode);
131  mock_observer.VerifySearchModelStates(expected_old_state, expected_new_state);
132  mock_observer.VerifyNotificationCount(2);
133  EXPECT_TRUE(model->state() == expected_new_state);
134}
135
136TEST_F(SearchModelTest, UpdateSearchModelState) {
137  SearchModel::State expected_new_state(model->state());
138  expected_new_state.instant_support = INSTANT_SUPPORT_NO;
139  EXPECT_FALSE(model->state() == expected_new_state);
140  model->SetState(expected_new_state);
141  mock_observer.VerifyNotificationCount(1);
142  EXPECT_TRUE(model->state() == expected_new_state);
143}
144
145TEST_F(SearchModelTest, UpdateVoiceSearchSupported) {
146  mock_observer.VerifyNotificationCount(0);
147  EXPECT_FALSE(model->voice_search_supported());
148
149  SearchModel::State expected_old_state = model->state();
150  SearchModel::State expected_new_state(model->state());
151  expected_new_state.voice_search_supported = true;
152
153  model->SetVoiceSearchSupported(true);
154  mock_observer.VerifySearchModelStates(expected_old_state, expected_new_state);
155  mock_observer.VerifyNotificationCount(1);
156  EXPECT_TRUE(model->voice_search_supported());
157}
158