| 2 |
raymond |
1 |
#!/bin/bash
|
|
|
2 |
|
|
|
3 |
# URI Matcher Test Script
|
|
|
4 |
# Tests all routes defined in URIMatcherTest.ino
|
|
|
5 |
|
|
|
6 |
SERVER_IP="${1:-192.168.4.1}"
|
|
|
7 |
SERVER_PORT="80"
|
|
|
8 |
BASE_URL="http://${SERVER_IP}:${SERVER_PORT}"
|
|
|
9 |
|
|
|
10 |
echo "Testing URI Matcher at $BASE_URL"
|
|
|
11 |
echo "=================================="
|
|
|
12 |
|
|
|
13 |
# Function to test a route
|
|
|
14 |
test_route() {
|
|
|
15 |
local path="$1"
|
|
|
16 |
local expected_status="$2"
|
|
|
17 |
local description="$3"
|
|
|
18 |
|
|
|
19 |
echo -n "Testing $path ... "
|
|
|
20 |
|
|
|
21 |
response=$(curl -s -w "HTTPSTATUS:%{http_code}" "$BASE_URL$path" 2>/dev/null)
|
|
|
22 |
status_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
|
|
|
23 |
|
|
|
24 |
if [ "$status_code" = "$expected_status" ]; then
|
|
|
25 |
echo "✅ PASS ($status_code)"
|
|
|
26 |
else
|
|
|
27 |
echo "❌ FAIL (expected $expected_status, got $status_code)"
|
|
|
28 |
return 1
|
|
|
29 |
fi
|
|
|
30 |
return 0
|
|
|
31 |
}
|
|
|
32 |
|
|
|
33 |
# Test counter
|
|
|
34 |
PASS=0
|
|
|
35 |
FAIL=0
|
|
|
36 |
|
|
|
37 |
# Test all routes that should return 200 OK
|
|
|
38 |
echo "Testing routes that should work (200 OK):"
|
|
|
39 |
|
|
|
40 |
if test_route "/status" "200" "Status endpoint"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
41 |
if test_route "/exact" "200" "Exact path"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
42 |
if test_route "/exact/" "200" "Exact path ending with /"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
43 |
if test_route "/exact/sub" "200" "Exact path with subpath /"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
44 |
if test_route "/api/users" "200" "Exact API path"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
45 |
if test_route "/api/data" "200" "API prefix match"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
46 |
if test_route "/api/v1/posts" "200" "API prefix deep"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
47 |
if test_route "/files/document.pdf" "200" "Files prefix"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
48 |
if test_route "/files/images/photo.jpg" "200" "Files prefix deep"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
49 |
if test_route "/config.json" "200" "JSON extension"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
50 |
if test_route "/data/settings.json" "200" "JSON extension in subfolder"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
51 |
if test_route "/style.css" "200" "CSS extension"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
52 |
if test_route "/assets/main.css" "200" "CSS extension in subfolder"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
53 |
|
|
|
54 |
echo ""
|
|
|
55 |
echo "Testing AsyncURIMatcher factory methods:"
|
|
|
56 |
|
|
|
57 |
# Factory exact match (should NOT match subpaths)
|
|
|
58 |
if test_route "/factory/exact" "200" "Factory exact match"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
59 |
|
|
|
60 |
# Factory prefix match
|
|
|
61 |
if test_route "/factory/prefix" "200" "Factory prefix base"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
62 |
if test_route "/factory/prefix-test" "200" "Factory prefix extended"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
63 |
if test_route "/factory/prefix/sub" "200" "Factory prefix subpath"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
64 |
|
|
|
65 |
# Factory directory match (should NOT match the directory itself)
|
|
|
66 |
if test_route "/factory/dir/users" "200" "Factory directory match"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
67 |
if test_route "/factory/dir/sub/path" "200" "Factory directory deep"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
68 |
|
|
|
69 |
# Factory extension match
|
|
|
70 |
if test_route "/factory/files/doc.txt" "200" "Factory extension match"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
71 |
if test_route "/factory/files/sub/readme.txt" "200" "Factory extension deep"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
72 |
|
|
|
73 |
echo ""
|
|
|
74 |
echo "Testing case insensitive matching:"
|
|
|
75 |
|
|
|
76 |
# Case insensitive exact
|
|
|
77 |
if test_route "/case/exact" "200" "Case exact lowercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
78 |
if test_route "/CASE/EXACT" "200" "Case exact uppercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
79 |
if test_route "/Case/Exact" "200" "Case exact mixed"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
80 |
|
|
|
81 |
# Case insensitive prefix
|
|
|
82 |
if test_route "/case/prefix" "200" "Case prefix lowercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
83 |
if test_route "/CASE/PREFIX-test" "200" "Case prefix uppercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
84 |
if test_route "/Case/Prefix/sub" "200" "Case prefix mixed"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
85 |
|
|
|
86 |
# Case insensitive directory
|
|
|
87 |
if test_route "/case/dir/users" "200" "Case dir lowercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
88 |
if test_route "/CASE/DIR/admin" "200" "Case dir uppercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
89 |
if test_route "/Case/Dir/settings" "200" "Case dir mixed"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
90 |
|
|
|
91 |
# Case insensitive extension
|
|
|
92 |
if test_route "/case/files/doc.pdf" "200" "Case ext lowercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
93 |
if test_route "/CASE/FILES/DOC.PDF" "200" "Case ext uppercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
94 |
if test_route "/Case/Files/Doc.Pdf" "200" "Case ext mixed"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
95 |
|
|
|
96 |
echo ""
|
|
|
97 |
echo "Testing special matchers:"
|
|
|
98 |
|
|
|
99 |
# Test POST to catch-all (all() matcher)
|
|
|
100 |
echo -n "Testing POST /any/path (all matcher) ... "
|
|
|
101 |
response=$(curl -s -X POST -w "HTTPSTATUS:%{http_code}" "$BASE_URL/any/path" 2>/dev/null)
|
|
|
102 |
status_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
|
|
|
103 |
if [ "$status_code" = "200" ]; then
|
|
|
104 |
echo "✅ PASS ($status_code)"
|
|
|
105 |
((PASS++))
|
|
|
106 |
else
|
|
|
107 |
echo "❌ FAIL (expected 200, got $status_code)"
|
|
|
108 |
((FAIL++))
|
|
|
109 |
fi
|
|
|
110 |
|
|
|
111 |
# Check if regex is enabled by testing the server
|
|
|
112 |
echo ""
|
|
|
113 |
echo "Checking for regex support..."
|
|
|
114 |
regex_test=$(curl -s "$BASE_URL/user/123" 2>/dev/null)
|
|
|
115 |
if curl -s -w "%{http_code}" "$BASE_URL/user/123" 2>/dev/null | grep -q "200"; then
|
|
|
116 |
echo "Regex support detected - testing traditional regex routes:"
|
|
|
117 |
if test_route "/user/123" "200" "Traditional regex user ID"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
118 |
if test_route "/user/456" "200" "Traditional regex user ID 2"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
119 |
if test_route "/blog/2023/10/15" "200" "Traditional regex blog date"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
120 |
if test_route "/blog/2024/12/25" "200" "Traditional regex blog date 2"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
121 |
|
|
|
122 |
echo "Testing AsyncURIMatcher regex factory methods:"
|
|
|
123 |
if test_route "/factory/user/123" "200" "Factory regex user ID"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
124 |
if test_route "/factory/user/789" "200" "Factory regex user ID 2"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
125 |
if test_route "/factory/blog/2023/10/15" "200" "Factory regex blog date"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
126 |
if test_route "/factory/blog/2024/12/31" "200" "Factory regex blog date 2"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
127 |
|
|
|
128 |
# Case insensitive regex
|
|
|
129 |
if test_route "/factory/search/hello" "200" "Factory regex search lowercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
130 |
if test_route "/FACTORY/SEARCH/WORLD" "200" "Factory regex search uppercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
131 |
if test_route "/Factory/Search/Test" "200" "Factory regex search mixed"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
132 |
|
|
|
133 |
# Test regex validation
|
|
|
134 |
if test_route "/user/abc" "404" "Invalid regex (letters instead of numbers)"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
135 |
if test_route "/blog/23/10/15" "404" "Invalid regex (2-digit year)"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
136 |
if test_route "/factory/user/abc" "404" "Factory regex invalid (letters)"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
137 |
else
|
|
|
138 |
echo "Regex support not detected (compile with ASYNCWEBSERVER_REGEX to enable)"
|
|
|
139 |
fi
|
|
|
140 |
|
|
|
141 |
echo ""
|
|
|
142 |
echo "Testing routes that should fail (404 Not Found):"
|
|
|
143 |
|
|
|
144 |
if test_route "/nonexistent" "404" "Non-existent route"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
145 |
|
|
|
146 |
# Test factory exact vs traditional behavior difference
|
|
|
147 |
if test_route "/factory/exact/sub" "404" "Factory exact should NOT match subpaths"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
148 |
|
|
|
149 |
# Test factory directory requires trailing slash
|
|
|
150 |
if test_route "/factory/dir" "404" "Factory directory should NOT match without trailing slash"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
151 |
|
|
|
152 |
# Test extension mismatch
|
|
|
153 |
if test_route "/factory/files/doc.pdf" "404" "Factory extension mismatch (.pdf vs .txt)"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
154 |
|
|
|
155 |
# Test case sensitive when flag not used
|
|
|
156 |
if test_route "/exact" "200" "Traditional exact lowercase"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
157 |
if test_route "/EXACT" "404" "Traditional exact should be case sensitive"; then ((PASS++)); else ((FAIL++)); fi
|
|
|
158 |
|
|
|
159 |
echo ""
|
|
|
160 |
echo "=================================="
|
|
|
161 |
echo "Test Results:"
|
|
|
162 |
echo "✅ Passed: $PASS"
|
|
|
163 |
echo "❌ Failed: $FAIL"
|
|
|
164 |
echo "Total: $((PASS + FAIL))"
|
|
|
165 |
|
|
|
166 |
if [ $FAIL -eq 0 ]; then
|
|
|
167 |
echo ""
|
|
|
168 |
echo "🎉 All tests passed! URI matching is working correctly."
|
|
|
169 |
exit 0
|
|
|
170 |
else
|
|
|
171 |
echo ""
|
|
|
172 |
echo "❌ Some tests failed. Check the server and routes."
|
|
|
173 |
exit 1
|
|
|
174 |
fi
|