// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <map>
#include "base/basictypes.h"
#include "chrome/browser/automation/automation_tab_helper.h"
#include "chrome/browser/automation/mock_tab_event_observer.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/test_tab_contents.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
class AutomationTabHelperTest : public TabContentsWrapperTestHarness {
public:
virtual void SetUp() {
TabContentsWrapperTestHarness::SetUp();
mock_observer_.StartObserving(tab_helper());
}
protected:
// These are here so that we don't have to add each test as a
// |AutomationTabHelper| friend.
void StartLoading() {
tab_helper()->DidStartLoading();
}
void StopLoading() {
tab_helper()->DidStopLoading();
}
void TabContentsDestroyed() {
tab_helper()->TabContentsDestroyed(contents_wrapper()->tab_contents());
}
void WillPerformClientRedirect(int64 frame_id) {
tab_helper()->OnWillPerformClientRedirect(frame_id, 0);
}
void CompleteOrCancelClientRedirect(int64 frame_id) {
tab_helper()->OnDidCompleteOrCancelClientRedirect(frame_id);
}
AutomationTabHelper* tab_helper() {
return contents_wrapper()->automation_tab_helper();
}
MockTabEventObserver mock_observer_;
};
ACTION_P2(CheckHasPendingLoads, tab_helper, has_pending_loads) {
EXPECT_EQ(has_pending_loads, tab_helper->has_pending_loads());
}
TEST_F(AutomationTabHelperTest, AddAndRemoveObserver) {
testing::MockFunction<void()> check;
{
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(_));
EXPECT_CALL(check, Call());
}
StartLoading();
check.Call();
tab_helper()->RemoveObserver(&mock_observer_);
StartLoading();
}
TEST_F(AutomationTabHelperTest, StartStopLoading) {
testing::MockFunction<void()> check;
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()))
.WillOnce(CheckHasPendingLoads(tab_helper(), true));
EXPECT_CALL(check, Call());
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()))
.WillOnce(CheckHasPendingLoads(tab_helper(), false));
EXPECT_FALSE(tab_helper()->has_pending_loads());
StartLoading();
EXPECT_TRUE(tab_helper()->has_pending_loads());
check.Call();
StopLoading();
EXPECT_FALSE(tab_helper()->has_pending_loads());
}
TEST_F(AutomationTabHelperTest, DuplicateLoads) {
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()));
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()));
StartLoading();
StartLoading();
StopLoading();
StopLoading();
}
TEST_F(AutomationTabHelperTest, ClientRedirect) {
testing::MockFunction<void()> check;
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()))
.WillOnce(CheckHasPendingLoads(tab_helper(), true));
EXPECT_CALL(check, Call());
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()))
.WillOnce(CheckHasPendingLoads(tab_helper(), false));
WillPerformClientRedirect(1);
EXPECT_TRUE(tab_helper()->has_pending_loads());
check.Call();
CompleteOrCancelClientRedirect(1);
EXPECT_FALSE(tab_helper()->has_pending_loads());
}
TEST_F(AutomationTabHelperTest, DiscardExtraClientRedirects) {
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()));
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()));
WillPerformClientRedirect(1);
WillPerformClientRedirect(1);
CompleteOrCancelClientRedirect(1);
EXPECT_FALSE(tab_helper()->has_pending_loads());
CompleteOrCancelClientRedirect(1);
CompleteOrCancelClientRedirect(2);
}
TEST_F(AutomationTabHelperTest, StartStopLoadingWithClientRedirect) {
testing::MockFunction<void()> check;
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()));
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()));
StartLoading();
WillPerformClientRedirect(1);
CompleteOrCancelClientRedirect(1);
StopLoading();
}
TEST_F(AutomationTabHelperTest, ClientRedirectBeforeLoad) {
testing::MockFunction<void()> check;
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()));
EXPECT_CALL(check, Call());
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()));
StartLoading();
WillPerformClientRedirect(1);
CompleteOrCancelClientRedirect(1);
EXPECT_TRUE(tab_helper()->has_pending_loads());
check.Call();
StopLoading();
}
TEST_F(AutomationTabHelperTest, ClientRedirectAfterLoad) {
testing::MockFunction<void()> check;
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()));
EXPECT_CALL(check, Call());
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()));
StartLoading();
WillPerformClientRedirect(1);
StopLoading();
EXPECT_TRUE(tab_helper()->has_pending_loads());
check.Call();
CompleteOrCancelClientRedirect(1);
EXPECT_FALSE(tab_helper()->has_pending_loads());
}
TEST_F(AutomationTabHelperTest, AllFramesMustFinishRedirects) {
testing::MockFunction<void()> check;
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()));
EXPECT_CALL(check, Call());
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()));
WillPerformClientRedirect(1);
WillPerformClientRedirect(2);
CompleteOrCancelClientRedirect(1);
check.Call();
EXPECT_TRUE(tab_helper()->has_pending_loads());
CompleteOrCancelClientRedirect(2);
EXPECT_FALSE(tab_helper()->has_pending_loads());
}
TEST_F(AutomationTabHelperTest, DestroyedTabStopsLoading) {
testing::MockFunction<void()> check;
testing::InSequence expect_in_sequence;
EXPECT_CALL(mock_observer_, OnFirstPendingLoad(contents()));
EXPECT_CALL(mock_observer_, OnNoMorePendingLoads(contents()));
StartLoading();
WillPerformClientRedirect(1);
TabContentsDestroyed();
EXPECT_FALSE(tab_helper()->has_pending_loads());
}