0
Files
src/content/common/web_ui_loading_util_unittest.cc
Alex Yang 5bc342f6ad Move WebUI Mojo loading code to a shared location
In a future commit, this code will be re-used in the implementation of
an in-renderer resource loader, which will not be located in
//content/browser.

Bug: 362511750
Change-Id: I58432846087a05fe165e3443d5f33d119a05d750
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6033036
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Commit-Queue: Alex Yang <aycyang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1385832}
2024-11-20 19:51:42 +00:00

144 lines
4.9 KiB
C++

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/common/web_ui_loading_util.h"
#include <cstdint>
#include <optional>
#include <vector>
#include "base/containers/span.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/test/task_environment.h"
#include "base/types/expected.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/types.h"
#include "net/base/net_errors.h"
#include "net/http/http_byte_range.h"
#include "net/http/http_request_headers.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/test/test_url_loader_client.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace webui {
namespace {
struct RangeTestCase {
std::optional<std::string> range;
std::optional<GetRequestedRangeError> error;
};
struct SendDataTestCase {
std::optional<net::HttpByteRange> range;
std::string data;
base::expected<std::string, int> result;
};
class WebUILoadingUtilGetRequestedRangeTest
: public ::testing::TestWithParam<RangeTestCase> {};
class WebUILoadingUtilSendDataTest
: public ::testing::TestWithParam<SendDataTestCase> {
private:
// For TestURLLoaderClient.
base::test::TaskEnvironment task_environment_;
};
std::optional<std::string> ReadAllData(network::TestURLLoaderClient& client) {
size_t response_size;
MojoResult result;
result = client.response_body().ReadData(
MOJO_READ_DATA_FLAG_QUERY, base::span<uint8_t>(), response_size);
if (result != MOJO_RESULT_OK) {
return std::nullopt;
}
std::vector<uint8_t> response_bytes(response_size);
result = client.response_body().ReadData(MOJO_READ_DATA_FLAG_ALL_OR_NONE,
response_bytes, response_size);
if (result != MOJO_RESULT_OK) {
return std::nullopt;
}
std::string response_body(response_bytes.begin(), response_bytes.end());
return std::make_optional(response_body);
}
} // namespace
TEST_P(WebUILoadingUtilGetRequestedRangeTest, GetRequestedRange) {
net::HttpRequestHeaders headers;
if (GetParam().range) {
headers.SetHeader(net::HttpRequestHeaders::kRange, *GetParam().range);
}
base::expected<net::HttpByteRange, GetRequestedRangeError> result =
GetRequestedRange(headers);
if (GetParam().error) {
EXPECT_FALSE(result.has_value());
EXPECT_EQ(result.error(), *GetParam().error);
} else {
EXPECT_TRUE(result.has_value());
}
}
INSTANTIATE_TEST_SUITE_P(
WebUILoadingUtilGetRequestedRangeTest,
WebUILoadingUtilGetRequestedRangeTest,
::testing::Values(
RangeTestCase(std::nullopt,
std::make_optional(GetRequestedRangeError::kNoRanges)),
RangeTestCase(std::make_optional("bytes=1-9"), std::nullopt),
RangeTestCase(
std::make_optional("bytes=1-9,11-19"),
std::make_optional(GetRequestedRangeError::kMultipleRanges)),
RangeTestCase(std::make_optional("bytes=3-2"),
std::make_optional(GetRequestedRangeError::kParseFailed)),
RangeTestCase(
std::make_optional("byt"),
std::make_optional(GetRequestedRangeError::kParseFailed))));
TEST_P(WebUILoadingUtilSendDataTest, SendData) {
network::TestURLLoaderClient client;
auto url_response_head = network::mojom::URLResponseHead::New();
const scoped_refptr<base::RefCountedString> data =
base::MakeRefCounted<base::RefCountedString>(GetParam().data);
const bool success = SendData(std::move(url_response_head),
client.CreateRemote(), GetParam().range, data);
client.RunUntilComplete();
// If an error is expected, verify the status error code is correct and
// terminate the test early.
if (!GetParam().result.has_value()) {
EXPECT_FALSE(success);
EXPECT_EQ(GetParam().result.error(), client.completion_status().error_code);
return;
}
// No error expected. Verify response body is correct.
EXPECT_TRUE(success);
EXPECT_EQ(net::OK, client.completion_status().error_code);
ASSERT_TRUE(client.response_body().is_valid());
std::optional<std::string> response_body = ReadAllData(client);
ASSERT_TRUE(response_body);
EXPECT_EQ(GetParam().result.value(), *response_body);
}
INSTANTIATE_TEST_SUITE_P(
WebUILoadingUtilSendDataTest,
WebUILoadingUtilSendDataTest,
::testing::Values(
SendDataTestCase(std::nullopt,
"this is some data",
"this is some data"),
SendDataTestCase(std::make_optional(net::HttpByteRange::Bounded(3, 8)),
"this is some data",
"s is s"),
SendDataTestCase(
std::make_optional(net::HttpByteRange::Bounded(3, 2)),
"this is some data",
base::unexpected(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE))));
} // namespace webui
} // namespace content