| // Copyright 2019 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/ash/crostini/crostini_force_close_watcher.h" |
| |
| #include <memory> |
| #include <type_traits> |
| |
| #include "base/bind.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/ash/crostini/crostini_simple_types.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/views/test/widget_test.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace crostini { |
| namespace { |
| |
| using ::testing::Return; |
| |
| class CrostiniForceCloseWatcherTest : public views::test::WidgetTest {}; |
| |
| class MockDelegate : public ForceCloseWatcher::Delegate { |
| public: |
| MOCK_METHOD(views::Widget*, GetClosableWidget, (), (override)); |
| MOCK_METHOD(void, Watched, (ForceCloseWatcher * watcher), (override)); |
| MOCK_METHOD(void, Prompt, (), (override)); |
| MOCK_METHOD(void, Hide, (), (override)); |
| |
| ~MockDelegate() override { |
| if (delete_flag) { |
| EXPECT_FALSE(*delete_flag); |
| *delete_flag = true; |
| } |
| } |
| bool* delete_flag = nullptr; |
| }; |
| |
| TEST_F(CrostiniForceCloseWatcherTest, CallsHideWhenWidgetIsDestroyed) { |
| auto delegate = std::make_unique<testing::NiceMock<MockDelegate>>(); |
| MockDelegate& delegate_ref = *delegate; |
| |
| WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); |
| |
| EXPECT_CALL(delegate_ref, GetClosableWidget).WillOnce(Return(widget.get())); |
| ForceCloseWatcher::Watch(std::move(delegate)); |
| |
| EXPECT_CALL(delegate_ref, Hide).Times(1); |
| widget.reset(); |
| } |
| |
| TEST_F(CrostiniForceCloseWatcherTest, DeletesSelfOnWidgetDeletion) { |
| bool deleted = false; |
| auto delegate = std::make_unique<testing::NiceMock<MockDelegate>>(); |
| MockDelegate& delegate_ref = *delegate; |
| |
| WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); |
| |
| EXPECT_CALL(delegate_ref, GetClosableWidget).WillOnce(Return(widget.get())); |
| ForceCloseWatcher::Watch(std::move(delegate)); |
| |
| delegate_ref.delete_flag = &deleted; |
| widget.reset(); |
| EXPECT_TRUE(deleted); |
| } |
| |
| TEST_F(CrostiniForceCloseWatcherTest, CallsForceCloseAfterSecondCloseAttempt) { |
| auto delegate = std::make_unique<testing::StrictMock<MockDelegate>>(); |
| MockDelegate& delegate_ref = *delegate; |
| |
| WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); |
| |
| EXPECT_CALL(delegate_ref, GetClosableWidget).WillOnce(Return(widget.get())); |
| EXPECT_CALL(delegate_ref, Watched) |
| .WillOnce(testing::Invoke([](ForceCloseWatcher* watcher) { |
| watcher->OverrideDelayForTesting(base::TimeDelta::FromSeconds(0)); |
| watcher->OnCloseRequested(); |
| watcher->OnCloseRequested(); |
| })); |
| EXPECT_CALL(delegate_ref, Prompt).Times(1); |
| EXPECT_CALL(delegate_ref, Hide).Times(1); |
| |
| ForceCloseWatcher::Watch(std::move(delegate)); |
| } |
| |
| TEST_F(CrostiniForceCloseWatcherTest, NoForceCloseUntilDelayPassed) { |
| auto delegate = std::make_unique<testing::StrictMock<MockDelegate>>(); |
| MockDelegate& delegate_ref = *delegate; |
| |
| WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); |
| |
| EXPECT_CALL(delegate_ref, GetClosableWidget).WillOnce(Return(widget.get())); |
| EXPECT_CALL(delegate_ref, Watched) |
| .WillOnce(testing::Invoke([](ForceCloseWatcher* watcher) { |
| watcher->OnCloseRequested(); |
| watcher->OnCloseRequested(); |
| })); |
| EXPECT_CALL(delegate_ref, Hide).Times(1); |
| |
| ForceCloseWatcher::Watch(std::move(delegate)); |
| } |
| |
| } // namespace |
| } // namespace crostini |