293 lines
9.7 KiB
Python
293 lines
9.7 KiB
Python
|
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='<?xml version="1.0" encoding="UTF-8"?><VertXMessage xmlns:hid="http://www.hidcorp.com/VertX"><hid:Banana></hid:Banana></VertXMessage>',
|
||
|
content_type="text/xml",
|
||
|
)
|
||
|
|
||
|
ret = door_controller.doXMLRequest(
|
||
|
b"<VertXMessage><hid:TEST></hid:TEST></VertXMessage>"
|
||
|
)
|
||
|
|
||
|
assert (
|
||
|
responses.calls[0].request.params["/cgi-bin/vertx_xml.cgi?XML"]
|
||
|
== '<?xml version="1.0" encoding="UTF-8"?><VertXMessage><hid:TEST></hid:TEST></VertXMessage>'
|
||
|
)
|
||
|
|
||
|
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='<?xml version="1.0" encoding="UTF-8"?><VertXMessage xmlns:hid="http://www.hidcorp.com/VertX"><hid:Banana></hid:Banana></VertXMessage>',
|
||
|
content_type="text/xml",
|
||
|
)
|
||
|
|
||
|
ret = door_controller.doXMLRequest(ROOT(E.TEST()))
|
||
|
|
||
|
assert (
|
||
|
responses.calls[0].request.params["/cgi-bin/vertx_xml.cgi?XML"]
|
||
|
== '<?xml version="1.0" encoding="UTF-8"?><VertXMessage xmlns:hid="http://www.hidglobal.com/VertX"><hid:TEST/></VertXMessage>'
|
||
|
)
|
||
|
|
||
|
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 = '<?xml version="1.0" encoding="UTF-8"?><VertXMessage xmlns:hid="http://www.hidcorp.com/VertX"><hid:Error action="RS" elementType="hid:TEST" errorCode="72" errorReporter="vertx" errorMessage="Unrecognized element"/></VertXMessage>'
|
||
|
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):
|