1 #include <unistd.h>
2
3 #include <json_serializer.hpp>
4
5 #include <filesystem>
6 #include <fstream>
7 #include <string>
8
9 #include <gtest/gtest.h>
10
11 namespace s = std::string_literals;
12
13 class JsonSerializerTest : public testing::Test
14 {
15 protected:
16 std::string test_file;
17
SetUp()18 void SetUp() override
19 {
20 char tmpTemplate[] = "/tmp/test_file_XXXXXX";
21 int fd = mkstemp(tmpTemplate);
22 if (fd == -1)
23 {
24 throw std::runtime_error("Failed to create temporary file.");
25 }
26 close(fd);
27 test_file = tmpTemplate;
28 }
29
TearDown()30 void TearDown() override
31 {
32 if (std::filesystem::exists(test_file))
33 {
34 std::filesystem::remove(test_file);
35 }
36 }
37 };
38
TEST_F(JsonSerializerTest,MakeJson)39 TEST_F(JsonSerializerTest, MakeJson)
40 {
41 JsonSerializer s(test_file);
42 nlohmann::json j = s.makeJson("foo/bar/baz", "value");
43 EXPECT_EQ(j["foo"]["bar"]["baz"], "value");
44 }
45
TEST_F(JsonSerializerTest,SerializeDeserialize)46 TEST_F(JsonSerializerTest, SerializeDeserialize)
47 {
48 JsonSerializer s(test_file);
49 s.serialize("foo/bar/baz", "value");
50 std::string value;
51 s.deserialize("foo/bar/baz", value);
52 EXPECT_EQ(value, "value");
53 }
54
TEST_F(JsonSerializerTest,StoreLoad)55 TEST_F(JsonSerializerTest, StoreLoad)
56 {
57 JsonSerializer s(test_file);
58 s.serialize("foo/bar/baz", "value");
59 s.store();
60
61 // Create a new JsonSerializer instance to load from the same file
62 // This simulates a fresh process loading the configuration
63 JsonSerializer s2(test_file);
64 s2.load();
65 std::string value;
66 s2.deserialize("foo/bar/baz", value);
67 EXPECT_EQ(value, "value");
68 }
69
TEST_F(JsonSerializerTest,Erase)70 TEST_F(JsonSerializerTest, Erase)
71 {
72 JsonSerializer s(test_file);
73 s.serialize("foo/bar/baz", "value");
74 // The current erase method only handles top-level keys.
75 // Calling erase with a nested path like "foo/bar/baz" will not remove
76 // "baz".
77 s.erase("foo/bar/baz");
78 s.store();
79
80 // Verify that the value is still present because erase did not remove the
81 // nested key.
82 JsonSerializer s2(test_file);
83 s2.load();
84 std::string value;
85 s2.deserialize("foo/bar/baz", value);
86 EXPECT_EQ(value, "value"); // Expect original value to remain
87 }
88
TEST_F(JsonSerializerTest,GetLeafNode)89 TEST_F(JsonSerializerTest, GetLeafNode)
90 {
91 JsonSerializer s(test_file);
92 s.serialize("foo/bar/baz", "value");
93 auto leaf = s.getLeafNode("foo/bar/baz");
94 EXPECT_TRUE(leaf.has_value());
95 if (leaf.has_value())
96 {
97 EXPECT_EQ(*leaf, "value");
98 }
99
100 leaf = s.getLeafNode("foo/bar/nonexistent");
101 EXPECT_FALSE(leaf.has_value());
102 }
103
TEST_F(JsonSerializerTest,LoadInvalidJsonFile)104 TEST_F(JsonSerializerTest, LoadInvalidJsonFile)
105 {
106 // Ensure the file is empty or contains invalid JSON
107 std::ofstream ofs(test_file, std::ios::trunc);
108 ofs.close();
109
110 JsonSerializer s(test_file);
111 EXPECT_FALSE(s.load());
112 EXPECT_FALSE(std::filesystem::exists(test_file));
113 }
114
TEST_F(JsonSerializerTest,LoadGarbledJsonFile)115 TEST_F(JsonSerializerTest, LoadGarbledJsonFile)
116 {
117 // Write a garbled JSON string to the file
118 std::ofstream ofs(test_file);
119 ofs << "{"; // Incomplete JSON object
120 ofs.close();
121
122 JsonSerializer s(test_file);
123 EXPECT_FALSE(s.load());
124 EXPECT_FALSE(std::filesystem::exists(test_file));
125 }
126