blob: 50ac53fd051cc1426fba423c41a6eea85aaeadba [file] [log] [blame]
Patrick Williams5cf5ddf2025-07-02 15:48:25 -04001#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
11namespace s = std::string_literals;
12
13class JsonSerializerTest : public testing::Test
14{
15 protected:
16 std::string test_file;
17
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
30 void TearDown() override
31 {
32 if (std::filesystem::exists(test_file))
33 {
34 std::filesystem::remove(test_file);
35 }
36 }
37};
38
39TEST_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
46TEST_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
55TEST_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
70TEST_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
89TEST_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
104TEST_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 // nlohmann::json will throw a parse error for empty files or invalid JSON
112 EXPECT_THROW(s.load(), nlohmann::json::parse_error);
113}
114
115TEST_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 // nlohmann::json will throw a parse error for incomplete JSON
124 EXPECT_THROW(s.load(), nlohmann::json::parse_error);
125}