// 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 "components/web_package/web_bundle_parser_factory.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/path_service.h" #include "base/test/task_environment.h" #include "base/test/test_future.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace web_package { namespace { base::FilePath GetTestFilePath(const base::FilePath& path) { base::FilePath test_path; base::PathService::Get(base::DIR_SOURCE_ROOT, &test_path); test_path = test_path.Append( base::FilePath(FILE_PATH_LITERAL("components/test/data/web_package"))); return test_path.Append(path); } } // namespace class WebBundleParserFactoryTest : public testing::Test { public: WebBundleParserFactoryTest() : factory_(std::make_unique()) {} std::unique_ptr CreateFileDataSource( mojo::PendingReceiver receiver, base::File file) { return factory_->CreateFileDataSourceForTesting(std::move(receiver), std::move(file)); } void GetParserForFile(mojo::PendingReceiver receiver, base::File file) { mojom::WebBundleParserFactory* factory = factory_.get(); return factory->GetParserForFile(std::move(receiver), std::move(file)); } private: std::unique_ptr factory_; base::test::TaskEnvironment task_environment_; }; TEST_F(WebBundleParserFactoryTest, FileDataSource) { base::FilePath test_file = GetTestFilePath(base::FilePath(FILE_PATH_LITERAL("hello_b2.wbn"))); base::File file(test_file, base::File::FLAG_OPEN | base::File::FLAG_READ); ASSERT_TRUE(file.IsValid()); int64_t file_length = file.GetLength(); constexpr int64_t test_length = 16; ASSERT_LE(test_length, file_length); std::vector first16b(test_length); ASSERT_EQ(test_length, file.Read(0, reinterpret_cast(first16b.data()), first16b.size())); std::vector last16b(test_length); ASSERT_EQ(test_length, file.Read(file_length - test_length, reinterpret_cast(last16b.data()), last16b.size())); mojo::PendingRemote remote; auto data_source = CreateFileDataSource( remote.InitWithNewPipeAndPassReceiver(), std::move(file)); { base::test::TestFuture>&> future; data_source->Read(/*offset=*/0, test_length, future.GetCallback()); ASSERT_TRUE(future.Get()); EXPECT_EQ(first16b, *future.Get()); } { base::test::TestFuture>&> future; data_source->Read(file_length - test_length, test_length, future.GetCallback()); ASSERT_TRUE(future.Get()); EXPECT_EQ(last16b, *future.Get()); } { base::test::TestFuture>&> future; data_source->Read(file_length - test_length, test_length + 1, future.GetCallback()); ASSERT_TRUE(future.Get()); EXPECT_EQ(last16b, *future.Get()); } { base::test::TestFuture>&> future; data_source->Read(file_length + 1, test_length, future.GetCallback()); ASSERT_FALSE(future.Get()); } { base::test::TestFuture future; data_source->Length(future.GetCallback()); EXPECT_EQ(file_length, future.Get()); } { base::test::TestFuture future; data_source->IsRandomAccessContext(future.GetCallback()); EXPECT_TRUE(future.Get()); } } TEST_F(WebBundleParserFactoryTest, GetParserForFile) { base::File file( GetTestFilePath(base::FilePath(FILE_PATH_LITERAL("hello_b2.wbn"))), base::File::FLAG_OPEN | base::File::FLAG_READ); ASSERT_TRUE(file.IsValid()); mojo::Remote parser; GetParserForFile(parser.BindNewPipeAndPassReceiver(), std::move(file)); mojom::BundleMetadataPtr metadata; { base::test::TestFuture future; parser->ParseMetadata(/*offset=*/-1, future.GetCallback()); metadata = std::get<0>(future.Take()); } ASSERT_TRUE(metadata); ASSERT_EQ(metadata->requests.size(), 4u); std::map responses; for (const auto& item : metadata->requests) { base::test::TestFuture future; parser->ParseResponse(item.second->offset, item.second->length, future.GetCallback()); auto [response, error] = future.Take(); ASSERT_TRUE(response); ASSERT_FALSE(error); responses[item.first.spec()] = std::move(response); } ASSERT_TRUE(responses["https://test.example.org/"]); EXPECT_EQ(responses["https://test.example.org/"]->response_code, 200); EXPECT_EQ( responses["https://test.example.org/"]->response_headers["content-type"], "text/html; charset=utf-8"); EXPECT_TRUE(responses["https://test.example.org/index.html"]); EXPECT_TRUE(responses["https://test.example.org/manifest.webmanifest"]); EXPECT_TRUE(responses["https://test.example.org/script.js"]); } } // namespace web_package