Add tests of visibility of hidden view and change button in system tray

This CL adds the tests of the hidden view and the change button in the
system tray.

This also introduces the Mode::PROHIBITED in AshMessageCenterLockScreen-
Controller, which indicates the lock screen notification is forcibly
prohibited by the policy or the flag.

Bug: none
Test: added unittests pass

Change-Id: I709d295c781848483d84d21058f73a427f0c2bc0
Reviewed-on: https://chromium-review.googlesource.com/c/1466226
Commit-Queue: Yoshiki Iguchi <yoshiki@chromium.org>
Auto-Submit: Yoshiki Iguchi <yoshiki@chromium.org>
Reviewed-by: Tetsui Ohkubo <tetsui@chromium.org>
Cr-Commit-Position: refs/heads/master@{#631541}
diff --git a/ash/system/message_center/ash_message_center_lock_screen_controller.cc b/ash/system/message_center/ash_message_center_lock_screen_controller.cc
index 02fcf07..524f10b 100644
--- a/ash/system/message_center/ash_message_center_lock_screen_controller.cc
+++ b/ash/system/message_center/ash_message_center_lock_screen_controller.cc
@@ -22,22 +22,38 @@
 
 namespace ash {
 
+// static private
+base::Optional<AshMessageCenterLockScreenController::Mode>
+    AshMessageCenterLockScreenController::overridden_mode_for_testing_;
+
 // static
 bool AshMessageCenterLockScreenController::IsEnabled() {
-  return GetMode() != Mode::HIDE;
+  auto mode = GetMode();
+  bool is_showing = (mode == Mode::SHOW || mode == Mode::HIDE_SENSITIVE);
+  // If |isAllowed()| is false, must return false;
+  DCHECK(!is_showing || IsAllowed());
+  return is_showing;
 }
 
 // static
+bool AshMessageCenterLockScreenController::IsAllowed() {
+  return GetMode() != Mode::PROHIBITED;
+}
+
+// static, private
 AshMessageCenterLockScreenController::Mode
 AshMessageCenterLockScreenController::GetMode() {
+  if (overridden_mode_for_testing_.has_value())
+    return *overridden_mode_for_testing_;
+
   if (!features::IsLockScreenNotificationsEnabled())
-    return Mode::HIDE;
+    return Mode::PROHIBITED;
 
   // User prefs may be null in some tests.
   PrefService* user_prefs =
       Shell::Get()->session_controller()->GetLastActiveUserPrefService();
   if (!user_prefs)
-    return Mode::HIDE;
+    return Mode::PROHIBITED;
 
   const std::string& mode =
       user_prefs->GetString(prefs::kMessageCenterLockScreenMode);
@@ -50,6 +66,12 @@
   return Mode::HIDE;
 }
 
+// static, only for testing
+void AshMessageCenterLockScreenController::OverrideModeForTest(
+    base::Optional<AshMessageCenterLockScreenController::Mode> new_mode) {
+  overridden_mode_for_testing_ = new_mode;
+}
+
 namespace {
 const char kToastId[] = "ash-lock-screen-manager";
 }  // anonymous namespace
diff --git a/ash/system/message_center/ash_message_center_lock_screen_controller.h b/ash/system/message_center/ash_message_center_lock_screen_controller.h
index 1c33856..d5e4b6b 100644
--- a/ash/system/message_center/ash_message_center_lock_screen_controller.h
+++ b/ash/system/message_center/ash_message_center_lock_screen_controller.h
@@ -7,6 +7,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/session/session_observer.h"
+#include "base/optional.h"
 #include "components/account_id/account_id.h"
 #include "ui/message_center/lock_screen/lock_screen_controller.h"
 
@@ -17,15 +18,14 @@
     : public message_center::LockScreenController,
       public SessionObserver {
  public:
-  // Modes of the lock screen notification.
-  enum class Mode { HIDE, SHOW, HIDE_SENSITIVE };
-
   // Returns if the message center shows the notifications on the lock screen
   // or not. True if it shows, false if doesn't.
   static ASH_EXPORT bool IsEnabled();
 
-  // Returns the current mode of the lock screen notification.
-  static Mode GetMode();
+  // Returns if the message center on the lock screen is forcibly disabled,
+  // due to the policy or the corrupt state.
+  // When this returns true, |IsEnabled()| must return false.
+  static ASH_EXPORT bool IsAllowed();
 
   AshMessageCenterLockScreenController();
   ~AshMessageCenterLockScreenController() override;
@@ -36,6 +36,27 @@
   bool IsScreenLocked() const override;
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(UnifiedSystemTrayControllerTest,
+                           NotificationHiddenView_ModeShow);
+  FRIEND_TEST_ALL_PREFIXES(UnifiedSystemTrayControllerTest,
+                           NotificationHiddenView_ModeHide);
+  FRIEND_TEST_ALL_PREFIXES(UnifiedSystemTrayControllerTest,
+                           NotificationHiddenView_ModeHideSensitive);
+  FRIEND_TEST_ALL_PREFIXES(UnifiedSystemTrayControllerTest,
+                           NotificationHiddenView_ModeProhibited);
+
+  // Modes of the lock screen notification.
+  enum class Mode { PROHIBITED, HIDE, SHOW, HIDE_SENSITIVE };
+
+  // Returns the current mode of the lock screen notification.
+  static Mode GetMode();
+
+  // Override the current mode for tests.
+  // Exporting for test.
+  static ASH_EXPORT void OverrideModeForTest(base::Optional<Mode> new_mode);
+
+  static base::Optional<Mode> overridden_mode_for_testing_;
+
   // SessionObserver:
   void OnLockStateChanged(bool locked) override;
   void OnActiveUserSessionChanged(const AccountId& account_id) override;
diff --git a/ash/system/unified/notification_hidden_view.cc b/ash/system/unified/notification_hidden_view.cc
index 799a0122..e83f781d 100644
--- a/ash/system/unified/notification_hidden_view.cc
+++ b/ash/system/unified/notification_hidden_view.cc
@@ -7,6 +7,7 @@
 #include "ash/public/cpp/ash_features.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
+#include "ash/system/message_center/ash_message_center_lock_screen_controller.h"
 #include "ash/system/message_center/message_center_controller.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/unified/sign_out_button.h"
@@ -34,9 +35,6 @@
 }  // namespace
 
 NotificationHiddenView::NotificationHiddenView() {
-  const bool lock_screen_notification_enabled =
-      features::IsLockScreenNotificationsEnabled();
-
   auto* label = new views::Label;
   label->SetEnabledColor(kUnifiedMenuTextColor);
   label->SetAutoColorReadabilityEnabled(false);
@@ -57,14 +55,16 @@
   container->AddChildView(label);
   layout->SetFlexForView(label, 1);
 
-  if (lock_screen_notification_enabled) {
-    auto* change_button = new RoundedLabelButton(
+  // Shows the "Change" button, unless the locks screen notification is
+  // prohibited by policy or flag.
+  if (AshMessageCenterLockScreenController::IsAllowed()) {
+    change_button_ = new RoundedLabelButton(
         this,
         l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_LOCKSCREEN_CHANGE));
-    change_button->SetTooltipText(l10n_util::GetStringUTF16(
+    change_button_->SetTooltipText(l10n_util::GetStringUTF16(
         IDS_ASH_MESSAGE_CENTER_LOCKSCREEN_CHANGE_TOOLTIP));
 
-    container->AddChildView(change_button);
+    container->AddChildView(change_button_);
   }
 
   SetBorder(
diff --git a/ash/system/unified/notification_hidden_view.h b/ash/system/unified/notification_hidden_view.h
index c7ae778..6ea96b92 100644
--- a/ash/system/unified/notification_hidden_view.h
+++ b/ash/system/unified/notification_hidden_view.h
@@ -21,7 +21,11 @@
   // views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
+  views::Button* change_button_for_testing() { return change_button_; }
+
  private:
+  views::Button* change_button_ = nullptr;
+
   DISALLOW_COPY_AND_ASSIGN(NotificationHiddenView);
 };
 
diff --git a/ash/system/unified/unified_system_tray_controller_unittest.cc b/ash/system/unified/unified_system_tray_controller_unittest.cc
index faad210..8f6c3f17 100644
--- a/ash/system/unified/unified_system_tray_controller_unittest.cc
+++ b/ash/system/unified/unified_system_tray_controller_unittest.cc
@@ -4,7 +4,12 @@
 
 #include "ash/system/unified/unified_system_tray_controller.h"
 
+#include "ash/public/cpp/ash_features.h"
+#include "ash/public/interfaces/session_controller.mojom.h"
+#include "ash/session/session_controller.h"
 #include "ash/shell.h"
+#include "ash/system/message_center/ash_message_center_lock_screen_controller.h"
+#include "ash/system/unified/notification_hidden_view.h"
 #include "ash/system/unified/unified_system_tray_model.h"
 #include "ash/system/unified/unified_system_tray_view.h"
 #include "ash/test/ash_test_base.h"
@@ -17,6 +22,17 @@
 
 namespace ash {
 
+namespace {
+
+void SetSessionState(const session_manager::SessionState& state) {
+  mojom::SessionInfoPtr info_ptr = mojom::SessionInfo::New();
+  info_ptr->state = state;
+  SessionController* session_controller = Shell::Get()->session_controller();
+  session_controller->SetSessionInfo(std::move(info_ptr));
+}
+
+}  // anonymous namespace
+
 class UnifiedSystemTrayControllerTest : public AshTestBase,
                                         public views::ViewObserver {
  public:
@@ -36,15 +52,11 @@
 
     model_ = std::make_unique<UnifiedSystemTrayModel>();
     controller_ = std::make_unique<UnifiedSystemTrayController>(model());
-    view_.reset(controller_->CreateView());
-
-    view_->AddObserver(this);
-    OnViewPreferredSizeChanged(view());
-
-    preferred_size_changed_count_ = 0;
   }
 
   void TearDown() override {
+    DCHECK(view_) << "Must call InitializeView() during the tests";
+
     view_->RemoveObserver(this);
 
     view_.reset();
@@ -75,6 +87,15 @@
     return preferred_size_changed_count_;
   }
 
+  void InitializeView() {
+    view_.reset(controller_->CreateView());
+
+    view_->AddObserver(this);
+    OnViewPreferredSizeChanged(view());
+
+    preferred_size_changed_count_ = 0;
+  }
+
   UnifiedSystemTrayModel* model() { return model_.get(); }
   UnifiedSystemTrayController* controller() { return controller_.get(); }
   UnifiedSystemTrayView* view() { return view_.get(); }
@@ -93,6 +114,8 @@
 };
 
 TEST_F(UnifiedSystemTrayControllerTest, ToggleExpanded) {
+  InitializeView();
+
   EXPECT_TRUE(model()->IsExpandedOnOpen());
   const int expanded_height = view()->GetPreferredSize().height();
 
@@ -105,6 +128,8 @@
 }
 
 TEST_F(UnifiedSystemTrayControllerTest, PreferredSizeChanged) {
+  InitializeView();
+
   // Checks PreferredSizeChanged is not called too frequently.
   EXPECT_EQ(0, preferred_size_changed_count());
   view()->SetExpandedAmount(0.0);
@@ -117,4 +142,55 @@
   EXPECT_EQ(4, preferred_size_changed_count());
 }
 
+TEST_F(UnifiedSystemTrayControllerTest, NotificationHiddenView_ModeShow) {
+  AshMessageCenterLockScreenController::OverrideModeForTest(
+      AshMessageCenterLockScreenController::Mode::SHOW);
+  SetSessionState(session_manager::SessionState::LOCKED);
+  InitializeView();
+
+  EXPECT_TRUE(AshMessageCenterLockScreenController::IsAllowed());
+  EXPECT_TRUE(AshMessageCenterLockScreenController::IsEnabled());
+  EXPECT_FALSE(view()->notification_hidden_view_for_testing()->visible());
+}
+
+TEST_F(UnifiedSystemTrayControllerTest, NotificationHiddenView_ModeHide) {
+  AshMessageCenterLockScreenController::OverrideModeForTest(
+      AshMessageCenterLockScreenController::Mode::HIDE);
+  SetSessionState(session_manager::SessionState::LOCKED);
+  InitializeView();
+
+  EXPECT_TRUE(AshMessageCenterLockScreenController::IsAllowed());
+  EXPECT_FALSE(AshMessageCenterLockScreenController::IsEnabled());
+  EXPECT_TRUE(view()->notification_hidden_view_for_testing()->visible());
+  EXPECT_NE(nullptr, view()
+                         ->notification_hidden_view_for_testing()
+                         ->change_button_for_testing());
+}
+
+TEST_F(UnifiedSystemTrayControllerTest,
+       NotificationHiddenView_ModeHideSensitive) {
+  AshMessageCenterLockScreenController::OverrideModeForTest(
+      AshMessageCenterLockScreenController::Mode::HIDE_SENSITIVE);
+  SetSessionState(session_manager::SessionState::LOCKED);
+  InitializeView();
+
+  EXPECT_TRUE(AshMessageCenterLockScreenController::IsAllowed());
+  EXPECT_TRUE(AshMessageCenterLockScreenController::IsEnabled());
+  EXPECT_FALSE(view()->notification_hidden_view_for_testing()->visible());
+}
+
+TEST_F(UnifiedSystemTrayControllerTest, NotificationHiddenView_ModeProhibited) {
+  AshMessageCenterLockScreenController::OverrideModeForTest(
+      AshMessageCenterLockScreenController::Mode::PROHIBITED);
+  SetSessionState(session_manager::SessionState::LOCKED);
+  InitializeView();
+
+  EXPECT_FALSE(AshMessageCenterLockScreenController::IsAllowed());
+  EXPECT_FALSE(AshMessageCenterLockScreenController::IsEnabled());
+  EXPECT_TRUE(view()->notification_hidden_view_for_testing()->visible());
+  EXPECT_EQ(nullptr, view()
+                         ->notification_hidden_view_for_testing()
+                         ->change_button_for_testing());
+}
+
 }  // namespace ash
diff --git a/ash/system/unified/unified_system_tray_view.h b/ash/system/unified/unified_system_tray_view.h
index 6e4640d..1b48c74 100644
--- a/ash/system/unified/unified_system_tray_view.h
+++ b/ash/system/unified/unified_system_tray_view.h
@@ -14,6 +14,7 @@
 class FeaturePodButton;
 class FeaturePodsContainerView;
 class TopShortcutsView;
+class NotificationHiddenView;
 class UnifiedMessageCenterView;
 class UnifiedSystemInfoView;
 class UnifiedSystemTrayController;
@@ -110,6 +111,10 @@
   views::FocusTraversable* GetFocusTraversableParent() override;
   views::View* GetFocusTraversableParentView() override;
 
+  NotificationHiddenView* notification_hidden_view_for_testing() {
+    return notification_hidden_view_;
+  }
+
  private:
   class FocusSearch;
 
@@ -119,7 +124,7 @@
   UnifiedSystemTrayController* const controller_;
 
   // Owned by views hierarchy.
-  views::View* const notification_hidden_view_;
+  NotificationHiddenView* const notification_hidden_view_;
   TopShortcutsView* const top_shortcuts_view_;
   FeaturePodsContainerView* const feature_pods_container_;
   UnifiedSlidersContainerView* const sliders_container_;