<commit_before>//@author A0097630B
#include "stdafx.h"
#include <unordered_map>
#include "You-NLP/parse_tree/task_priority.h"
#include "internal/query_executor.h"
#include "internal/query_executor_builder_visitor.h"
#include "exceptions/context_index_out_of_range_exception.h"

#include "../mocks/task_list.h"
#include "../mocks/query.h"

using Assert = Microsoft::VisualStudio::CppUnitTestFramework::Assert;

namespace Microsoft {
namespace VisualStudio {
namespace CppUnitTestFramework {

std::wstring ToString(You::Controller::Task::Priority priority) {
	return ToString(static_cast<int>(priority));
}

}  // namespace CppUnitTestFramework
}  // namespace VisualStudio
}  // namespace Microsoft

namespace You {
namespace Controller {
namespace Internal {
namespace UnitTests {

namespace Mocks {
	// NOLINTNEXTLINE(build/namespaces)
	using namespace You::Controller::UnitTests::Mocks;
}

using Task = You::Controller::Task;
using TaskPriority = You::NLP::TaskPriority;

TEST_CLASS(QueryExecutorBuilderVisitorTests) {
	TEST_METHOD(getsCorrectTypeForAddQueries) {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::ADD_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		ADD_RESULT result(
			boost::get<ADD_RESULT>(executor->execute()));

		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.description,
			result.task.getDescription());
		Assert::AreEqual(
			Task::Priority::NORMAL,
			result.task.getPriority());
		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.deadline.get(),
			result.task.getDeadline());

		You::NLP::ADD_QUERY queryWithoutDeadline(Mocks::Queries::ADD_QUERY);
		queryWithoutDeadline.deadline =
			You::Utils::Option<boost::posix_time::ptime>();
		query = queryWithoutDeadline;
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<ADD_RESULT>(executor->execute());

		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.description,
			result.task.getDescription());
		Assert::AreEqual(
			Task::Priority::NORMAL,
			result.task.getPriority());
		Assert::AreEqual(
			Task::DEFAULT_DEADLINE,
			result.task.getDeadline());

		You::NLP::ADD_QUERY queryWithPriority(Mocks::Queries::ADD_QUERY);
		queryWithPriority.priority = TaskPriority::HIGH;
		query = queryWithPriority;
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<ADD_RESULT>(executor->execute());

		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.description,
			result.task.getDescription());
		Assert::AreEqual(
			Task::Priority::HIGH,
			result.task.getPriority());
		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	TEST_METHOD(getsCorrectTypeForShowQueries) {
		Mocks::TaskList taskList(5);
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::SHOW_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		SHOW_RESULT result(
			boost::get<SHOW_RESULT>(executor->execute()));

		Assert::IsTrue(
			std::is_sorted(begin(result.tasks), end(result.tasks),
			[](const Task& left, const Task& right) {
				return left.getDeadline() >= right.getDeadline();
		}));

		{  // NOLINT(whitespace/braces)
			You::NLP::SHOW_QUERY templ = Mocks::Queries::SHOW_QUERY;
			templ.order = {
				{
					You::NLP::TaskField::DESCRIPTION,
					You::NLP::SHOW_QUERY::Order::ASCENDING
				}
			};
			query = std::move(templ);
		}
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<SHOW_RESULT>(executor->execute());

		Assert::IsTrue(
			std::is_sorted(begin(result.tasks), end(result.tasks),
			[](const Task& left, const Task& right) {
			return left.getDescription() <= right.getDescription();
		}));

		{  // NOLINT(whitespace/braces)
			You::NLP::SHOW_QUERY templ = Mocks::Queries::SHOW_QUERY;
			templ.order = {
				{
					You::NLP::TaskField::PRIORITY,
					You::NLP::SHOW_QUERY::Order::DESCENDING
				}
			};
			query = std::move(templ);
		}
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<SHOW_RESULT>(executor->execute());

		Assert::IsTrue(
			std::is_sorted(begin(result.tasks), end(result.tasks),
			[](const Task& left, const Task& right) {
			return left.getPriority() >= right.getPriority();
		}));
	}

	TEST_METHOD(getsCorrectTypeForEditQueries) {
		getsCorrectTypeForEditQueries1();
		getsCorrectTypeForEditQueries2();
		getsCorrectTypeForEditQueries3();
		getsCorrectTypeForEditQueries4();
	}

	void getsCorrectTypeForEditQueries1() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::EDIT_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.description.get(),
			result.task.getDescription());
		Assert::AreEqual(nlpPriorityToTaskPriority(
			Mocks::Queries::EDIT_QUERY.priority.get()),
			result.task.getPriority());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	void getsCorrectTypeForEditQueries2() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::EDIT_QUERY query2(Mocks::Queries::EDIT_QUERY);
		query2.deadline =
			You::Utils::Option<boost::posix_time::ptime>();
		You::NLP::QUERY query(query2);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.description.get(),
			result.task.getDescription());
		Assert::AreEqual(nlpPriorityToTaskPriority(
			Mocks::Queries::EDIT_QUERY.priority.get()),
			result.task.getPriority());
		Assert::AreEqual(taskList.front().getDeadline(),
			result.task.getDeadline());
	}

	void getsCorrectTypeForEditQueries3() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::EDIT_QUERY query2(Mocks::Queries::EDIT_QUERY);
		query2.description =
			You::Utils::Option<std::wstring>();
		You::NLP::QUERY query(query2);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(taskList.front().getDescription(),
			result.task.getDescription());
		Assert::AreEqual(nlpPriorityToTaskPriority(
			Mocks::Queries::EDIT_QUERY.priority.get()),
			result.task.getPriority());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	void getsCorrectTypeForEditQueries4() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::EDIT_QUERY query2(Mocks::Queries::EDIT_QUERY);
		query2.priority =
			You::Utils::Option<You::NLP::TaskPriority>();
		You::NLP::QUERY query(query2);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.description.get(),
			result.task.getDescription());
		Assert::AreEqual(taskList.front().getPriority(),
			result.task.getPriority());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	TEST_METHOD(editQueriesOutOfBoundsThrowsContextOutOfRange) {
		Mocks::TaskList taskList(0);
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::EDIT_QUERY);
		Assert::ExpectException<ContextIndexOutOfRangeException>([&]() {
			boost::apply_visitor(visitor, query);
		});
	}

	TEST_METHOD(getsCorrectTypeForDeleteQueries) {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::DELETE_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		DELETE_RESULT result(
			boost::get<DELETE_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task);
	}

	TEST_METHOD(deleteQueriesOutOfBoundsThrowsContextOutOfRange) {
		Mocks::TaskList taskList(0);
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::DELETE_QUERY);
		Assert::ExpectException<ContextIndexOutOfRangeException>([&]() {
			boost::apply_visitor(visitor, query);
		});
	}

	TEST_METHOD(getsCorrectTypeForUndoQueries) {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::UNDO_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		UNDO_RESULT result(
			boost::get<UNDO_RESULT>(executor->execute()));

		// TODO(lowjoel): test for..?
	}

private:
	Task::Priority nlpPriorityToTaskPriority(NLP::TaskPriority priority) {
		auto iterator = nlpPriorityToTaskPriorityMap.find(priority);
		assert(iterator != end(nlpPriorityToTaskPriorityMap));
		return iterator->second;
	}

private:
	static const std::unordered_map<NLP::TaskPriority, Task::Priority>
		nlpPriorityToTaskPriorityMap;
};

const std::unordered_map<NLP::TaskPriority, Task::Priority>
QueryExecutorBuilderVisitorTests::nlpPriorityToTaskPriorityMap({
	{ NLP::TaskPriority::NORMAL, Task::Priority::NORMAL },
	{ NLP::TaskPriority::HIGH, Task::Priority::HIGH }
});

}  // namespace UnitTests
}  // namespace Internal
}  // namespace Controller
}  // namespace You
<commit_msg>Comparators in C++ never check for equality.<commit_after>//@author A0097630B
#include "stdafx.h"
#include <unordered_map>
#include "You-NLP/parse_tree/task_priority.h"
#include "internal/query_executor.h"
#include "internal/query_executor_builder_visitor.h"
#include "exceptions/context_index_out_of_range_exception.h"

#include "../mocks/task_list.h"
#include "../mocks/query.h"

using Assert = Microsoft::VisualStudio::CppUnitTestFramework::Assert;

namespace Microsoft {
namespace VisualStudio {
namespace CppUnitTestFramework {

std::wstring ToString(You::Controller::Task::Priority priority) {
	return ToString(static_cast<int>(priority));
}

}  // namespace CppUnitTestFramework
}  // namespace VisualStudio
}  // namespace Microsoft

namespace You {
namespace Controller {
namespace Internal {
namespace UnitTests {

namespace Mocks {
	// NOLINTNEXTLINE(build/namespaces)
	using namespace You::Controller::UnitTests::Mocks;
}

using Task = You::Controller::Task;
using TaskPriority = You::NLP::TaskPriority;

TEST_CLASS(QueryExecutorBuilderVisitorTests) {
	TEST_METHOD(getsCorrectTypeForAddQueries) {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::ADD_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		ADD_RESULT result(
			boost::get<ADD_RESULT>(executor->execute()));

		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.description,
			result.task.getDescription());
		Assert::AreEqual(
			Task::Priority::NORMAL,
			result.task.getPriority());
		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.deadline.get(),
			result.task.getDeadline());

		You::NLP::ADD_QUERY queryWithoutDeadline(Mocks::Queries::ADD_QUERY);
		queryWithoutDeadline.deadline =
			You::Utils::Option<boost::posix_time::ptime>();
		query = queryWithoutDeadline;
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<ADD_RESULT>(executor->execute());

		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.description,
			result.task.getDescription());
		Assert::AreEqual(
			Task::Priority::NORMAL,
			result.task.getPriority());
		Assert::AreEqual(
			Task::DEFAULT_DEADLINE,
			result.task.getDeadline());

		You::NLP::ADD_QUERY queryWithPriority(Mocks::Queries::ADD_QUERY);
		queryWithPriority.priority = TaskPriority::HIGH;
		query = queryWithPriority;
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<ADD_RESULT>(executor->execute());

		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.description,
			result.task.getDescription());
		Assert::AreEqual(
			Task::Priority::HIGH,
			result.task.getPriority());
		Assert::AreEqual(
			Mocks::Queries::ADD_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	TEST_METHOD(getsCorrectTypeForShowQueries) {
		Mocks::TaskList taskList(5);
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::SHOW_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		SHOW_RESULT result(
			boost::get<SHOW_RESULT>(executor->execute()));

		Assert::IsTrue(
			std::is_sorted(begin(result.tasks), end(result.tasks),
			[](const Task& left, const Task& right) {
				return left.getDeadline() > right.getDeadline();
		}));

		{  // NOLINT(whitespace/braces)
			You::NLP::SHOW_QUERY templ = Mocks::Queries::SHOW_QUERY;
			templ.order = {
				{
					You::NLP::TaskField::DESCRIPTION,
					You::NLP::SHOW_QUERY::Order::ASCENDING
				}
			};
			query = std::move(templ);
		}
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<SHOW_RESULT>(executor->execute());

		Assert::IsTrue(
			std::is_sorted(begin(result.tasks), end(result.tasks),
			[](const Task& left, const Task& right) {
			return left.getDescription() < right.getDescription();
		}));

		{  // NOLINT(whitespace/braces)
			You::NLP::SHOW_QUERY templ = Mocks::Queries::SHOW_QUERY;
			templ.order = {
				{
					You::NLP::TaskField::PRIORITY,
					You::NLP::SHOW_QUERY::Order::DESCENDING
				}
			};
			query = std::move(templ);
		}
		executor = boost::apply_visitor(visitor, query);
		result = boost::get<SHOW_RESULT>(executor->execute());

		Assert::IsTrue(
			std::is_sorted(begin(result.tasks), end(result.tasks),
			[](const Task& left, const Task& right) {
			return left.getPriority() > right.getPriority();
		}));
	}

	TEST_METHOD(getsCorrectTypeForEditQueries) {
		getsCorrectTypeForEditQueries1();
		getsCorrectTypeForEditQueries2();
		getsCorrectTypeForEditQueries3();
		getsCorrectTypeForEditQueries4();
	}

	void getsCorrectTypeForEditQueries1() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::EDIT_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.description.get(),
			result.task.getDescription());
		Assert::AreEqual(nlpPriorityToTaskPriority(
			Mocks::Queries::EDIT_QUERY.priority.get()),
			result.task.getPriority());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	void getsCorrectTypeForEditQueries2() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::EDIT_QUERY query2(Mocks::Queries::EDIT_QUERY);
		query2.deadline =
			You::Utils::Option<boost::posix_time::ptime>();
		You::NLP::QUERY query(query2);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.description.get(),
			result.task.getDescription());
		Assert::AreEqual(nlpPriorityToTaskPriority(
			Mocks::Queries::EDIT_QUERY.priority.get()),
			result.task.getPriority());
		Assert::AreEqual(taskList.front().getDeadline(),
			result.task.getDeadline());
	}

	void getsCorrectTypeForEditQueries3() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::EDIT_QUERY query2(Mocks::Queries::EDIT_QUERY);
		query2.description =
			You::Utils::Option<std::wstring>();
		You::NLP::QUERY query(query2);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(taskList.front().getDescription(),
			result.task.getDescription());
		Assert::AreEqual(nlpPriorityToTaskPriority(
			Mocks::Queries::EDIT_QUERY.priority.get()),
			result.task.getPriority());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	void getsCorrectTypeForEditQueries4() {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::EDIT_QUERY query2(Mocks::Queries::EDIT_QUERY);
		query2.priority =
			You::Utils::Option<You::NLP::TaskPriority>();
		You::NLP::QUERY query(query2);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		EDIT_RESULT result(
			boost::get<EDIT_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task.getID());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.description.get(),
			result.task.getDescription());
		Assert::AreEqual(taskList.front().getPriority(),
			result.task.getPriority());
		Assert::AreEqual(Mocks::Queries::EDIT_QUERY.deadline.get(),
			result.task.getDeadline());
	}

	TEST_METHOD(editQueriesOutOfBoundsThrowsContextOutOfRange) {
		Mocks::TaskList taskList(0);
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::EDIT_QUERY);
		Assert::ExpectException<ContextIndexOutOfRangeException>([&]() {
			boost::apply_visitor(visitor, query);
		});
	}

	TEST_METHOD(getsCorrectTypeForDeleteQueries) {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::DELETE_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		DELETE_RESULT result(
			boost::get<DELETE_RESULT>(executor->execute()));

		Assert::AreEqual(taskList.front().getID(),
			result.task);
	}

	TEST_METHOD(deleteQueriesOutOfBoundsThrowsContextOutOfRange) {
		Mocks::TaskList taskList(0);
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::DELETE_QUERY);
		Assert::ExpectException<ContextIndexOutOfRangeException>([&]() {
			boost::apply_visitor(visitor, query);
		});
	}

	TEST_METHOD(getsCorrectTypeForUndoQueries) {
		Mocks::TaskList taskList;
		QueryExecutorBuilderVisitor visitor(taskList);

		You::NLP::QUERY query(Mocks::Queries::UNDO_QUERY);
		std::unique_ptr<QueryExecutor> executor(
			boost::apply_visitor(visitor, query));
		UNDO_RESULT result(
			boost::get<UNDO_RESULT>(executor->execute()));

		// TODO(lowjoel): test for..?
	}

private:
	Task::Priority nlpPriorityToTaskPriority(NLP::TaskPriority priority) {
		auto iterator = nlpPriorityToTaskPriorityMap.find(priority);
		assert(iterator != end(nlpPriorityToTaskPriorityMap));
		return iterator->second;
	}

private:
	static const std::unordered_map<NLP::TaskPriority, Task::Priority>
		nlpPriorityToTaskPriorityMap;
};

const std::unordered_map<NLP::TaskPriority, Task::Priority>
QueryExecutorBuilderVisitorTests::nlpPriorityToTaskPriorityMap({
	{ NLP::TaskPriority::NORMAL, Task::Priority::NORMAL },
	{ NLP::TaskPriority::HIGH, Task::Priority::HIGH }
});

}  // namespace UnitTests
}  // namespace Internal
}  // namespace Controller
}  // namespace You
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "base/process_util.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/find_bar/find_notification_details.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/find_bar_host.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "net/test/test_server.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/keycodes/keyboard_codes.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/view.h"
#include "ui/views/views_delegate.h"

using content::WebContents;

namespace {

// The delay waited after sending an OS simulated event.
static const int kActionDelayMs = 500;
static const char kSimplePage[] = "files/find_in_page/simple.html";

void Checkpoint(const char* message, const base::TimeTicks& start_time) {
  LOG(INFO) << message << " : "
    << (base::TimeTicks::Now() - start_time).InMilliseconds()
    << " ms" << std::flush;
}

class FindInPageTest : public InProcessBrowserTest {
 public:
  FindInPageTest() :
#if defined(USE_AURA)
      location_bar_focus_view_id_(VIEW_ID_OMNIBOX)
#else
      location_bar_focus_view_id_(VIEW_ID_LOCATION_BAR)
#endif
  {
    set_show_window(true);
    FindBarHost::disable_animations_during_testing_ = true;
  }

  string16 GetFindBarText() {
    FindBarTesting* find_bar =
        browser()->GetFindBarController()->find_bar()->GetFindBarTesting();
    return find_bar->GetFindText();
  }

  string16 GetFindBarSelectedText() {
    FindBarTesting* find_bar =
        browser()->GetFindBarController()->find_bar()->GetFindBarTesting();
    return find_bar->GetFindSelectedText();
  }

  ViewID location_bar_focus_view_id_;

 private:
  DISALLOW_COPY_AND_ASSIGN(FindInPageTest);
};

}  // namespace

IN_PROC_BROWSER_TEST_F(FindInPageTest, CrashEscHandlers) {
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page (tab A).
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  browser()->Find();

  // Open another tab (tab B).
  browser()->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_TYPED);

  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Select tab A.
  browser()->ActivateTabAt(0, true);

  // Close tab B.
  browser()->CloseTabContents(browser()->GetWebContentsAt(1));

  // Click on the location bar so that Find box loses focus.
  ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(),
                                                     VIEW_ID_LOCATION_BAR));
  // Check the location bar is focused.
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));

  // This used to crash until bug 1303709 was fixed.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_ESCAPE, false, false, false, false));
}

IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestore) {
  ASSERT_TRUE(test_server()->Start());

  GURL url = test_server()->GetURL("title1.html");
  ui_test_utils::NavigateToURL(browser(), url);

  // Focus the location bar, open and close the find-in-page, focus should
  // return to the location bar.
  browser()->FocusLocationBar();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
  // Ensure the creation of the find bar controller.
  browser()->GetFindBarController()->Show();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  browser()->GetFindBarController()->EndFindSession(
      FindBarController::kKeepSelection);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));

  // Focus the location bar, find something on the page, close the find box,
  // focus should go to the page.
  browser()->FocusLocationBar();
  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(),
                            ASCIIToUTF16("a"), true, false, NULL);
  browser()->GetFindBarController()->EndFindSession(
      FindBarController::kKeepSelection);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  // Focus the location bar, open and close the find box, focus should return to
  // the location bar (same as before, just checking that http://crbug.com/23599
  // is fixed).
  browser()->FocusLocationBar();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
  browser()->GetFindBarController()->Show();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  browser()->GetFindBarController()->EndFindSession(
      FindBarController::kKeepSelection);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
}

IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestoreOnTabSwitch) {
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page (tab A).
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  FindBarTesting* find_bar =
      browser()->GetFindBarController()->find_bar()->GetFindBarTesting();

  // Search for 'a'.
  ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(),
                            ASCIIToUTF16("a"), true, false, NULL);
  EXPECT_TRUE(ASCIIToUTF16("a") == find_bar->GetFindSelectedText());

  // Open another tab (tab B).
  ui_test_utils::WindowedNotificationObserver observer(
      content::NOTIFICATION_LOAD_STOP,
      content::NotificationService::AllSources());
  browser()->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_TYPED);
  observer.Wait();

  // Make sure Find box is open.
  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Search for 'b'.
  ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(),
                            ASCIIToUTF16("b"), true, false, NULL);
  EXPECT_TRUE(ASCIIToUTF16("b") == find_bar->GetFindSelectedText());

  // Set focus away from the Find bar (to the Location bar).
  browser()->FocusLocationBar();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));

  // Select tab A. Find bar should get focus.
  browser()->ActivateTabAt(0, true);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  EXPECT_TRUE(ASCIIToUTF16("a") == find_bar->GetFindSelectedText());

  // Select tab B. Location bar should get focus.
  browser()->ActivateTabAt(1, true);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
}

// This tests that whenever you clear values from the Find box and close it that
// it respects that and doesn't show you the last search, as reported in bug:
// http://crbug.com/40121.
IN_PROC_BROWSER_TEST_F(FindInPageTest, PrepopulateRespectBlank) {
#if defined(OS_MACOSX)
  // FindInPage on Mac doesn't use prepopulated values. Search there is global.
  return;
#endif
  base::TimeTicks start_time = base::TimeTicks::Now();
  Checkpoint("Test starting", start_time);

  ASSERT_TRUE(test_server()->Start());

  // Make sure Chrome is in the foreground, otherwise sending input
  // won't do anything and the test will hang.
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  Checkpoint("Navigate", start_time);

  // First we navigate to any page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  Checkpoint("Show Find bar", start_time);

  // Show the Find bar.
  browser()->GetFindBarController()->Show();

  Checkpoint("Search for 'a'", start_time);

  // Search for "a".
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_A, false, false, false, false));

  // We should find "a" here.
  EXPECT_EQ(ASCIIToUTF16("a"), GetFindBarText());

  Checkpoint("Delete 'a'", start_time);

  // Delete "a".
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_BACK, false, false, false, false));

  // Validate we have cleared the text.
  EXPECT_EQ(string16(), GetFindBarText());

  Checkpoint("Close find bar", start_time);

  // Close the Find box.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_ESCAPE, false, false, false, false));

  Checkpoint("Show Find bar", start_time);

  // Show the Find bar.
  browser()->GetFindBarController()->Show();

  Checkpoint("Validate text", start_time);

  // After the Find box has been reopened, it should not have been prepopulated
  // with "a" again.
  EXPECT_EQ(string16(), GetFindBarText());

  Checkpoint("Close Find bar", start_time);

  // Close the Find box.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_ESCAPE, false, false, false, false));

  Checkpoint("FindNext", start_time);

  // Press F3 to trigger FindNext.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F3, false, false, false, false));

  Checkpoint("Validate", start_time);

  // After the Find box has been reopened, it should still have no prepopulate
  // value.
  EXPECT_EQ(string16(), GetFindBarText());

  Checkpoint("Test done", start_time);
}

// Flaky on Win. http://crbug.com/92467
#if defined(OS_WIN)
#define MAYBE_PasteWithoutTextChange DISABLED_PasteWithoutTextChange
#else
#define MAYBE_PasteWithoutTextChange PasteWithoutTextChange
#endif

IN_PROC_BROWSER_TEST_F(FindInPageTest, MAYBE_PasteWithoutTextChange) {
  ASSERT_TRUE(test_server()->Start());

  // Make sure Chrome is in the foreground, otherwise sending input
  // won't do anything and the test will hang.
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  // First we navigate to any page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  // Show the Find bar.
  browser()->GetFindBarController()->Show();

  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Search for "a".
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_A, false, false, false, false));

  // We should find "a" here.
  EXPECT_EQ(ASCIIToUTF16("a"), GetFindBarText());

  // Reload the page to clear the matching result.
  browser()->Reload(CURRENT_TAB);

  // Focus the Find bar again to make sure the text is selected.
  browser()->GetFindBarController()->Show();

  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // "a" should be selected.
  EXPECT_EQ(ASCIIToUTF16("a"), GetFindBarSelectedText());

  // Press Ctrl-C to copy the content.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_C, true, false, false, false));

  string16 str;
  views::ViewsDelegate::views_delegate->GetClipboard()->
      ReadText(ui::Clipboard::BUFFER_STANDARD, &str);

  // Make sure the text is copied successfully.
  EXPECT_EQ(ASCIIToUTF16("a"), str);

  // Press Ctrl-V to paste the content back, it should start finding even if the
  // content is not changed.
  content::Source<WebContents> notification_source(
      browser()->GetSelectedWebContents());
  ui_test_utils::WindowedNotificationObserverWithDetails
      <FindNotificationDetails> observer(
          chrome::NOTIFICATION_FIND_RESULT_AVAILABLE, notification_source);

  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_V, true, false, false, false));

  ASSERT_NO_FATAL_FAILURE(observer.Wait());
  FindNotificationDetails details;
  ASSERT_TRUE(observer.GetDetailsFor(notification_source.map_key(), &details));
  EXPECT_TRUE(details.number_of_matches() > 0);
}
<commit_msg>Mark FindInPageTest.PasteWithoutTextChange flaky on CrOS<commit_after>// Copyright (c) 2012 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 "base/process_util.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/find_bar/find_notification_details.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/find_bar_host.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "net/test/test_server.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/keycodes/keyboard_codes.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/view.h"
#include "ui/views/views_delegate.h"

using content::WebContents;

namespace {

// The delay waited after sending an OS simulated event.
static const int kActionDelayMs = 500;
static const char kSimplePage[] = "files/find_in_page/simple.html";

void Checkpoint(const char* message, const base::TimeTicks& start_time) {
  LOG(INFO) << message << " : "
    << (base::TimeTicks::Now() - start_time).InMilliseconds()
    << " ms" << std::flush;
}

class FindInPageTest : public InProcessBrowserTest {
 public:
  FindInPageTest() :
#if defined(USE_AURA)
      location_bar_focus_view_id_(VIEW_ID_OMNIBOX)
#else
      location_bar_focus_view_id_(VIEW_ID_LOCATION_BAR)
#endif
  {
    set_show_window(true);
    FindBarHost::disable_animations_during_testing_ = true;
  }

  string16 GetFindBarText() {
    FindBarTesting* find_bar =
        browser()->GetFindBarController()->find_bar()->GetFindBarTesting();
    return find_bar->GetFindText();
  }

  string16 GetFindBarSelectedText() {
    FindBarTesting* find_bar =
        browser()->GetFindBarController()->find_bar()->GetFindBarTesting();
    return find_bar->GetFindSelectedText();
  }

  ViewID location_bar_focus_view_id_;

 private:
  DISALLOW_COPY_AND_ASSIGN(FindInPageTest);
};

}  // namespace

IN_PROC_BROWSER_TEST_F(FindInPageTest, CrashEscHandlers) {
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page (tab A).
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  browser()->Find();

  // Open another tab (tab B).
  browser()->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_TYPED);

  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Select tab A.
  browser()->ActivateTabAt(0, true);

  // Close tab B.
  browser()->CloseTabContents(browser()->GetWebContentsAt(1));

  // Click on the location bar so that Find box loses focus.
  ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(),
                                                     VIEW_ID_LOCATION_BAR));
  // Check the location bar is focused.
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));

  // This used to crash until bug 1303709 was fixed.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_ESCAPE, false, false, false, false));
}

IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestore) {
  ASSERT_TRUE(test_server()->Start());

  GURL url = test_server()->GetURL("title1.html");
  ui_test_utils::NavigateToURL(browser(), url);

  // Focus the location bar, open and close the find-in-page, focus should
  // return to the location bar.
  browser()->FocusLocationBar();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
  // Ensure the creation of the find bar controller.
  browser()->GetFindBarController()->Show();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  browser()->GetFindBarController()->EndFindSession(
      FindBarController::kKeepSelection);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));

  // Focus the location bar, find something on the page, close the find box,
  // focus should go to the page.
  browser()->FocusLocationBar();
  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(),
                            ASCIIToUTF16("a"), true, false, NULL);
  browser()->GetFindBarController()->EndFindSession(
      FindBarController::kKeepSelection);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  // Focus the location bar, open and close the find box, focus should return to
  // the location bar (same as before, just checking that http://crbug.com/23599
  // is fixed).
  browser()->FocusLocationBar();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
  browser()->GetFindBarController()->Show();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  browser()->GetFindBarController()->EndFindSession(
      FindBarController::kKeepSelection);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
}

IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestoreOnTabSwitch) {
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page (tab A).
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  FindBarTesting* find_bar =
      browser()->GetFindBarController()->find_bar()->GetFindBarTesting();

  // Search for 'a'.
  ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(),
                            ASCIIToUTF16("a"), true, false, NULL);
  EXPECT_TRUE(ASCIIToUTF16("a") == find_bar->GetFindSelectedText());

  // Open another tab (tab B).
  ui_test_utils::WindowedNotificationObserver observer(
      content::NOTIFICATION_LOAD_STOP,
      content::NotificationService::AllSources());
  browser()->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_TYPED);
  observer.Wait();

  // Make sure Find box is open.
  browser()->Find();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Search for 'b'.
  ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(),
                            ASCIIToUTF16("b"), true, false, NULL);
  EXPECT_TRUE(ASCIIToUTF16("b") == find_bar->GetFindSelectedText());

  // Set focus away from the Find bar (to the Location bar).
  browser()->FocusLocationBar();
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));

  // Select tab A. Find bar should get focus.
  browser()->ActivateTabAt(0, true);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  EXPECT_TRUE(ASCIIToUTF16("a") == find_bar->GetFindSelectedText());

  // Select tab B. Location bar should get focus.
  browser()->ActivateTabAt(1, true);
  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           location_bar_focus_view_id_));
}

// This tests that whenever you clear values from the Find box and close it that
// it respects that and doesn't show you the last search, as reported in bug:
// http://crbug.com/40121.
IN_PROC_BROWSER_TEST_F(FindInPageTest, PrepopulateRespectBlank) {
#if defined(OS_MACOSX)
  // FindInPage on Mac doesn't use prepopulated values. Search there is global.
  return;
#endif
  base::TimeTicks start_time = base::TimeTicks::Now();
  Checkpoint("Test starting", start_time);

  ASSERT_TRUE(test_server()->Start());

  // Make sure Chrome is in the foreground, otherwise sending input
  // won't do anything and the test will hang.
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  Checkpoint("Navigate", start_time);

  // First we navigate to any page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  Checkpoint("Show Find bar", start_time);

  // Show the Find bar.
  browser()->GetFindBarController()->Show();

  Checkpoint("Search for 'a'", start_time);

  // Search for "a".
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_A, false, false, false, false));

  // We should find "a" here.
  EXPECT_EQ(ASCIIToUTF16("a"), GetFindBarText());

  Checkpoint("Delete 'a'", start_time);

  // Delete "a".
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_BACK, false, false, false, false));

  // Validate we have cleared the text.
  EXPECT_EQ(string16(), GetFindBarText());

  Checkpoint("Close find bar", start_time);

  // Close the Find box.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_ESCAPE, false, false, false, false));

  Checkpoint("Show Find bar", start_time);

  // Show the Find bar.
  browser()->GetFindBarController()->Show();

  Checkpoint("Validate text", start_time);

  // After the Find box has been reopened, it should not have been prepopulated
  // with "a" again.
  EXPECT_EQ(string16(), GetFindBarText());

  Checkpoint("Close Find bar", start_time);

  // Close the Find box.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_ESCAPE, false, false, false, false));

  Checkpoint("FindNext", start_time);

  // Press F3 to trigger FindNext.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F3, false, false, false, false));

  Checkpoint("Validate", start_time);

  // After the Find box has been reopened, it should still have no prepopulate
  // value.
  EXPECT_EQ(string16(), GetFindBarText());

  Checkpoint("Test done", start_time);
}

// Flaky on Win. http://crbug.com/92467
// Flaky on ChromeOS. http://crbug.com/118216
#if defined(OS_WIN) || defined(OS_CHROMEOS)
#define MAYBE_PasteWithoutTextChange DISABLED_PasteWithoutTextChange
#else
#define MAYBE_PasteWithoutTextChange PasteWithoutTextChange
#endif

IN_PROC_BROWSER_TEST_F(FindInPageTest, MAYBE_PasteWithoutTextChange) {
  ASSERT_TRUE(test_server()->Start());

  // Make sure Chrome is in the foreground, otherwise sending input
  // won't do anything and the test will hang.
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  // First we navigate to any page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  // Show the Find bar.
  browser()->GetFindBarController()->Show();

  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Search for "a".
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_A, false, false, false, false));

  // We should find "a" here.
  EXPECT_EQ(ASCIIToUTF16("a"), GetFindBarText());

  // Reload the page to clear the matching result.
  browser()->Reload(CURRENT_TAB);

  // Focus the Find bar again to make sure the text is selected.
  browser()->GetFindBarController()->Show();

  EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                           VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // "a" should be selected.
  EXPECT_EQ(ASCIIToUTF16("a"), GetFindBarSelectedText());

  // Press Ctrl-C to copy the content.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_C, true, false, false, false));

  string16 str;
  views::ViewsDelegate::views_delegate->GetClipboard()->
      ReadText(ui::Clipboard::BUFFER_STANDARD, &str);

  // Make sure the text is copied successfully.
  EXPECT_EQ(ASCIIToUTF16("a"), str);

  // Press Ctrl-V to paste the content back, it should start finding even if the
  // content is not changed.
  content::Source<WebContents> notification_source(
      browser()->GetSelectedWebContents());
  ui_test_utils::WindowedNotificationObserverWithDetails
      <FindNotificationDetails> observer(
          chrome::NOTIFICATION_FIND_RESULT_AVAILABLE, notification_source);

  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_V, true, false, false, false));

  ASSERT_NO_FATAL_FAILURE(observer.Wait());
  FindNotificationDetails details;
  ASSERT_TRUE(observer.GetDetailsFor(notification_source.map_key(), &details));
  EXPECT_TRUE(details.number_of_matches() > 0);
}
<|endoftext|>


<commit_before>// 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 "chrome/browser/ui/webui/options/language_options_handler.h"

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

LanguageOptionsHandler::LanguageOptionsHandler() {
}

LanguageOptionsHandler::~LanguageOptionsHandler() {
}

void LanguageOptionsHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  LanguageOptionsHandlerCommon::GetLocalizedValues(localized_strings);

  localized_strings->SetString("restart_button",
      l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_LANGUAGES_RELAUNCH_BUTTON));
  localized_strings->Set("languageList", GetLanguageList());
}

void LanguageOptionsHandler::RegisterMessages() {
  LanguageOptionsHandlerCommon::RegisterMessages();

  web_ui_->RegisterMessageCallback("uiLanguageRestart",
      NewCallback(this, &LanguageOptionsHandler::RestartCallback));
}

ListValue* LanguageOptionsHandler::GetLanguageList() {
  // Collect the language codes from the supported accept-languages.
  const std::string app_locale = g_browser_process->GetApplicationLocale();
  std::vector<std::string> language_codes;
  l10n_util::GetAcceptLanguagesForLocale(app_locale, &language_codes);

  // Map of display name -> {language code, native_display_name}.
  // In theory, we should be able to create a map that is sorted by
  // display names using ICU comparator, but doing it is hard, thus we'll
  // use an auxiliary vector to achieve the same result.
  typedef std::pair<std::string, string16> LanguagePair;
  typedef std::map<string16, LanguagePair> LanguageMap;
  LanguageMap language_map;
  // The auxiliary vector mentioned above.
  std::vector<string16> display_names;

  // Build the list of display names, and build the language map.
  for (size_t i = 0; i < language_codes.size(); ++i) {
    const string16 display_name =
        l10n_util::GetDisplayNameForLocale(language_codes[i], app_locale, true);
    const string16 native_display_name =
        l10n_util::GetDisplayNameForLocale(language_codes[i], language_codes[i],
                                           true);
    display_names.push_back(display_name);
    language_map[display_name] =
        std::make_pair(language_codes[i], native_display_name);
  }
  DCHECK_EQ(display_names.size(), language_map.size());

  // Sort display names using locale specific sorter.
  l10n_util::SortStrings16(app_locale, &display_names);

  // Build the language list from the language map.
  ListValue* language_list = new ListValue();
  for (size_t i = 0; i < display_names.size(); ++i) {
    const LanguagePair& pair = language_map[display_names[i]];
    DictionaryValue* dictionary = new DictionaryValue();
    dictionary->SetString("code",  pair.first);
    dictionary->SetString("displayName", display_names[i]);
    dictionary->SetString("nativeDisplayName", pair.second);
    language_list->Append(dictionary);
  }

  return language_list;
}

string16 LanguageOptionsHandler::GetProductName() {
  return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
}

void LanguageOptionsHandler::SetApplicationLocale(
    const std::string& language_code) {
  PrefService* pref_service = g_browser_process->local_state();
  pref_service->SetString(prefs::kApplicationLocale, language_code);
}

void LanguageOptionsHandler::RestartCallback(const ListValue* args) {
  UserMetrics::RecordAction(UserMetricsAction("LanguageOptions_Restart"));

  // Set the flag to restore state after the restart.
  PrefService* pref_service = g_browser_process->local_state();
  pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true);
  BrowserList::CloseAllBrowsersAndExit();
}
<commit_msg>web-ui settings: Fix display of languages for RTL systems.<commit_after>// 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 "chrome/browser/ui/webui/options/language_options_handler.h"

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

LanguageOptionsHandler::LanguageOptionsHandler() {
}

LanguageOptionsHandler::~LanguageOptionsHandler() {
}

void LanguageOptionsHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  LanguageOptionsHandlerCommon::GetLocalizedValues(localized_strings);

  localized_strings->SetString("restart_button",
      l10n_util::GetStringUTF16(
          IDS_OPTIONS_SETTINGS_LANGUAGES_RELAUNCH_BUTTON));
  localized_strings->Set("languageList", GetLanguageList());
}

void LanguageOptionsHandler::RegisterMessages() {
  LanguageOptionsHandlerCommon::RegisterMessages();

  web_ui_->RegisterMessageCallback("uiLanguageRestart",
      NewCallback(this, &LanguageOptionsHandler::RestartCallback));
}

ListValue* LanguageOptionsHandler::GetLanguageList() {
  // Collect the language codes from the supported accept-languages.
  const std::string app_locale = g_browser_process->GetApplicationLocale();
  std::vector<std::string> language_codes;
  l10n_util::GetAcceptLanguagesForLocale(app_locale, &language_codes);

  // Map of display name -> {language code, native_display_name}.
  // In theory, we should be able to create a map that is sorted by
  // display names using ICU comparator, but doing it is hard, thus we'll
  // use an auxiliary vector to achieve the same result.
  typedef std::pair<std::string, string16> LanguagePair;
  typedef std::map<string16, LanguagePair> LanguageMap;
  LanguageMap language_map;
  // The auxiliary vector mentioned above.
  std::vector<string16> display_names;

  // Build the list of display names, and build the language map.
  for (size_t i = 0; i < language_codes.size(); ++i) {
    string16 display_name =
        l10n_util::GetDisplayNameForLocale(language_codes[i], app_locale,
                                           false);
    base::i18n::AdjustStringForLocaleDirection(&display_name);
    string16 native_display_name =
        l10n_util::GetDisplayNameForLocale(language_codes[i], language_codes[i],
                                           false);
    base::i18n::AdjustStringForLocaleDirection(&native_display_name);
    display_names.push_back(display_name);
    language_map[display_name] =
        std::make_pair(language_codes[i], native_display_name);
  }
  DCHECK_EQ(display_names.size(), language_map.size());

  // Sort display names using locale specific sorter.
  l10n_util::SortStrings16(app_locale, &display_names);

  // Build the language list from the language map.
  ListValue* language_list = new ListValue();
  for (size_t i = 0; i < display_names.size(); ++i) {
    const LanguagePair& pair = language_map[display_names[i]];
    DictionaryValue* dictionary = new DictionaryValue();
    dictionary->SetString("code",  pair.first);
    dictionary->SetString("displayName", display_names[i]);
    dictionary->SetString("nativeDisplayName", pair.second);
    language_list->Append(dictionary);
  }

  return language_list;
}

string16 LanguageOptionsHandler::GetProductName() {
  return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
}

void LanguageOptionsHandler::SetApplicationLocale(
    const std::string& language_code) {
  PrefService* pref_service = g_browser_process->local_state();
  pref_service->SetString(prefs::kApplicationLocale, language_code);
}

void LanguageOptionsHandler::RestartCallback(const ListValue* args) {
  UserMetrics::RecordAction(UserMetricsAction("LanguageOptions_Restart"));

  // Set the flag to restore state after the restart.
  PrefService* pref_service = g_browser_process->local_state();
  pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true);
  BrowserList::CloseAllBrowsersAndExit();
}
<|endoftext|>


<commit_before>// Copyright 2013 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 "chrome/browser/extensions/api/sessions/sessions_api.h"

#include "base/command_line.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/api/tabs/tabs_api.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sync/glue/session_model_associator.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_switches.h"
#include "chrome/test/base/testing_browser_process.h"

namespace utils = extension_function_test_utils;

namespace extensions {

namespace {

// If more sessions are added to session tags, num sessions should be updated.
const char* kSessionTags[] = {"tag0", "tag1", "tag2", "tag3", "tag4"};
const size_t kNumSessions = 5;

void BuildSessionSpecifics(const std::string& tag,
                           sync_pb::SessionSpecifics* meta) {
  meta->set_session_tag(tag);
  sync_pb::SessionHeader* header = meta->mutable_header();
  header->set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
  header->set_client_name(tag);
}

void BuildWindowSpecifics(int window_id,
                          const std::vector<int>& tab_list,
                          sync_pb::SessionSpecifics* meta) {
  sync_pb::SessionHeader* header = meta->mutable_header();
  sync_pb::SessionWindow* window = header->add_window();
  window->set_window_id(window_id);
  window->set_selected_tab_index(0);
  window->set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
  for (std::vector<int>::const_iterator iter = tab_list.begin();
       iter != tab_list.end(); ++iter) {
    window->add_tab(*iter);
  }
}

void BuildTabSpecifics(const std::string& tag, int window_id, int tab_id,
                       sync_pb::SessionSpecifics* tab_base) {
  tab_base->set_session_tag(tag);
  tab_base->set_tab_node_id(0);
  sync_pb::SessionTab* tab = tab_base->mutable_tab();
  tab->set_tab_id(tab_id);
  tab->set_tab_visual_index(1);
  tab->set_current_navigation_index(0);
  tab->set_pinned(true);
  tab->set_extension_app_id("app_id");
  sync_pb::TabNavigation* navigation = tab->add_navigation();
  navigation->set_virtual_url("http://foo/1");
  navigation->set_referrer("referrer");
  navigation->set_title("title");
  navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED);
}

} // namespace

class ExtensionSessionsTest : public InProcessBrowserTest {
 public:
  virtual void SetUpOnMainThread() OVERRIDE;
 protected:
  void CreateTestProfileSyncService();
  void CreateTestExtension();
  void CreateSessionModels();

  template <class T>
  scoped_refptr<T> CreateFunction(bool has_callback) {
    scoped_refptr<T> fn(new T());
    fn->set_extension(extension_.get());
    fn->set_has_callback(has_callback);
    return fn;
  };

  Browser* browser_;
  browser_sync::SessionModelAssociator* associator_;
  scoped_refptr<extensions::Extension> extension_;
};

void ExtensionSessionsTest::SetUpOnMainThread() {
  CreateTestProfileSyncService();
  CreateTestExtension();
}

void ExtensionSessionsTest::CreateTestProfileSyncService() {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  base::FilePath path;
  PathService::Get(chrome::DIR_USER_DATA, &path);
  path = path.AppendASCII("test_profile");
  if (!base::PathExists(path))
    CHECK(file_util::CreateDirectory(path));
  Profile* profile =
      Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
  profile_manager->RegisterTestingProfile(profile, true, false);
  browser_ = new Browser(Browser::CreateParams(
      profile, chrome::HOST_DESKTOP_TYPE_NATIVE));
  ProfileSyncServiceMock* service = static_cast<ProfileSyncServiceMock*>(
      ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
      profile, &ProfileSyncServiceMock::BuildMockProfileSyncService));

  associator_ = new browser_sync::SessionModelAssociator(
      static_cast<ProfileSyncService*>(service), true);
  syncer::ModelTypeSet preferred_types;
  preferred_types.Put(syncer::SESSIONS);
  GoogleServiceAuthError no_error(GoogleServiceAuthError::NONE);

  ON_CALL(*service, GetSessionModelAssociator()).WillByDefault(
      testing::Return(associator_));
  ON_CALL(*service, GetPreferredDataTypes()).WillByDefault(
      testing::Return(preferred_types));
  EXPECT_CALL(*service, GetAuthError()).WillRepeatedly(
      testing::ReturnRef(no_error));
  ON_CALL(*service, GetActiveDataTypes()).WillByDefault(
      testing::Return(preferred_types));
  EXPECT_CALL(*service, AddObserver(testing::_)).Times(testing::AnyNumber());
  EXPECT_CALL(*service, RemoveObserver(testing::_)).Times(testing::AnyNumber());

  service->Initialize();
}

void ExtensionSessionsTest::CreateTestExtension() {
  scoped_ptr<base::DictionaryValue> test_extension_value(
      utils::ParseDictionary(
      "{\"name\": \"Test\", \"version\": \"1.0\", "
      "\"permissions\": [\"sessions\", \"tabs\"]}"));
  extension_ = utils::CreateExtension(test_extension_value.get());
}

void ExtensionSessionsTest::CreateSessionModels() {
  for (size_t index = 0; index < kNumSessions; ++index) {
    // Fill an instance of session specifics with a foreign session's data.
    sync_pb::SessionSpecifics meta;
    BuildSessionSpecifics(kSessionTags[index], &meta);
    SessionID::id_type tab_nums1[] = {5, 10, 13, 17};
    std::vector<SessionID::id_type> tab_list1(
        tab_nums1, tab_nums1 + arraysize(tab_nums1));
    BuildWindowSpecifics(index, tab_list1, &meta);
    std::vector<sync_pb::SessionSpecifics> tabs1;
    tabs1.resize(tab_list1.size());
    for (size_t i = 0; i < tab_list1.size(); ++i) {
      BuildTabSpecifics(kSessionTags[index], 0, tab_list1[i], &tabs1[i]);
    }

    associator_->SetCurrentMachineTagForTesting(kSessionTags[index]);
    // Update associator with the session's meta node containing one window.
    associator_->AssociateForeignSpecifics(meta, base::Time());
    // Add tabs for the window.
    for (std::vector<sync_pb::SessionSpecifics>::iterator iter = tabs1.begin();
         iter != tabs1.end(); ++iter) {
      associator_->AssociateForeignSpecifics(*iter, base::Time());
    }
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevices) {
  CreateSessionModels();

  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsGetDevicesFunction>(true).get(),
          "[{\"maxResults\": 0}]",
          browser_)));
  ASSERT_TRUE(result);
  ListValue* devices = result.get();
  EXPECT_EQ(5u, devices->GetSize());
  DictionaryValue* device = NULL;
  ListValue* sessions = NULL;
  for (size_t i = 0; i < devices->GetSize(); ++i) {
    EXPECT_TRUE(devices->GetDictionary(i, &device));
    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "info"));
    EXPECT_TRUE(device->GetList("sessions", &sessions));
    EXPECT_EQ(0u, sessions->GetSize());
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevicesMaxResults) {
  CreateSessionModels();

  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsGetDevicesFunction>(true).get(),
          "[]",
          browser_)));
  ASSERT_TRUE(result);
  ListValue* devices = result.get();
  EXPECT_EQ(5u, devices->GetSize());
  DictionaryValue* device = NULL;
  ListValue* sessions = NULL;
  for (size_t i = 0; i < devices->GetSize(); ++i) {
    EXPECT_TRUE(devices->GetDictionary(i, &device));
    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "info"));
    EXPECT_TRUE(device->GetList("sessions", &sessions));
    EXPECT_EQ(1u, sessions->GetSize());
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevicesListEmpty) {
  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsGetDevicesFunction>(true).get(),
          "[]",
          browser_)));

  ASSERT_TRUE(result);
  ListValue* devices = result.get();
  EXPECT_EQ(0u, devices->GetSize());
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, RestoreForeignSessionWindow) {
  CreateSessionModels();

  scoped_ptr<base::DictionaryValue> restored_window_session(utils::ToDictionary(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsRestoreFunction>(true).get(),
          "[\"tag3.3\"]",
          browser_,
          utils::INCLUDE_INCOGNITO)));
  ASSERT_TRUE(restored_window_session);

  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<WindowsGetAllFunction>(true).get(),
          "[]",
          browser_)));
  ASSERT_TRUE(result);

  ListValue* windows = result.get();
  EXPECT_EQ(2u, windows->GetSize());
  DictionaryValue* restored_window = NULL;
  EXPECT_TRUE(restored_window_session->GetDictionary("window",
                                                     &restored_window));
  DictionaryValue* window = NULL;
  int restored_id = utils::GetInteger(restored_window, "id");
  for (size_t i = 0; i < windows->GetSize(); ++i) {
    EXPECT_TRUE(windows->GetDictionary(i, &window));
    if (utils::GetInteger(window, "id") == restored_id)
      break;
  }
  EXPECT_EQ(restored_id, utils::GetInteger(window, "id"));
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, RestoreForeignSessionInvalidId) {
  CreateSessionModels();

  EXPECT_TRUE(MatchPattern(utils::RunFunctionAndReturnError(
      CreateFunction<SessionsRestoreFunction>(true).get(),
      "[\"tag3.0\"]",
      browser_), "Invalid session id: \"tag3.0\"."));
}

// Flaky on ChromeOS, times out on OSX Debug http://crbug.com/251199
#if defined(OS_CHROMEOS) || (defined(OS_MACOSX) && !defined(NDEBUG))
#define MAYBE_SessionsApis DISABLED_SessionsApis
#else
#define MAYBE_SessionsApis SessionsApis
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_SessionsApis) {
#if defined(OS_WIN) && defined(USE_ASH)
  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    return;
#endif

  ASSERT_TRUE(RunExtensionSubtest("sessions",
                                  "sessions.html")) << message_;
}

}  // namespace extensions
<commit_msg>Disable flaky ExtensionSessionsTest.RestoreForeignSessionWindow.<commit_after>// Copyright 2013 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 "chrome/browser/extensions/api/sessions/sessions_api.h"

#include "base/command_line.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/api/tabs/tabs_api.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sync/glue/session_model_associator.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_switches.h"
#include "chrome/test/base/testing_browser_process.h"

namespace utils = extension_function_test_utils;

namespace extensions {

namespace {

// If more sessions are added to session tags, num sessions should be updated.
const char* kSessionTags[] = {"tag0", "tag1", "tag2", "tag3", "tag4"};
const size_t kNumSessions = 5;

void BuildSessionSpecifics(const std::string& tag,
                           sync_pb::SessionSpecifics* meta) {
  meta->set_session_tag(tag);
  sync_pb::SessionHeader* header = meta->mutable_header();
  header->set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
  header->set_client_name(tag);
}

void BuildWindowSpecifics(int window_id,
                          const std::vector<int>& tab_list,
                          sync_pb::SessionSpecifics* meta) {
  sync_pb::SessionHeader* header = meta->mutable_header();
  sync_pb::SessionWindow* window = header->add_window();
  window->set_window_id(window_id);
  window->set_selected_tab_index(0);
  window->set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
  for (std::vector<int>::const_iterator iter = tab_list.begin();
       iter != tab_list.end(); ++iter) {
    window->add_tab(*iter);
  }
}

void BuildTabSpecifics(const std::string& tag, int window_id, int tab_id,
                       sync_pb::SessionSpecifics* tab_base) {
  tab_base->set_session_tag(tag);
  tab_base->set_tab_node_id(0);
  sync_pb::SessionTab* tab = tab_base->mutable_tab();
  tab->set_tab_id(tab_id);
  tab->set_tab_visual_index(1);
  tab->set_current_navigation_index(0);
  tab->set_pinned(true);
  tab->set_extension_app_id("app_id");
  sync_pb::TabNavigation* navigation = tab->add_navigation();
  navigation->set_virtual_url("http://foo/1");
  navigation->set_referrer("referrer");
  navigation->set_title("title");
  navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED);
}

} // namespace

class ExtensionSessionsTest : public InProcessBrowserTest {
 public:
  virtual void SetUpOnMainThread() OVERRIDE;
 protected:
  void CreateTestProfileSyncService();
  void CreateTestExtension();
  void CreateSessionModels();

  template <class T>
  scoped_refptr<T> CreateFunction(bool has_callback) {
    scoped_refptr<T> fn(new T());
    fn->set_extension(extension_.get());
    fn->set_has_callback(has_callback);
    return fn;
  };

  Browser* browser_;
  browser_sync::SessionModelAssociator* associator_;
  scoped_refptr<extensions::Extension> extension_;
};

void ExtensionSessionsTest::SetUpOnMainThread() {
  CreateTestProfileSyncService();
  CreateTestExtension();
}

void ExtensionSessionsTest::CreateTestProfileSyncService() {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  base::FilePath path;
  PathService::Get(chrome::DIR_USER_DATA, &path);
  path = path.AppendASCII("test_profile");
  if (!base::PathExists(path))
    CHECK(file_util::CreateDirectory(path));
  Profile* profile =
      Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
  profile_manager->RegisterTestingProfile(profile, true, false);
  browser_ = new Browser(Browser::CreateParams(
      profile, chrome::HOST_DESKTOP_TYPE_NATIVE));
  ProfileSyncServiceMock* service = static_cast<ProfileSyncServiceMock*>(
      ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
      profile, &ProfileSyncServiceMock::BuildMockProfileSyncService));

  associator_ = new browser_sync::SessionModelAssociator(
      static_cast<ProfileSyncService*>(service), true);
  syncer::ModelTypeSet preferred_types;
  preferred_types.Put(syncer::SESSIONS);
  GoogleServiceAuthError no_error(GoogleServiceAuthError::NONE);

  ON_CALL(*service, GetSessionModelAssociator()).WillByDefault(
      testing::Return(associator_));
  ON_CALL(*service, GetPreferredDataTypes()).WillByDefault(
      testing::Return(preferred_types));
  EXPECT_CALL(*service, GetAuthError()).WillRepeatedly(
      testing::ReturnRef(no_error));
  ON_CALL(*service, GetActiveDataTypes()).WillByDefault(
      testing::Return(preferred_types));
  EXPECT_CALL(*service, AddObserver(testing::_)).Times(testing::AnyNumber());
  EXPECT_CALL(*service, RemoveObserver(testing::_)).Times(testing::AnyNumber());

  service->Initialize();
}

void ExtensionSessionsTest::CreateTestExtension() {
  scoped_ptr<base::DictionaryValue> test_extension_value(
      utils::ParseDictionary(
      "{\"name\": \"Test\", \"version\": \"1.0\", "
      "\"permissions\": [\"sessions\", \"tabs\"]}"));
  extension_ = utils::CreateExtension(test_extension_value.get());
}

void ExtensionSessionsTest::CreateSessionModels() {
  for (size_t index = 0; index < kNumSessions; ++index) {
    // Fill an instance of session specifics with a foreign session's data.
    sync_pb::SessionSpecifics meta;
    BuildSessionSpecifics(kSessionTags[index], &meta);
    SessionID::id_type tab_nums1[] = {5, 10, 13, 17};
    std::vector<SessionID::id_type> tab_list1(
        tab_nums1, tab_nums1 + arraysize(tab_nums1));
    BuildWindowSpecifics(index, tab_list1, &meta);
    std::vector<sync_pb::SessionSpecifics> tabs1;
    tabs1.resize(tab_list1.size());
    for (size_t i = 0; i < tab_list1.size(); ++i) {
      BuildTabSpecifics(kSessionTags[index], 0, tab_list1[i], &tabs1[i]);
    }

    associator_->SetCurrentMachineTagForTesting(kSessionTags[index]);
    // Update associator with the session's meta node containing one window.
    associator_->AssociateForeignSpecifics(meta, base::Time());
    // Add tabs for the window.
    for (std::vector<sync_pb::SessionSpecifics>::iterator iter = tabs1.begin();
         iter != tabs1.end(); ++iter) {
      associator_->AssociateForeignSpecifics(*iter, base::Time());
    }
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevices) {
  CreateSessionModels();

  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsGetDevicesFunction>(true).get(),
          "[{\"maxResults\": 0}]",
          browser_)));
  ASSERT_TRUE(result);
  ListValue* devices = result.get();
  EXPECT_EQ(5u, devices->GetSize());
  DictionaryValue* device = NULL;
  ListValue* sessions = NULL;
  for (size_t i = 0; i < devices->GetSize(); ++i) {
    EXPECT_TRUE(devices->GetDictionary(i, &device));
    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "info"));
    EXPECT_TRUE(device->GetList("sessions", &sessions));
    EXPECT_EQ(0u, sessions->GetSize());
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevicesMaxResults) {
  CreateSessionModels();

  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsGetDevicesFunction>(true).get(),
          "[]",
          browser_)));
  ASSERT_TRUE(result);
  ListValue* devices = result.get();
  EXPECT_EQ(5u, devices->GetSize());
  DictionaryValue* device = NULL;
  ListValue* sessions = NULL;
  for (size_t i = 0; i < devices->GetSize(); ++i) {
    EXPECT_TRUE(devices->GetDictionary(i, &device));
    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "info"));
    EXPECT_TRUE(device->GetList("sessions", &sessions));
    EXPECT_EQ(1u, sessions->GetSize());
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevicesListEmpty) {
  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsGetDevicesFunction>(true).get(),
          "[]",
          browser_)));

  ASSERT_TRUE(result);
  ListValue* devices = result.get();
  EXPECT_EQ(0u, devices->GetSize());
}

// Flaky timeout: http://crbug.com/278372
IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest,
                       DISABLED_RestoreForeignSessionWindow) {
  CreateSessionModels();

  scoped_ptr<base::DictionaryValue> restored_window_session(utils::ToDictionary(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<SessionsRestoreFunction>(true).get(),
          "[\"tag3.3\"]",
          browser_,
          utils::INCLUDE_INCOGNITO)));
  ASSERT_TRUE(restored_window_session);

  scoped_ptr<base::ListValue> result(utils::ToList(
      utils::RunFunctionAndReturnSingleResult(
          CreateFunction<WindowsGetAllFunction>(true).get(),
          "[]",
          browser_)));
  ASSERT_TRUE(result);

  ListValue* windows = result.get();
  EXPECT_EQ(2u, windows->GetSize());
  DictionaryValue* restored_window = NULL;
  EXPECT_TRUE(restored_window_session->GetDictionary("window",
                                                     &restored_window));
  DictionaryValue* window = NULL;
  int restored_id = utils::GetInteger(restored_window, "id");
  for (size_t i = 0; i < windows->GetSize(); ++i) {
    EXPECT_TRUE(windows->GetDictionary(i, &window));
    if (utils::GetInteger(window, "id") == restored_id)
      break;
  }
  EXPECT_EQ(restored_id, utils::GetInteger(window, "id"));
}

IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, RestoreForeignSessionInvalidId) {
  CreateSessionModels();

  EXPECT_TRUE(MatchPattern(utils::RunFunctionAndReturnError(
      CreateFunction<SessionsRestoreFunction>(true).get(),
      "[\"tag3.0\"]",
      browser_), "Invalid session id: \"tag3.0\"."));
}

// Flaky on ChromeOS, times out on OSX Debug http://crbug.com/251199
#if defined(OS_CHROMEOS) || (defined(OS_MACOSX) && !defined(NDEBUG))
#define MAYBE_SessionsApis DISABLED_SessionsApis
#else
#define MAYBE_SessionsApis SessionsApis
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_SessionsApis) {
#if defined(OS_WIN) && defined(USE_ASH)
  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    return;
#endif

  ASSERT_TRUE(RunExtensionSubtest("sessions",
                                  "sessions.html")) << message_;
}

}  // namespace extensions
<|endoftext|>