-
Notifications
You must be signed in to change notification settings - Fork 21
/
test.py
125 lines (95 loc) · 4.25 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Utilities to run tests around `pydocusign`."""
import json
import os
import requests
import pydocusign
def fixtures_dir():
"""Return absolute path to `pydocusign`'s fixtures dir, as best guess.
This function supports two situations:
* you use it in code repository's root, i.e. ``fixtures/`` folder is in the
same folder than ``pydocusign/test.py``.
* `tox` runs the documentation build, i.e. ``fixtures/`` folder is in the
code repository's root, whereas ``pydocusign/test.py`` lives somewhere in
``.tox/``.
Other situations are not supported at the moment.
"""
here = os.path.dirname(os.path.abspath(__file__))
here_parts = here.split(os.path.sep)
is_tox = '.tox' in here_parts
if is_tox:
tox_index = here_parts.index('.tox')
project_dir = here
for i in range(len(here_parts) - tox_index):
project_dir = os.path.dirname(project_dir)
else:
project_dir = os.path.dirname(here)
return os.path.normpath(os.path.join(project_dir, 'fixtures'))
def docusign_client_factory(settings=os.environ, **kwargs):
"""Return :class:`pydocusign.DocuSignClient` using ``settings``.
The following keys are used in ``settings``:
* ``PYDOCUSIGN_TEST_ROOT_URL``, defaults to
'https://demo.docusign.net/restapi/v2'
* ``PYDOCUSIGN_TEST_USERNAME``
* ``PYDOCUSIGN_TEST_PASSWORD``
* ``PYDOCUSIGN_TEST_INTEGRATOR_KEY``
By default, ``settings`` is ``os.environ``, i.e. environment variables are
used.
Additional keyword arguments override settings and are proxied to
:class:`pydocusign.DocuSignClient` constructor.
"""
options = {
'root_url': settings.get('PYDOCUSIGN_TEST_ROOT_URL',
'https://demo.docusign.net/restapi/v2'),
'username': settings.get('PYDOCUSIGN_TEST_USERNAME'),
'password': settings.get('PYDOCUSIGN_TEST_PASSWORD'),
'integrator_key': settings.get('PYDOCUSIGN_TEST_INTEGRATOR_KEY'),
}
options.update(kwargs)
client = pydocusign.DocuSignClient(**options)
return client
def generate_notification_callback_body(
data,
template_url='https://diecutter.alwaysdata.net/github/novapost/'
'pydocusign/master/pydocusign/templates/callback.xml'):
"""Return custom body content to mimic DocuSign notification callbacks.
Body content is generated from template, using diecutter web service.
``data`` argument is a dictionary of data you expect in the callback.
``template_url`` is diecutter's template resource URL, which is typically
in the form
https://diecutter.alwaysdata.net/github/{owner}/{project}/{revision}/{path}
Raise exception if a problem occurs during content generation.
"""
payload = json.dumps(data)
headers = {'content-type': 'application/json'}
try:
response = requests.post(template_url, data=payload, headers=headers)
except requests.exceptions.RequestException as exception:
raise Exception(
'Error while generating notification callback body using '
'template generation service at URL {url} with data {data}. '
'Exception is {exception}.'
.format(url=template_url,
data=json.dumps(data),
exception=exception)
)
if response.status_code != 200:
raise Exception(
'Error while generating notification callback body using '
'template generation service at URL {url} with data {data}. '
'Response code {status}, body:\n{body}.'
.format(url=template_url,
data=json.dumps(data),
status=response.status_code,
body=response.text)
)
return response.text
def post_notification_callback(callback_url, data, template_url=None):
"""Post fake notification callback to ``callback_url``, return response.
Additional arguments: ``data`` and ``template_url``. See
:func:`generate_notification_callback_body`.
"""
body = generate_notification_callback_body(data, template_url)
# POST body to callback URL.
headers = {'content-type': 'text/xml'}
response = requests.post(callback_url, data=body, headers=headers)
return response