11#! /bin/bash
22set -e
33
4- # Colors for better output
4+ # Colors for output
55GREEN=' \033[0;32m'
66RED=' \033[0;31m'
77YELLOW=' \033[0;33m'
88NC=' \033[0m' # No Color
99
10- # Generate a unique test ID for the database only
10+ # Test configuration
1111UNIQUE_ID=$(( RANDOM % 10000 ))
12-
13- # Fixed custom ID for testing
1412CUSTOM_ID=" customid"
15-
16- # Test server configuration
1713TEST_SERVER_HOST=" 127.0.0.1"
1814TEST_SERVER_PORT=" 8081"
19-
20- # Create test database with full path - global variables
2115TEST_DB_NAME=" test_api_${UNIQUE_ID} .db"
2216TEST_DB_PATH=" ${TEST_DB_NAME} "
2317
24- # Setup function
18+ # CI environment detection
19+ if [ -n " $CI " ]; then
20+ STARTUP_WAIT=5
21+ READY_WAIT=5
22+ else
23+ STARTUP_WAIT=2
24+ READY_WAIT=2
25+ fi
26+
2527setup () {
2628 echo -e " ${YELLOW} Setting up test environment...${NC} "
27-
28- # Print current directory for debugging
2929 echo -e " ${YELLOW} Current directory: $( pwd) ${NC} "
3030
31- # Use a simple relative path for the test database
3231 TEST_DB_NAME=" test_api_${UNIQUE_ID} .db"
3332 TEST_DB_PATH=" ${TEST_DB_NAME} "
3433
35- # Create empty database file to ensure directory is writable
3634 touch " ${TEST_DB_PATH} "
3735
38- # Start the server in the background using environment variables directly
3936 echo -e " ${YELLOW} Starting server with test database at ${TEST_DB_PATH} ...${NC} "
40-
41- # Use the proper SQLite connection string format for sqlx
42- # Format for sqlx is: sqlite:/path/to/db
4337 echo -e " ${YELLOW} Database URL: sqlite:${TEST_DB_PATH}${NC} "
4438
4539 DATABASE_URL=" sqlite:${TEST_DB_PATH} " \
@@ -51,26 +45,22 @@ setup() {
5145 cargo run &
5246 SERVER_PID=$!
5347
54- # Wait longer for server to start and become fully ready
5548 echo -e " ${YELLOW} Waiting for server to start (PID: ${SERVER_PID} )...${NC} "
56- sleep 2 # Give it more time to start and initialize
49+ sleep $STARTUP_WAIT
5750
58- # Check if server process is still running
5951 if kill -0 $SERVER_PID 2> /dev/null; then
6052 echo -e " ${GREEN} Server started successfully with PID: ${SERVER_PID}${NC} "
6153 echo -e " ${YELLOW} Waiting for server to fully initialize...${NC} "
62- sleep 2 # Additional time for server to be ready to accept connections
54+ sleep $READY_WAIT
6355 else
6456 echo -e " ${RED} Failed to start server. Check logs for errors.${NC} "
6557 exit 1
6658 fi
6759}
6860
69- # Teardown function
7061teardown () {
7162 echo -e " ${YELLOW} Tearing down test environment...${NC} "
7263
73- # Kill the server process
7464 if [ -n " $SERVER_PID " ]; then
7565 if kill -0 $SERVER_PID 2> /dev/null; then
7666 echo -e " ${YELLOW} Stopping server (PID: ${SERVER_PID} )...${NC} "
@@ -81,7 +71,6 @@ teardown() {
8171 fi
8272 fi
8373
84- # Remove test database
8574 if [ -f " ${TEST_DB_PATH} " ]; then
8675 echo -e " ${YELLOW} Removing test database: ${TEST_DB_PATH}${NC} "
8776 rm " ${TEST_DB_PATH} "
@@ -92,17 +81,15 @@ teardown() {
9281 echo -e " ${GREEN} Teardown complete.${NC} "
9382}
9483
95- # Safe JSON parsing function
9684parse_json () {
9785 echo " $1 " | jq -r " $2 " 2> /dev/null || echo " null"
9886}
9987
100- # Function to run tests
10188run_tests () {
10289 echo -e " ${YELLOW} Running API tests...${NC} "
10390
104- # Use the test server configuration
10591 local base_url=" http://${TEST_SERVER_HOST} :${TEST_SERVER_PORT} "
92+ local test_failed=0
10693
10794 echo -e " ${YELLOW} Using test server at: ${base_url}${NC} "
10895 echo -e " ${YELLOW} Using unique test database ID: ${UNIQUE_ID}${NC} "
@@ -112,124 +99,113 @@ run_tests() {
11299 echo -e " \n${YELLOW} Test 1: Creating a shortened URL...${NC} "
113100 RESPONSE=$( curl -X POST -H " Content-Type: application/json" -d ' {"url": "https://example.com"}' ${base_url} /api/shorten -s -w " \nStatus: %{http_code}" )
114101
115- # Extract status code
116102 STATUS_CODE=$( echo " $RESPONSE " | grep -o ' Status: [0-9]*' | cut -d' ' -f2)
117- RESPONSE_BODY=$( echo " $RESPONSE " | sed ' $d' ) # Remove the last line containing the status
103+ RESPONSE_BODY=$( echo " $RESPONSE " | sed ' $d' )
118104
119105 echo " $RESPONSE_BODY " | jq . || echo " $RESPONSE_BODY "
120106
121- # Check status code
122107 if [ " $STATUS_CODE " -lt 200 ] || [ " $STATUS_CODE " -ge 300 ]; then
123108 echo -e " ${RED} Request failed with status code: ${STATUS_CODE}${NC} "
124- exit 1
109+ test_failed=1
110+ return $test_failed
125111 fi
126112
127- # Extract the short_id from the response, fallback to null if parsing fails
128113 SHORT_ID=$( parse_json " $RESPONSE_BODY " " .short_id" )
129114 if [ " $SHORT_ID " = " null" ]; then
130115 echo -e " ${RED} Failed to extract short_id from response${NC} "
131116 echo -e " ${RED} Response was: $RESPONSE_BODY ${NC} "
132- exit 1
117+ test_failed=1
118+ return $test_failed
133119 fi
134120
135121 echo -e " ${GREEN} Successfully created URL with short ID: $SHORT_ID ${NC} "
136-
137- # Wait a moment
138122 sleep 1
139123
140- # Test 2: Create another URL with a custom ID
124+ # Test 2: Create URL with custom ID
141125 echo -e " \n${YELLOW} Test 2: Creating a shortened URL with custom ID...${NC} "
142126 CUSTOM_RESPONSE=$( curl -X POST -H " Content-Type: application/json" -d " {\" url\" : \" https://rust-lang.org\" , \" custom_id\" : \" $CUSTOM_ID \" }" ${base_url} /api/shorten -s -w " \nStatus: %{http_code}" )
143127
144- # Extract status code
145128 CUSTOM_STATUS_CODE=$( echo " $CUSTOM_RESPONSE " | grep -o ' Status: [0-9]*' | cut -d' ' -f2)
146- CUSTOM_RESPONSE_BODY=$( echo " $CUSTOM_RESPONSE " | sed ' $d' ) # Remove the last line containing the status
129+ CUSTOM_RESPONSE_BODY=$( echo " $CUSTOM_RESPONSE " | sed ' $d' )
147130
148131 echo " $CUSTOM_RESPONSE_BODY " | jq . || echo " $CUSTOM_RESPONSE_BODY "
149132
150- # Check status code
151133 if [ " $CUSTOM_STATUS_CODE " -lt 200 ] || [ " $CUSTOM_STATUS_CODE " -ge 300 ]; then
152134 echo -e " ${RED} Request failed with status code: ${CUSTOM_STATUS_CODE}${NC} "
153- exit 1
135+ test_failed=1
136+ return $test_failed
154137 fi
155138
156- # Extract the custom short_id
157139 CUSTOM_SHORT_ID=$( parse_json " $CUSTOM_RESPONSE_BODY " " .short_id" )
158140 if [ " $CUSTOM_SHORT_ID " = " null" ]; then
159141 echo -e " ${RED} Failed to create URL with custom ID${NC} "
160142 echo -e " ${RED} Response was: $CUSTOM_RESPONSE_BODY ${NC} "
161- exit 1
143+ test_failed=1
144+ return $test_failed
162145 fi
163146
164147 echo -e " ${GREEN} Successfully created URL with custom ID: $CUSTOM_ID ${NC} "
165-
166- # Wait a moment
167148 sleep 1
168149
169- # Test 3: Get statistics for the first URL
150+ # Test 3: Get stats for first URL
170151 echo -e " \n${YELLOW} Test 3: Getting statistics for first URL...${NC} "
171152 STATS_RESPONSE=$( curl ${base_url} /api/stats/$SHORT_ID -s -w " \nStatus: %{http_code}" )
172153
173- # Extract status code
174154 STATS_STATUS_CODE=$( echo " $STATS_RESPONSE " | grep -o ' Status: [0-9]*' | cut -d' ' -f2)
175- STATS_RESPONSE_BODY=$( echo " $STATS_RESPONSE " | sed ' $d' ) # Remove the last line containing the status
155+ STATS_RESPONSE_BODY=$( echo " $STATS_RESPONSE " | sed ' $d' )
176156
177157 echo " $STATS_RESPONSE_BODY " | jq . || echo " $STATS_RESPONSE_BODY "
178158
179- # Check status code
180159 if [ " $STATS_STATUS_CODE " -lt 200 ] || [ " $STATS_STATUS_CODE " -ge 300 ]; then
181160 echo -e " ${RED} Stats request failed with status code: ${STATS_STATUS_CODE}${NC} "
182- exit 1
161+ test_failed=1
162+ return $test_failed
183163 fi
184164
185- # Test 4: Get statistics for the custom URL
165+ # Test 4: Get stats for custom URL
186166 echo -e " \n${YELLOW} Test 4: Getting statistics for custom URL...${NC} "
187167 CUSTOM_STATS_RESPONSE=$( curl ${base_url} /api/stats/$CUSTOM_ID -s -w " \nStatus: %{http_code}" )
188168
189- # Extract status code
190169 CUSTOM_STATS_STATUS_CODE=$( echo " $CUSTOM_STATS_RESPONSE " | grep -o ' Status: [0-9]*' | cut -d' ' -f2)
191- CUSTOM_STATS_RESPONSE_BODY=$( echo " $CUSTOM_STATS_RESPONSE " | sed ' $d' ) # Remove the last line containing the status
170+ CUSTOM_STATS_RESPONSE_BODY=$( echo " $CUSTOM_STATS_RESPONSE " | sed ' $d' )
192171
193172 echo " $CUSTOM_STATS_RESPONSE_BODY " | jq . || echo " $CUSTOM_STATS_RESPONSE_BODY "
194173
195- # Check status code
196174 if [ " $CUSTOM_STATS_STATUS_CODE " -lt 200 ] || [ " $CUSTOM_STATS_STATUS_CODE " -ge 300 ]; then
197175 echo -e " ${RED} Custom stats request failed with status code: ${CUSTOM_STATS_STATUS_CODE}${NC} "
198- exit 1
176+ test_failed=1
177+ return $test_failed
199178 fi
200179
201- # Test 5: Call redirection endpoint to increment the visit count
180+ # Test 5: Test redirect
202181 echo -e " \n${YELLOW} Test 5: Calling redirection endpoint...${NC} "
203182 REDIRECT_RESPONSE=$( curl -I ${base_url} /$CUSTOM_ID -s)
204183 REDIRECT_STATUS=$( echo " $REDIRECT_RESPONSE " | head -n 1 | grep -o ' [0-9]\{3\}' )
205184
206185 echo " $REDIRECT_RESPONSE " | head -n 3
207186
208- # Check for appropriate redirect status code (3xx)
209187 if ! [[ " $REDIRECT_STATUS " =~ ^3[0-9]{2}$ ]]; then
210188 echo -e " ${RED} Redirect failed, expected 3xx status code, got: ${REDIRECT_STATUS}${NC} "
211- exit 1
189+ test_failed=1
190+ return $test_failed
212191 fi
213192
214193 echo -e " ${GREEN} Redirect successful with status code: ${REDIRECT_STATUS}${NC} "
215-
216- # Wait a moment for the visit to be recorded
217194 sleep 1
218195
219- # Test 6: Check if the visit count increased
196+ # Test 6: Verify visit count
220197 echo -e " \n${YELLOW} Test 6: Verifying visit count increased...${NC} "
221198 UPDATED_STATS=$( curl ${base_url} /api/stats/$CUSTOM_ID -s -w " \nStatus: %{http_code}" )
222199
223- # Extract status code
224200 UPDATED_STATS_STATUS_CODE=$( echo " $UPDATED_STATS " | grep -o ' Status: [0-9]*' | cut -d' ' -f2)
225- UPDATED_STATS_BODY=$( echo " $UPDATED_STATS " | sed ' $d' ) # Remove the last line containing the status
201+ UPDATED_STATS_BODY=$( echo " $UPDATED_STATS " | sed ' $d' )
226202
227203 echo " $UPDATED_STATS_BODY " | jq . || echo " $UPDATED_STATS_BODY "
228204
229- # Check status code
230205 if [ " $UPDATED_STATS_STATUS_CODE " -lt 200 ] || [ " $UPDATED_STATS_STATUS_CODE " -ge 300 ]; then
231206 echo -e " ${RED} Updated stats request failed with status code: ${UPDATED_STATS_STATUS_CODE}${NC} "
232- exit 1
207+ test_failed=1
208+ return $test_failed
233209 fi
234210
235211 VISIT_COUNT=$( parse_json " $UPDATED_STATS_BODY " " .visit_count" )
@@ -239,33 +215,34 @@ run_tests() {
239215 else
240216 echo -e " ${RED} Visit count test failed! Expected 1, got $VISIT_COUNT ${NC} "
241217 echo -e " ${RED} Response was: $UPDATED_STATS_BODY ${NC} "
218+ test_failed=1
219+ return $test_failed
242220 fi
243221
244222 # Test 7: List all URLs
245223 echo -e " \n${YELLOW} Test 7: Listing all URLs...${NC} "
246224 URLS_RESPONSE=$( curl ${base_url} /api/urls -s)
247225 echo " $URLS_RESPONSE " | jq . || echo " $URLS_RESPONSE "
248226
249- # Validate we have at least 2 URLs in the response
250227 URL_COUNT=$( parse_json " $URLS_RESPONSE " " . | length" )
251228 if [ " $URL_COUNT " -ge 2 ]; then
252229 echo -e " ${GREEN} URL listing test passed! Found $URL_COUNT URLs${NC} "
253230 else
254231 echo -e " ${RED} URL listing test failed! Expected at least 2 URLs, got $URL_COUNT ${NC} "
232+ test_failed=1
233+ return $test_failed
255234 fi
256235
257236 echo -e " \n${GREEN} All tests completed.${NC} "
237+ return $test_failed
258238}
259239
260240# Main execution
261- # Trap to ensure teardown happens even if script fails
262241trap teardown EXIT
263-
264- # Run the test sequence
265242setup
266243run_tests
244+ TEST_RESULT=$?
267245
268- echo -e " \n${GREEN} E2E tests completed successfully!${NC} "
269- # Force removal of database files to ensure cleanup
246+ echo -e " \n${GREEN} E2E tests completed.${NC} "
270247rm -f " ${TEST_DB_PATH} " test_* .db 2> /dev/null || true
271- exit 0
248+ exit $TEST_RESULT
0 commit comments