From 6c0fc36dad3ac2b02f283b0541859ffc369b7a2a Mon Sep 17 00:00:00 2001 From: Robert Habermann <mail@rhab.de> Date: Sun, 24 Apr 2016 16:34:49 +0200 Subject: [PATCH] fix tests after refactoring --- cli/PyOTRS.py | 18 +- pyotrs/lib.py | 34 ++-- tests/test_client.py | 218 ++++++++++++++------- tests/test_dynamic_field.py | 10 +- tests/test_pyotrs_responses.py | 344 ++++++++++++++++++++------------- tests/test_ticket.py | 10 + 6 files changed, 400 insertions(+), 234 deletions(-) diff --git a/cli/PyOTRS.py b/cli/PyOTRS.py index f89f8a8..55cd6fa 100644 --- a/cli/PyOTRS.py +++ b/cli/PyOTRS.py @@ -92,12 +92,12 @@ def get(baseurl=None, webservicename=None, username=None, password=None, ticket_ click.secho("Connecting to %s as %s.." % (baseurl, username)) client = Client(baseurl, webservicename, username, password) client.session_create() - ticket = client.ticket_get_by_id(ticket_id) - - click.secho("Ticket: \t%s" % ticket['Title']) - click.secho("Queue: \t\t%s" % ticket['Queue']) - click.secho("State: \t\t%s" % ticket['State']) - click.secho("Priority: \t%s" % ticket['Priority']) - - click.secho("\nRaw Ticket:") - print(ticket) + if client.ticket_get_by_id(ticket_id): + for ticket in client.ticket_get_result_list: + click.secho("Ticket: \t%s" % ticket['Title']) + click.secho("Queue: \t\t%s" % ticket['Queue']) + click.secho("State: \t\t%s" % ticket['State']) + click.secho("Priority: \t%s" % ticket['Priority']) + + click.secho("\nRaw Ticket:") + print(ticket) diff --git a/pyotrs/lib.py b/pyotrs/lib.py index fc8e80d..91190b3 100644 --- a/pyotrs/lib.py +++ b/pyotrs/lib.py @@ -247,7 +247,6 @@ class Ticket(object): """PyOTRS Ticket class """ def __init__(self, dct): - self.attachment_list = [] self.dynamic_field_list = [] @@ -257,7 +256,10 @@ class Ticket(object): self.__dict__ = dct def __repr__(self): - return "<{0}>".format(self.__class__.__name__) + if hasattr(self, 'TicketID'): + return "<{0}: {1}>".format(self.__class__.__name__, self.TicketID) + else: + return "<{0}>".format(self.__class__.__name__) @classmethod def create_basic(cls, @@ -525,8 +527,9 @@ class Client(object): webservicename, username=None, password=None, - session_id_file=None, session_timeout=None, + session_id_file=None, + session_validation_ticket_id=1, proxies=None, https_verify=True, ca_cert_bundle=None): @@ -551,6 +554,8 @@ class Client(object): self.session_id_store = SessionIDStore(file_path=session_id_file, session_timeout=self.session_timeout) + self.session_validation_ticket_id = session_validation_ticket_id + if not proxies: self.proxies = {"http": "", "https": "", "no": ""} else: @@ -580,8 +585,9 @@ class Client(object): self.ticket_search_result_list = [] self.ticket_get_result_list = [] - # self.response_json = None - # self.response_type = None + self.response_json = None + self.response_status_code = None + self.response_content = None """ GenericInterface::Operation::Session::SessionCreate @@ -614,9 +620,10 @@ class Client(object): # TODO 2016-04-13 (RH): Is there a nicer way to check whether session is valid?! url = ("{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" - "{0.webservicename}/Ticket/1".format(self)) + "{0.webservicename}/Ticket".format(self)) - payload = {"SessionID": self.session_id_store.value} + payload = {"SessionID": self.session_id_store.value, + "TicketID": self.session_validation_ticket_id} return self._ticket_get_json(url, payload) @@ -791,7 +798,7 @@ class Client(object): return self._ticket_get_json(url, payload) - def ticket_get_by_list_of_ids(self, ticket_id_list, dynamic_fields=True, all_articles=False): + def ticket_get_by_ids(self, ticket_id_list, dynamic_fields=True, all_articles=False): """ticket_get_by_list Args: @@ -1034,7 +1041,6 @@ class Client(object): datetime_now = datetime.datetime.utcnow() pending_till = datetime_now + datetime.timedelta(days=pending_days, hours=pending_hours) - pending_till_str = pending_till.strftime("%Y-%m-%d %H:%M:%S UTC") pt = Ticket.datetime_to_pending_time_text(datetime_obj=pending_till) @@ -1142,8 +1148,8 @@ class Client(object): """ - # if not isinstance(response, requests.Response): - # raise ValueError("requests.Response object expected!") + if not isinstance(response, requests.models.Response): + raise ValueError("requests.Response object expected!") # clear data from Client self.ticket_get_result_list = [] @@ -1193,6 +1199,12 @@ class Client(object): "OTRS Error Code: {0}\nOTRS Error Message: {1}" "".format(self.response_json["Error"]["ErrorCode"], self.response_json["Error"]["ErrorMessage"])) + + # for operation TicketGet: parse result list into Ticket object list + if self.operation == "TicketGet": + for item in self.response_json['Ticket']: + self.ticket_get_result_list.append(Ticket(item)) + return True # EOF diff --git a/tests/test_client.py b/tests/test_client.py index 3ca5e77..052b039 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -132,7 +132,7 @@ class ClientTests(unittest.TestCase): result = obj.session_check_is_valid(session_id="some_value") self.assertEqual(obj.session_id_store.value, "some_value") - self.assertEqual(result, True) + self.assertTrue(result) @mock.patch('pyotrs.Client._ticket_get_json', autospec=True) def test_session_check_is_valid_self_session_id(self, mock_ticket_get_json): @@ -144,7 +144,7 @@ class ClientTests(unittest.TestCase): result = obj.session_check_is_valid() self.assertEqual(obj.session_id_store.value, "some_other_value2") - self.assertEqual(result, True) + self.assertTrue(result) def test_init_session_default_session_timeout(self): client = Client(baseurl="http://localhost/", webservicename="foo") @@ -154,35 +154,34 @@ class ClientTests(unittest.TestCase): client = Client(baseurl="http://localhost/", webservicename="foo", session_timeout=4711) self.assertEqual(client.session_timeout, 4711) - @mock.patch('pyotrs.Client._session_create_json', autospec=True) - def test_session_create_json(self, mock_s_create_json): - """Tests session_create fail""" - # create object - obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") - - mock_s_create_json.return_value = False - result = obj.session_create() - - self.assertEqual(mock_s_create_json.call_count, 1) - self.assertFalse(result) - - @mock.patch('pyotrs.Client._session_create_json', autospec=True) - def test_session_create_json_ok(self, mock_s_create_json): - """Tests session_create ok""" - # create object - obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") - obj.response_json = {'SessionID': 'this_is_a_s_id', 'a': 'response'} - mock_s_create_json.return_value = True - result = obj.session_create() - - self.assertEqual(mock_s_create_json.call_count, 1) - self.assertTrue(result) + # @mock.patch('pyotrs.Client._session_create_json', autospec=True) + # def test_session_create_json(self, mock_s_create_json): + # """Tests session_create fail""" + # # create object + # obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") + # + # mock_s_create_json.return_value = False + # result = obj.session_create() + # + # self.assertEqual(mock_s_create_json.call_count, 1) + # self.assertFalse(result) + # + # @mock.patch('pyotrs.Client._session_create_json', autospec=True) + # def test_session_create_json_ok(self, mock_s_create_json): + # """Tests session_create ok""" + # # create object + # obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") + # obj.response_json = {'SessionID': 'this_is_a_s_id', 'a': 'response'} + # mock_s_create_json.return_value = True + # result = obj.session_create() + # + # self.assertEqual(mock_s_create_json.call_count, 1) + # self.assertTrue(result) @mock.patch('pyotrs.Client.session_check_is_valid', autospec=True) @mock.patch('pyotrs.SessionIDStore.read', autospec=True) def test_session_restore_or_set_up_new_with_file_nok(self, mock_read_s_id, mock_is_valid): """Tests session_restore_or_set_up_new when read from file successful but session nok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.session_id_store.value = "foobar" @@ -202,7 +201,6 @@ class ClientTests(unittest.TestCase): @mock.patch('pyotrs.SessionIDStore.read', autospec=True) def test_session_restore_or_set_up_new_with_file_ok(self, mock_read_s_id, mock_is_valid): """Tests session_restore_or_set_up_new when read from file successful and session ok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.session_id_store.value = "foobar2" @@ -213,7 +211,7 @@ class ClientTests(unittest.TestCase): self.assertEqual(mock_read_s_id.call_count, 1) self.assertEqual(mock_is_valid.call_count, 1) - self.assertEqual(result, True) + self.assertTrue(result) @mock.patch('pyotrs.Client.session_create', autospec=True) @mock.patch('pyotrs.Client.session_check_is_valid', autospec=True) @@ -223,7 +221,6 @@ class ClientTests(unittest.TestCase): mock_is_valid, mock_s_create): """Tests session_restore_or_set_up_new when read from file successful but session nok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.session_id_store.value = "foobar" @@ -243,7 +240,6 @@ class ClientTests(unittest.TestCase): @mock.patch('pyotrs.SessionIDStore.read', autospec=True) def test_session_restore_or_set_up_new_nok(self, mock_read_s_id, mock_s_create): """Tests session_restore_or_set_up_new no file; create unsuccessful""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.session_id_store.value = "foobar" @@ -262,7 +258,6 @@ class ClientTests(unittest.TestCase): @mock.patch('pyotrs.SessionIDStore.read', autospec=True) def test_session_restore_or_set_up_new_ok_no_wr(self, mock_read_s_id, mock_s_create, mock_wr): """Tests session_restore_or_set_up_new no file; create successful; write (wr) not ok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.session_id_store.value = "foobar" obj.response_json = {'SessionID': "the_other_sid1"} @@ -284,7 +279,6 @@ class ClientTests(unittest.TestCase): @mock.patch('pyotrs.SessionIDStore.read', autospec=True) def test_session_restore_or_set_up_new_ok_wr_ok(self, mock_read_s_id, mock_s_create, mock_wr): """Tests session_restore_or_set_up_new no file; create successful; write (wr) ok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.session_id_store.value = "foobar" obj.response_json = {'SessionID': "the_other_sid2"} @@ -302,30 +296,50 @@ class ClientTests(unittest.TestCase): @mock.patch('pyotrs.Client._ticket_get_json', autospec=True) def test_ticket_get_by_id_fail(self, mock_ticket_get_json): """Tests ticket_get_by_id fail""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") mock_ticket_get_json.return_value = False result = obj.ticket_get_by_id(1) self.assertEqual(mock_ticket_get_json.call_count, 1) - self.assertEqual(result, None) + self.assertFalse(result) @mock.patch('pyotrs.Client._ticket_get_json', autospec=True) def test_ticket_get_by_id_ok(self, mock_ticket_get_json): """Tests ticket_get_by_id ok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.response_json = {'Ticket': [{'Some': 'Ticket'}]} mock_ticket_get_json.return_value = True result = obj.ticket_get_by_id(1) self.assertEqual(mock_ticket_get_json.call_count, 1) - self.assertDictEqual(result, {'Some': 'Ticket'}) + self.assertTrue(result) + self.assertDictEqual(obj.response_json['Ticket'][0], {'Some': 'Ticket'}) + + @mock.patch('pyotrs.Client._ticket_get_json', autospec=True) + def test_ticket_get_by_ids_fail(self, mock_ticket_get_json): + """Tests ticket_get_by_id fail""" + obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") + + mock_ticket_get_json.return_value = False + result = obj.ticket_get_by_ids([1]) + + self.assertEqual(mock_ticket_get_json.call_count, 1) + self.assertFalse(result) + + @mock.patch('pyotrs.Client._ticket_get_json', autospec=True) + def test_ticket_get_by_ids_ok(self, mock_ticket_get_json): + """Tests ticket_get_by_id fail""" + obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") + + mock_ticket_get_json.return_value = True + result = obj.ticket_get_by_ids([1]) + + self.assertEqual(mock_ticket_get_json.call_count, 1) + self.assertTrue(result) def test_ticket_get_by_number_with_int(self): """Tests ticket_get_by_number provided int not str -> fail""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") self.assertRaisesRegex(TicketError, @@ -335,19 +349,17 @@ class ClientTests(unittest.TestCase): @mock.patch('pyotrs.Client.ticket_search', autospec=True) def test_ticket_get_by_number_with_string_no_result(self, mock_ticket_search): """Tests ticket_get_by_number provided as int -> ok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") mock_ticket_search.return_value = [] result = obj.ticket_get_by_number("SomeOtherNumber") - self.assertEqual(result, None) + self.assertIsNone(result) self.assertEqual(mock_ticket_search.call_count, 1) @mock.patch('pyotrs.Client._ticket_get_json', autospec=True) @mock.patch('pyotrs.Client.ticket_search', autospec=True) def test_ticket_get_by_number_with_string_one_result(self, mock_t_search, mock_t_get): """Tests ticket_get_by_number provided as int -> ok; 1 result""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") obj.response_json = {'Ticket': [{'SomeOne': 'TicketOne'}]} @@ -356,13 +368,13 @@ class ClientTests(unittest.TestCase): result = obj.ticket_get_by_number("SomeOtherNumber1") - self.assertDictEqual(result, {'SomeOne': 'TicketOne'}) + self.assertTrue(result) + self.assertDictEqual(obj.response_json['Ticket'][0], {'SomeOne': 'TicketOne'}) self.assertEqual(mock_t_search.call_count, 1) @mock.patch('pyotrs.Client.ticket_search', autospec=True) def test_ticket_get_by_number_with_string_three_results(self, mock_ticket_search): """Tests ticket_get_by_number provided as int; 3 results -> nok""" - # create object obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") mock_ticket_search.return_value = [1, 2, 3] @@ -407,7 +419,7 @@ class ClientTests(unittest.TestCase): 'Charset': 'UTF8'}) mock_t_create_json.return_value = False result = obj.ticket_create(ticket=tic, article=art) - self.assertEqual(result, None) + self.assertFalse(result) @mock.patch('pyotrs.lib.Client._ticket_create_json', autospec=True) def test_ticket_create_mocked_true(self, mock_t_create_json): @@ -449,7 +461,7 @@ class ClientTests(unittest.TestCase): obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") dyn1 = DynamicField(name="firstname", value="Jane") - dyn2 = DynamicField(dct={'Name': 'lastname', 'Value': 'Doe'}) + dyn2 = DynamicField.from_dct({'Name': 'lastname', 'Value': 'Doe'}) obj.session_id_store.value = "some_session_id" tic = Ticket(dct={'Title': 'foo'}) art = Article({'Subject': 'mySubject', @@ -561,7 +573,7 @@ class ClientTests(unittest.TestCase): result = obj.ticket_update(1, QueueID="1") self.assertEqual(mock_ticket_update_json.call_count, 1) - self.assertEqual(result, None) + self.assertFalse(result) @mock.patch('pyotrs.Client._ticket_update_json', autospec=True) def test_ticket_update_article_nok(self, mock_ticket_update_json): @@ -578,7 +590,7 @@ class ClientTests(unittest.TestCase): result = obj.ticket_update(1, article=art) self.assertEqual(mock_ticket_update_json.call_count, 1) - self.assertEqual(result, None) + self.assertFalse(result) @mock.patch('pyotrs.Client._ticket_update_json', autospec=True) def test_ticket_update_attachment_list_no_article_nok(self, mock_ticket_update_json): @@ -628,7 +640,7 @@ class ClientTests(unittest.TestCase): result = obj.ticket_update(8, article=art, attachment_list=[att1, att2]) self.assertEqual(mock_ticket_update_json.call_count, 1) - self.assertEqual(result, None) + self.assertFalse(result) mock_ticket_update_json.assert_called_once_with(url, payload) @mock.patch('pyotrs.Client._ticket_update_json') @@ -655,14 +667,14 @@ class ClientTests(unittest.TestCase): 'Charset': 'UTF8'}) dyn1 = DynamicField(name="firstname", value="Jane") - dyn2 = DynamicField(dct={'Name': 'lastname', 'Value': 'Doe'}) + dyn2 = DynamicField.from_dct({'Name': 'lastname', 'Value': 'Doe'}) mock_ticket_update_json.return_value = False result = obj.ticket_update(7, article=art, dynamic_field_list=[dyn1, dyn2]) self.assertEqual(mock_ticket_update_json.call_count, 1) - self.assertEqual(result, None) + self.assertFalse(result) mock_ticket_update_json.assert_called_once_with(url, payload) @mock.patch('pyotrs.Client._ticket_update_json', autospec=True) @@ -686,7 +698,7 @@ class ClientTests(unittest.TestCase): result = obj.ticket_update_set_pending(1) self.assertEqual(mock_ticket_update_json.call_count, 1) - self.assertEqual(result, None) + self.assertFalse(result) def test__send_request_invalid_signature(self): """Test _send_request with invalid signature """ @@ -755,29 +767,47 @@ class ClientTests(unittest.TestCase): def test__validate_response_init_invalid(self): """Test _validate_response_init_invalid - missing response """ client = Client(baseurl="http://localhost", webservicename="foo") + + # mocked_response = mock.Mock(spec=requests.Response) + # mocked_response.status_code = 200 + # mocked_response.json.return_value = {} + self.assertRaisesRegex(ValueError, 'requests.Response object expected!', client._parse_and_validate_response, 'just_some_string') def test__validate_response_invalid_operation(self): - """Test Method Client._ticket_request """ + """Test _validate_response with an invalid operation""" client = Client(baseurl="http://localhost", webservicename="foo") client.operation = "DoTheMagicRainDance" + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = {} + self.assertRaisesRegex(NotImplementedError, 'Unknown Operation!', client._parse_and_validate_response, - requests.Response) + mocked_response) def test__validate_response_operation_session_create(self): + """Test _validate_response with SessionCreate""" client = Client(baseurl="http://localhost", webservicename="foo") - client.response_json = {u'SessionID': u'tMtTFDg1PxCXfoobarue4W5oQtNsFd0k'} client.operation = "SessionCreate" - client._parse_and_validate_response(requests.Response) + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = {u'SessionID': u'tMtTFDg1PxCXfoobarue4W5oQtNsFd0k'} + + client._parse_and_validate_response(mocked_response) + self.assertEqual(client.response_type, 'SessionID') def test__validate_response_operation_ticket_get(self): + """Test _validate_response with TicketGet""" client = Client(baseurl="http://localhost", webservicename="foo") + client.operation = "TicketGet" tkt = {u'Ticket': [{u'Age': 24040576, u'CreateBy': u'1', u'CustomerID': None, @@ -787,63 +817,107 @@ class ClientTests(unittest.TestCase): {u'Name': u'ProcessManagementProcessID', u'Value': None}], u'EscalationResponseTime': u'0'}]} - client.response_json = tkt - client.operation = "TicketGet" - client._parse_and_validate_response(requests.Response) + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = tkt + + client._parse_and_validate_response(mocked_response) + self.assertEqual(client.response_type, 'Ticket') + self.assertDictEqual(client.response_json, tkt) def test__validate_response_operation_ticket_create(self): + """Test _validate_response with TicketCreate""" client = Client(baseurl="http://localhost", webservicename="foo") - client.response_json = {u'ArticleID': u'26', u'TicketID': u'9', u'TicketNumber': u'000008'} client.operation = "TicketCreate" - client._parse_and_validate_response(requests.Response) + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = {u'ArticleID': u'26', + u'TicketID': u'9', + u'TicketNumber': u'000008'} + + client._parse_and_validate_response(mocked_response) + self.assertEqual(client.response_type, 'TicketID') + # self.assertEqual(mocked_response_json.call_count, 1) + self.assertDictEqual(client.response_json, {u'ArticleID': u'26', + u'TicketID': u'9', + u'TicketNumber': u'000008'}) def test__validate_response_operation_ticket_update(self): + """Test _validate_response with TicketUpdate""" client = Client(baseurl="http://localhost", webservicename="foo") - client.response_json = {u'TicketID': u'9', u'TicketNumber': u'000008'} client.operation = "TicketCreate" - client._parse_and_validate_response(requests.Response) + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = {u'TicketID': u'9', u'TicketNumber': u'000008'} + + client._parse_and_validate_response(mocked_response) self.assertEqual(client.response_type, 'TicketID') + self.assertDictEqual(client.response_json, {u'TicketID': u'9', + u'TicketNumber': u'000008'}) def test__validate_response_operation_ticket_search(self): + """Test _validate_response with TicketSearch""" client = Client(baseurl="http://localhost", webservicename="foo") - client.response_json = {u'TicketID': [u'9']} client.operation = "TicketSearch" - client._parse_and_validate_response(requests.Response) + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = {u'TicketID': [u'9']} + + client._parse_and_validate_response(mocked_response) self.assertEqual(client.response_type, 'TicketID') + self.assertDictEqual(client.response_json, {u'TicketID': [u'9']}) def test__validate_response_operation_ticket_search_empty(self): + """Test _validate_response with TicketSearch with empty result""" client = Client(baseurl="http://localhost", webservicename="foo") - client.response_json = {} client.operation = "TicketSearch" - client._parse_and_validate_response(requests.Response) + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = {} + + client._parse_and_validate_response(mocked_response) self.assertEqual(client.response_type, 'TicketID') + self.assertDictEqual(client.response_json, {}) def test__validate_response_operation_ticket_search_nonsense(self): + """Test _validate_response with TicketSearch with a nonsence response""" client = Client(baseurl="http://localhost", webservicename="foo") - client.response_json = {u'FooBar': [u'1', u'3']} client.operation = "TicketSearch" + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = {u'FooBar': [u'1', u'3']} + self.assertRaises(ResponseJSONParseError, client._parse_and_validate_response, - requests.Response) + mocked_response) self.assertEqual(client.response_type, 'TicketID') self.assertTrue(client.response_error) + self.assertDictEqual(client.response_json, {u'FooBar': [u'1', u'3']}) - # @mock.patch('pyotrs.Client._ticket_update_json', autospec=True) def test__validate_response_operation_ticket_get_error(self): - """ _parse_and_validate_response for a ticket_get operation when an error is received """ + """Test _validate_response with TicketGet when an error is received""" obj = Client(baseurl="http://localhost", webservicename="foo") + obj.operation = "TicketGet" tkt = {"Error": {"ErrorMessage": "TicketGet: Authorization failing!", "ErrorCode": "TicketGet.AuthFail"}} - obj.operation = "TicketGet" - obj.response_json = tkt + + mocked_response = mock.Mock(spec=requests.Response) + mocked_response.status_code = 200 + mocked_response.json.return_value = tkt self.assertRaisesRegex(OTRSAPIError, 'Failed to access OTRS API. Check Username and Password.*', obj._parse_and_validate_response, - requests.Response) + mocked_response) def main(): diff --git a/tests/test_dynamic_field.py b/tests/test_dynamic_field.py index 38f4e46..fc9854d 100644 --- a/tests/test_dynamic_field.py +++ b/tests/test_dynamic_field.py @@ -22,17 +22,13 @@ from pyotrs import DynamicField # noqa class DynamicFieldTests(unittest.TestCase): def test_init_blank(self): - self.assertRaisesRegex(TypeError, ".*takes exactly 3 arguments.*", DynamicField) + self.assertRaises(TypeError, DynamicField) def test_init_name_only(self): - self.assertRaisesRegex(TypeError, - ".*takes exactly 3 arguments.*", - DynamicField, name="foo") + self.assertRaises(TypeError, DynamicField, name="foo") def test_init_value_only(self): - self.assertRaisesRegex(TypeError, - ".*takes exactly 3 arguments.*", - DynamicField, value="bar") + self.assertRaises(TypeError, DynamicField, value="bar") def test_dummy1_static(self): dyn1 = DynamicField(name="firstname", value="Jane") diff --git a/tests/test_pyotrs_responses.py b/tests/test_pyotrs_responses.py index 8be94be..4dd364d 100644 --- a/tests/test_pyotrs_responses.py +++ b/tests/test_pyotrs_responses.py @@ -20,86 +20,78 @@ from pyotrs.lib import UpdateAddArticleError # noqa class PyOTRSResponsesTests(unittest.TestCase): - """Test Responses: """ - # - # def test_session_check_is_valid(self): - # """Tests session_check_is_valid""" - # - # with responses.RequestsMock() as rsps: - # rsps.add(responses.GET, - # 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' - # 'GenericTicketConnectorREST/Ticket/1', - # json={'Ticket': [{'Age': 24040576, - # 'DynamicField': [{'Name': 'ProcessManagementActivityID', - # 'Value': None}, - # {'Name': 'lastname', - # 'Value': None}], - # 'EscalationResponseTime': '0'}]}, - # status=200, - # content_type='application/json') - # # Define values for function call - # - # # create object - # obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") - # obj.session_check_is_valid(session_id="tMtTFDg1PxCX51dWnjue4W5oQtNsFd0k") - # self.assertEqual(obj.response_type, 'Ticket') - # - # @mock.patch('pyotrs.Client._read_session_id_from_file', autospec=True) - # def test_session_restore_or_set_up_new_with_file_ok(self, mock_read_session_id): - # """Tests session_restore_or_set_up_new when read from file successful and session ok""" - # # create object - # obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") - # obj.session_id = "foobar" - # - # with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: - # rsps.add(responses.GET, - # 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' - # 'GenericTicketConnectorREST/Ticket/1', - # json={'Ticket': [{'Age': 24040576, - # 'DynamicField': [{'Name': 'ProcessManagementActivityID', - # 'Value': None}, - # {'Name': 'lastname', - # 'Value': None}], - # 'EscalationResponseTime': '0'}]}, - # status=200, - # content_type='application/json') - # # Define values for function call - # - # mock_read_session_id.return_value = True - # obj.session_restore_or_set_up_new() - # - # self.assertEqual(mock_read_session_id.call_count, 1) - # - # def test_session_create(self): - # """Tests whether a SessionCreate call response would be made parsed correctly""" - # with responses.RequestsMock() as rsps: - # rsps.add(responses.POST, - # 'https://fqdn/otrs/nph-genericinterface.pl/Webservice' - # '/GenericTicketConnectorREST/Session', - # json={u'SessionID': u'tMtTFDg1PxCX51dWnjue4W5oQtNsFd0k'}, - # status=200, - # content_type='application/json') - # # Define values for function call - # username = 'right_username' - # password = 'right_password' - # - # # create object - # obj = Client('https://fqdn', 'GenericTicketConnectorREST', username, password) - # obj.session_create() - # self.assertDictEqual(obj.response_json, - # {'SessionID': 'tMtTFDg1PxCX51dWnjue4W5oQtNsFd0k'}) + """Tests using the responses module""" + def test_session_create_req_mocked_valid(self): + """Test session_create and _parse_and_validate_response; _send_request mocked; valid""" + obj = Client(baseurl="http://fqdn", + webservicename="GenericTicketConnectorREST") + + self.assertIsNone(obj.response_json) + self.assertIsNone(obj.response_status_code) + self.assertIsNone(obj.response_content) + self.assertIsNone(obj.session_id_store.value) + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + rsps.add(responses.POST, + 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' + 'GenericTicketConnectorREST/Session', + json={u'SessionID': u'tMtTFDg1PxCX51dWnjue4W5oQtNsFd0k'}, + status=200, + content_type='application/json') + + result = obj.session_create() + + self.assertEqual(result, True) + self.assertFalse(obj.response_error) + self.assertEqual(obj.operation, 'SessionCreate') + self.assertEqual(obj.response_status_code, 200) + self.assertDictEqual(obj.response_json, + {u'SessionID': u'tMtTFDg1PxCX51dWnjue4W5oQtNsFd0k'}) + self.assertEqual(obj.session_id_store.value, 'tMtTFDg1PxCX51dWnjue4W5oQtNsFd0k') + + def test_session_create_req_mocked_invalid(self): + """Test session_create and _parse_and_validate_response; _send_request mocked; invalid""" + obj = Client(baseurl="http://fqdn", + webservicename="GenericTicketConnectorREST") + + self.assertIsNone(obj.response_json) + self.assertIsNone(obj.response_status_code) + self.assertIsNone(obj.response_content) + self.assertIsNone(obj.session_id_store.value) + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + rsps.add(responses.POST, + 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' + 'GenericTicketConnectorREST/Session', + json={"Error": {"ErrorCode": "SessionCreate.AuthFail", + "ErrorMessage": "SessionCreate: Authorization failing!"}}, + status=200, + content_type='application/json') + + self.assertRaisesRegex(OTRSAPIError, + 'Failed to access OTRS API. Check Username and Password.*', + obj.session_create) + + self.assertTrue(obj.response_error) + self.assertEqual(obj.operation, 'SessionCreate') + self.assertEqual(obj.response_status_code, 200) + self.assertDictEqual(obj.response_json, + {"Error": {"ErrorCode": "SessionCreate.AuthFail", + "ErrorMessage": "SessionCreate: Authorization failing!"}}) + self.assertIsNone(obj.session_id_store.value) @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) - def test_session_create_json_mocked(self, mock_validate_resp): - """Test session_create_json - mocked""" + def test_session_create_req_mocked_failed_validation(self, mock_validate_resp): + """Test session_create; _parse_and_validate_response and _send_request mocked; fail vali""" obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") - url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ - "{0.webservicename}/Session".format(obj) - self.http_method = "POST" + self.assertIsNone(obj.response_json) + self.assertIsNone(obj.response_status_code) + self.assertIsNone(obj.response_content) + self.assertIsNone(obj.session_id_store.value) - mock_validate_resp.return_value = True + mock_validate_resp.return_value = False with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: rsps.add(responses.POST, @@ -109,11 +101,9 @@ class PyOTRSResponsesTests(unittest.TestCase): status=200, content_type='application/json') - result = obj._session_create_json(url=url, payload={"foo": "session-create"}) + result = obj.session_create() - self.assertEqual(obj.operation, 'SessionCreate') - self.assertEqual(result, True) - self.assertEqual(mock_validate_resp.call_count, 1) + self.assertFalse(result) @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) def test__ticket_create_json_mocked(self, mock_validate_resp): @@ -123,8 +113,6 @@ class PyOTRSResponsesTests(unittest.TestCase): url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ "{0.webservicename}/Ticket".format(obj) - self.http_method = "POST" - mock_validate_resp.return_value = True with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: @@ -138,7 +126,31 @@ class PyOTRSResponsesTests(unittest.TestCase): result = obj._ticket_create_json(url=url, payload={"bar": "ticket-create"}) self.assertEqual(obj.operation, 'TicketCreate') - self.assertEqual(result, True) + self.assertTrue(result) + self.assertEqual(mock_validate_resp.call_count, 1) + + @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) + def test__ticket_create_json_mocked_fail_validation(self, mock_validate_resp): + """Test _ticket_create_json - mocked _fail_validation""" + obj = Client(baseurl="http://fqdn", + webservicename="GenericTicketConnectorREST") + url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ + "{0.webservicename}/Ticket".format(obj) + + mock_validate_resp.return_value = False + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + rsps.add(responses.POST, + 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' + 'GenericTicketConnectorREST/Ticket', + json={u'ArticleID': u'2', u'TicketID': u'2', u'TicketNumber': u'000001'}, + status=200, + content_type='application/json') + + result = obj._ticket_create_json(url=url, payload={"bar": "ticket-create"}) + + self.assertEqual(obj.operation, 'TicketCreate') + self.assertFalse(result) self.assertEqual(mock_validate_resp.call_count, 1) @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) @@ -147,51 +159,19 @@ class PyOTRSResponsesTests(unittest.TestCase): obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ - "{0.webservicename}/Ticket/{1}".format(obj, 1) - - self.http_method = "GET" + "{0.webservicename}/Ticket".format(obj) mock_validate_resp.return_value = True with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: rsps.add(responses.GET, 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' - 'GenericTicketConnectorREST/Ticket/1', + 'GenericTicketConnectorREST/Ticket', json={u'Ticket': [{u'Age': 24040576, u'ArchiveFlag': u'n', u'ChangeBy': u'1', u'Changed': u'2016-04-13 20:41:19', u'CreateBy': u'1', - u'CreateTimeUnix': u'1436949030', - u'Created': u'2015-07-15 08:30:30', - u'CustomerID': None, - u'CustomerUserID': None, - u'DynamicField': [{u'Name': u'ProcessManagementActivityID', - u'Value': None}, - {u'Name': u'ProcessManagementProcessID', - u'Value': None}, - {u'Name': u'firstname', u'Value': None}, - {u'Name': u'lastname', u'Value': None}], - u'EscalationResponseTime': u'0', - u'EscalationSolutionTime': u'0', - u'EscalationTime': u'0', - u'EscalationUpdateTime': u'0', - u'GroupID': u'1', - u'Lock': u'unlock', - u'LockID': u'1', - u'Owner': u'root@localhost', - u'OwnerID': u'1', - u'Priority': u'3 normal', - u'PriorityID': u'3', - u'Queue': u'Raw', - u'QueueID': u'2', - u'RealTillTimeNotUsed': u'0', - u'Responsible': u'root@localhost', - u'ResponsibleID': u'1', - u'SLAID': u'', - u'ServiceID': u'', - u'State': u'open', - u'StateID': u'4', u'StateType': u'open', u'TicketID': u'1', u'TicketNumber': u'2015071510123456', @@ -206,7 +186,40 @@ class PyOTRSResponsesTests(unittest.TestCase): result = obj._ticket_get_json(url=url, payload={"bla": "ticket-get"}) self.assertEqual(obj.operation, 'TicketGet') - self.assertEqual(result, True) + self.assertTrue(result) + self.assertEqual(mock_validate_resp.call_count, 1) + + @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) + def test__ticket_get_json_mocked_fail_validation(self, mock_validate_resp): + """Test _ticket_create_json - mocked _fail_validation""" + obj = Client(baseurl="http://fqdn", + webservicename="GenericTicketConnectorREST") + url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ + "{0.webservicename}/Ticket".format(obj) + + mock_validate_resp.return_value = False + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + rsps.add(responses.GET, + 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' + 'GenericTicketConnectorREST/Ticket', + json={u'Ticket': [{u'Age': 24040576, + u'ArchiveFlag': u'n', + u'ChangeBy': u'1', + u'TicketID': u'1', + u'TicketNumber': u'2015071510123456', + u'Title': u'Welcome to OTRS!', + u'Type': u'Unclassified', + u'TypeID': 1, + u'UnlockTimeout': u'0', + u'UntilTime': 0}]}, + status=200, + content_type='application/json') + + result = obj._ticket_get_json(url=url, payload={"bar": "ticket-create"}) + + self.assertEqual(obj.operation, 'TicketGet') + self.assertFalse(result) self.assertEqual(mock_validate_resp.call_count, 1) @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) @@ -217,8 +230,6 @@ class PyOTRSResponsesTests(unittest.TestCase): url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ "{0.webservicename}/Ticket".format(obj) - self.http_method = "GET" - mock_validate_resp.return_value = True with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: @@ -232,8 +243,31 @@ class PyOTRSResponsesTests(unittest.TestCase): result = obj._ticket_search_json(url=url, payload={"bla": "ticket-search"}) self.assertEqual(obj.operation, 'TicketSearch') - self.assertEqual(obj.http_method, 'GET') - self.assertEqual(result, True) + self.assertTrue(result) + self.assertEqual(mock_validate_resp.call_count, 1) + + @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) + def test__ticket_search_json_mocked_fail_validation(self, mock_validate_resp): + """Test _ticket_search_json - mocked""" + obj = Client(baseurl="http://fqdn", + webservicename="GenericTicketConnectorREST") + url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ + "{0.webservicename}/Ticket".format(obj) + + mock_validate_resp.return_value = False + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + rsps.add(responses.GET, + 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' + 'GenericTicketConnectorREST/Ticket', + json={u'TicketID': [u'1']}, + status=200, + content_type='application/json') + + result = obj._ticket_search_json(url=url, payload={"bla": "ticket-search"}) + + self.assertEqual(obj.operation, 'TicketSearch') + self.assertFalse(result) self.assertEqual(mock_validate_resp.call_count, 1) @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) @@ -244,8 +278,6 @@ class PyOTRSResponsesTests(unittest.TestCase): url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ "{0.webservicename}/Ticket/{1}".format(obj, 1) - self.http_method = "PATCH" - mock_validate_resp.return_value = True with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: @@ -259,12 +291,35 @@ class PyOTRSResponsesTests(unittest.TestCase): result = obj._ticket_update_json(url=url, payload={"alb": "ticket-update"}) self.assertEqual(obj.operation, 'TicketUpdate') - self.assertEqual(result, True) + self.assertTrue(result) self.assertEqual(mock_validate_resp.call_count, 1) @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) - def test__ticket_update_json_w_article_ok_mocked(self, mock_validate_resp): - """Test _ticket_update_json with article - ok - mocked""" + def test__ticket_update_json_mocked_fail_validation(self, mock_validate_resp): + """Test _ticket_update_json - mocked _fail_validation""" + obj = Client(baseurl="http://fqdn", + webservicename="GenericTicketConnectorREST") + url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ + "{0.webservicename}/Ticket/{1}".format(obj, 1) + + mock_validate_resp.return_value = False + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + rsps.add(responses.PATCH, + 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' + 'GenericTicketConnectorREST/Ticket/1', + json={u'TicketID': u'9', u'TicketNumber': u'000008'}, + status=200, + content_type='application/json') + + result = obj._ticket_update_json(url=url, payload={"alb": "ticket-update"}) + + self.assertEqual(obj.operation, 'TicketUpdate') + self.assertFalse(result) + self.assertEqual(mock_validate_resp.call_count, 1) + + def test__ticket_update_json_w_article_ok_mocked(self): + """Test _ticket_update_json with article and parse+validate - ok - mocked""" obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST") url = "{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" \ @@ -276,10 +331,6 @@ class PyOTRSResponsesTests(unittest.TestCase): 'MimeType': 'text/plain', 'Charset': 'UTF8'}} - self.http_method = "PATCH" - - mock_validate_resp.return_value = True - with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: rsps.add(responses.PATCH, 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' @@ -291,8 +342,7 @@ class PyOTRSResponsesTests(unittest.TestCase): result = obj._ticket_update_json(url=url, payload=art) self.assertEqual(obj.operation, 'TicketUpdate') - self.assertEqual(result, True) - self.assertEqual(mock_validate_resp.call_count, 1) + self.assertTrue(result) @mock.patch('pyotrs.lib.Client._parse_and_validate_response', autospec=True) def test__ticket_update_json_w_article_nok_unknown_exception_mocked(self, mock_validate_resp): @@ -308,8 +358,6 @@ class PyOTRSResponsesTests(unittest.TestCase): 'MimeType': 'text/plain', 'Charset': 'UTF8'}} - self.http_method = "PATCH" - mock_validate_resp.return_value = True with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: @@ -342,8 +390,6 @@ class PyOTRSResponsesTests(unittest.TestCase): 'MimeType': 'text/plain', 'Charset': 'UTF8'}} - self.http_method = "PATCH" - mock_validate_resp.return_value = True with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: @@ -362,6 +408,34 @@ class PyOTRSResponsesTests(unittest.TestCase): self.assertEqual(obj.operation, 'TicketUpdate') self.assertEqual(mock_validate_resp.call_count, 1) + def test__ticket_update_json_w_article_nok_exception_mocked_no_art(self): + """Test _ticket_update_json with article - nok - reraised exception - mocked - no art""" + obj = Client(baseurl="http://fqdn", + webservicename="GenericTicketConnectorREST") + url = ("{0.baseurl}/otrs/nph-genericinterface.pl/Webservice/" + "{0.webservicename}/Ticket/{1}".format(obj, 4)) + + art = {'Article': {'Subject': 'Dümmy Subject', + 'Body': 'Hallo Bjørn,\n[kt]\n\n -- The End', + 'TimeUnit': 0, + 'MimeType': 'text/plain', + 'Charset': 'UTF8'}} + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + rsps.add(responses.PATCH, + 'http://fqdn/otrs/nph-genericinterface.pl/Webservice/' + 'GenericTicketConnectorREST/Ticket/4', + json={u'TicketID': u'4', u'TicketNumber': u'000004'}, + status=200, + content_type='application/json') + + self.assertRaisesRegex(UpdateAddArticleError, + 'Unknown Ex.*', + obj._ticket_update_json, + url=url, payload=art) + + self.assertEqual(obj.operation, 'TicketUpdate') + # Main def main(): diff --git a/tests/test_ticket.py b/tests/test_ticket.py index 831bcc6..5d3ac29 100644 --- a/tests/test_ticket.py +++ b/tests/test_ticket.py @@ -128,6 +128,16 @@ class TicketTests(unittest.TestCase): self.assertIsInstance(tic, Ticket) self.assertEqual(tic.__repr__(), '<Ticket>') + def test_create_basic_title_queue_state_prio_customer_five(self): + tic = Ticket.create_basic(Title='foobar', + Queue='raw', + StateID='4', + Priority='average', + CustomerUser='root@localhost') + self.assertIsInstance(tic, Ticket) + tic.TicketID = '5' + self.assertEqual(tic.__repr__(), '<Ticket: 5>') + def test_create_basic_title_queue_state_prio_customer_to_dct(self): tic = Ticket.create_basic(Title='foobar', QueueID='1', -- GitLab