Line data Source code
1 : // Copyright (c) 2011-2026 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/edhttp
4 : // contact@m2osw.com
5 : //
6 : // This program is free software: you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation, either version 3 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 : /** \file
20 : * \brief Verify the token class and functions.
21 : *
22 : * This file implements tests to verify that the token class functions
23 : * properly. It also includes tests for the standalone functions.
24 : */
25 :
26 : // edhttp
27 : //
28 : #include <edhttp/token.h>
29 :
30 : #include <edhttp/exception.h>
31 :
32 :
33 : // self
34 : //
35 : #include "catch_main.h"
36 :
37 :
38 : // snapdev
39 : //
40 : //#include <snapdev/tokenize_string.h>
41 :
42 :
43 : // snaplogger
44 : //
45 : #include <snaplogger/message.h>
46 :
47 :
48 : // C
49 : //
50 : #include <string.h>
51 :
52 :
53 :
54 4 : CATCH_TEST_CASE("token", "[token]")
55 : {
56 4 : CATCH_START_SECTION("token: verify simple tokens")
57 : {
58 3 : CATCH_REQUIRE(edhttp::is_token("snap"));
59 3 : CATCH_REQUIRE(edhttp::is_token("!not"));
60 3 : CATCH_REQUIRE(edhttp::is_token("#hash"));
61 3 : CATCH_REQUIRE(edhttp::is_token("$dollar"));
62 3 : CATCH_REQUIRE(edhttp::is_token("%percent"));
63 3 : CATCH_REQUIRE(edhttp::is_token("&"));
64 3 : CATCH_REQUIRE(edhttp::is_token("'apostrophe"));
65 3 : CATCH_REQUIRE(edhttp::is_token("*asterisk"));
66 3 : CATCH_REQUIRE(edhttp::is_token("+plus"));
67 3 : CATCH_REQUIRE(edhttp::is_token("-minus"));
68 3 : CATCH_REQUIRE(edhttp::is_token(".dot"));
69 3 : CATCH_REQUIRE(edhttp::is_token("^caret"));
70 3 : CATCH_REQUIRE(edhttp::is_token("_underscore"));
71 3 : CATCH_REQUIRE(edhttp::is_token("`backtick"));
72 3 : CATCH_REQUIRE(edhttp::is_token("|pipe"));
73 3 : CATCH_REQUIRE(edhttp::is_token("~tilde"));
74 3 : CATCH_REQUIRE(edhttp::is_token("num0"));
75 3 : CATCH_REQUIRE(edhttp::is_token("num1"));
76 3 : CATCH_REQUIRE(edhttp::is_token("num2"));
77 3 : CATCH_REQUIRE(edhttp::is_token("num3"));
78 3 : CATCH_REQUIRE(edhttp::is_token("num4"));
79 3 : CATCH_REQUIRE(edhttp::is_token("num5"));
80 3 : CATCH_REQUIRE(edhttp::is_token("num6"));
81 3 : CATCH_REQUIRE(edhttp::is_token("num7"));
82 3 : CATCH_REQUIRE(edhttp::is_token("num8"));
83 3 : CATCH_REQUIRE(edhttp::is_token("num9"));
84 3 : CATCH_REQUIRE(edhttp::is_token("ALL-CAPS"));
85 3 : CATCH_REQUIRE(edhttp::is_token("Flipped~Flopped"));
86 : }
87 5 : CATCH_END_SECTION()
88 :
89 4 : CATCH_START_SECTION("token: verify restricted tokens")
90 : {
91 3 : CATCH_REQUIRE(edhttp::is_restricted_token("snap"));
92 3 : CATCH_REQUIRE(edhttp::is_restricted_token("-minus"));
93 3 : CATCH_REQUIRE(edhttp::is_restricted_token("_underscore"));
94 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num0"));
95 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num1"));
96 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num2"));
97 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num3"));
98 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num4"));
99 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num5"));
100 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num6"));
101 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num7"));
102 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num8"));
103 3 : CATCH_REQUIRE(edhttp::is_restricted_token("num9"));
104 3 : CATCH_REQUIRE(edhttp::is_restricted_token("ALL-CAPS"));
105 3 : CATCH_REQUIRE(edhttp::is_restricted_token("Flipped_Flopped"));
106 :
107 3 : CATCH_REQUIRE_FALSE(edhttp::is_restricted_token("Flipped~Flopped"));
108 3 : CATCH_REQUIRE_FALSE(edhttp::is_restricted_token("[enclosed]"));
109 : }
110 5 : CATCH_END_SECTION()
111 :
112 4 : CATCH_START_SECTION("token: compare tokens")
113 : {
114 5 : CATCH_REQUIRE(edhttp::compare_tokens("snap", "websites", false) == -1);
115 5 : CATCH_REQUIRE(edhttp::compare_tokens("SNAP", "websites", false) == -1);
116 5 : CATCH_REQUIRE(edhttp::compare_tokens("websites", "Snap", false) == 1);
117 5 : CATCH_REQUIRE(edhttp::compare_tokens("Websites", "snap", false) == 1);
118 :
119 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow-up", "follow_up", false) == -1);
120 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow-up", "follow_up", true) == 0);
121 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow_up", "follow-up", false) == 1);
122 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow_up", "follow-up", true) == 0);
123 :
124 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow-", "follow_up", true) == -1);
125 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow-up", "follow_", true) == 1);
126 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow_", "follow-up", true) == -1);
127 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow_up", "follow-", true) == 1);
128 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow-", "follow_up", false) == -1);
129 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow-up", "follow_", false) == -1);
130 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow_", "follow-up", false) == 1);
131 5 : CATCH_REQUIRE(edhttp::compare_tokens("follow_up", "follow-", false) == 1);
132 : }
133 5 : CATCH_END_SECTION()
134 :
135 4 : CATCH_START_SECTION("token: token objects")
136 : {
137 3 : edhttp::token t1("this-is-a-token");
138 3 : edhttp::token const t2("another-token");
139 1 : edhttp::token t3(t2);
140 :
141 1 : CATCH_REQUIRE(t1.is_valid());
142 1 : CATCH_REQUIRE(t2.is_valid());
143 1 : CATCH_REQUIRE(t3.is_valid());
144 1 : CATCH_REQUIRE(t1 > t2);
145 1 : CATCH_REQUIRE(t1 >= t2);
146 1 : CATCH_REQUIRE(t2 < t1);
147 1 : CATCH_REQUIRE(t2 <= t1);
148 1 : CATCH_REQUIRE(t2 == t3);
149 1 : CATCH_REQUIRE(t3 == t2);
150 :
151 1 : edhttp::token t4;
152 1 : t4 = t1;
153 1 : CATCH_REQUIRE(t4 > t3);
154 1 : CATCH_REQUIRE(t4 == t1);
155 1 : CATCH_REQUIRE(t4 != t2);
156 :
157 3 : std::string s("colorful");
158 1 : edhttp::token const t5(s);
159 1 : CATCH_REQUIRE(t5 != t4);
160 1 : CATCH_REQUIRE(t5 < t4);
161 :
162 1 : CATCH_REQUIRE(t5 == s);
163 1 : CATCH_REQUIRE(s == t5);
164 1 : CATCH_REQUIRE(s <= t4);
165 1 : CATCH_REQUIRE(t4 >= s);
166 1 : CATCH_REQUIRE(t4 != s);
167 1 : CATCH_REQUIRE(s != t4);
168 :
169 3 : edhttp::token t6("test-a-long-token-with-the-move-operator");
170 1 : CATCH_REQUIRE(t6 == "test-a-long-token-with-the-move-operator");
171 1 : edhttp::token t7(std::move(t6));
172 1 : CATCH_REQUIRE(t7 == "test-a-long-token-with-the-move-operator");
173 1 : CATCH_REQUIRE(t6.empty());
174 :
175 3 : std::string org("this-long-token-name-can-be-copied-from-a-string");
176 1 : edhttp::token t8(std::move(org));
177 1 : CATCH_REQUIRE(t8 == "this-long-token-name-can-be-copied-from-a-string");
178 1 : CATCH_REQUIRE(org.empty());
179 1 : }
180 5 : CATCH_END_SECTION()
181 4 : }
182 :
183 :
184 3 : CATCH_TEST_CASE("token_error", "[token][error]")
185 : {
186 3 : CATCH_START_SECTION("token_error: empty strings generate an error")
187 : {
188 5 : CATCH_REQUIRE_THROWS_MATCHES(
189 : edhttp::is_token(std::string())
190 : , edhttp::invalid_token
191 : , Catch::Matchers::ExceptionMessage(
192 : "edhttp_exception: an HTTP token cannot be empty."));
193 : }
194 4 : CATCH_END_SECTION()
195 :
196 3 : CATCH_START_SECTION("token_error: compare invalid tokens")
197 : {
198 11 : CATCH_REQUIRE_THROWS_MATCHES(
199 : edhttp::compare_tokens("co lor", "color")
200 : , edhttp::invalid_token
201 : , Catch::Matchers::ExceptionMessage(
202 : "edhttp_exception: one of the input token includes an invalid character."));
203 :
204 11 : CATCH_REQUIRE_THROWS_MATCHES(
205 : edhttp::compare_tokens("color", "co lor")
206 : , edhttp::invalid_token
207 : , Catch::Matchers::ExceptionMessage(
208 : "edhttp_exception: one of the input token includes an invalid character."));
209 : }
210 4 : CATCH_END_SECTION()
211 :
212 3 : CATCH_START_SECTION("token_error: compare invalid tokens")
213 : {
214 5 : CATCH_REQUIRE_THROWS_MATCHES(
215 : edhttp::is_restricted_token(std::string())
216 : , edhttp::invalid_token
217 : , Catch::Matchers::ExceptionMessage(
218 : "edhttp_exception: a restricted HTTP token cannot be empty."));
219 : }
220 4 : CATCH_END_SECTION()
221 3 : }
222 :
223 :
224 : // vim: ts=4 sw=4 et
|