error de rama
[asis-2023-electronic-vote.git] / test-api.sh
blob31a4276981a0d104e8323b7ad6517dcd8d87dfca
1 #!/bin/bash
3 # --------------------------------------
4 # REST API - Test Frameworks
5 # --------------------------
6 # https://github.com/subeshb1/api-test
7 # https://github.com/apiaryio/dredd
8 # https://github.com/vlucas/frisby
9 # https://github.com/bbyars/mountebank
10 # https://github.com/schemathesis/schemathesis
11 # https://github.com/ladjs/supertest
12 # https://github.com/taverntesting/tavern
13 # https://github.com/Kong/insomnia
14 # --------------------------------------
16 which curl &> /dev/null
18 if (($? != 0)); then
19 echo "> curl not found"
20 exit 1
23 which php &> /dev/null
25 if (($? != 0)); then
26 echo "> php not found"
27 exit 1
30 HOST="${1:-localhost}"
31 PORT="${2:-8000}"
33 # Colors:
34 # @see https://stackoverflow.com/a/5947802
36 # NO COLOR 0
37 # Black 0;30 Dark Gray 1;30
38 # Red 0;31 Light Red 1;31
39 # Green 0;32 Light Green 1;32
40 # Brown/Orange 0;33 Yellow 1;33
41 # Blue 0;34 Light Blue 1;34
42 # Purple 0;35 Light Purple 1;35
43 # Cyan 0;36 Light Cyan 1;36
44 # Light Gray 0;37 White 1;37
46 # .---------- constant part!
47 # vvvv vvvv-- the code from above
48 # RED='\033[0;31m'
49 # NC='\033[0m' # No Color
50 # printf "I ${RED}love${NC} Stack Overflow\n"
52 # --------------------------------------
53 # Display message
55 # Flags:
56 # - 'f': Failure message
57 # - 's': Success message
58 # - (empty): Normal message
60 # @param string $1 Message
61 # @param string $2 Flag
62 # --------------------------------------
63 function msg {
64 local rd='\033[0;31m'
65 local gr='\033[0;32m'
66 local nc='\033[0m'
68 local message="${1}"
69 local flag="${2}"
71 if [[ 's' == "${flag}" ]]; then
72 echo -e "${gr}[✅ SUCCESS] ${message}${nc}"
73 elif [[ 'f' == "${flag}" ]]; then
74 echo -e "${rd}[❌ FAILURE] ${message}${nc}"
75 else
76 echo ">>>>>>>>>>>> ${message}"
80 # --------------------------------------
81 # Call cURL command
83 # Use following global variables to return/export values:
85 # - CURL_EXIT_CODE
86 # - CURL_RESPONSE_HEADER
87 # - CURL_RESPONSE_DATA
89 # @param string $1 Path
90 # @param string $2 Method
91 # @param string $3 Data
92 # --------------------------------------
93 function callRestApi {
94 CURL_EXIT_CODE=1
95 CURL_RESPONSE_HEADER=''
96 CURL_RESPONSE_DATA=''
98 local path="${1}"
99 local method="${2:-GET}"
100 local data="${3}"
102 if [[ ! -z "${data}" ]]; then
103 data="--data ${data}"
106 curl "${HOST}:${PORT}${path}" \
107 --request "${method}" \
108 --header "Content-Type: application/json" \
109 --header "Accept: application/json" \
110 --dump-header curl_response_header.txt \
111 --output curl_response_data.txt \
112 $data &> /dev/null
114 CURL_EXIT_CODE=$?
116 if [ -f curl_response_header.txt ]; then
117 CURL_RESPONSE_HEADER=$(cat curl_response_header.txt)
118 rm curl_response_header.txt
121 if [ -f curl_response_data.txt ]; then
122 CURL_RESPONSE_DATA=$(cat curl_response_data.txt)
123 rm curl_response_data.txt
127 # --------------------------------------
128 # Get the value from a response header
130 # @param string $1 Headers list
131 # @param string $2 Header name
132 # --------------------------------------
133 function getValueFromHeader {
134 local list="${1}"
135 local key="${2}"
136 if [[ "code" == "${key}" ]]; then
137 echo $(echo "${list}" | grep '^HTTP/' | cut -d' ' -f2 | xargs)
138 else
139 echo $(echo "${list}" | grep "^${key}:" | cut -d':' -f2 | xargs)
143 # --------------------------------------
144 # Get a value from a JSON string
146 # @param string $1 JSON
147 # @param string $2 KEY
148 # --------------------------------------
149 function getValueFromJson {
150 local json="${1}"
151 local key="${2}"
152 local php=$(cat << PHP
153 \$list = json_decode('${json}', true);
154 echo \$list['${key}'];
157 echo $(php -r "${php}")
160 # --------------------------------------
161 # Count items in JSON list
163 # @param string $1 JSON
164 # --------------------------------------
165 function countItemsInJsonList {
166 local json="${1}"
167 local php=$(cat << PHP
168 \$list = json_decode('${json}', true);
169 echo count(\$list);
172 echo $(php -r "${php}")
175 # --------------------------------------
176 # Get name for a given id from a JSON string
178 # @param string $1 JSON
179 # @param string $2 ID
180 # --------------------------------------
181 function getNameFromId {
182 local json="${1}"
183 local id="${2}"
184 local php=$(cat << PHP
185 \$list = json_decode('${json}', true);
186 \$name = 0;
187 foreach (\$list as \$candidato) {
188 if (${id} == \$candidato['id']) {
189 \$name = \$candidato['name'];
190 break;
193 echo \$name;
196 echo $(php -r "${php}")
199 # --------------------------------------
200 # Get amount of votes for a given id from a JSON string
202 # @param string $1 JSON
203 # @param string $2 ID
204 # --------------------------------------
205 function getVotesFromId {
206 local json="${1}"
207 local id="${2}"
208 local php=$(cat << PHP
209 \$list = json_decode('${json}', true);
210 \$votes = 0;
211 foreach (\$list as \$candidato) {
212 if (${id} == \$candidato['id']) {
213 \$votes = \$candidato['votes'];
214 break;
217 echo \$votes;
220 echo $(php -r "${php}")
223 # ====================================================================
225 # --------------------------------------
226 # Test candidate creation
228 # @param string $1 Candidate name
229 # --------------------------------------
230 function testCreateCandidate {
231 local name="${1}"
233 echo '========================================'
234 msg 'Test create candidate'
236 callRestApi '/candidates' 'POST' '{"name":"'"${name}"'"}'
238 if (( 0 != "${CURL_EXIT_CODE}" )); then
239 msg 'Failed curl call' f
240 else
241 local code="$(getValueFromHeader "${CURL_RESPONSE_HEADER}" "code")"
243 if (( 200 != $code )); then
244 msg 'Failed to create candidate' f
245 else
246 local flag=""
248 local rname="$(getValueFromJson "${CURL_RESPONSE_DATA}" "name")"
249 flag=$([[ "${rname}" == "${name}" ]] && echo "s" || echo "f")
250 msg "Candidate name (${name}, ${rname})" "${flag}"
252 NEW_ID="$(getValueFromJson "${CURL_RESPONSE_DATA}" "id")"
256 echo
259 # --------------------------------------
260 # Test get list of candidates
262 # @param string $1 Items amount
263 # @param null|string $2 ID: If present will search the ID
264 # @param null|string $3 Name: If present will check name from ID search
265 # --------------------------------------
266 function testGetCandidates {
267 local amount="${1}"
268 local id="${2}"
269 local name="${3}"
271 echo '========================================'
272 msg 'Test get list of candidates'
274 callRestApi "/candidates" 'GET'
276 if (( 0 != "${CURL_EXIT_CODE}" )); then
277 msg 'Failed curl call' f
278 else
279 local code="$(getValueFromHeader "${CURL_RESPONSE_HEADER}" "code")"
281 if (( 200 != $code )); then
282 msg 'Failed to get list of candidates' f
283 else
284 local ramount="$(countItemsInJsonList "${CURL_RESPONSE_DATA}")"
285 flag=$([[ "${amount}" == "${ramount}" ]] && echo "s" || echo "f")
286 msg "Candidates listed (${amount}, ${ramount})" "${flag}"
288 if [[ -n "${id}" ]]; then
289 local rname="$(getNameFromId "${CURL_RESPONSE_DATA}" "${id}")"
290 flag=$([[ -n "${rname}" ]] && echo "s" || echo "f")
291 msg "Search id (${id}, ${rname})" "${flag}"
293 if [[ -n "${name}" ]]; then
294 flag=$([[ "${name}" == "${rname}" ]] && echo "s" || echo "f")
295 msg "Candidate name (${name}, ${rname})" "${flag}"
301 echo
304 # --------------------------------------
305 # Test delete candidate
307 # @param string $1 Candidate id
308 # --------------------------------------
309 function testDeleteCandidate {
310 local id="${1}"
312 echo '========================================'
313 msg 'Test delete candidate'
315 callRestApi "/candidates/${id}" 'DELETE'
317 if (( 0 != "${CURL_EXIT_CODE}" )); then
318 msg 'Failed curl call' f
319 else
320 local code="$(getValueFromHeader "${CURL_RESPONSE_HEADER}" "code")"
322 if (( 200 != $code )); then
323 msg 'Failed to delete candidate' f
324 else
325 msg 'Candidate deleted' s
329 echo
332 # --------------------------------------
333 # Test delete all candidates
334 # --------------------------------------
335 function testDeleteAllCandidates {
336 echo '========================================'
337 msg 'Test delete all candidates'
339 callRestApi "/candidates" 'DELETE'
341 if (( 0 != "${CURL_EXIT_CODE}" )); then
342 msg 'Failed curl call' f
343 else
344 local code="$(getValueFromHeader "${CURL_RESPONSE_HEADER}" "code")"
346 if (( 200 != $code )); then
347 msg 'Failed to delete all candidates' f
348 else
349 msg 'All candidates deleted' s
353 echo
356 # --------------------------------------
357 # Test vote a candidate
359 # @param string $1 Candidate id
360 # --------------------------------------
361 function testVoteCandiate {
362 local id="${1}"
364 echo '========================================'
365 msg 'Test vote candidate'
367 callRestApi '/vote' 'POST' '{"id":"'"${id}"'"}'
369 if (( 0 != "${CURL_EXIT_CODE}" )); then
370 msg 'Failed curl call' f
371 else
372 local code="$(getValueFromHeader "${CURL_RESPONSE_HEADER}" "code")"
374 if (( 200 != $code )); then
375 msg 'Failed to vote a candidates' f
376 else
377 msg 'Candidate voted' s
381 echo
384 # --------------------------------------
385 # Test votes report
387 # @param string $1 List count
388 # @param string $2 Candidate id
389 # @param string $3 Candidate name
390 # @param string $4 Candidate votes
391 # --------------------------------------
392 function testVotesReport {
393 local count="${1}"
394 local id="${2}"
395 local name="${3}"
396 local votes="${4}"
398 echo '========================================'
399 msg 'Test votes report'
401 callRestApi '/report' 'GET'
403 if (( 0 != "${CURL_EXIT_CODE}" )); then
404 msg 'Failed curl call' f
405 else
406 local code="$(getValueFromHeader "${CURL_RESPONSE_HEADER}" "code")"
408 if (( 200 != $code )); then
409 msg 'Failed to get votes report' f
410 else
411 local flag=""
413 local rcount="$(countItemsInJsonList "${CURL_RESPONSE_DATA}")"
414 flag=$([[ "${rcount}" == "${count}" ]] && echo "s" || echo "f")
415 msg "List count (${count}, ${rcount})" "${flag}"
417 local rname="$(getNameFromId "${CURL_RESPONSE_DATA}" "${id}")"
418 flag=$([[ "${rname}" == "${name}" ]] && echo "s" || echo "f")
419 msg "Candidate name (${name}, ${rname})" "${flag}"
421 local rvotes="$(getVotesFromId "${CURL_RESPONSE_DATA}" "${id}")"
422 flag=$([[ "${rvotes}" == "${votes}" ]] && echo "s" || echo "f")
423 msg "Candidate votes (${votes}, ${rvotes})" "${flag}"
427 echo
430 # ====================================================================
432 # First Test (One Candidate)
433 # --------------------------
435 testDeleteAllCandidates
437 testGetCandidates 0
439 CANDIATE_0_ID=''
440 CANDIATE_0_NAME='FIRST_TEST'
441 testCreateCandidate "${CANDIATE_0_NAME}"
442 CANDIATE_0_ID="${NEW_ID}"
443 testGetCandidates 1
445 testDeleteCandidate "${CANDIATE_0_ID}"
446 testGetCandidates 0
448 testCreateCandidate "${CANDIATE_0_NAME}"
449 CANDIATE_0_ID="${NEW_ID}"
451 testGetCandidates 1 "${CANDIATE_0_ID}" "${CANDIATE_0_NAME}"
453 testVoteCandiate "${CANDIATE_0_ID}"
455 testVotesReport 1 "${CANDIATE_0_ID}" "${CANDIATE_0_NAME}" 1
457 testDeleteAllCandidates
459 testGetCandidates 0
462 # Second Test (Multiple Candidates)
463 # ---------------------------------
465 testDeleteAllCandidates
467 testGetCandidates 0
469 CANDIATE_1_ID=''
470 CANDIATE_1_NAME='Mate'
471 testCreateCandidate "${CANDIATE_1_NAME}"
472 CANDIATE_1_ID="${NEW_ID}"
473 testGetCandidates 1 "${CANDIATE_1_ID}" "${CANDIATE_1_NAME}"
475 CANDIATE_2_ID=''
476 CANDIATE_2_NAME='Tea'
477 testCreateCandidate "${CANDIATE_2_NAME}"
478 CANDIATE_2_ID="${NEW_ID}"
479 testGetCandidates 2 "${CANDIATE_2_ID}" "${CANDIATE_2_NAME}"
481 CANDIATE_3_ID=''
482 CANDIATE_3_NAME='Coffee'
483 testCreateCandidate "${CANDIATE_3_NAME}"
484 CANDIATE_3_ID="${NEW_ID}"
485 testGetCandidates 3 "${CANDIATE_3_ID}" "${CANDIATE_3_NAME}"
487 CANDIATE_TMP_ID=''
488 CANDIATE_TMP_NAME='TEMPORAL'
489 testCreateCandidate "${CANDIATE_TMP_NAME}"
490 CANDIATE_TMP_ID="${NEW_ID}"
491 testGetCandidates 4 "${CANDIATE_TMP_ID}" "${CANDIATE_TMP_NAME}"
492 testDeleteCandidate "${CANDIATE_TMP_ID}"
493 testGetCandidates 3
495 testVoteCandiate "${CANDIATE_1_ID}"
496 testVoteCandiate "${CANDIATE_1_ID}"
497 testVoteCandiate "${CANDIATE_1_ID}"
498 testVoteCandiate "${CANDIATE_2_ID}"
499 testVoteCandiate "${CANDIATE_2_ID}"
500 testVoteCandiate "${CANDIATE_3_ID}"
502 testVotesReport 3 "${CANDIATE_1_ID}" "${CANDIATE_1_NAME}" 3
503 testVotesReport 3 "${CANDIATE_2_ID}" "${CANDIATE_2_NAME}" 2
504 testVotesReport 3 "${CANDIATE_3_ID}" "${CANDIATE_3_NAME}" 1
506 testDeleteCandidate "${CANDIATE_3_ID}"
508 testGetCandidates 2
510 testVotesReport 2 "${CANDIATE_1_ID}" "${CANDIATE_1_NAME}" 3
511 testVotesReport 2 "${CANDIATE_2_ID}" "${CANDIATE_2_NAME}" 2
513 testDeleteAllCandidates
515 testGetCandidates 0