1 #include "helpers.hpp" 2 #include "persistent_json_storage.hpp" 3 4 #include <fstream> 5 6 #include "gmock/gmock.h" 7 #include "gtest/gtest.h" 8 9 using namespace testing; 10 11 class TestPersistentJsonStorage : public Test 12 { 13 public: 14 using FilePath = interfaces::JsonStorage::FilePath; 15 using DirectoryPath = interfaces::JsonStorage::DirectoryPath; 16 17 static void SetUpTestSuite() 18 { 19 ASSERT_FALSE(std::filesystem::exists(directory)); 20 } 21 22 void TearDown() override 23 { 24 if (std::filesystem::exists(directory)) 25 { 26 std::filesystem::remove_all(directory); 27 } 28 } 29 30 const FilePath fileName = FilePath("report/1/file.txt"); 31 32 static const DirectoryPath directory; 33 PersistentJsonStorage sut{directory}; 34 }; 35 36 const interfaces::JsonStorage::DirectoryPath 37 TestPersistentJsonStorage::directory = 38 interfaces::JsonStorage::DirectoryPath( 39 std::filesystem::temp_directory_path() / "telemetry-tests"); 40 41 TEST_F(TestPersistentJsonStorage, storesJsonData) 42 { 43 nlohmann::json data = nlohmann::json::object(); 44 data["name"] = "kevin"; 45 data["lastname"] = "mc calister"; 46 47 sut.store(fileName, data); 48 49 ASSERT_THAT(sut.load(fileName), Eq(data)); 50 } 51 52 TEST_F(TestPersistentJsonStorage, emptyListWhenNoReportsCreated) 53 { 54 EXPECT_THAT(sut.list(), SizeIs(0u)); 55 } 56 57 TEST_F(TestPersistentJsonStorage, listSavedReports) 58 { 59 sut.store(FilePath("report/domain-1/name-1/conf-1.json"), 60 nlohmann::json("data-1a")); 61 sut.store(FilePath("report/domain-1/name-2/conf-1.json"), 62 nlohmann::json("data-2a")); 63 sut.store(FilePath("report/domain-1/name-2/conf-2.json"), 64 nlohmann::json("data-2b")); 65 sut.store(FilePath("report/domain-2/name-1/conf-1.json"), 66 nlohmann::json("data-3a")); 67 68 EXPECT_THAT( 69 sut.list(), 70 UnorderedElementsAre(FilePath("report/domain-1/name-1/conf-1.json"), 71 FilePath("report/domain-1/name-2/conf-1.json"), 72 FilePath("report/domain-1/name-2/conf-2.json"), 73 FilePath("report/domain-2/name-1/conf-1.json"))); 74 } 75 76 TEST_F(TestPersistentJsonStorage, listSavedReportsWithoutRemovedOnes) 77 { 78 sut.store(FilePath("report/domain-1/name-1/conf-1.json"), 79 nlohmann::json("data-1a")); 80 sut.store(FilePath("report/domain-1/name-2/conf-1.json"), 81 nlohmann::json("data-2a")); 82 sut.store(FilePath("report/domain-1/name-2/conf-2.json"), 83 nlohmann::json("data-2b")); 84 sut.store(FilePath("report/domain-2/name-1/conf-1.json"), 85 nlohmann::json("data-3a")); 86 sut.remove(FilePath("report/domain-1/name-1/conf-1.json")); 87 sut.remove(FilePath("report/domain-1/name-2/conf-2.json")); 88 89 EXPECT_THAT( 90 sut.list(), 91 UnorderedElementsAre(FilePath("report/domain-1/name-2/conf-1.json"), 92 FilePath("report/domain-2/name-1/conf-1.json"))); 93 } 94 95 TEST_F(TestPersistentJsonStorage, removesStoredJson) 96 { 97 nlohmann::json data = nlohmann::json::object(); 98 data["name"] = "kevin"; 99 data["lastname"] = "mc calister"; 100 101 sut.store(fileName, data); 102 103 ASSERT_THAT(sut.remove(fileName), Eq(true)); 104 ASSERT_THAT(sut.load(fileName), Eq(std::nullopt)); 105 } 106 107 TEST_F(TestPersistentJsonStorage, returnsFalseWhenDeletingNonExistingFile) 108 { 109 ASSERT_THAT(sut.remove(fileName), Eq(false)); 110 } 111 112 TEST_F(TestPersistentJsonStorage, returnsNulloptWhenFileDoesntExist) 113 { 114 ASSERT_THAT(sut.load(fileName), Eq(std::nullopt)); 115 } 116 117 class TestPersistentJsonStorageWithSymlink : public TestPersistentJsonStorage 118 { 119 public: 120 TestPersistentJsonStorageWithSymlink() 121 { 122 std::ofstream file(dummyReportPath); 123 file << "{}"; 124 file.close(); 125 126 std::filesystem::create_directories(std::filesystem::path(directory) / 127 "report"); 128 std::filesystem::create_symlink(dummyReportPath, 129 std::filesystem::path(directory) / 130 "report/symlink.json"); 131 } 132 133 static void SetUpTestSuite() 134 { 135 TestPersistentJsonStorage::SetUpTestSuite(); 136 ASSERT_FALSE(std::filesystem::exists(dummyReportPath)); 137 } 138 139 void TearDown() override 140 { 141 TestPersistentJsonStorage::TearDown(); 142 if (std::filesystem::exists(dummyReportPath)) 143 { 144 std::filesystem::remove(dummyReportPath); 145 } 146 } 147 148 static const std::filesystem::path dummyReportPath; 149 }; 150 151 const std::filesystem::path 152 TestPersistentJsonStorageWithSymlink::dummyReportPath = 153 std::filesystem::temp_directory_path() / "report"; 154 155 TEST_F(TestPersistentJsonStorageWithSymlink, symlinksAreNotListed) 156 { 157 ASSERT_THAT(sut.list(), UnorderedElementsAre()); 158 } 159 160 TEST_F(TestPersistentJsonStorageWithSymlink, throwsWhenStoreTargetIsSymlink) 161 { 162 ASSERT_THROW( 163 sut.store(FilePath("report/symlink.json"), nlohmann::json("data")), 164 std::runtime_error); 165 166 ASSERT_THAT(sut.list(), UnorderedElementsAre()); 167 } 168 169 TEST_F(TestPersistentJsonStorageWithSymlink, returnsNulloptWhenFileIsSymlink) 170 { 171 ASSERT_THAT(sut.load(FilePath("report/symlink.json")), Eq(std::nullopt)); 172 } 173 174 TEST_F(TestPersistentJsonStorageWithSymlink, 175 returnsFalseWhenTryingToDeleteSymlink) 176 { 177 EXPECT_THAT(sut.remove(FilePath("report/symlink.json")), Eq(false)); 178 EXPECT_TRUE(std::filesystem::exists(std::filesystem::path(directory) / 179 "report/symlink.json")); 180 EXPECT_TRUE(std::filesystem::exists(dummyReportPath)); 181 } 182