1 #include "helpers.hpp"
2 #include "utils/dbus_path_utils.hpp"
3 #include "utils/make_id_name.hpp"
4 #include "utils/string_utils.hpp"
5
6 #include <sdbusplus/exception.hpp>
7
8 #include <gmock/gmock.h>
9
10 using namespace testing;
11 using namespace std::literals::string_literals;
12 using namespace utils::string_utils;
13
14 class ScenarioBase : public Test
15 {
16 public:
17 std::string_view defaultName = "defName";
18 std::vector<std::string> conflicts;
19 };
20
21 class ScenarioNameProvided : public ScenarioBase
22 {
23 public:
makeIdName(std::string_view id,std::string_view name) const24 auto makeIdName(std::string_view id, std::string_view name) const
25 {
26 return utils::makeIdName(id, name, defaultName, conflicts);
27 }
28 };
29
TEST_F(ScenarioNameProvided,throwsWhenProvidedNameIsTooLong)30 TEST_F(ScenarioNameProvided, throwsWhenProvidedNameIsTooLong)
31 {
32 EXPECT_THROW(this->makeIdName("", getTooLongName()),
33 errors::InvalidArgument);
34 }
35
36 class TestMakeIdNameNameProvided : public ScenarioNameProvided
37 {};
38
TEST_F(TestMakeIdNameNameProvided,usesIdWhenProvided)39 TEST_F(TestMakeIdNameNameProvided, usesIdWhenProvided)
40 {
41 const std::string name = "name";
42
43 EXPECT_THAT(this->makeIdName("id0", name), Eq(std::pair{"id0"s, name}));
44 EXPECT_THAT(this->makeIdName("prefix/id2", name),
45 Eq(std::pair{"prefix/id2"s, name}));
46 }
47
TEST_F(TestMakeIdNameNameProvided,usedDefaultWhenNothingProvided)48 TEST_F(TestMakeIdNameNameProvided, usedDefaultWhenNothingProvided)
49 {
50 this->defaultName = "def";
51
52 EXPECT_THAT(this->makeIdName("", ""), Eq(std::pair{"def"s, "def"s}));
53 EXPECT_THAT(this->makeIdName("abc/", ""),
54 Eq(std::pair{"abc/def"s, "def"s}));
55 }
56
TEST_F(TestMakeIdNameNameProvided,usedDefaultWhenNameContainsNoIdChars)57 TEST_F(TestMakeIdNameNameProvided, usedDefaultWhenNameContainsNoIdChars)
58 {
59 this->defaultName = "def";
60 const std::string name = " !";
61
62 EXPECT_THAT(this->makeIdName("", name), Eq(std::pair{"def"s, name}));
63 EXPECT_THAT(this->makeIdName("prefix/", name),
64 Eq(std::pair{"prefix/def"s, name}));
65 }
66
67 class ScenarioNameNotProvided : public ScenarioBase
68 {
69 public:
makeIdName(std::string_view id,std::string_view name) const70 auto makeIdName(std::string_view id, std::string_view name) const
71 {
72 return utils::makeIdName(id, "", name, conflicts);
73 }
74 };
75
76 class TestMakeIdNameNameNotProvided : public ScenarioNameNotProvided
77 {};
78
TEST_F(TestMakeIdNameNameNotProvided,usesIdAsNameWhenProvided)79 TEST_F(TestMakeIdNameNameNotProvided, usesIdAsNameWhenProvided)
80 {
81 EXPECT_THAT(this->makeIdName("id0", defaultName),
82 Eq(std::pair{"id0"s, "id0"s}));
83 EXPECT_THAT(this->makeIdName("prefix/id2", defaultName),
84 Eq(std::pair{"prefix/id2"s, "id2"s}));
85 }
86
87 template <class Scenario>
88 class TestMakeIdName : public Scenario
89 {};
90
91 using TestScenarios =
92 ::testing::Types<ScenarioNameProvided, ScenarioNameNotProvided>;
93 TYPED_TEST_SUITE(TestMakeIdName, TestScenarios);
94
TYPED_TEST(TestMakeIdName,throwsWhenProvidedIdContainsIncorrectCharacters)95 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdContainsIncorrectCharacters)
96 {
97 EXPECT_THROW(this->makeIdName("Id%@%!@%!%()%fooo/Id", "name"),
98 errors::InvalidArgument);
99 EXPECT_THROW(this->makeIdName("Id/Id%@%!@%!%()%fooo", "name"),
100 errors::InvalidArgument);
101 EXPECT_THROW(this->makeIdName("/123", "trigger"), errors::InvalidArgument);
102 EXPECT_THROW(this->makeIdName("/123/", "trigger"), errors::InvalidArgument);
103 }
104
TYPED_TEST(TestMakeIdName,throwsWhenProvidedIdContainsTooLongSegment)105 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdContainsTooLongSegment)
106 {
107 std::string longPrefix = getTooLongPrefix();
108 std::string longSuffix = getTooLongId();
109 EXPECT_THROW(this->makeIdName(longPrefix + "/", "name"),
110 errors::InvalidArgument);
111 EXPECT_THROW(this->makeIdName(longPrefix + "/Id", "name"),
112 errors::InvalidArgument);
113 EXPECT_THROW(this->makeIdName(longPrefix + "/" + longSuffix, "name"),
114 errors::InvalidArgument);
115 EXPECT_THROW(this->makeIdName("Prefix/" + longSuffix, "name"),
116 errors::InvalidArgument);
117 EXPECT_THROW(this->makeIdName(longSuffix, "name"), errors::InvalidArgument);
118 }
119
TYPED_TEST(TestMakeIdName,throwsWhenProvidedIdOrPrefixTooLong)120 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdOrPrefixTooLong)
121 {
122 EXPECT_THROW(this->makeIdName(getTooLongId(), "name"),
123 errors::InvalidArgument);
124 EXPECT_THROW(this->makeIdName(getTooLongPrefix() + "/Id", "name"),
125 errors::InvalidArgument);
126 EXPECT_THROW(this->makeIdName("Prefix/" + getTooLongId(), "trigger"),
127 errors::InvalidArgument);
128 }
129
TYPED_TEST(TestMakeIdName,throwsWhenIdContainsMoreThanOneSlash)130 TYPED_TEST(TestMakeIdName, throwsWhenIdContainsMoreThanOneSlash)
131 {
132 EXPECT_THROW(this->makeIdName("/12/", "name"), errors::InvalidArgument);
133 EXPECT_THROW(this->makeIdName("12//", "name"), errors::InvalidArgument);
134 EXPECT_THROW(this->makeIdName("12//123", "name"), errors::InvalidArgument);
135 EXPECT_THROW(this->makeIdName("12/12/123", "name"),
136 errors::InvalidArgument);
137 }
138
TYPED_TEST(TestMakeIdName,usesNameWhenThereAreConflicts)139 TYPED_TEST(TestMakeIdName, usesNameWhenThereAreConflicts)
140 {
141 this->conflicts = {"trigger"};
142 EXPECT_THAT(this->makeIdName("", "trigger"),
143 Eq(std::pair{"trigger0"s, "trigger"s}));
144
145 this->conflicts = {"trigger", "trigger0"};
146 EXPECT_THAT(this->makeIdName("", "trigger"),
147 Eq(std::pair{"trigger1"s, "trigger"s}));
148
149 this->conflicts = {getMaxId()};
150 std::string expectedId = getMaxId();
151 expectedId[expectedId.length() - 1] = '0';
152 EXPECT_THAT(this->makeIdName("", getMaxId()),
153 Eq(std::pair{expectedId, getMaxId()}));
154 }
155
TYPED_TEST(TestMakeIdName,throwsWhenProvidedIdIsTaken)156 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdIsTaken)
157 {
158 this->conflicts = {"id", "prefix/id"};
159
160 EXPECT_THROW(this->makeIdName("id", "name"),
161 sdbusplus::exception::SdBusError);
162 EXPECT_THROW(this->makeIdName("prefix/id", "name"),
163 sdbusplus::exception::SdBusError);
164 }
165
TYPED_TEST(TestMakeIdName,usesNameWhenIdNotProvided)166 TYPED_TEST(TestMakeIdName, usesNameWhenIdNotProvided)
167 {
168 EXPECT_THAT(this->makeIdName("", "name"), Eq(std::pair{"name"s, "name"s}));
169 EXPECT_THAT(this->makeIdName("abc/", "name"),
170 Eq(std::pair{"abc/name"s, "name"s}));
171 EXPECT_THAT(this->makeIdName("123/", "name"),
172 Eq(std::pair{"123/name"s, "name"s}));
173 }
174
TYPED_TEST(TestMakeIdName,usesNameWithoutInvalidCharactersWhenIdNotProvided)175 TYPED_TEST(TestMakeIdName, usesNameWithoutInvalidCharactersWhenIdNotProvided)
176 {
177 EXPECT_THAT(this->makeIdName("", "n#a$/m@e"),
178 Eq(std::pair{"name"s, "n#a$/m@e"s}));
179 EXPECT_THAT(this->makeIdName("", "n!^aŹ/me"),
180 Eq(std::pair{"name"s, "n!^aŹ/me"s}));
181 EXPECT_THAT(this->makeIdName("p/", "n!^aŹ/m*(e"),
182 Eq(std::pair{"p/name"s, "n!^aŹ/m*(e"s}));
183 }
184