From d98eda8676a0e838c59d52d3ae5e8c58ff6cda15 Mon Sep 17 00:00:00 2001
From: Robert Habermann <mail@rhab.de>
Date: Thu, 21 Apr 2016 17:46:24 +0200
Subject: [PATCH] extend tests

---
 pyotrs/lib.py                  |   3 +-
 tests/disabled_test_pyotrs.py  | 271 ----------------------------
 tests/test_client.py           |  25 ++-
 tests/test_pyotrs.py           | 317 +++++++++++++++++++++++++++++++++
 tests/test_pyotrs_responses.py | 103 +++++++++++
 tox.ini                        |  23 ++-
 6 files changed, 462 insertions(+), 280 deletions(-)
 delete mode 100644 tests/disabled_test_pyotrs.py
 create mode 100644 tests/test_pyotrs.py
 create mode 100644 tests/test_pyotrs_responses.py

diff --git a/pyotrs/lib.py b/pyotrs/lib.py
index b829897..b425f27 100644
--- a/pyotrs/lib.py
+++ b/pyotrs/lib.py
@@ -476,7 +476,7 @@ class Client(object):
 
         if not baseurl:
             raise NoBaseURL("Missing Baseurl (e.g. https://otrs.example.com)")
-        self.baseurl = baseurl
+        self.baseurl = baseurl.rstrip("/")
 
         if not webservicename:
             raise NoWebServiceName("Missing WebServiceName (e.g. GenericTicketConnectorREST)")
@@ -1085,6 +1085,7 @@ class Client(object):
 
         headers = {"Content-Type": "application/json"}
         json_payload = json.dumps(payload)
+        print("sending {0} to {1} as {2}".format(payload, url, http_method.upper()))
         try:
             response = requests.request(http_method.upper(),
                                         url,
diff --git a/tests/disabled_test_pyotrs.py b/tests/disabled_test_pyotrs.py
deleted file mode 100644
index 02f7cf4..0000000
--- a/tests/disabled_test_pyotrs.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Name:         disabled_test_pyotrs.py
-# Description:  Test for pyotrs module
-#
-# Author:       robert.habermann@dlh.de
-# Date:         2015-07-14
-
-
-# make sure (early) that parent dir (main app) is in path
-import os.path
-import sys
-
-current_path = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(current_path, os.pardir))
-
-import unittest2 as unittest
-import responses
-from mock import MagicMock, patch
-
-from pyotrs import Client, Ticket
-from pyotrs.lib import NoBaseURL, NoWebServiceName, NoCredentials
-from pyotrs.lib import SessionCreateError, SessionIDFileError, OTRSAPIError, OTRSHTTPError
-
-
-class PyOTRSTests(unittest.TestCase):
-    """ Test Responses: Check whether direct call to _helper function raises the 'get api'
-        exception when Error is recvd
-    """
-    @responses.activate
-    def test_resp___get_json_ticket_data(self):
-        # responses will return this data:
-        responses.add(**{
-            'method':        responses.POST,
-            'url':           'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Session',
-            'body':          '{"SessionID":"fakesessionid"}',
-            'status':        200,
-            'content_type': 'application/json'
-        })
-        responses.add(**{
-            'method':        responses.GET,
-            'url':           'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/1',
-            'body':          '{"Error":{"ErrorMessage":"TicketGet: Authorization failing!","ErrorCode":"TicketGet.AuthFail"}}',
-            'status':        200,
-            'content_type': 'application/json'
-        })
-
-        username = "wrong_username"
-        password = "wrong_password"
-
-        url = "https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/1"
-        payload = {
-            'UserLogin':     username,
-            'Password':      password,
-            'AllArticles':   0,
-            'DynamicFields': 1
-        }
-
-        obj = Client(self.base_url, self.webservice_name, username, password)
-        obj.session_restore_or_set_up_new()
-
-        self.assertRaisesRegexp(OTRSAPIError, 'TicketGet API Error.*',
-                                obj._ticket_get_json, url=url,
-                                payload=payload)
-
-    """ Test Responses: when calling: get_json_ticket_data_by_ticket_id - Test 200 OK; Body Error
-    """
-    @responses.activate
-    def test_resp_get_json_ticket_data_by_ticket_id(self):
-        # responses will return this data:
-        responses.add(**{
-            'method':       responses.POST,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Session',
-            'body':         '{"SessionID":"fakesessionid"}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-        responses.add(**{
-            'method':       responses.GET,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/1',
-            'body':         '{"Error":{"ErrorMessage":"TicketGet: Authorization failing!","ErrorCode":"TicketGet.AuthFail"}}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-
-        username = "wrong_username"
-        password = "wrong_password"
-
-        obj = Client(self.base_url, self.webservice_name, username, password)
-        obj.session_restore_or_set_up_new()
-        obj.ticket_get_by_id(1)
-
-        self.assertEqual({"Error": {"ErrorMessage": "TicketGet: Authorization failing!",
-                                    "ErrorCode":    "TicketGet.AuthFail"}}, obj.response.json())
-        self.assertEqual(200, obj.response.status_code)
-
-    """ Test Responses: update title on valid ticket """
-    @responses.activate
-    def test_resp_update_by_ticket_id_set_title_valid(self):
-        # responses will return this data:
-        responses.add(**{
-            'method':       responses.POST,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Session',
-            'body':         '{"SessionID":"fakesessionid"}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-        responses.add(**{
-            'method':        responses.PATCH,
-            'url':           'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/10',
-            'body':          '{"TicketNumber":"1970010100000010","TicketID":"10"}',
-            'status':        200,
-            'content_type': 'application/json'
-        })
-
-        username = "fake_username"
-        password = "fake_password"
-
-        obj = Client(self.base_url, self.webservice_name, username, password)
-        obj.session_restore_or_set_up_new()
-        obj.ticket_update_set_title(10, "Full New Title")
-
-        self.assertEqual({"TicketNumber": "1970010100000010", "TicketID": "10"}, obj.response.json())
-        self.assertEqual(200, obj.response.status_code)
-
-    """ Test Responses: update title on invalid ticket (or wrong credentials) """
-    @responses.activate
-    def test_resp_update_by_ticket_id_set_title_invalid(self):
-        # responses will return this data:
-        responses.add(**{
-            'method':       responses.POST,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Session',
-            'body':         '{"SessionID":"fakesessionid"}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-        responses.add(**{
-            'method':       responses.PATCH,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/20',
-            'body':         '{"Error":{"ErrorCode":"TicketUpdate.AccessDenied","ErrorMessage":"TicketUpdate: User does not have access to the ticket!"}}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-
-        username = "fake_username"
-        password = "fake_password"
-
-        obj = Client(self.base_url, self.webservice_name, username, password)
-        obj.session_restore_or_set_up_new()
-        obj.ticket_update_set_title(20, "Full New Title")
-
-        self.assertEqual({"Error": {"ErrorCode":    "TicketUpdate.AccessDenied",
-                                    "ErrorMessage": "TicketUpdate: User does not have access to the ticket!"}},
-                         obj.response.json())
-        self.assertEqual(200, obj.response.status_code)
-
-    """ Test Mock: Validate that the right call to _get_json_ticket_data
-        is made by requests when calling: get_json_ticket_data_by_ticket_id
-    """
-    @responses.activate
-    def test_mock_get_json_ticket_data_by_ticket_id(self):
-        responses.add(**{
-            'method':       responses.POST,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Session',
-            'body':         '{"SessionID":"fakesessionid"}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-        # Define values for function call
-        username = "wrong_username"
-        password = "wrong_password"
-
-        # Define data that should be called later:
-        url = "https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/1"
-        payload = {
-            'SessionID':     "fakesessionid",
-            'AllArticles':   0,
-            'DynamicFields': 1
-        }
-
-        # create object
-        obj = Client(self.base_url, self.webservice_name, username, password)
-        obj.session_restore_or_set_up_new()
-
-        # enable Mock
-        obj._ticket_get_json = MagicMock()
-
-        # call function
-        obj.ticket_get_by_id(1)
-
-        # test whether predefined data and call (hooked by MagicMock) match
-        obj._ticket_get_json.assert_called_with(url, payload)
-
-    """ Test Mock: Validate that the right call to requests is made """
-    @responses.activate
-    def test_mock_get_json_ticket_data_by_ticket_id_with(self):
-        responses.add(**{
-            'method':       responses.POST,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Session',
-            'body':         '{"SessionID":"fakesessionid"}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-        # expected content of request:
-        mock_url = "https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/1"
-        mock_payload = {
-            'SessionID':     "fakesessionid",
-            'AllArticles':   0,
-            'DynamicFields': 1
-        }
-
-        mock_username = "wrong_username"
-        mock_password = "wrong_password"
-
-        obj = Client(self.base_url, self.webservice_name, mock_username, mock_password)
-        obj.session_restore_or_set_up_new()
-
-        with patch('requests.get') as patched_get:
-            obj.ticket_get_by_id(1)
-            # Ensure patched get was called, called only once and with exactly these params.
-            patched_get.assert_called_once_with(mock_url, params=mock_payload,
-                                                proxies=self.proxies, verify=True)
-
-    """ Test Responses: when calling: get_json_ticket_data_by_ticket_id - Test 200 OK; Body Error
-    """
-    @responses.activate
-    def test_session_handling(self):
-        # responses will return this data:
-        responses.add(**{
-            'method':       responses.POST,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Session',
-            'body':         '{"SessionID":"fakesessionid"}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-
-        responses.add(**{
-            'method':       responses.GET,
-            'url':          'https://fqdn/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorREST/Ticket/1',
-            'body':         '{"Ticket":[{"Age":156717521,"PriorityID":"3","ServiceID":"","Type":"Unclassified","Responsible":"root@localhost","StateID":"2","ResponsibleID":"1","ChangeBy":"2","EscalationTime":"0","OwnerID":"2","Changed":"2015-06-08 11:36:17","RealTillTimeNotUsed":"0","GroupID":"7","Owner":"User","CustomerID":null,"TypeID":1,"Created":"2010-08-02 12:00:00","Priority":"3 normal","UntilTime":0,"EscalationUpdateTime":"0","QueueID":"9","Queue":"Operations::OTRS","State":"closed","Title":"Welcome to OTRS!","CreateBy":"1","TicketID":"1","StateType":"closed","UnlockTimeout":"1433763374","EscalationResponseTime":"0","EscalationSolutionTime":"0","LockID":"1","TicketNumber":"2010080210123456","ArchiveFlag":"n","CreateTimeUnix":"1280750400","Lock":"unlock","SLAID":"","CustomerUserID":null}]}',
-            'status':       200,
-            'content_type': 'application/json'
-        })
-
-        # TODO.. mock sending of the error mail..
-        mock_username = "correct_username"
-        mock_password = "correct_password"
-
-        """
-        with patch('modules.pymisc.send_message_via_mail') as patched_send_message:
-            obj = pyotrs.PyOTRS(self.base_url, self.webservice_name, mock_username, mock_password)
-        """
-
-''' TODOs
-
-Write tests for
-* _get_json_ticket_data with http request failing (e.g. due to wrong fqdn or proxy)
-* search_ticket(self, payload)
-* _search_json_ticket_data(self, url, payload):
-
-'''
-
-
-# Main
-def main():
-    unittest.main()
-
-if __name__ == '__main__':
-    main()
-
-# EOF
diff --git a/tests/test_client.py b/tests/test_client.py
index fe2f2f8..3c82cea 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -9,16 +9,12 @@ from __future__ import unicode_literals  # support both Python2 and 3
 
 
 # make sure (early) that parent dir (main app) is in path
-import os.path
-import sys
 import unittest2 as unittest
 # from mock import MagicMock, patch
 
-current_path = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(current_path, os.pardir))
-
-from pyotrs import Client  # noqa
-from pyotrs.lib import NoBaseURL, NoWebServiceName, ResponseJSONParseError  # noqa
+from pyotrs import Client
+from pyotrs.lib import NoBaseURL, NoWebServiceName, ResponseJSONParseError
+from pyotrs.lib import SessionError
 
 
 class ClientTests(unittest.TestCase):
@@ -29,6 +25,14 @@ class ClientTests(unittest.TestCase):
     def test_init_no_base(self):
         self.assertRaisesRegex(NoBaseURL, 'Missing Baseurl.*', Client, '', '')
 
+    def test_init_strip_trailing_slash1(self):
+        obj = Client(baseurl="http://fqdn", webservicename="GenericTicketConnectorREST")
+        self.assertEqual(obj.baseurl, "http://fqdn")
+
+    def test_init_strip_trailing_slash2(self):
+        obj = Client(baseurl="http://fqdn/", webservicename="GenericTicketConnectorREST")
+        self.assertEqual(obj.baseurl, "http://fqdn")
+
     def test_init_no_webservice(self):
         self.assertRaisesRegex(NoWebServiceName, 'Missing WebSe.*', Client, 'http://localhost', '')
 
@@ -36,6 +40,13 @@ class ClientTests(unittest.TestCase):
         client = Client(baseurl="http://localhost/", webservicename="foo", session_id_file=".sid")
         self.assertEqual(client.session_id_file, '.sid')
 
+    def test_session_check_is_valid_no_session_id_error(self):
+        """Test Method Client._ticket_request """
+        client = Client(baseurl="http://localhost/", webservicename="foo")
+        self.assertRaisesRegex(SessionError,
+                               'No value set for session_id!',
+                               client.session_check_is_valid)
+
     def test__ticket_request_invalid_signature(self):
         """Test Method Client._ticket_request """
         self.assertRaisesRegex(ValueError,
diff --git a/tests/test_pyotrs.py b/tests/test_pyotrs.py
new file mode 100644
index 0000000..8ef2c76
--- /dev/null
+++ b/tests/test_pyotrs.py
@@ -0,0 +1,317 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals  # support both Python2 and 3
+#
+# Name:         test_pyotrs.py
+# Description:  Test for pyotrs module
+#
+# Author:       robert.habermann@dlh.de
+# Date:         2015-07-14
+
+
+# make sure (early) that parent dir (main app) is in path
+import os.path
+import sys
+
+current_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(current_path, os.pardir))
+
+import unittest2 as unittest
+import responses
+import requests
+
+from mock import MagicMock, patch
+
+from pyotrs import Client, Ticket
+from pyotrs.lib import NoBaseURL, NoWebServiceName, NoCredentials
+from pyotrs.lib import SessionCreateError, SessionIDFileError, OTRSAPIError, OTRSHTTPError
+
+
+class PyOTRSTests(unittest.TestCase):
+    """ Test Responses: Check whether direct call to _helper function raises the 'get api'
+        exception when Error is recvd
+    """
+
+    # def test_resp___get_json_ticket_data(self):
+    #     with responses.RequestsMock() as rsps:
+    #         # responses will return this data:
+    #         rsps.add(responses.POST,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Session',
+    #                  body={'SessionID': 'fakesessionid'},
+    #                  status=200,
+    #                  content_type='application/json')
+    #         rsps.add(responses.GET,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Ticket/1',
+    #                  body={'Error': {'ErrorMessage': 'TicketGet: Authorization failing!',
+    #                                  'ErrorCode'   : 'TicketGet.AuthFail'}},
+    #                  status=200,
+    #                  content_type='application/json')
+    #
+    #         username = 'wrong_username'
+    #         password = 'wrong_password'
+    #
+    #         url = 'https://fqdn/otrs/nph-genericinterface.pl/Webservice' \
+    #               '/GenericTicketConnectorREST/Ticket/1'
+    #         payload = {
+    #             'UserLogin'    : username,
+    #             'Password'     : password,
+    #             'AllArticles'  : 0,
+    #             'DynamicFields': 1
+    #         }
+    #
+    #         obj = Client('http://localhost/', 'dummy', 'username', 'password')
+    #         obj.session_restore_or_set_up_new()
+    #
+    #         self.assertRaisesRegexp(OTRSAPIError,
+    #                                 'TicketGet API Error.*',
+    #                                 obj._ticket_get_json,
+    #                                 url=url,
+    #                                 payload=payload)
+    #
+    # def test_resp_get_json_ticket_data_by_ticket_id(self):
+    #     """ This tests: get_json_ticket_data_by_ticket_id - Test 200 OK;
+    #     Body Error  """
+    #     with responses.RequestsMock() as rsps:
+    #         # responses will return this data:
+    #         rsps.add(responses.POST,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Session',
+    #                  body={'SessionID': 'fakesessionid'},
+    #                  status=200,
+    #                  content_type='application/json')
+    #         rsps.add(responses.GET,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Ticket/1',
+    #                  body={'Error': {'ErrorMessage': 'TicketGet: Authorization failing!',
+    #                                  'ErrorCode'   : 'TicketGet.AuthFail'}},
+    #                  status=200,
+    #                  content_type='application/json')
+    #
+    #         username = 'wrong_username'
+    #         password = 'wrong_password'
+    #
+    #         obj = Client('http://localhost/', 'dummy', 'username', 'password')
+    #         obj.session_restore_or_set_up_new()
+    #         obj.ticket_get_by_id(1)
+    #
+    #         self.assertEqual({'Error': {'ErrorMessage': 'TicketGet: Authorization failing!',
+    #                                     'ErrorCode'   : 'TicketGet.AuthFail'}},
+    #                          obj.response.json())
+    #         self.assertEqual(200, obj.response.status_code)
+    #
+    # def test_resp_update_by_ticket_id_set_title_valid(self):
+    #     """ This tests: Test Responses: update title on valid ticket """
+    #     with responses.RequestsMock() as rsps:
+    #         # responses will return this data:
+    #         rsps.add(responses.POST,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Session',
+    #                  body={'SessionID': 'fakesessionid'},
+    #                  status=200,
+    #                  content_type='application/json'
+    #                  )
+    #         rsps.add(responses.PATCH,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Ticket/10',
+    #                  body={'TicketNumber': '1970010100000010',
+    #                        'TicketID'    : '10'},
+    #                  status=200,
+    #                  content_type='application/json')
+    #
+    #         username = 'fake_username'
+    #         password = 'fake_password'
+    #
+    #         obj = Client('http://localhost/', 'dummy', 'username', 'password')
+    #         obj.session_restore_or_set_up_new()
+    #         obj.ticket_update_set_title(10, 'Full New Title')
+    #
+    #         self.assertEqual({'TicketNumber': '1970010100000010', 'TicketID': '10'},
+    #                          obj.response.json())
+    #         self.assertEqual(200, obj.response.status_code)
+    #
+    # def test_resp_update_by_ticket_id_set_title_invalid(self):
+    #     """ This tests: Test Responses: update title on invalid ticket (or wrong credentials) """
+    #     # responses will return this data:
+    #     with responses.RequestsMock() as rsps:
+    #         rsps.add(responses.POST,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Session',
+    #                  body={'SessionID': 'fakesessionid'},
+    #                  status=200,
+    #                  content_type='application/json')
+    #         rsps.add(responses.PATCH,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Ticket/20',
+    #                  body={'Error': {'ErrorCode'   : 'TicketUpdate.AccessDenied',
+    #                                  'ErrorMessage': 'TicketUpdate: User does not have access '
+    #                                                  'to the ticket!'}},
+    #                  status=200,
+    #                  content_type='application/json')
+    #
+    #         username = 'fake_username'
+    #         password = 'fake_password'
+    #
+    #         obj = Client('http://localhost/', 'dummy', 'username', 'password')
+    #         obj.session_restore_or_set_up_new()
+    #         obj.ticket_update_set_title(20, 'Full New Title')
+    #
+    #         self.assertEqual({'Error': {'ErrorCode'   : 'TicketUpdate.AccessDenied',
+    #                                     'ErrorMessage': 'TicketUpdate: User does not have access '
+    #                                                     'to the ticket!'}},
+    #                          obj.response.json())
+    #         self.assertEqual(200, obj.response.status_code)
+    #
+    # def test_mock_get_json_ticket_data_by_ticket_id(self):
+    #     """ This tests: Test Mock: Validate that the right call to _get_json_ticket_data
+    #     is made by requests when calling: get_json_ticket_data_by_ticket_id
+    #     """
+    #     with responses.RequestsMock() as rsps:
+    #         rsps.add(responses.POST,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Session',
+    #                  body={'UserLogin': 'wrong_username',
+    #                        'Password': 'wrong_password'},
+    #                  status=200,
+    #                  content_type='application/json')
+    #         # Define values for function call
+    #         username = 'wrong_username'
+    #         password = 'wrong_password'
+    #
+    #         # Define data that should be called later:
+    #         url = 'https://fqdn/otrs/nph-genericinterface.pl/Webservice' \
+    #               '/GenericTicketConnectorREST/Ticket/1'
+    #         payload = {
+    #             'SessionID': 'fakesessionid',
+    #             'AllArticles': 0,
+    #             'DynamicFields': 1
+    #         }
+    #
+    #         # create object
+    #         obj = Client('http://fqdn/', 'GenericTicketConnectorREST', username, password)
+    #         obj.session_create()
+
+            # enable Mock
+            # obj._ticket_get_json = MagicMock()
+
+            # call function
+            # obj.ticket_get_by_id(1)
+
+    #
+    # def test_mock_get_json_ticket_data_by_ticket_id_with(self):
+    #     """ This tests: Test Mock: Validate that the right call to requests is made """
+    #     with responses.RequestsMock() as rsps:
+    #         rsps.add(responses.POST,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST/Session',
+    #                  body={'SessionID': 'fakesessionid'},
+    #                  status=200,
+    #                  content_type='application/json')
+    #         # expected content of request:
+    #         mock_url = 'https://fqdn/otrs/nph-genericinterface.pl/Webservice' \
+    #                    '/GenericTicketConnectorREST/Ticket/1'
+    #         mock_payload = {
+    #             'SessionID'    : 'fakesessionid',
+    #             'AllArticles'  : 0,
+    #             'DynamicFields': 1
+    #         }
+    #
+    #         mock_username = 'wrong_username'
+    #         mock_password = 'wrong_password'
+    #
+    #         obj = Client('http://localhost/', 'dummy', 'username', 'password')
+    #         obj.session_restore_or_set_up_new()
+    #
+    #         with patch('requests.get') as patched_get:
+    #             obj.ticket_get_by_id(1)
+    #             # Ensure patched get was called, called only once and with exactly these params.
+    #             patched_get.assert_called_once_with(mock_url,
+    #                                                 params=mock_payload,
+    #                                                 verify=True)
+    #
+    # def test_session_handling(self):
+    #     """ This tests: Test Responses: when calling: get_json_ticket_data_by_ticket_id - Test
+    #     200 OK;
+    #     Body Error  """
+    #     with responses.RequestsMock() as rsps:
+    #         # responses will return this data:
+    #         rsps.add(responses.POST,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST'
+    #                  '/Session',
+    #                  body={'SessionID': 'fakesessionid'},
+    #                  status=200,
+    #                  content_type='application/json')
+    #
+    #         rsps.add(responses.GET,
+    #                  'https://fqdn/otrs/nph-genericinterface.pl/Webservice'
+    #                  '/GenericTicketConnectorREST'
+    #                  '/Ticket/1',
+    #                  body={'Ticket':
+    #                            [{'Age': 156717521,
+    #                              'PriorityID': '3',
+    #                              'ServiceID': '',
+    #                              'Type': 'Unclassified',
+    #                              'Responsible': 'root@localhost',
+    #                              'StateID': '2',
+    #                              'ResponsibleID': '1',
+    #                              'ChangeBy': '2',
+    #                              'EscalationTime': '0',
+    #                              'OwnerID': '2',
+    #                              'Changed': '2015-06-08 11:36:17',
+    #                              'RealTillTimeNotUsed': '0',
+    #                              'GroupID': '7',
+    #                              'Owner': 'User',
+    #                              'CustomerID': '',
+    #                              'TypeID': 1,
+    #                              'Created': '2010-08-02 12:00:00',
+    #                              'Priority': '3 normal',
+    #                              'UntilTime': 0,
+    #                              'EscalationUpdateTime': '0',
+    #                              'QueueID': '9',
+    #                              'Queue': 'Operations::OTRS',
+    #                              'State': 'closed',
+    #                              'Title': 'Welcome to OTRS!',
+    #                              'CreateBy': '1',
+    #                              'TicketID': '1',
+    #                              'StateType': 'closed',
+    #                              'UnlockTimeout': '1433763374',
+    #                              'EscalationResponseTime': '0',
+    #                              'EscalationSolutionTime': '0',
+    #                              'LockID': '1',
+    #                              'TicketNumber': '2010080210123456',
+    #                              'ArchiveFlag': 'n',
+    #                              'CreateTimeUnix': '1280750400',
+    #                              'Lock': 'unlock',
+    #                              'SLAID': '',
+    #                              'CustomerUser': 'root@localhost'}]},
+    #                  status=200,
+    #                  content_type='application/json')
+
+            # mock_username = 'correct_username'
+            # mock_password = 'correct_password'
+
+            # with patch('modules.pymisc.send_message_via_mail') as patched_send_message:
+            #     obj = pyotrs.PyOTRS(self.baseurl, self.webservice_name, mock_username,
+            # mock_password)
+
+
+""" TODOs
+
+Write tests for
+* _get_json_ticket_data with http request failing (e.g. due to wrong fqdn or proxy)
+* search_ticket(self, payload)
+* _search_json_ticket_data(self, url, payload):
+
+"""
+
+
+# Main
+def main():
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
+
+    # EOF
diff --git a/tests/test_pyotrs_responses.py b/tests/test_pyotrs_responses.py
new file mode 100644
index 0000000..ae3059b
--- /dev/null
+++ b/tests/test_pyotrs_responses.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals  # support both Python2 and 3
+#
+# Name:         test_pyotrs_responses.py
+# Description:  Test for pyotrs module
+#
+# Author:       robert.habermann@dlh.de
+# Date:         2015-07-14
+
+
+# make sure (early) that parent dir (main app) is in path
+import os.path
+import sys
+import unittest2 as unittest
+import responses
+
+current_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(current_path, os.pardir))
+
+from pyotrs import Client, Ticket  # noqa
+from pyotrs.lib import NoBaseURL, NoWebServiceName, NoCredentials  # noqa
+from pyotrs.lib import SessionCreateError, SessionIDFileError, OTRSAPIError, OTRSHTTPError  # 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")
+            print(obj.session_check_is_valid(session_id="tMtTFDg1PxCX51dWnjue4W5oQtNsFd0k"))
+            self.assertEqual(obj.response_type, 'Ticket')
+
+    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'})
+
+    """
+    def test_my_api_mocked(self):
+        with responses.RequestsMock() as rsps:
+            rsps.add(responses.GET,
+                     'http://localhost',
+                     body='{}',
+                     status=302,
+                     content_type='text/html')
+            rsps.add(responses.GET,
+                     'https://localhost',
+                     body='This is Sparta',
+                     status=200,
+                     content_type='text/html')
+            requests.get('http://localhost')
+            resp = requests.get('https://localhost')
+            print(resp.content)
+            # self.assertEqual(resp.status_code, 200)
+
+    def test_my_api_real(self):
+        # outside the context manager requests will hit the remote server
+        resp = requests.get('http://localhost')
+        self.assertEqual(resp.status_code, 200)
+
+    """
+
+
+# Main
+def main():
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
+
+    # EOF
diff --git a/tox.ini b/tox.ini
index d55f74c..81a0ec1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -28,6 +28,16 @@ commands =
     coverage erase
     rm -rf htmlcov
 
+[testenv:py26]
+whitelist_externals =
+    bash
+    mv
+
+commands =
+    bash -c "if [ ! -d .coverage.data ]; then mkdir .coverage.data; fi"
+    coverage run -a setup.py test
+    mv {toxinidir}/.coverage {toxinidir}/.coverage.data/.coverage.{envname}
+
 [testenv:py27]
 whitelist_externals =
     bash
@@ -48,6 +58,17 @@ commands =
     coverage run -a setup.py test
     mv {toxinidir}/.coverage {toxinidir}/.coverage.data/.coverage.{envname}
 
+[testenv:py35]
+whitelist_externals =
+    bash
+    mv
+
+commands =
+    bash -c "if [ ! -d .coverage.data ]; then mkdir .coverage.data; fi"
+    coverage run -a setup.py test
+    mv {toxinidir}/.coverage {toxinidir}/.coverage.data/.coverage.{envname}
+
+
 [testenv:cov_report]
 commands =
     coverage combine .coverage.data
@@ -81,7 +102,7 @@ basepython =
 commands =
     flake8 \
       --max-complexity=15 \
-      --exclude=./build,.venv,.tox,dist,docs,test_pyotrs.py,disabled_test_pyotrs.py \
+      --exclude=./build,.venv,.tox,dist,docs,test_pyotrs.py \
       --ignore=Q000 \
       --max-line-length=99 \
       []
-- 
GitLab