blob: 175b1782a4cba6bb100ffb7e7d562e6bf0478cbb [file] [log] [blame]
// Copyright 2016 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 "ios/chrome/browser/reading_list/reading_list_web_state_observer.h"
#include <memory>
#include "base/time/default_clock.h"
#include "components/reading_list/core/reading_list_model_impl.h"
#include "ios/chrome/browser/reading_list/offline_url_utils.h"
#import "ios/web/public/navigation_item.h"
#include "ios/web/public/reload_type.h"
#import "ios/web/public/test/fakes/test_navigation_manager.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "ios/web/public/test/web_test.h"
#import "ios/web/public/web_state/web_state.h"
#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
const char kTestURL[] = "http://foo.bar";
const char kTestTitle[] = "title";
const char kTestDistilledPath[] = "distilled/page.html";
const char kTestDistilledURL[] = "http://foo.bar/distilled";
}
// A Test navigation manager that checks if Reload was called.
class TestNavigationManager : public web::TestNavigationManager {
public:
void Reload(web::ReloadType reload_type, bool check_for_repost) override {
reload_called_ = true;
}
bool ReloadCalled() { return reload_called_; }
int GetLastCommittedItemIndex() const override { return 1; }
void GoToIndex(int index) override { go_to_index_called_index_ = index; }
int GoToIndexCalled() { return go_to_index_called_index_; }
private:
bool reload_called_ = false;
int go_to_index_called_index_ = -1;
};
// A Test navigation manager that remembers the last opened parameters.
class TestWebState : public web::TestWebState {
public:
void OpenURL(const web::WebState::OpenURLParams& params) override {
last_opened_url_ = params.url;
}
const GURL& LastOpenedUrl() { return last_opened_url_; }
private:
GURL last_opened_url_;
};
// Test fixture to test loading of Reading list entries.
class ReadingListWebStateObserverTest : public web::WebTest {
public:
ReadingListWebStateObserverTest() {
auto test_navigation_manager = std::make_unique<TestNavigationManager>();
test_navigation_manager_ = test_navigation_manager.get();
pending_item_ = web::NavigationItem::Create();
last_committed_item_ = web::NavigationItem::Create();
test_navigation_manager->SetPendingItem(pending_item_.get());
test_navigation_manager->SetLastCommittedItem(last_committed_item_.get());
test_web_state_.SetNavigationManager(std::move(test_navigation_manager));
reading_list_model_ = std::make_unique<ReadingListModelImpl>(
nullptr, nullptr, base::DefaultClock::GetInstance());
reading_list_model_->AddEntry(GURL(kTestURL), kTestTitle,
reading_list::ADDED_VIA_CURRENT_APP);
ReadingListWebStateObserver::CreateForWebState(&test_web_state_,
reading_list_model_.get());
}
protected:
std::unique_ptr<web::NavigationItem> pending_item_;
std::unique_ptr<web::NavigationItem> last_committed_item_;
std::unique_ptr<ReadingListModelImpl> reading_list_model_;
TestNavigationManager* test_navigation_manager_;
TestWebState test_web_state_;
};
// Tests that failing loading an online version does not mark it read.
TEST_F(ReadingListWebStateObserverTest, TestLoadReadingListFailure) {
GURL url(kTestURL);
const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url);
test_navigation_manager_->GetPendingItem()->SetURL(url);
test_web_state_.SetLoading(true);
test_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::FAILURE);
test_web_state_.SetLoading(false);
EXPECT_FALSE(test_navigation_manager_->ReloadCalled());
EXPECT_EQ(test_navigation_manager_->GoToIndexCalled(), -1);
// Check that |GetLastCommittedItem()| has not been altered.
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetVirtualURL(),
GURL());
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetURL(), GURL());
EXPECT_FALSE(entry->IsRead());
}
// Tests that loading an online version of an entry does not alter navigation
// stack and mark entry read.
TEST_F(ReadingListWebStateObserverTest, TestLoadReadingListOnline) {
GURL url(kTestURL);
std::string distilled_path = kTestDistilledPath;
reading_list_model_->SetEntryDistilledInfo(
url, base::FilePath(distilled_path), GURL(kTestDistilledURL), 50,
base::Time::FromTimeT(100));
const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url);
test_navigation_manager_->GetPendingItem()->SetURL(url);
test_web_state_.SetLoading(true);
test_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS);
test_web_state_.SetLoading(false);
EXPECT_FALSE(test_navigation_manager_->ReloadCalled());
EXPECT_EQ(test_navigation_manager_->GoToIndexCalled(), -1);
// Check that |GetLastCommittedItem()| has not been altered.
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetVirtualURL(),
GURL());
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetURL(), GURL());
EXPECT_TRUE(entry->IsRead());
}
// Tests that loading an online version of an entry does update navigation
// stack and mark entry read.
TEST_F(ReadingListWebStateObserverTest, TestLoadReadingListDistilledCommitted) {
GURL url(kTestURL);
std::string distilled_path = kTestDistilledPath;
reading_list_model_->SetEntryDistilledInfo(
url, base::FilePath(distilled_path), GURL(kTestDistilledURL), 50,
base::Time::FromTimeT(100));
const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url);
GURL distilled_url = reading_list::OfflineURLForPath(
entry->DistilledPath(), entry->URL(), entry->DistilledURL());
// Test on committed entry, there must be no pending item.
test_navigation_manager_->SetPendingItem(nullptr);
test_navigation_manager_->GetLastCommittedItem()->SetURL(url);
test_web_state_.SetLoading(true);
test_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::FAILURE);
test_web_state_.SetLoading(false);
EXPECT_FALSE(test_navigation_manager_->ReloadCalled());
EXPECT_EQ(test_navigation_manager_->GoToIndexCalled(),
test_navigation_manager_->GetLastCommittedItemIndex());
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetVirtualURL(),
url);
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetURL(),
distilled_url);
EXPECT_TRUE(entry->IsRead());
}
// Tests that loading an online version of a pending entry on reload does update
// committed entry, reload, and mark entry read.
TEST_F(ReadingListWebStateObserverTest, TestLoadReadingListDistilledPending) {
GURL url(kTestURL);
std::string distilled_path = kTestDistilledPath;
reading_list_model_->SetEntryDistilledInfo(
url, base::FilePath(distilled_path), GURL(kTestDistilledURL), 50,
base::Time::FromTimeT(100));
const ReadingListEntry* entry = reading_list_model_->GetEntryByURL(url);
GURL distilled_url = reading_list::OfflineURLForPath(
entry->DistilledPath(), entry->URL(), entry->DistilledURL());
test_navigation_manager_->SetPendingItem(nil);
test_navigation_manager_->GetLastCommittedItem()->SetURL(url);
test_web_state_.SetLoading(true);
test_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::FAILURE);
test_web_state_.SetLoading(false);
EXPECT_FALSE(test_navigation_manager_->ReloadCalled());
EXPECT_EQ(test_navigation_manager_->GoToIndexCalled(),
test_navigation_manager_->GetLastCommittedItemIndex());
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetVirtualURL(),
url);
EXPECT_EQ(test_navigation_manager_->GetLastCommittedItem()->GetURL(),
distilled_url);
EXPECT_TRUE(entry->IsRead());
}