from re import search from nose.tools import * import requests_mock import requests from sucks import * import paho.mqtt # There are few tests for the MQTT stuff here because it's relatively complicated to test given # the library's design and its multithreaded nature and lack of explicit testing support. def test_subscribe_to_ctls(): response = None def save_response(value): nonlocal response response = value x = make_ecovacs_iotmq() x.subscribe_to_ctls(save_response) #Test MQTT ctl mqtt_message = paho.mqtt.client.MQTTMessage mqtt_message.topic = 'iot/atr/CleanReport/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) mqtt_message.payload = b"" x._handle_ctl_mqtt('','',mqtt_message) assert_dict_equal(response, {'event': 'clean_report', 'ts':'1547824270099','type': 'auto','speed':'standard', 'st':'h','rsn':'a', 'a':'', 'l':'', 'sts':''}) #Test API ctl api_message = {} api_message['resp'] = ' ' x.subscribe_to_ctls(save_response) x._handle_ctl_api("Clean", api_message) assert_dict_equal(response, {'event': 'clean_report', 'type': 'auto'}) def test_is_iotmq(): x = make_ecovacs_iotmq() assert_equal(x.vacuum['iotmq'], True) def test_wrap_command(): x = make_ecovacs_iotmq() c = x._wrap_command(Charge(), 'E0000000001234567890') assert_equal(c['cmdName'], Charge().name) assert_equal(c['toId'], 'E0000000001234567890') assert_equal(c['payload'], '') def test_iotapi_response(): x = make_ecovacs_iotmq() with requests_mock.mock() as m: url = (EcoVacsAPI.PORTAL_URL_FORMAT + "/iot/devmanager.do").format(continent=x.continent) #Test GetCleanState resp = {"ret":"ok","resp":"","id":"Qgxa"} r1 = m.post(url, json=resp) #r1 = m.post(compile('devmanager.do'), json=resp) cmd = VacBotCommand("GetCleanState") c = x._wrap_command(cmd, x.vacuum['did']) rtnval = x._EcoVacsIOTMQ__call_iotdevmanager_api(c) assert_equal(rtnval, {'ret':'ok','resp':"",'id':'Qgxa'}) #Test Exception ReadTimeout r2 = m.post(url, exc=requests.exceptions.ReadTimeout) #r2 = m.post(compile('iot/devmanager.do'),exc=requests.exceptions.ReadTimeout) cmd = VacBotCommand("GetCleanState") c = x._wrap_command(cmd, x.vacuum['did']) rtnval = x._EcoVacsIOTMQ__call_iotdevmanager_api(c) assert_equal(rtnval, {}) #Right now it sends back a blank object #Test Response Fail - Timeout resp = {"ret":"fail","resp": None, "debug":"wait for response timed out" ,"id":"Qgxa"} r2 = m.post(url, json=resp) #r1 = m.post(compile('devmanager.do'), json=resp) cmd = VacBotCommand("TestCommand") c = x._wrap_command(cmd, x.vacuum['did']) rtnval = x._EcoVacsIOTMQ__call_iotdevmanager_api(c) assert_equal(rtnval, {}) #Test Response Fail - No debug resp = {"ret":"fail","resp": None ,"id":"Qgxa"} r2 = m.post(url, json=resp) #r1 = m.post(compile('devmanager.do'), json=resp) cmd = VacBotCommand("TestCommand") c = x._wrap_command(cmd, x.vacuum['did']) rtnval = x._EcoVacsIOTMQ__call_iotdevmanager_api(c) assert_equal(rtnval, {}) def test_send_command(): from unittest.mock import MagicMock x = make_ecovacs_iotmq() x._handle_ctl_api = MagicMock() EcoVacsIOTMQ._EcoVacsIOTMQ__call_iotdevmanager_api = MagicMock() x.send_command(Clean(iotmq=True), '123') def test_send_ping(): from unittest.mock import MagicMock x = make_ecovacs_iotmq() EcoVacsIOTMQ._send_simple_command = MagicMock(return_value=MQTTPublish.paho.MQTT_ERR_SUCCESS) assert_true(x.send_ping()) #Test ping response success EcoVacsIOTMQ._send_simple_command = MagicMock(return_value=MQTTPublish.paho.MQTT_ERR_NOT_FOUND) assert_false(x.send_ping()) #Test ping response fail def test_on_connect_rc_nonzero(): x = make_ecovacs_iotmq() assert_raises(RuntimeError, x.on_connect, "client", "userdata", "flags", 1) def test_xml_to_dict_mqtt(): x = make_ecovacs_iotmq() test_topic = 'iot/atr/CleanReport/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'clean_report', 'ts':'1547824270099','type': 'auto','speed':'standard', 'st':'h','rsn':'a', 'a':'', 'l':'', 'sts':''}) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'clean_report', 'ts':'1547824270099','type': 'auto','speed':'strong', 'st':'h','rsn':'a', 'a':'', 'l':'', 'sts':''}) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'clean_report', 'ts':'1547824270099','type': 'auto','speed':'strong', 'st':'h','rsn':'a', 'a':'', 'l':'', 'sts':''}) #Test without td test_topic = 'iot/atr/BatteryInfo/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'battery_info', 'ts':'1547823289924', 'power': '64'}) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'battery_info', 'ts':'1547823289924', 'power': '64'}) #Test without td test_topic = 'iot/atr/SleepStatus/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'sleep_status', 'ts':'1547823129670', 'st': '1'}) test_topic = 'iot/atr/errors/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'errors', 'ts':'1547822982581','old':'','new':'102'}) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'errors', 'ts':'1547822982581','old':'102','new':''}) test_topic = 'iot/atr/Pos/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'pos', 't':'p', 'p':'7,-10', 'a':'-42','valid':'0'}) test_topic = 'iot/atr/DustCaseST/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'dust_case_s_t', 'ts':'1547822871328','st':'1'}) test_topic = 'iot/atr/MapSt/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'map_st', 'ts':'1547823592934', 'st':'reloc_go_chg_start', 'method':'', 'info':''}) test_topic = 'iot/atr/LifeSpan/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ""), {'event': 'life_span','ret':'ok', 'type': 'brush', 'left': '9876', 'total': '18000'}) test_topic = 'iot/atr/CustomCommand/%s/%s/%s/x'.format(x.vacuum['did'], x.vacuum['class'], x.vacuum['resource']) assert_dict_equal( x._ctl_to_dict_mqtt(test_topic, ''), {'event': 'custom_command', 'customvar': 'customvalue1'}) def test_xml_to_dict_api(): x = make_ecovacs_iotmq() message = {} cmd = VacBotCommand("Clean") message['resp'] = "" assert_dict_equal( x._ctl_to_dict_api(cmd,message['resp']), {'event': 'clean_report', 'type': 'auto', 'speed': 'standard', 'st':'h','t':'1159','a':'15','s':'0','tr':''}) cmd = VacBotCommand("Clean") message['resp'] = "" assert_dict_equal( x._ctl_to_dict_api(cmd,message['resp']), {'event': 'clean_report', 'type': 'auto', 'speed': 'strong', 'st':'h','t':'1159','a':'15','s':'0','tr':''}) cmd = VacBotCommand("GetBatteryInfo") message['resp'] = "" assert_dict_equal( x._ctl_to_dict_api(cmd,message['resp']), {'event': 'battery_info', 'power': '82'}) cmd = VacBotCommand("GetLifeSpan") message['resp'] = "" assert_dict_equal( x._ctl_to_dict_api(cmd,message['resp']), {'event': 'life_span','ret':'ok', 'type': 'brush', 'left': '9876', 'total': '18000'}) cmd = VacBotCommand("Charge") message['resp'] = "" assert_dict_equal( x._ctl_to_dict_api(cmd,message['resp']), {'type': 'going', 'h': '', 'r': 'a', 's': '', 'g': '0', 'event': 'charge_state'}) cmd = VacBotCommand("GetTestCommand") message['resp'] = "" assert_dict_equal( x._ctl_to_dict_api(cmd,message['resp']), {'type': 'command', 'event': 'test_command'}) #Test action.name.replace Get cmd = VacBotCommand("Charge") message['resp'] = "" assert_dict_equal( x._ctl_to_dict_api(cmd,message['resp']), {'event': 'charge_state','ret':'fail', 'errno': '8'}) #Test fail from charge command def test_bad_port(): bot = {"did": "E0000000001234567890", "class": "126","resource":"test_resource", "nick": "bob", "iotmq": True} mqtt = EcoVacsIOTMQ('20170101abcdefabcdefa', 'ecouser.net', 'abcdef12', 'A1b2C3d4efghijklmNOPQrstuvwxyz12', 'na', bot, server_address='test.com:f123') assert_equal(8883, mqtt.port) def test_good_port(): bot = {"did": "E0000000001234567890", "class": "126","resource":"test_resource", "nick": "bob", "iotmq": True} mqtt = EcoVacsIOTMQ('20170101abcdefabcdefa', 'ecouser.net', 'abcdef12', 'A1b2C3d4efghijklmNOPQrstuvwxyz12', 'na', bot, server_address='test.com:8000') assert_equal(8000, mqtt.port) def make_ecovacs_iotmq(bot=None): if bot is None: bot = {"did": "E0000000001234567890", "class": "126","resource":"test_resource", "nick": "bob", "iotmq": True} return EcoVacsIOTMQ('20170101abcdefabcdefa', 'ecouser.net', 'abcdef12', 'A1b2C3d4efghijklmNOPQrstuvwxyz12', 'na', bot)