blob: ac38fb3ec57ce7f4dc5d56d4c4acf004bd51a42f [file] [log] [blame]
// 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 "content/browser/web_package/mock_bundled_exchanges_reader_factory.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "content/browser/web_package/bundled_exchanges_reader.h"
#include "content/browser/web_package/bundled_exchanges_source.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/data_decoder/public/mojom/bundled_exchanges_parser.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
class MockParser final : public data_decoder::mojom::BundledExchangesParser {
public:
MockParser(mojo::PendingReceiver<data_decoder::mojom::BundledExchangesParser>
receiver)
: receiver_(this, std::move(receiver)) {}
~MockParser() override = default;
void RunMetadataCallback(data_decoder::mojom::BundleMetadataPtr metadata) {
std::move(metadata_callback_).Run(std::move(metadata), nullptr);
}
void RunResponseCallback(data_decoder::mojom::BundleResponsePtr response) {
std::move(response_callback_).Run(std::move(response), nullptr);
}
void WaitUntilParseMetadataCalled(base::OnceClosure closure) {
if (metadata_callback_.is_null())
wait_parse_metadata_callback_ = std::move(closure);
else
std::move(closure).Run();
}
void WaitUntilParseResponseCalled(base::OnceClosure closure) {
if (response_callback_.is_null())
wait_parse_response_callback_ = std::move(closure);
else
std::move(closure).Run();
}
private:
// data_decoder::mojom::BundledExchangesParser implementation.
void ParseMetadata(ParseMetadataCallback callback) override {
metadata_callback_ = std::move(callback);
if (!wait_parse_metadata_callback_.is_null())
std::move(wait_parse_metadata_callback_).Run();
}
void ParseResponse(uint64_t response_offset,
uint64_t response_length,
ParseResponseCallback callback) override {
response_callback_ = std::move(callback);
if (!wait_parse_response_callback_.is_null())
std::move(wait_parse_response_callback_).Run();
}
mojo::Receiver<data_decoder::mojom::BundledExchangesParser> receiver_;
ParseMetadataCallback metadata_callback_;
ParseResponseCallback response_callback_;
base::OnceClosure wait_parse_metadata_callback_;
base::OnceClosure wait_parse_response_callback_;
DISALLOW_COPY_AND_ASSIGN(MockParser);
};
class MockParserFactory final
: public data_decoder::mojom::BundledExchangesParserFactory {
public:
MockParserFactory() {}
~MockParserFactory() override = default;
void WaitUntilParseMetadataCalled(base::OnceClosure closure) {
if (parser_)
parser_->WaitUntilParseMetadataCalled(std::move(closure));
else
wait_parse_metadata_callback_ = std::move(closure);
}
void WaitUntilParseResponseCalled(base::OnceClosure closure) {
if (parser_)
parser_->WaitUntilParseResponseCalled(std::move(closure));
else
wait_parse_response_callback_ = std::move(closure);
}
void RunMetadataCallback(data_decoder::mojom::BundleMetadataPtr metadata) {
base::RunLoop run_loop;
WaitUntilParseMetadataCalled(run_loop.QuitClosure());
run_loop.Run();
ASSERT_TRUE(parser_);
parser_->RunMetadataCallback(std::move(metadata));
}
void RunResponseCallback(data_decoder::mojom::BundleResponsePtr response) {
base::RunLoop run_loop;
WaitUntilParseResponseCalled(run_loop.QuitClosure());
run_loop.Run();
ASSERT_TRUE(parser_);
parser_->RunResponseCallback(std::move(response));
}
private:
// data_decoder::mojom::BundledExchangesParserFactory implementation.
void GetParserForFile(
mojo::PendingReceiver<data_decoder::mojom::BundledExchangesParser>
receiver,
base::File file) override {
parser_ = std::make_unique<MockParser>(std::move(receiver));
if (!wait_parse_metadata_callback_.is_null()) {
parser_->WaitUntilParseMetadataCalled(
std::move(wait_parse_metadata_callback_));
}
}
void GetParserForDataSource(
mojo::PendingReceiver<data_decoder::mojom::BundledExchangesParser>
receiver,
mojo::PendingRemote<data_decoder::mojom::BundleDataSource> data_source)
override {
NOTREACHED();
}
std::unique_ptr<MockParser> parser_;
base::OnceClosure wait_parse_metadata_callback_;
base::OnceClosure wait_parse_response_callback_;
DISALLOW_COPY_AND_ASSIGN(MockParserFactory);
};
class MockBundledExchangesReaderFactoryImpl final
: public MockBundledExchangesReaderFactory {
public:
MockBundledExchangesReaderFactoryImpl()
: MockBundledExchangesReaderFactory() {}
~MockBundledExchangesReaderFactoryImpl() override = default;
std::unique_ptr<BundledExchangesReader> CreateReader(
const std::string& test_file_data) override {
if (!temp_dir_.CreateUniqueTempDir() ||
!CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file_path_) ||
(test_file_data.size() !=
static_cast<size_t>(base::WriteFile(
temp_file_path_, test_file_data.data(), test_file_data.size())))) {
return nullptr;
}
BundledExchangesSource source(temp_file_path_);
auto reader = std::make_unique<BundledExchangesReader>(source);
std::unique_ptr<MockParserFactory> factory =
std::make_unique<MockParserFactory>();
factory_ = factory.get();
mojo::Remote<data_decoder::mojom::BundledExchangesParserFactory> remote;
mojo::MakeSelfOwnedReceiver(std::move(factory),
remote.BindNewPipeAndPassReceiver());
reader->SetBundledExchangesParserFactoryForTesting(std::move(remote));
return reader;
}
void ReadAndFullfillMetadata(
BundledExchangesReader* reader,
data_decoder::mojom::BundleMetadataPtr metadata,
BundledExchangesReader::MetadataCallback callback) override {
ASSERT_TRUE(factory_);
DCHECK(reader);
base::RunLoop run_loop;
reader->ReadMetadata(base::BindOnce(
[](base::Closure quit_closure,
BundledExchangesReader::MetadataCallback callback,
data_decoder::mojom::BundleMetadataParseErrorPtr error) {
std::move(callback).Run(std::move(error));
std::move(quit_closure).Run();
},
run_loop.QuitClosure(), std::move(callback)));
factory_->RunMetadataCallback(std::move(metadata));
run_loop.Run();
}
void ReadAndFullfillResponse(
BundledExchangesReader* reader,
const GURL& url,
data_decoder::mojom::BundleResponsePtr response,
BundledExchangesReader::ResponseCallback callback) override {
ASSERT_TRUE(factory_);
DCHECK(reader);
base::RunLoop run_loop;
reader->ReadResponse(
url, base::BindOnce(
[](base::Closure quit_closure,
BundledExchangesReader::ResponseCallback callback,
data_decoder::mojom::BundleResponsePtr response) {
std::move(callback).Run(std::move(response));
std::move(quit_closure).Run();
},
run_loop.QuitClosure(), std::move(callback)));
factory_->RunResponseCallback(std::move(response));
run_loop.Run();
}
void FullfillResponse(
data_decoder::mojom::BundleResponsePtr response,
BundledExchangesReader::ResponseCallback callback) override {
ASSERT_TRUE(factory_);
factory_->RunResponseCallback(std::move(response));
}
private:
std::string test_file_data_;
base::ScopedTempDir temp_dir_;
base::FilePath temp_file_path_;
MockParserFactory* factory_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(MockBundledExchangesReaderFactoryImpl);
};
} // namespace
// static
std::unique_ptr<MockBundledExchangesReaderFactory>
MockBundledExchangesReaderFactory::Create() {
return std::make_unique<MockBundledExchangesReaderFactoryImpl>();
}
} // namespace content