This file is indexed.

/usr/lib/python2.7/dist-packages/ubuntu-kylin-sso-client/ubuntu_kylin_sso/utils/webclient/tests/test_restful.py is in python-ubuntu-kylin-sso-client.tests 0.1.2.5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# -*- coding: utf-8 -*-
#
# Copyright 2011-2012 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT AN WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the
# OpenSSL library under certain conditions as described in each
# individual source file, and distribute linked combinations
# including the two.
# You must obey the GNU General Public License in all respects
# for all of the code used other than OpenSSL.  If you modify
# file(s) with this exception, you may extend this exception to your
# version of the file(s), but you are not obligated to do so.  If you
# do not wish to do so, delete this exception statement from your
# version.  If you delete this exception statement from all source
# files in the program, then also delete it here.
"""Tests for the proxy-enabled restful client."""

import logging

try:
    # pylint: disable=E0611,F0401
    from urllib.parse import urlparse, parse_qs, parse_qsl
    # pylint: enable=E0611,F0401
except ImportError:
    from urlparse import urlparse, parse_qs, parse_qsl

from twisted.internet import defer
from ubuntuone.devtools.handlers import MementoHandler
from ubuntuone.devtools.testcases import TestCase

from ubuntu_kylin_sso.utils.webclient import restful
from ubuntu_kylin_sso.utils.webclient.common import Response


SAMPLE_SERVICE_IRI = u"http://localhost/"
SAMPLE_NAMESPACE = u"sample_namespace"
SAMPLE_METHOD = u"sample_method"
SAMPLE_OPERATION = SAMPLE_NAMESPACE + u"." + SAMPLE_METHOD
SAMPLE_ARGS = dict(uno=1, dos=u"2", tres=u"ñandú")
SAMPLE_RESPONSE = restful.json.dumps(SAMPLE_ARGS)
SAMPLE_USERNAME = "joeuser@example.com"
SAMPLE_PASSWORD = "clavesecreta"
SAMPLE_OAUTH_CREDS = dict(token="1234", etc="456")


class FakeWebClient(object):
    """A fake web client."""

    def __init__(self, **kwargs):
        """Initialize this faker."""
        self.return_value = SAMPLE_RESPONSE
        self.called = []
        self.init_kwargs = kwargs
        self.running = True

    def request(self, iri, *args, **kwargs):
        """Return a deferred that will be fired with a Response object."""
        self.called.append((iri, args, kwargs))
        return defer.succeed(Response(self.return_value))

    def shutdown(self):
        """Stop this fake webclient."""
        self.running = False


class BaseTestCase(TestCase):
    """The base for the Restful Client testcases."""

    @defer.inlineCallbacks
    def setUp(self):
        """Initialize this test case."""
        yield super(BaseTestCase, self).setUp()
        self.wc = None
        self.patch(restful.webclient, "webclient_factory",
                   self.webclient_factory)

    def webclient_factory(self, **kwargs):
        """A factory that saves the webclient created."""
        self.wc = FakeWebClient(**kwargs)
        return self.wc


class RestfulClientTestCase(BaseTestCase):
    """Tests for the proxy-enabled Restful Client."""

    @defer.inlineCallbacks
    def setUp(self):
        """Initialize this testcase."""
        yield super(RestfulClientTestCase, self).setUp()
        self.rc = restful.RestfulClient(SAMPLE_SERVICE_IRI)
        self.addCleanup(self.rc.shutdown)

    def test_has_a_webclient(self):
        """The RC has a webclient."""
        self.assertEqual(self.rc.webclient, self.wc)

    def test_shutsdown_the_webclient(self):
        """Calling shutdown on the restful shuts down the webclient too."""
        self.rc.shutdown()
        # pylint: disable=E1101
        self.assertFalse(self.rc.webclient.running, "The webclient is stopped")

    @defer.inlineCallbacks
    def test_can_make_calls(self):
        """The RC can make webcalls."""
        yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)
        self.assertEqual(len(self.wc.called), 1)

    @defer.inlineCallbacks
    def test_restful_namespace_added_to_url(self):
        """The restful namespace is added to the url."""
        yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)
        iri, _, _ = self.wc.called[0]
        uri = iri.encode("ascii")
        url = urlparse(uri)
        # pylint: disable=E1101,E1103
        self.assertTrue(url.path.endswith(SAMPLE_NAMESPACE),
                        "The namespace is included in url")

    @defer.inlineCallbacks
    def test_restful_method_added_to_params(self):
        """The restful method is added to the params."""
        yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)
        _, _, webcall_kwargs = self.wc.called[0]
        wc_params = parse_qs(webcall_kwargs["post_content"])
        self.assertEqual(wc_params["ws.op"][0], SAMPLE_METHOD)

    @defer.inlineCallbacks
    def test_arguments_added_as_json_to_webcall(self):
        """The keyword arguments are used as json in the webcall."""
        yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)
        _, _, webcall_kwargs = self.wc.called[0]
        params = parse_qsl(webcall_kwargs["post_content"])
        result = {}
        for key, value in params:
            if key == "ws.op":
                continue
            result[key] = restful.json.loads(value)
        self.assertEqual(result, SAMPLE_ARGS)

    @defer.inlineCallbacks
    def test_post_header_sent(self):
        """A header is sent specifying the contents of the post."""
        yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)
        _, _, webcall_kwargs = self.wc.called[0]
        self.assertEqual(restful.POST_HEADERS,
                         webcall_kwargs["extra_headers"])

    @defer.inlineCallbacks
    def test_post_method_set(self):
        """The method of the webcall is set to POST."""
        yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)
        _, _, webcall_kwargs = self.wc.called[0]
        self.assertEqual("POST", webcall_kwargs["method"])

    @defer.inlineCallbacks
    def test_return_value_json_parsed(self):
        """The result is json parsed before being returned."""
        result = yield self.rc.restcall(SAMPLE_OPERATION)
        self.assertEqual(result, SAMPLE_ARGS)


class AuthenticationOptionsTestCase(BaseTestCase):
    """Tests for the authentication options."""

    def test_passes_userpass_to_webclient_init(self):
        """The RestfulClient passes the user and pass to the webclient."""
        params = dict(username=SAMPLE_USERNAME, password=SAMPLE_PASSWORD)
        restful.RestfulClient(SAMPLE_SERVICE_IRI, **params)
        expected = dict(params)
        expected["oauth_sign_plain"] = True
        self.assertEqual(self.wc.init_kwargs, expected)

    @defer.inlineCallbacks
    def test_passes_oauth_creds_to_request(self):
        """The RestfulClient passes the credentials in each request."""
        kwargs = dict(oauth_credentials=SAMPLE_OAUTH_CREDS)
        rc = restful.RestfulClient(SAMPLE_SERVICE_IRI, **kwargs)
        yield rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)
        _, _, kwargs = self.wc.called[0]
        self.assertEqual(kwargs["oauth_credentials"], SAMPLE_OAUTH_CREDS)


class LogginTestCase(BaseTestCase):
    """Ensure that proper debug logging is done."""

    @defer.inlineCallbacks
    def setUp(self):
        """Initialize this testcase."""
        yield super(LogginTestCase, self).setUp()
        self.memento = MementoHandler()
        restful.logger.addHandler(self.memento)
        restful.logger.setLevel(logging.DEBUG)
        self.addCleanup(restful.logger.removeHandler, self.memento)

        self.rc = restful.RestfulClient(SAMPLE_SERVICE_IRI)
        self.addCleanup(self.rc.shutdown)

    @defer.inlineCallbacks
    def test_log_rest_call(self):
        """Check that proper DEBUG is made for every REST call."""
        yield self.rc.restcall(SAMPLE_OPERATION, **SAMPLE_ARGS)

        expected_msgs = (
            SAMPLE_SERVICE_IRI + SAMPLE_NAMESPACE,
        )
        self.assertTrue(self.memento.check_debug(*expected_msgs))

    @defer.inlineCallbacks
    def test_log_json_loads_exception(self):
        """Check that json load errors are properly logged."""
        invalid_json = 'NOTAVALIDJSON'
        self.patch(self.wc, 'return_value', invalid_json)
        yield self.assertFailure(self.rc.restcall(SAMPLE_OPERATION),
                                 ValueError)

        self.memento.debug = True
        expected_msgs = (
            ValueError,
            'Can not load json from REST request response',
            invalid_json
        )
        self.assertTrue(self.memento.check_exception(*expected_msgs))