blob: 87c8f74d0e0346fd4f816817596427387f420f45 [file] [log] [blame]
// Copyright 2015 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 <string>
#include <vector>
#include "base/macros.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/media/router/issue_manager.h"
#include "chrome/browser/media/router/test/test_helper.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
using testing::_;
using testing::SaveArg;
namespace media_router {
namespace {
IssueInfo CreateTestIssue(IssueInfo::Severity severity) {
IssueInfo issue("title", IssueInfo::Action::DISMISS, severity);
issue.message = "message";
issue.help_page_id = 12345;
return issue;
}
} // namespace
class IssueManagerTest : public ::testing::Test {
protected:
IssueManagerTest()
: thread_bundle_(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {
manager_.set_task_runner_for_test(thread_bundle_.GetMainThreadTaskRunner());
}
~IssueManagerTest() override {}
content::TestBrowserThreadBundle thread_bundle_;
IssueManager manager_;
};
TEST_F(IssueManagerTest, AddAndClearIssue) {
IssueInfo issue_info1 = CreateTestIssue(IssueInfo::Severity::WARNING);
// Add initial issue.
manager_.AddIssue(issue_info1);
Issue issue1((IssueInfo()));
MockIssuesObserver observer(&manager_);
EXPECT_CALL(observer, OnIssue(_)).WillOnce(SaveArg<0>(&issue1));
observer.Init();
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer));
EXPECT_EQ(issue_info1, issue1.info());
Issue::Id issue1_id = issue1.id();
EXPECT_FALSE(issue1.info().is_blocking);
IssueInfo issue_info2 = CreateTestIssue(IssueInfo::Severity::FATAL);
EXPECT_TRUE(issue_info2.is_blocking);
// Blocking issue takes precedence.
Issue issue2((IssueInfo()));
EXPECT_CALL(observer, OnIssue(_)).WillOnce(SaveArg<0>(&issue2));
manager_.AddIssue(issue_info2);
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer));
EXPECT_EQ(issue_info2, issue2.info());
// Clear |issue2|. Observer will be notified with |issue1| again as it is now
// the top issue.
EXPECT_CALL(observer, OnIssue(_)).WillOnce(SaveArg<0>(&issue1));
manager_.ClearIssue(issue2.id());
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer));
EXPECT_EQ(issue1_id, issue1.id());
EXPECT_EQ(issue_info1, issue1.info());
// All issues cleared. Observer will be notified with |nullptr| that there are
// no more issues.
EXPECT_CALL(observer, OnIssuesCleared());
manager_.ClearIssue(issue1.id());
}
TEST_F(IssueManagerTest, AddSameIssueInfoHasNoEffect) {
IssueInfo issue_info = CreateTestIssue(IssueInfo::Severity::WARNING);
MockIssuesObserver observer(&manager_);
observer.Init();
Issue issue((IssueInfo()));
EXPECT_CALL(observer, OnIssue(_)).WillOnce(SaveArg<0>(&issue));
manager_.AddIssue(issue_info);
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer));
EXPECT_EQ(issue_info, issue.info());
// Adding the same IssueInfo has no effect.
manager_.AddIssue(issue_info);
EXPECT_CALL(observer, OnIssuesCleared());
manager_.ClearIssue(issue.id());
}
TEST_F(IssueManagerTest, NonBlockingIssuesGetAutoDismissed) {
MockIssuesObserver observer(&manager_);
observer.Init();
EXPECT_CALL(observer, OnIssue(_)).Times(1);
IssueInfo issue_info1 = CreateTestIssue(IssueInfo::Severity::NOTIFICATION);
manager_.AddIssue(issue_info1);
EXPECT_CALL(observer, OnIssuesCleared()).Times(1);
base::TimeDelta timeout = IssueManager::GetAutoDismissTimeout(issue_info1);
EXPECT_FALSE(timeout.is_zero());
EXPECT_TRUE(thread_bundle_.MainThreadHasPendingTask());
thread_bundle_.FastForwardBy(timeout);
EXPECT_CALL(observer, OnIssue(_)).Times(1);
IssueInfo issue_info2 = CreateTestIssue(IssueInfo::Severity::WARNING);
manager_.AddIssue(issue_info2);
EXPECT_CALL(observer, OnIssuesCleared()).Times(1);
timeout = IssueManager::GetAutoDismissTimeout(issue_info2);
EXPECT_FALSE(timeout.is_zero());
EXPECT_TRUE(thread_bundle_.MainThreadHasPendingTask());
thread_bundle_.FastForwardBy(timeout);
EXPECT_FALSE(thread_bundle_.MainThreadHasPendingTask());
}
TEST_F(IssueManagerTest, IssueAutoDismissNoopsIfAlreadyCleared) {
MockIssuesObserver observer(&manager_);
observer.Init();
Issue issue1((IssueInfo()));
EXPECT_CALL(observer, OnIssue(_)).Times(1).WillOnce(SaveArg<0>(&issue1));
IssueInfo issue_info1 = CreateTestIssue(IssueInfo::Severity::NOTIFICATION);
manager_.AddIssue(issue_info1);
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer));
EXPECT_CALL(observer, OnIssuesCleared()).Times(1);
EXPECT_TRUE(thread_bundle_.MainThreadHasPendingTask());
manager_.ClearIssue(issue1.id());
EXPECT_CALL(observer, OnIssuesCleared()).Times(0);
base::TimeDelta timeout = IssueManager::GetAutoDismissTimeout(issue_info1);
EXPECT_FALSE(timeout.is_zero());
EXPECT_FALSE(thread_bundle_.MainThreadHasPendingTask());
}
TEST_F(IssueManagerTest, BlockingIssuesDoNotGetAutoDismissed) {
MockIssuesObserver observer(&manager_);
observer.Init();
EXPECT_CALL(observer, OnIssue(_)).Times(1);
IssueInfo issue_info1 = CreateTestIssue(IssueInfo::Severity::WARNING);
issue_info1.is_blocking = true;
manager_.AddIssue(issue_info1);
EXPECT_CALL(observer, OnIssuesCleared()).Times(0);
base::TimeDelta timeout = IssueManager::GetAutoDismissTimeout(issue_info1);
EXPECT_TRUE(timeout.is_zero());
EXPECT_FALSE(thread_bundle_.MainThreadHasPendingTask());
// FATAL issues are always blocking.
IssueInfo issue_info2 = CreateTestIssue(IssueInfo::Severity::FATAL);
manager_.AddIssue(issue_info2);
timeout = IssueManager::GetAutoDismissTimeout(issue_info2);
EXPECT_TRUE(timeout.is_zero());
EXPECT_FALSE(thread_bundle_.MainThreadHasPendingTask());
}
TEST_F(IssueManagerTest, ClearNonBlockingIssues) {
MockIssuesObserver observer(&manager_);
observer.Init();
EXPECT_CALL(observer, OnIssue(_)).Times(1);
manager_.AddIssue(CreateTestIssue(IssueInfo::Severity::NOTIFICATION));
manager_.AddIssue(CreateTestIssue(IssueInfo::Severity::WARNING));
EXPECT_CALL(observer, OnIssuesCleared()).Times(1);
manager_.ClearNonBlockingIssues();
}
TEST_F(IssueManagerTest, ClearNonBlockingIssuesDoesNotClearBlockingIssue) {
MockIssuesObserver observer(&manager_);
observer.Init();
// Add a blocking issue and a couple of non-blocking issues.
Issue blocking_issue((IssueInfo()));
EXPECT_CALL(observer, OnIssue(_))
.Times(1)
.WillOnce(SaveArg<0>(&blocking_issue));
manager_.AddIssue(CreateTestIssue(IssueInfo::Severity::FATAL));
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer));
manager_.AddIssue(CreateTestIssue(IssueInfo::Severity::NOTIFICATION));
manager_.AddIssue(CreateTestIssue(IssueInfo::Severity::WARNING));
EXPECT_CALL(observer, OnIssuesCleared()).Times(0);
// The blocking issue remains.
manager_.ClearNonBlockingIssues();
Issue same_blocking_issue((IssueInfo()));
MockIssuesObserver observer2(&manager_);
EXPECT_CALL(observer2, OnIssue(_))
.Times(1)
.WillOnce(SaveArg<0>(&same_blocking_issue));
observer2.Init();
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer2));
EXPECT_EQ(blocking_issue.id(), same_blocking_issue.id());
}
} // namespace media_router