blob: 8e064fc104e516935446fce49b56fb81631b11a7 [file] [log] [blame]
[email protected]af9db5f2011-10-05 05:13:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]1683aedf2009-09-29 23:06:132// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Devlin Cronin06ba0812017-08-03 00:23:335#include "extensions/browser/file_reader.h"
6
[email protected]1ec27eb52011-11-03 21:59:097#include "base/bind.h"
danakjdb9ae7942020-11-11 16:01:358#include "base/callback_helpers.h"
[email protected]57999812013-02-24 05:40:529#include "base/files/file_path.h"
thestig94712702014-09-10 07:46:5910#include "base/files/file_util.h"
[email protected]1683aedf2009-09-29 23:06:1311#include "base/path_service.h"
fdoray2edf4dd2016-06-22 17:09:0212#include "base/run_loop.h"
Gabriel Charettec7108742019-08-23 03:31:4013#include "base/test/task_environment.h"
[email protected]fdd28372014-08-21 02:27:2614#include "components/crx_file/id_util.h"
[email protected]32efb042013-03-29 00:23:2115#include "extensions/common/extension_paths.h"
[email protected]993da5e2013-03-23 21:25:1616#include "extensions/common/extension_resource.h"
Devlin Croninac674c862021-07-08 18:46:3717#include "testing/gmock/include/gmock/gmock.h"
[email protected]1683aedf2009-09-29 23:06:1318#include "testing/gtest/include/gtest/gtest.h"
Devlin Croninac674c862021-07-08 18:46:3719#include "third_party/abseil-cpp/absl/types/optional.h"
[email protected]1683aedf2009-09-29 23:06:1320
[email protected]32efb042013-03-29 00:23:2121namespace extensions {
[email protected]1683aedf2009-09-29 23:06:1322
23class FileReaderTest : public testing::Test {
24 public:
Devlin Cronin06ba0812017-08-03 00:23:3325 FileReaderTest() {}
26
Peter Boströmc3d907172021-09-24 18:39:5227 FileReaderTest(const FileReaderTest&) = delete;
28 FileReaderTest& operator=(const FileReaderTest&) = delete;
29
[email protected]1683aedf2009-09-29 23:06:1330 private:
Gabriel Charette694c3c332019-08-19 14:53:0531 base::test::TaskEnvironment task_environment_;
[email protected]1683aedf2009-09-29 23:06:1332};
33
34class Receiver {
35 public:
Devlin Croninac674c862021-07-08 18:46:3736 explicit Receiver(std::vector<ExtensionResource> resources)
37 : file_reader_(base::MakeRefCounted<FileReader>(
38 std::move(resources),
Devlin Cronin06ba0812017-08-03 00:23:3339 FileReader::OptionalFileSequenceTask(),
Jan Wilken Dörrie222bd832020-04-20 09:14:3040 base::BindOnce(&Receiver::DidReadFile, base::Unretained(this)))) {}
[email protected]1683aedf2009-09-29 23:06:1341
Peter Boströmc3d907172021-09-24 18:39:5242 Receiver(const Receiver&) = delete;
43 Receiver& operator=(const Receiver&) = delete;
44
Devlin Cronin06ba0812017-08-03 00:23:3345 void Run() {
46 file_reader_->Start();
47 run_loop_.Run();
[email protected]1683aedf2009-09-29 23:06:1348 }
49
Devlin Croninac674c862021-07-08 18:46:3750 // Removes the pointer indirection from the read data for use with
51 // comparators.
52 std::vector<std::string> GetStringData() const {
53 std::vector<std::string> string_data;
54 string_data.reserve(data_.size());
55 for (const auto& entry : data_) {
56 EXPECT_TRUE(entry);
57 string_data.push_back(*entry);
58 }
59 return string_data;
60 }
61
62 const absl::optional<std::string>& error() const { return error_; }
63 bool succeeded() const { return !error_; }
64 const std::vector<std::unique_ptr<std::string>>& data() const {
65 return data_;
66 }
[email protected]1683aedf2009-09-29 23:06:1367
68 private:
Devlin Croninac674c862021-07-08 18:46:3769 void DidReadFile(std::vector<std::unique_ptr<std::string>> data,
70 absl::optional<std::string> error) {
71 error_ = std::move(error);
lazyboyb81e69a2016-08-18 22:35:0472 data_ = std::move(data);
Devlin Cronin06ba0812017-08-03 00:23:3373 run_loop_.QuitWhenIdle();
[email protected]1683aedf2009-09-29 23:06:1374 }
75
Devlin Croninac674c862021-07-08 18:46:3776 absl::optional<std::string> error_;
77 std::vector<std::unique_ptr<std::string>> data_;
Devlin Cronin06ba0812017-08-03 00:23:3378 scoped_refptr<FileReader> file_reader_;
79 base::RunLoop run_loop_;
[email protected]1683aedf2009-09-29 23:06:1380};
81
Devlin Croninac674c862021-07-08 18:46:3782void RunBasicTest(const std::vector<std::string>& filenames) {
83 base::FilePath root_path;
84 base::PathService::Get(DIR_TEST_DATA, &root_path);
[email protected]fdd28372014-08-21 02:27:2685 std::string extension_id = crx_file::id_util::GenerateId("test");
[email protected]1683aedf2009-09-29 23:06:1386
Devlin Croninac674c862021-07-08 18:46:3787 std::vector<ExtensionResource> resources;
88 resources.reserve(filenames.size());
89 std::vector<std::string> expected_contents;
90 expected_contents.reserve(filenames.size());
91 for (const auto& filename : filenames) {
92 resources.emplace_back(extension_id, root_path,
93 base::FilePath().AppendASCII(filename));
[email protected]1683aedf2009-09-29 23:06:1394
Devlin Croninac674c862021-07-08 18:46:3795 base::FilePath path = root_path.AppendASCII(filename);
96 std::string file_contents;
97 ASSERT_TRUE(base::ReadFileToString(path, &file_contents));
98 expected_contents.push_back(std::move(file_contents));
99 }
100
101 Receiver receiver(resources);
Devlin Cronin06ba0812017-08-03 00:23:33102 receiver.Run();
[email protected]1683aedf2009-09-29 23:06:13103
Devlin Croninac674c862021-07-08 18:46:37104 EXPECT_TRUE(receiver.succeeded()) << *receiver.error();
105 EXPECT_THAT(receiver.GetStringData(),
106 ::testing::ElementsAreArray(expected_contents));
[email protected]1683aedf2009-09-29 23:06:13107}
108
109TEST_F(FileReaderTest, SmallFile) {
Devlin Croninac674c862021-07-08 18:46:37110 RunBasicTest({"smallfile"});
[email protected]1683aedf2009-09-29 23:06:13111}
112
113TEST_F(FileReaderTest, BiggerFile) {
Devlin Croninac674c862021-07-08 18:46:37114 RunBasicTest({"bigfile"});
115}
116
117TEST_F(FileReaderTest, MultiFile) {
118 RunBasicTest({"smallfile", "bigfile"});
[email protected]1683aedf2009-09-29 23:06:13119}
120
Solomon Kinard015f38fb2020-10-15 21:58:34121TEST_F(FileReaderTest, NonExistentFile) {
[email protected]650b2d52013-02-10 03:41:45122 base::FilePath path;
Avi Drissman210441b72018-05-01 15:51:00123 base::PathService::Get(DIR_TEST_DATA, &path);
[email protected]fdd28372014-08-21 02:27:26124 std::string extension_id = crx_file::id_util::GenerateId("test");
[email protected]32efb042013-03-29 00:23:21125 ExtensionResource resource(extension_id, path, base::FilePath(
[email protected]ecabe6ee2009-10-07 22:49:10126 FILE_PATH_LITERAL("file_that_does_not_exist")));
[email protected]1683aedf2009-09-29 23:06:13127 path = path.AppendASCII("file_that_does_not_exist");
128
Devlin Croninac674c862021-07-08 18:46:37129 Receiver receiver({resource});
Devlin Cronin06ba0812017-08-03 00:23:33130 receiver.Run();
[email protected]1683aedf2009-09-29 23:06:13131
132 EXPECT_FALSE(receiver.succeeded());
Devlin Croninac674c862021-07-08 18:46:37133 EXPECT_EQ("Could not load file: 'file_that_does_not_exist'.",
134 *receiver.error());
[email protected]1683aedf2009-09-29 23:06:13135}
136
[email protected]32efb042013-03-29 00:23:21137} // namespace extensions