from unittest.mock import patch import pytest import responses from lxml.etree import Element from ..DoorController import ROOT, DoorController, E, E_corp, RemoteError # https://stackoverflow.com/questions/7905380/testing-equivalence-of-xml-etree-elementtree def assert_elements_equal(e1: Element, e2: Element) -> None: assert e1.tag == e2.tag assert e1.text == e2.text assert e1.tail == e2.tail assert e1.attrib == e2.attrib assert len(e1) == len(e2) for c1, c2 in zip(e1, e2): assert_elements_equal(c1, c2) @pytest.fixture def door_controller(): return DoorController("127.0.0.1", "test", "test", name="Test", access="Test") @responses.activate def test_doXMLRequest_bytes(door_controller: DoorController) -> None: responses.add( responses.GET, "https://127.0.0.1/cgi-bin/vertx_xml.cgi", body='', content_type="text/xml", ) ret = door_controller.doXMLRequest( b"" ) assert ( responses.calls[0].request.params["/cgi-bin/vertx_xml.cgi?XML"] == '' ) assert_elements_equal(ret, ROOT(E_corp.Banana())) @responses.activate def test_doXMLRequest_xml(door_controller: DoorController) -> None: responses.add( responses.GET, "https://127.0.0.1/cgi-bin/vertx_xml.cgi", body='', content_type="text/xml", ) ret = door_controller.doXMLRequest(ROOT(E.TEST())) assert ( responses.calls[0].request.params["/cgi-bin/vertx_xml.cgi?XML"] == '' ) assert_elements_equal(ret, ROOT(E_corp.Banana())) @responses.activate def test_doXMLRequest_HTTPError(door_controller: DoorController) -> None: responses.add( responses.GET, "https://127.0.0.1/cgi-bin/vertx_xml.cgi", body="whatever", status=403, ) with pytest.raises(RemoteError) as excinfo: door_controller.doXMLRequest(ROOT(E.TEST())) assert excinfo.value.args[0] == "Door Updating Error: 403 Forbidden\nwhatever" @responses.activate def test_doXMLRequest_XMLerror(door_controller: DoorController) -> None: body = '' responses.add( responses.GET, "https://127.0.0.1/cgi-bin/vertx_xml.cgi", body=body, status=200, ) with pytest.raises(RemoteError) as excinfo: door_controller.doXMLRequest(ROOT(E.TEST())) assert excinfo.value.args[0] == "Door Updating Error: 200 OK\n" + body # def doImport(self, params=None, files=None): # def doCSVImport(self, csv): def test_get_scheduleMap(door_controller: DoorController) -> None: with patch.object(door_controller, "doXMLRequest") as mockXMLRequest: mockXMLRequest.return_value = E_corp.VertXMessage( E_corp.Schedules( {"action": "RL"}, E_corp.Schedule({"scheduleID": "1", "scheduleName": "Test1"}), E_corp.Schedule({"scheduleID": "2", "scheduleName": "Test2"}), E_corp.Schedule({"scheduleID": "3", "scheduleName": "Test3"}), ) ) ret = door_controller.get_scheduleMap() assert ret == {"Test1": "1", "Test2": "2", "Test3": "3"} # TODO: these two methods might want to be reworked: they are a bit clunky # def get_schedules(self): # def set_schedules(self, schedules): def test_set_cardholder_schedules(door_controller: DoorController) -> None: with patch.object(door_controller, "doXMLRequest") as mockXMLRequest: door_controller._scheduleMap = {"Test1": "1", "Test2": "2", "Test3": "3"} # TODO: should replace with a captured output mockXMLRequest.return_value = ROOT() ret = door_controller.set_cardholder_schedules("123", ["Test1", "Test3"]) assert_elements_equal( door_controller.doXMLRequest.call_args[0][0], ROOT( E.RoleSet( {"action": "UD", "roleSetID": "123"}, E.Roles( E.Role({"roleID": "123", "scheduleID": "1", "resourceID": "0"}), E.Role({"roleID": "123", "scheduleID": "3", "resourceID": "0"}), ), ) ), ) assert_elements_equal(ret, ROOT()) def test_get_cardFormats(door_controller): with patch.object(door_controller, "doXMLRequest") as mockXMLRequest: mockXMLRequest.return_value = E_corp.VertXMessage( E_corp.CardFormats( {"action": "RL"}, E_corp.CardFormat( { "formatID": "1", "formatName": "H10301 26-Bit", "isTemplate": "true", "templateID": "1", } ), # irrelevant templates omitted E_corp.CardFormat( { "formatID": "6", "formatName": "A901146A-123", "isTemplate": "false", "templateID": "1", }, E_corp.FixedField({"value": "123"}), ), E_corp.CardFormat( { "formatID": "7", "formatName": "A901146A-456", "isTemplate": "false", "templateID": "1", }, E_corp.FixedField({"value": "456"}), ), ) ) ret = door_controller.get_cardFormats() assert ret == {"123": "6", "456": "7"} def test_set_cardFormat(door_controller): with patch.object(door_controller, "doXMLRequest") as mockXMLRequest: # TODO: should replace with a captured output mockXMLRequest.return_value = ROOT() ret = door_controller.set_cardFormat("testname", 3, 123) assert_elements_equal( door_controller.doXMLRequest.call_args[0][0], ROOT( E.CardFormats( {"action": "AD"}, E.CardFormat( {"formatName": "testname", "templateID": "3"}, E.FixedField({"value": "123"}), ), ) ), ) assert_elements_equal(ret, ROOT()) def test_get_records_no_morerecords(door_controller): """Test for when all the records fit in one 'page'""" with patch.object(door_controller, "doXMLRequest") as mockXMLRequest: mockXMLRequest.return_value = E_corp.VertXMessage( E_corp.TestElements( { "action": "RL", "recordOffset": "0", "recordCount": "2", "moreRecords": "false", }, E_corp.TestElement({"asdf": "a"}), E_corp.TestElement({"qwer": "b"}), ) ) ret = door_controller.get_records(E.TestElements, 12, {"blah": "test"}) assert_elements_equal( door_controller.doXMLRequest.call_args[0][0], ROOT( E.TestElements( { "action": "LR", # TODO: should really be 12, but isn't for bug workaround "recordCount": "13", "recordOffset": "0", "blah": "test", }, ) ), ) assert_elements_equal(ret[0], E_corp.TestElement({"asdf": "a"})) assert_elements_equal(ret[1], E_corp.TestElement({"qwer": "b"})) # def test_get_records_morerecords(door_controller): # """Test for when all the records span multiple 'pages'""" # pass # def test_get_records_morerecords_bad_last_record(door_controller): # """Test for bug in which last record of each 'page' is missing data""" # pass # def test_get_records_stopFunction(door_controller): # pass # def test_get_cardholders(door_controller): # door_controller = DoorController( # "172.18.51.11", # "admin", # "PVic6ydFS/", # name="Test", # access="Test", # cert="../../hidglobal.com.pem", # ) # with patch.object(door_controller, "doXMLRequest") as mockXMLRequest: # mockXMLRequest.return_value = E_corp.VertXMessage( # E_corp.Cardholders( # {"action": "RL"}, # E_corp.Cardholder({"scheduleID": "1", "scheduleName": "Test1"}), # E_corp.Cardholder({"scheduleID": "2", "scheduleName": "Test2"}), # E_corp.Cardholder({"scheduleID": "3", "scheduleName": "Test3"}), # ) # ) # for x in [0]: # ret = door_controller.get_cardholders() # assert ret == {"Test1": "1", "Test2": "2", "Test3": "3"} # def add_cardholder(self, attribs): # def update_cardholder(self, cardholderID, attribs): # def get_credentials(self): # def add_credentials(self, credentials, cardholderID=None): # def assign_credential(self, credential, cardholderID=None): # def get_events(self, threshold): # def get_lock(self): # def set_lock(self, lock=True):