| // Copyright 2017 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. |
| |
| #import "ios/chrome/browser/web/page_placeholder_tab_helper.h" |
| |
| #import <Foundation/Foundation.h> |
| |
| #include <memory> |
| |
| #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" |
| #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" |
| #import "ios/testing/wait_util.h" |
| #import "ios/web/public/test/fakes/test_web_state.h" |
| #include "ios/web/public/test/test_web_thread_bundle.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "testing/platform_test.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| using testing::kWaitForUIElementTimeout; |
| using testing::WaitUntilConditionOrTimeout; |
| |
| // Test fixture for PagePlaceholderTabHelper class. |
| class PagePlaceholderTabHelperTest : public PlatformTest { |
| protected: |
| PagePlaceholderTabHelperTest() { |
| browser_state_ = TestChromeBrowserState::Builder().Build(); |
| web_state_ = std::make_unique<web::TestWebState>(); |
| web_state_->SetBrowserState(browser_state_.get()); |
| |
| CGRect frame = {CGPointZero, CGSizeMake(400, 300)}; |
| web_state_view_ = [[UIView alloc] initWithFrame:frame]; |
| web_state_view_.backgroundColor = [UIColor blueColor]; |
| web_state_->SetView(web_state_view_); |
| |
| // PagePlaceholderTabHelper uses SnapshotTabHelper, so ensure it has been |
| // created. |
| SnapshotTabHelper::CreateForWebState(web_state_.get(), |
| [[NSUUID UUID] UUIDString]); |
| PagePlaceholderTabHelper::CreateForWebState(web_state_.get()); |
| } |
| |
| PagePlaceholderTabHelper* tab_helper() { |
| return PagePlaceholderTabHelper::FromWebState(web_state_.get()); |
| } |
| |
| web::TestWebThreadBundle thread_bundle_; |
| std::unique_ptr<ios::ChromeBrowserState> browser_state_; |
| std::unique_ptr<web::TestWebState> web_state_; |
| UIView* web_state_view_ = nil; |
| }; |
| |
| // Tests that placeholder is not shown after DidStartNavigation if it was not |
| // requested. |
| TEST_F(PagePlaceholderTabHelperTest, NotShown) { |
| ASSERT_FALSE(tab_helper()->displaying_placeholder()); |
| ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| web_state_->OnNavigationStarted(nullptr); |
| EXPECT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| } |
| |
| // Tests that placehold is not shown after DidStartNavigation if it was |
| // cancelled before the navigation. |
| TEST_F(PagePlaceholderTabHelperTest, NotShownIfCancelled) { |
| ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| tab_helper()->AddPlaceholderForNextNavigation(); |
| ASSERT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| tab_helper()->CancelPlaceholderForNextNavigation(); |
| ASSERT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| web_state_->OnNavigationStarted(nullptr); |
| EXPECT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| } |
| |
| // Tests that placeholder is shown between DidStartNavigation/PageLoaded |
| // WebStateObserver callbacks. |
| TEST_F(PagePlaceholderTabHelperTest, Shown) { |
| ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| tab_helper()->AddPlaceholderForNextNavigation(); |
| ASSERT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| |
| web_state_->OnNavigationStarted(nullptr); |
| EXPECT_TRUE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| |
| web_state_->OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS); |
| EXPECT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| } |
| |
| // Tests that placeholder is removed if cancelled while presented. |
| TEST_F(PagePlaceholderTabHelperTest, RemovedIfCancelledWhileShown) { |
| ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| tab_helper()->AddPlaceholderForNextNavigation(); |
| ASSERT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| web_state_->OnNavigationStarted(nullptr); |
| EXPECT_TRUE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| |
| tab_helper()->CancelPlaceholderForNextNavigation(); |
| EXPECT_FALSE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| } |
| |
| // Tests that destructing WebState removes the placeholder. |
| TEST_F(PagePlaceholderTabHelperTest, DestructWebStateWhenShowingPlaceholder) { |
| ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| tab_helper()->AddPlaceholderForNextNavigation(); |
| ASSERT_FALSE(tab_helper()->displaying_placeholder()); |
| |
| EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| web_state_->OnNavigationStarted(nullptr); |
| |
| EXPECT_TRUE(tab_helper()->displaying_placeholder()); |
| EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation()); |
| EXPECT_TRUE([[web_state_view_ subviews] count] != 0); |
| web_state_.reset(); |
| |
| // The tab helper has been deleted at this point, so do not check the value |
| // of displaying_placeholder(). Check that the view has no subviews (i.e. no |
| // placeholder is presented) after some time (since the placeholder view is |
| // removed with an animation). |
| EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ |
| return [[web_state_view_ subviews] count] == 0; |
| })); |
| } |