1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar/reload_button.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReloadButtonTest : public testing::Test {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReloadButtonTest();
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckState(bool enabled,
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ReloadButton::Mode intended_mode,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ReloadButton::Mode visible_mode,
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  bool double_click_timer_running,
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  bool stop_to_reload_timer_running);
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These accessors eliminate the need to declare each testcase as a friend.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_mouse_hovered(bool hovered) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reload_.testing_mouse_hovered_ = hovered;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int reload_count() { return reload_.testing_reload_count_; }
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need a message loop for the timers to post events.
27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop loop_;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReloadButton reload_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
320529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochReloadButtonTest::ReloadButtonTest() : reload_(NULL) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the timer delays to 0 so that timers will fire as soon as we tell the
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message loop to run pending tasks.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.double_click_timer_delay_ = base::TimeDelta();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.stop_to_reload_timer_delay_ = base::TimeDelta();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReloadButtonTest::CheckState(bool enabled,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  ReloadButton::Mode intended_mode,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  ReloadButton::Mode visible_mode,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bool double_click_timer_running,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bool stop_to_reload_timer_running) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enabled, reload_.enabled());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(intended_mode, reload_.intended_mode_);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(visible_mode, reload_.visible_mode_);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(double_click_timer_running,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            reload_.double_click_timer_.IsRunning());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(stop_to_reload_timer_running,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            reload_.stop_to_reload_timer_.IsRunning());
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ReloadButtonTest, Basic) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The stop/reload button starts in the "enabled reload" state with no timers
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // running.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Press the button.  This should start the double-click timer.
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), 0, 0);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, true,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now change the mode (as if the browser had started loading the page).  This
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should cancel the double-click timer since the button is not hovered.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ChangeMode(ReloadButton::MODE_STOP, false);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_STOP, false,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Press the button again.  This should change back to reload.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ReloadButtonTest, DoubleClickTimer) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start by pressing the button.
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), 0, 0);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to press the button again.  This should do nothing because the timer is
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // running.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int original_reload_count = reload_count();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, true,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_reload_count, reload_count());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hover the button, and change mode.  The visible mode should not change,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // again because the timer is running.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_mouse_hovered(true);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ChangeMode(ReloadButton::MODE_STOP, false);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_RELOAD, true,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now fire the timer.  This should complete the mode change.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  loop_.RunUntilIdle();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_STOP, false,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ReloadButtonTest, DisableOnHover) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change to stop and hover.
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), 0, 0);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ChangeMode(ReloadButton::MODE_STOP, false);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_mouse_hovered(true);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now change back to reload.  This should result in a disabled stop button
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // due to the hover.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ChangeMode(ReloadButton::MODE_RELOAD, false);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(false, ReloadButton::MODE_RELOAD, ReloadButton::MODE_STOP, false,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             true);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Un-hover the button, which should allow it to reset.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_mouse_hovered(false);
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent e2(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), 0, 0);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.OnMouseExited(e2);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ReloadButtonTest, ResetOnClick) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change to stop and hover.
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), 0, 0);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ChangeMode(ReloadButton::MODE_STOP, false);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_mouse_hovered(true);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Press the button.  This should change back to reload despite the hover,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because it's a direct user action.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ReloadButtonTest, ResetOnTimer) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change to stop, hover, and change back to reload.
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), 0, 0);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ButtonPressed(&reload_, e);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ChangeMode(ReloadButton::MODE_STOP, false);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_mouse_hovered(true);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_.ChangeMode(ReloadButton::MODE_RELOAD, false);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now fire the stop-to-reload timer.  This should reset the button.
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  loop_.RunUntilIdle();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             false);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
151