15cf5ddf3SPatrick Williams #include <unistd.h>
25cf5ddf3SPatrick Williams
35cf5ddf3SPatrick Williams #include <json_serializer.hpp>
45cf5ddf3SPatrick Williams
55cf5ddf3SPatrick Williams #include <filesystem>
65cf5ddf3SPatrick Williams #include <fstream>
75cf5ddf3SPatrick Williams #include <string>
85cf5ddf3SPatrick Williams
95cf5ddf3SPatrick Williams #include <gtest/gtest.h>
105cf5ddf3SPatrick Williams
115cf5ddf3SPatrick Williams namespace s = std::string_literals;
125cf5ddf3SPatrick Williams
135cf5ddf3SPatrick Williams class JsonSerializerTest : public testing::Test
145cf5ddf3SPatrick Williams {
155cf5ddf3SPatrick Williams protected:
165cf5ddf3SPatrick Williams std::string test_file;
175cf5ddf3SPatrick Williams
SetUp()185cf5ddf3SPatrick Williams void SetUp() override
195cf5ddf3SPatrick Williams {
205cf5ddf3SPatrick Williams char tmpTemplate[] = "/tmp/test_file_XXXXXX";
215cf5ddf3SPatrick Williams int fd = mkstemp(tmpTemplate);
225cf5ddf3SPatrick Williams if (fd == -1)
235cf5ddf3SPatrick Williams {
245cf5ddf3SPatrick Williams throw std::runtime_error("Failed to create temporary file.");
255cf5ddf3SPatrick Williams }
265cf5ddf3SPatrick Williams close(fd);
275cf5ddf3SPatrick Williams test_file = tmpTemplate;
285cf5ddf3SPatrick Williams }
295cf5ddf3SPatrick Williams
TearDown()305cf5ddf3SPatrick Williams void TearDown() override
315cf5ddf3SPatrick Williams {
325cf5ddf3SPatrick Williams if (std::filesystem::exists(test_file))
335cf5ddf3SPatrick Williams {
345cf5ddf3SPatrick Williams std::filesystem::remove(test_file);
355cf5ddf3SPatrick Williams }
365cf5ddf3SPatrick Williams }
375cf5ddf3SPatrick Williams };
385cf5ddf3SPatrick Williams
TEST_F(JsonSerializerTest,MakeJson)395cf5ddf3SPatrick Williams TEST_F(JsonSerializerTest, MakeJson)
405cf5ddf3SPatrick Williams {
415cf5ddf3SPatrick Williams JsonSerializer s(test_file);
425cf5ddf3SPatrick Williams nlohmann::json j = s.makeJson("foo/bar/baz", "value");
435cf5ddf3SPatrick Williams EXPECT_EQ(j["foo"]["bar"]["baz"], "value");
445cf5ddf3SPatrick Williams }
455cf5ddf3SPatrick Williams
TEST_F(JsonSerializerTest,SerializeDeserialize)465cf5ddf3SPatrick Williams TEST_F(JsonSerializerTest, SerializeDeserialize)
475cf5ddf3SPatrick Williams {
485cf5ddf3SPatrick Williams JsonSerializer s(test_file);
495cf5ddf3SPatrick Williams s.serialize("foo/bar/baz", "value");
505cf5ddf3SPatrick Williams std::string value;
515cf5ddf3SPatrick Williams s.deserialize("foo/bar/baz", value);
525cf5ddf3SPatrick Williams EXPECT_EQ(value, "value");
535cf5ddf3SPatrick Williams }
545cf5ddf3SPatrick Williams
TEST_F(JsonSerializerTest,StoreLoad)555cf5ddf3SPatrick Williams TEST_F(JsonSerializerTest, StoreLoad)
565cf5ddf3SPatrick Williams {
575cf5ddf3SPatrick Williams JsonSerializer s(test_file);
585cf5ddf3SPatrick Williams s.serialize("foo/bar/baz", "value");
595cf5ddf3SPatrick Williams s.store();
605cf5ddf3SPatrick Williams
615cf5ddf3SPatrick Williams // Create a new JsonSerializer instance to load from the same file
625cf5ddf3SPatrick Williams // This simulates a fresh process loading the configuration
635cf5ddf3SPatrick Williams JsonSerializer s2(test_file);
645cf5ddf3SPatrick Williams s2.load();
655cf5ddf3SPatrick Williams std::string value;
665cf5ddf3SPatrick Williams s2.deserialize("foo/bar/baz", value);
675cf5ddf3SPatrick Williams EXPECT_EQ(value, "value");
685cf5ddf3SPatrick Williams }
695cf5ddf3SPatrick Williams
TEST_F(JsonSerializerTest,Erase)705cf5ddf3SPatrick Williams TEST_F(JsonSerializerTest, Erase)
715cf5ddf3SPatrick Williams {
725cf5ddf3SPatrick Williams JsonSerializer s(test_file);
735cf5ddf3SPatrick Williams s.serialize("foo/bar/baz", "value");
745cf5ddf3SPatrick Williams // The current erase method only handles top-level keys.
755cf5ddf3SPatrick Williams // Calling erase with a nested path like "foo/bar/baz" will not remove
765cf5ddf3SPatrick Williams // "baz".
775cf5ddf3SPatrick Williams s.erase("foo/bar/baz");
785cf5ddf3SPatrick Williams s.store();
795cf5ddf3SPatrick Williams
805cf5ddf3SPatrick Williams // Verify that the value is still present because erase did not remove the
815cf5ddf3SPatrick Williams // nested key.
825cf5ddf3SPatrick Williams JsonSerializer s2(test_file);
835cf5ddf3SPatrick Williams s2.load();
845cf5ddf3SPatrick Williams std::string value;
855cf5ddf3SPatrick Williams s2.deserialize("foo/bar/baz", value);
865cf5ddf3SPatrick Williams EXPECT_EQ(value, "value"); // Expect original value to remain
875cf5ddf3SPatrick Williams }
885cf5ddf3SPatrick Williams
TEST_F(JsonSerializerTest,GetLeafNode)895cf5ddf3SPatrick Williams TEST_F(JsonSerializerTest, GetLeafNode)
905cf5ddf3SPatrick Williams {
915cf5ddf3SPatrick Williams JsonSerializer s(test_file);
925cf5ddf3SPatrick Williams s.serialize("foo/bar/baz", "value");
935cf5ddf3SPatrick Williams auto leaf = s.getLeafNode("foo/bar/baz");
945cf5ddf3SPatrick Williams EXPECT_TRUE(leaf.has_value());
955cf5ddf3SPatrick Williams if (leaf.has_value())
965cf5ddf3SPatrick Williams {
975cf5ddf3SPatrick Williams EXPECT_EQ(*leaf, "value");
985cf5ddf3SPatrick Williams }
995cf5ddf3SPatrick Williams
1005cf5ddf3SPatrick Williams leaf = s.getLeafNode("foo/bar/nonexistent");
1015cf5ddf3SPatrick Williams EXPECT_FALSE(leaf.has_value());
1025cf5ddf3SPatrick Williams }
1035cf5ddf3SPatrick Williams
TEST_F(JsonSerializerTest,LoadInvalidJsonFile)1045cf5ddf3SPatrick Williams TEST_F(JsonSerializerTest, LoadInvalidJsonFile)
1055cf5ddf3SPatrick Williams {
1065cf5ddf3SPatrick Williams // Ensure the file is empty or contains invalid JSON
1075cf5ddf3SPatrick Williams std::ofstream ofs(test_file, std::ios::trunc);
1085cf5ddf3SPatrick Williams ofs.close();
1095cf5ddf3SPatrick Williams
1105cf5ddf3SPatrick Williams JsonSerializer s(test_file);
111*f2196659SPatrick Williams EXPECT_FALSE(s.load());
112*f2196659SPatrick Williams EXPECT_FALSE(std::filesystem::exists(test_file));
1135cf5ddf3SPatrick Williams }
1145cf5ddf3SPatrick Williams
TEST_F(JsonSerializerTest,LoadGarbledJsonFile)1155cf5ddf3SPatrick Williams TEST_F(JsonSerializerTest, LoadGarbledJsonFile)
1165cf5ddf3SPatrick Williams {
1175cf5ddf3SPatrick Williams // Write a garbled JSON string to the file
1185cf5ddf3SPatrick Williams std::ofstream ofs(test_file);
1195cf5ddf3SPatrick Williams ofs << "{"; // Incomplete JSON object
1205cf5ddf3SPatrick Williams ofs.close();
1215cf5ddf3SPatrick Williams
1225cf5ddf3SPatrick Williams JsonSerializer s(test_file);
123*f2196659SPatrick Williams EXPECT_FALSE(s.load());
124*f2196659SPatrick Williams EXPECT_FALSE(std::filesystem::exists(test_file));
1255cf5ddf3SPatrick Williams }
126