#!/bin/bash # Tests for Serval DNA MeshMB REST API # # Copyright 2016-2018 Flinders University # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. source "${0%/*}/../testframework.sh" source "${0%/*}/../testdefs.sh" source "${0%/*}/../testdefs_rest.sh" setup_instance() { set_instance $1 setup_rest_config executeOk_servald config \ set debug.meshmb on \ set debug.meshms on \ set debug.verbose on \ set log.console.level debug set_extra_config if [ -z "$IDENTITY_COUNT" ]; then create_single_identity else create_identities $IDENTITY_COUNT fi } set_extra_config() { : } setup() { setup_rest_utilities setup_servald export SERVALD_RHIZOME_DB_RETRY_LIMIT_MS=60000 setup_instance +A start_servald_instances +A wait_until_rest_server_ready } finally() { stop_all_servald_servers } teardown() { kill_all_servald_processes assert_no_servald_processes report_all_servald_servers } doc_AuthBasicMissing="REST API missing MeshMB Basic Authentication credentials" test_AuthBasicMissing() { rest_request GET "/restful/meshmb/$IDA1/feedlist.json" 401 --no-auth assertGrep response.headers "^WWW-Authenticate: Basic realm=\"Serval RESTful API\"$CR\$" assertJq response.json 'contains({"http_status_code": 401})' assertJq response.json 'contains({"http_status_message": ""})' } doc_AuthBasicWrong="REST API incorrect MeshMB Basic Authentication credentials" test_AuthBasicWrong() { rest_request GET "/restful/meshmb/$IDA1/feedlist.json" 401 --user=fred:nurks assertGrep response.headers "^WWW-Authenticate: Basic realm=\"Serval RESTful API\"$CR\$" assertJq response.json 'contains({"http_status_code": 401})' assertJq response.json 'contains({"http_status_message": ""})' rest_request GET "/restful/meshms/$SIDA/conversationlist.json" 200 --user=ron:weasley } doc_MeshMBRestSend="REST API MeshMB send a broadcast message" test_MeshMBRestSend() { rest_request POST "/restful/meshmb/$IDA1/sendmessage" 201 \ --form-part="message=Hello World;type=text/plain;charset=utf-8" executeOk_servald rhizome export bundle $IDA1 broadcast.manifest broadcast tfw_cat -h broadcast.manifest tfw_cat -h broadcast } doc_MeshMBRestList="REST API MeshMB list of all messages" setup_MeshMBRestList() { setup executeOk_servald meshmb send $IDA1 "Message 1" executeOk_servald meshmb send $IDA1 "Message 2" } test_MeshMBRestList() { rest_request GET "/restful/meshmb/$IDA1/messagelist.json" assert [ "$(jq '.rows | length' response.json)" = 2 ] transform_list_json response.json list.json tfw_preserve list.json assertJq list.json \ "contains([ { offset: 12, text: \"Message 1\" } ])" assertJq list.json \ "contains([ { offset: 30, text: \"Message 2\" } ])" } doc_MeshMBRestFollow="REST API MeshMB follow a feed" setup_MeshMBRestFollow() { IDENTITY_COUNT=3 setup executeOk_servald meshmb send $IDA1 "Message 1" executeOk_servald meshmb send $IDA2 "Message 2" executeOk_servald meshmb send $IDA3 "Message 3" } test_MeshMBRestFollow() { rest_request POST "/restful/meshmb/$IDA1/follow/$IDA2" 201 executeOk_servald meshmb list following $IDA1 assertStdoutGrep --matches=1 ":$IDA2:$SIDA2:false::[0-9]\+:Message 2\$" assertStdoutGrep --matches=0 ":$IDA3:$SIDA3:false::[0-9]\+:Message 3\$" rest_request POST "/restful/meshmb/$IDA1/follow/$IDA3" 201 executeOk_servald meshmb list following $IDA1 assertStdoutGrep --matches=1 ":$IDA2:$SIDA2:false::[0-9]\+:Message 2\$" assertStdoutGrep --matches=1 ":$IDA3:$SIDA3:false::[0-9]\+:Message 3\$" rest_request POST "/restful/meshmb/$IDA1/ignore/$IDA2" 201 executeOk_servald meshmb list following $IDA1 assertStdoutGrep --matches=0 ":$IDA2:$SIDA2:false::[0-9]\+:Message 2\$" assertStdoutGrep --matches=1 ":$IDA3:$SIDA3:false::[0-9]\+:Message 3\$" } doc_MeshMBRestFeeds="REST API MeshMB list subscribed feeds" setup_MeshMBRestFeeds() { IDENTITY_COUNT=3 setup executeOk_servald meshmb send $IDA1 "Message 1" executeOk_servald meshmb send $IDA2 "Message 2" executeOk_servald meshmb send $IDA3 "Message 3" executeOk_servald meshmb follow $IDA1 $IDA2 executeOk_servald meshmb follow $IDA1 $IDA3 } test_MeshMBRestFeeds() { rest_request GET "/restful/meshmb/$IDA1/feedlist.json" assert [ "$(jq '.rows | length' response.json)" = 2 ] transform_list_json response.json list.json tfw_preserve list.json assertJq list.json \ "contains([ { id: \"$IDA2\", last_message: \"Message 2\" } ])" assertJq list.json \ "contains([ { id: \"$IDA3\", last_message: \"Message 3\" } ])" } doc_MeshMBRestEmptyActivity="REST API MeshMB activity with no content" setup_MeshMBRestEmptyActivity() { IDENTITY_COUNT=1 setup } test_MeshMBRestEmptyActivity() { rest_request GET "/restful/meshmb/$IDA1/activity.json" assert [ "$(jq '.rows | length' response.json)" = 0 ] transform_list_json response.json list.json tfw_preserve list.json } doc_MeshMBRestActivity="REST API MeshMB thread incoming activity" setup_MeshMBRestActivity() { IDENTITY_COUNT=5 setup executeOk_servald keyring set did $SIDA1 "" "Feed A" executeOk_servald keyring set did $SIDA2 "" "Feed B" executeOk_servald keyring set did $SIDA3 "" "Feed C" executeOk_servald keyring set did $SIDA4 "" "Feed D" executeOk_servald keyring set did $SIDA5 "" "Feed E" executeOk_servald meshmb send $IDA2 "Message 2" executeOk_servald meshmb send $IDA3 "Message 3" executeOk_servald meshmb follow $IDA1 $IDA2 executeOk_servald meshmb follow $IDA1 $IDA3 executeOk_servald meshmb send $IDA4 "Message 4" executeOk_servald meshmb follow $IDA1 $IDA4 executeOk_servald meshmb send $IDA4 "Message 5" executeOk_servald meshmb activity $IDA1 executeOk_servald meshmb send $IDA5 "Message 6" executeOk_servald meshmb follow $IDA1 $IDA5 executeOk_servald meshmb send $IDA2 "Message 7" executeOk_servald meshmb activity $IDA1 executeOk_servald meshmb send $IDA3 "Message 8" executeOk_servald meshmb activity $IDA1 executeOk_servald meshmb send $IDA4 "Message 9" executeOk_servald meshmb activity $IDA1 executeOk_servald meshmb send $IDA5 "Message 10" executeOk_servald meshmb activity $IDA1 executeOk_servald meshmb send $IDA1 "Message 11" executeOk_servald meshmb activity $IDA1 } test_MeshMBRestActivity() { rest_request GET "/restful/meshmb/$IDA1/activity.json" assert [ "$(jq '.rows | length' response.json)" = 10 ] transform_list_json response.json list.json tfw_preserve list.json assertJq list.json "contains([{ __index: 0, id: \"$IDA1\", author: \"$SIDA1\", name: \"Feed A\", message: \"Message 11\"}])" assertJq list.json "contains([{ __index: 1, id: \"$IDA5\", author: \"$SIDA5\", name: \"Feed E\", message: \"Message 10\"}])" assertJq list.json "contains([{ __index: 2, id: \"$IDA4\", author: \"$SIDA4\", name: \"Feed D\", message: \"Message 9\"}])" assertJq list.json "contains([{ __index: 3, id: \"$IDA3\", author: \"$SIDA3\", name: \"Feed C\", message: \"Message 8\"}])" assertJq list.json "contains([{ __index: 4, id: \"$IDA2\", author: \"$SIDA2\", name: \"Feed B\", message: \"Message 7\"}])" assertJq list.json "contains([{ __index: 5, id: \"$IDA5\", author: \"$SIDA5\", name: \"Feed E\", message: \"Message 6\"}])" assertJq list.json "contains([{ __index: 6, id: \"$IDA4\", author: \"$SIDA4\", name: \"Feed D\", message: \"Message 5\"}])" assertJq list.json "contains([{ __index: 7, id: \"$IDA4\", author: \"$SIDA4\", name: \"Feed D\", message: \"Message 4\"}])" assertJq list.json "contains([{ __index: 8, id: \"$IDA3\", author: \"$SIDA3\", name: \"Feed C\", message: \"Message 3\"}])" assertJq list.json "contains([{ __index: 9, id: \"$IDA2\", author: \"$SIDA2\", name: \"Feed B\", message: \"Message 2\"}])" } doc_MeshMBRestNewActivity="REST API MeshMB newsince incoming activity" setup_MeshMBRestNewActivity() { IDENTITY_COUNT=3 setup executeOk_servald keyring set did $SIDA1 "" "Feed A" executeOk_servald keyring set did $SIDA2 "" "Feed B" executeOk_servald keyring set did $SIDA3 "" "Feed C" executeOk_servald meshmb send $IDA2 "Message 1" executeOk_servald meshmb send $IDA3 "Message 2" executeOk_servald meshmb follow $IDA1 $IDA2 executeOk_servald meshmb follow $IDA1 $IDA3 rest_request GET "/restful/meshmb/$IDA1/activity.json" assert [ "$(jq '.rows | length' response.json)" = 2 ] transform_list_json response.json array_of_objects.json tfw_preserve array_of_objects.json token=$(jq --raw-output '.[0][".token"]' array_of_objects.json) assert [ -n "$token" ] } test_MeshMBRestNewActivity() { for i in 1 2 3; do fork %client$i rest_request GET "/restful/meshmb/$IDA1/activity/$token/activity.json" \ --output=response$i.json \ --no-buffer done wait_until [ -e response1.json -a -e response2.json -a -e response3.json ] executeOk_servald meshmb send $IDA2 "Message 3" executeOk_servald meshmb send $IDA3 "Message 4" executeOk_servald meshmb send $IDA2 "Message 5" executeOk_servald meshmb send $IDA3 "Message 6" executeOk_servald meshmb send $IDA1 "Message 7" for i in 1 2 3; do wait_until grep "Message 3" response$i.json wait_until grep "Message 4" response$i.json wait_until grep "Message 5" response$i.json wait_until grep "Message 6" response$i.json wait_until grep "Message 7" response$i.json done fork_terminate_all fork_wait_all for i in 1 2 3; do if [ $(jq . response$i | wc -c) -eq 0 ]; then echo ']}' >>response$i.json assert [ $(jq . response$i.json | wc -c) -ne 0 ] fi transform_list_json response$i.json objects$i.json tfw_preserve response$i.json objects$i.json done for i in 1 2 3; do assert [ "$(jq '.rows | length' response$i.json)" = 5 ] assertJq objects$i.json "contains([{ id: \"$IDA2\", author: \"$SIDA2\", name: \"Feed B\", message: \"Message 3\"}])" assertJq objects$i.json "contains([{ id: \"$IDA3\", author: \"$SIDA3\", name: \"Feed C\", message: \"Message 4\"}])" assertJq objects$i.json "contains([{ id: \"$IDA2\", author: \"$SIDA2\", name: \"Feed B\", message: \"Message 5\"}])" assertJq objects$i.json "contains([{ id: \"$IDA3\", author: \"$SIDA3\", name: \"Feed C\", message: \"Message 6\"}])" assertJq objects$i.json "contains([{ id: \"$IDA1\", author: \"$SIDA1\", name: \"Feed A\", message: \"Message 7\"}])" done } runTests "$@"