Skip to content

Commit

Permalink
ADD add_attachment() method to servicenow.py
Browse files Browse the repository at this point in the history
- Add add_attachment() method to servicenow.py.
- Update test_servicenow.py with add_attachment test cases.
- Update ServiceNow.rst with add_attachment example.
  • Loading branch information
mjagelka authored and dmranck committed Aug 8, 2018
1 parent 2498515 commit 4149d32
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
15 changes: 14 additions & 1 deletion read-the-docs/source/ServiceNow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Methods
- `add_cc() <#add_cc>`__
- `rewrite_cc() <#rewrite_cc>`__
- `remove_cc() <#remove_cc>`__
- `add_attachment() <#add_attachment>`__

set_ticket_id()
---------------
Expand Down Expand Up @@ -198,6 +199,18 @@ representing one email address.
t = ticket.remove_cc(['username@domain.com', 'user3@domain.com'])
add_attachment()
----------------

``add_attachment(self, file_name, name=None)``

Attaches the file to existing ServiceNow ticket. Required parameter is
file_name. If name is specified, it is used to rename the saved file.

.. code:: python
t = ticket.add_attachment('scan01234.jpg', 'scan.jpg')
Examples
^^^^^^^^
Expand Down Expand Up @@ -261,6 +274,7 @@ Create new ServiceNow ticket
t = ticket.add_cc(['username1@mail.com', 'username2@mail.com'])
t = ticket.remove_cc('username1@mail.com')
t = ticket.change_status('Work in Progress')
t = ticket.add_attachment('scan01234.jpg', 'scan.jpg')
# Retrieve ticket content
t = ticket.get_ticket_content()
Expand Down Expand Up @@ -290,4 +304,3 @@ Update existing ServiceNow tickets
# Close Requests session
ticket.close_requests_session()
41 changes: 41 additions & 0 deletions tests/test_servicenow.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,5 +316,46 @@ def test_remove_cc_unexpected_response(self, mock_session):
t = ticket.remove_cc(['dranck@redhat.com', 'mail@redhat.com'])
self.assertEqual(t.status, MOCK_RETURN_FAILURE.status)

@patch.object(servicenow.ServiceNowTicket, '_create_requests_session')
@patch('servicenow.ServiceNowTicket._verify_project', mock_verify_project)
@patch('servicenow.ServiceNowTicket.get_ticket_content', mock_get_ticket_content)
def test_add_attachment_no_ticket_id(self, mock_session):
mock_session.return_value = FakeSession()
ticket = servicenow.ServiceNowTicket(TEST_URL, TABLE)
t = ticket.add_attachment('file_name')
error_message = 'No ticket ID associated with ticket object. Set ticket ID with set_ticket_id(<ticket_id>)'
self.assertEqual(t.error_message, error_message)

@patch.object(servicenow.ServiceNowTicket, '_create_requests_session')
@patch('servicenow.ServiceNowTicket._verify_project', mock_verify_project)
@patch('servicenow.ServiceNowTicket.get_ticket_content', mock_get_ticket_content)
def test_add_attachment_ioerror(self, mock_session):
mock_session.return_value = FakeSession()
ticket = servicenow.ServiceNowTicket(TEST_URL, TABLE, ticket_id=TICKET_ID)
t = ticket.add_attachment('file_name')
error_message = 'File file_name not found'
self.assertEqual(t.error_message, error_message)

@patch('builtins.open')
@patch.object(servicenow.ServiceNowTicket, '_create_requests_session')
@patch('servicenow.ServiceNowTicket._verify_project', mock_verify_project)
@patch('servicenow.ServiceNowTicket.get_ticket_content', mock_get_ticket_content)
def test_add_attachment_unexpected_response(self, mock_session, mock_open):
mock_session.return_value = FakeSession(status_code=404)
ticket = servicenow.ServiceNowTicket(TEST_URL, TABLE, ticket_id=TICKET_ID)
t = ticket.add_attachment('file_name')
self.assertEqual(t.error_message, '')

@patch('builtins.open')
@patch.object(servicenow.ServiceNowTicket, '_create_requests_session')
@patch('servicenow.ServiceNowTicket._verify_project', mock_verify_project)
@patch('servicenow.ServiceNowTicket.get_ticket_content', mock_get_ticket_content)
def test_add_attachment(self, mock_session, mock_open):
mock_session.return_value = FakeSession()
ticket = servicenow.ServiceNowTicket(TEST_URL, TABLE, ticket_id=TICKET_ID)
t = ticket.add_attachment('file_name')
self.assertEqual(t.status, 'Success')


if __name__ == '__main__':
main()
34 changes: 34 additions & 0 deletions ticketutil/servicenow.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,40 @@ def remove_cc(self, user):
self.request_result = self.request_result._replace(ticket_content=self.ticket_content)
return self.request_result

def add_attachment(self, file_name, name=None):
"""
Attaches a file to a ServiceNow ticket.
:param file_name: A string representing the file to attach.
:param name: A string representing the name under which the file is attached.
:return: self.request_result: Named tuple containing request status, error_message, and url info.
"""
if not self.ticket_id:
error_message = "No ticket ID associated with ticket object. Set ticket ID with set_ticket_id(<ticket_id>)"
logger.error(error_message)
return self.request_result._replace(status='Failure', error_message=error_message)

if not name:
name = file_name

url = '{}/api/now/attachment/file?table_name={}&table_sys_id={}&file_name={}'.format(self.url, self.project,
self.sys_id, name)
try:
with open(file_name, 'rb') as f:
data = f.read()
r = self.s.post(url, data=data)
logger.debug("Add attachment: status code: {0}".format(r.status_code))
r.raise_for_status()
logger.info("Attached file {0} to ticket {1} - {2}".format(file_name, self.ticket_id, self.ticket_url))
return self.request_result
except requests.RequestException as e:
logger.error("Error attaching file {0}".format(file_name))
logger.error(e)
return self.request_result._replace(status='Failure', error_message=str(e))
except IOError:
error_message = "File {0} not found".format(file_name)
logger.error(error_message)
return self.request_result._replace(status='Failure', error_message=error_message)


def _prepare_ticket_fields(fields):
"""
Expand Down

0 comments on commit 4149d32

Please sign in to comment.