Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / tests / api.py @ 5f28aa14

History | View | Annotate | Download (23.9 kB)

1 bd1f667b Giorgos Korfiatis
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2 1ac3349d Kostas Papadimitriou
#
3 1ac3349d Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 1ac3349d Kostas Papadimitriou
# without modification, are permitted provided that the following
5 1ac3349d Kostas Papadimitriou
# conditions are met:
6 1ac3349d Kostas Papadimitriou
#
7 1ac3349d Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 1ac3349d Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 1ac3349d Kostas Papadimitriou
#      disclaimer.
10 1ac3349d Kostas Papadimitriou
#
11 1ac3349d Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 1ac3349d Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 1ac3349d Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 1ac3349d Kostas Papadimitriou
#      provided with the distribution.
15 1ac3349d Kostas Papadimitriou
#
16 1ac3349d Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 1ac3349d Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 1ac3349d Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1ac3349d Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 1ac3349d Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 1ac3349d Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 1ac3349d Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 1ac3349d Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 1ac3349d Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1ac3349d Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 1ac3349d Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 1ac3349d Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 1ac3349d Kostas Papadimitriou
#
29 1ac3349d Kostas Papadimitriou
# The views and conclusions contained in the software and
30 1ac3349d Kostas Papadimitriou
# documentation are those of the authors and should not be
31 1ac3349d Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 1ac3349d Kostas Papadimitriou
# or implied, of GRNET S.A.
33 1ac3349d Kostas Papadimitriou
34 1ac3349d Kostas Papadimitriou
from astakos.im.tests.common import *
35 7ac2131c Sofia Papagiannaki
36 baa9073a Kostas Papadimitriou
from django.test import TestCase
37 1ac3349d Kostas Papadimitriou
38 7ac2131c Sofia Papagiannaki
from urllib import quote
39 7ac2131c Sofia Papagiannaki
from urlparse import urlparse, parse_qs
40 f870efe2 Sofia Papagiannaki
from xml.dom import minidom
41 7ac2131c Sofia Papagiannaki
42 7ac2131c Sofia Papagiannaki
import json
43 7ac2131c Sofia Papagiannaki
44 1ac3349d Kostas Papadimitriou
ROOT = '/astakos/api/'
45 1ac3349d Kostas Papadimitriou
u = lambda url: ROOT + url
46 1ac3349d Kostas Papadimitriou
47 1ac3349d Kostas Papadimitriou
48 1ac3349d Kostas Papadimitriou
class QuotaAPITest(TestCase):
49 1ac3349d Kostas Papadimitriou
    def test_0(self):
50 1ac3349d Kostas Papadimitriou
        client = Client()
51 bd1f667b Giorgos Korfiatis
52 bd1f667b Giorgos Korfiatis
        component1 = Component.objects.create(name="comp1")
53 bd1f667b Giorgos Korfiatis
        register.add_service(component1, "service1", "type1", [])
54 1ac3349d Kostas Papadimitriou
        # custom service resources
55 1ac3349d Kostas Papadimitriou
        resource11 = {"name": "service1.resource11",
56 1ac3349d Kostas Papadimitriou
                      "desc": "resource11 desc",
57 bd1f667b Giorgos Korfiatis
                      "service_type": "type1",
58 1ac3349d Kostas Papadimitriou
                      "allow_in_projects": True}
59 bd1f667b Giorgos Korfiatis
        r, _ = register.add_resource(resource11)
60 bd1f667b Giorgos Korfiatis
        register.update_resource(r, 100)
61 1ac3349d Kostas Papadimitriou
        resource12 = {"name": "service1.resource12",
62 1ac3349d Kostas Papadimitriou
                      "desc": "resource11 desc",
63 bd1f667b Giorgos Korfiatis
                      "service_type": "type1",
64 1ac3349d Kostas Papadimitriou
                      "unit": "bytes"}
65 bd1f667b Giorgos Korfiatis
        r, _ = register.add_resource(resource12)
66 bd1f667b Giorgos Korfiatis
        register.update_resource(r, 1024)
67 1ac3349d Kostas Papadimitriou
68 1ac3349d Kostas Papadimitriou
        # create user
69 1ac3349d Kostas Papadimitriou
        user = get_local_user('test@grnet.gr')
70 1ac3349d Kostas Papadimitriou
        quotas.qh_sync_user(user)
71 1ac3349d Kostas Papadimitriou
72 bd1f667b Giorgos Korfiatis
        component2 = Component.objects.create(name="comp2")
73 bd1f667b Giorgos Korfiatis
        register.add_service(component2, "service2", "type2", [])
74 1ac3349d Kostas Papadimitriou
        # create another service
75 1ac3349d Kostas Papadimitriou
        resource21 = {"name": "service2.resource21",
76 1ac3349d Kostas Papadimitriou
                      "desc": "resource11 desc",
77 bd1f667b Giorgos Korfiatis
                      "service_type": "type2",
78 1ac3349d Kostas Papadimitriou
                      "allow_in_projects": False}
79 bd1f667b Giorgos Korfiatis
        r, _ = register.add_resource(resource21)
80 bd1f667b Giorgos Korfiatis
        register.update_resource(r, 3)
81 1ac3349d Kostas Papadimitriou
82 1ac3349d Kostas Papadimitriou
        resource_names = [r['name'] for r in
83 1ac3349d Kostas Papadimitriou
                          [resource11, resource12, resource21]]
84 1ac3349d Kostas Papadimitriou
85 1ac3349d Kostas Papadimitriou
        # get resources
86 1ac3349d Kostas Papadimitriou
        r = client.get(u('resources'))
87 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
88 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
89 1ac3349d Kostas Papadimitriou
        for name in resource_names:
90 1ac3349d Kostas Papadimitriou
            assertIn(name, body)
91 1ac3349d Kostas Papadimitriou
92 1ac3349d Kostas Papadimitriou
        # get quota
93 1ac3349d Kostas Papadimitriou
        r = client.get(u('quotas'))
94 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 401)
95 1ac3349d Kostas Papadimitriou
96 1ac3349d Kostas Papadimitriou
        headers = {'HTTP_X_AUTH_TOKEN': user.auth_token}
97 1ac3349d Kostas Papadimitriou
        r = client.get(u('quotas/'), **headers)
98 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
99 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
100 1ac3349d Kostas Papadimitriou
        system_quota = body['system']
101 1ac3349d Kostas Papadimitriou
        assertIn('system', body)
102 1ac3349d Kostas Papadimitriou
        for name in resource_names:
103 1ac3349d Kostas Papadimitriou
            assertIn(name, system_quota)
104 1ac3349d Kostas Papadimitriou
105 1ac3349d Kostas Papadimitriou
        r = client.get(u('service_quotas'))
106 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 401)
107 1ac3349d Kostas Papadimitriou
108 bd1f667b Giorgos Korfiatis
        s1_headers = {'HTTP_X_AUTH_TOKEN': component1.auth_token}
109 1ac3349d Kostas Papadimitriou
        r = client.get(u('service_quotas'), **s1_headers)
110 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
111 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
112 1ac3349d Kostas Papadimitriou
        assertIn(user.uuid, body)
113 1ac3349d Kostas Papadimitriou
114 1ac3349d Kostas Papadimitriou
        r = client.get(u('commissions'), **s1_headers)
115 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
116 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
117 1ac3349d Kostas Papadimitriou
        self.assertEqual(body, [])
118 1ac3349d Kostas Papadimitriou
119 1ac3349d Kostas Papadimitriou
        # issue some commissions
120 1ac3349d Kostas Papadimitriou
        commission_request = {
121 1ac3349d Kostas Papadimitriou
            "force": False,
122 1ac3349d Kostas Papadimitriou
            "auto_accept": False,
123 1ac3349d Kostas Papadimitriou
            "name": "my commission",
124 1ac3349d Kostas Papadimitriou
            "provisions": [
125 1ac3349d Kostas Papadimitriou
                {
126 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
127 1ac3349d Kostas Papadimitriou
                    "source": "system",
128 1ac3349d Kostas Papadimitriou
                    "resource": resource11['name'],
129 1ac3349d Kostas Papadimitriou
                    "quantity": 1
130 1ac3349d Kostas Papadimitriou
                },
131 1ac3349d Kostas Papadimitriou
                {
132 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
133 1ac3349d Kostas Papadimitriou
                    "source": "system",
134 1ac3349d Kostas Papadimitriou
                    "resource": resource12['name'],
135 1ac3349d Kostas Papadimitriou
                    "quantity": 30000
136 1ac3349d Kostas Papadimitriou
                }]}
137 1ac3349d Kostas Papadimitriou
138 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
139 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
140 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
141 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 413)
142 1ac3349d Kostas Papadimitriou
143 1ac3349d Kostas Papadimitriou
        commission_request = {
144 1ac3349d Kostas Papadimitriou
            "force": False,
145 1ac3349d Kostas Papadimitriou
            "auto_accept": False,
146 1ac3349d Kostas Papadimitriou
            "name": "my commission",
147 1ac3349d Kostas Papadimitriou
            "provisions": [
148 1ac3349d Kostas Papadimitriou
                {
149 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
150 1ac3349d Kostas Papadimitriou
                    "source": "system",
151 1ac3349d Kostas Papadimitriou
                    "resource": resource11['name'],
152 1ac3349d Kostas Papadimitriou
                    "quantity": 1
153 1ac3349d Kostas Papadimitriou
                },
154 1ac3349d Kostas Papadimitriou
                {
155 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
156 1ac3349d Kostas Papadimitriou
                    "source": "system",
157 1ac3349d Kostas Papadimitriou
                    "resource": resource12['name'],
158 1ac3349d Kostas Papadimitriou
                    "quantity": 100
159 1ac3349d Kostas Papadimitriou
                }]}
160 1ac3349d Kostas Papadimitriou
161 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
162 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
163 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
164 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 201)
165 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
166 1ac3349d Kostas Papadimitriou
        serial = body['serial']
167 1ac3349d Kostas Papadimitriou
        self.assertEqual(serial, 1)
168 1ac3349d Kostas Papadimitriou
169 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
170 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
171 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
172 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 201)
173 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
174 1ac3349d Kostas Papadimitriou
        self.assertEqual(body['serial'], 2)
175 1ac3349d Kostas Papadimitriou
176 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
177 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
178 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
179 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 201)
180 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
181 1ac3349d Kostas Papadimitriou
        self.assertEqual(body['serial'], 3)
182 1ac3349d Kostas Papadimitriou
183 1ac3349d Kostas Papadimitriou
        r = client.get(u('commissions'), **s1_headers)
184 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
185 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
186 1ac3349d Kostas Papadimitriou
        self.assertEqual(body, [1, 2, 3])
187 1ac3349d Kostas Papadimitriou
188 1ac3349d Kostas Papadimitriou
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
189 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
190 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
191 1ac3349d Kostas Papadimitriou
        self.assertEqual(body['serial'], serial)
192 1ac3349d Kostas Papadimitriou
        assertIn('issue_time', body)
193 1ac3349d Kostas Papadimitriou
        self.assertEqual(body['provisions'], commission_request['provisions'])
194 1ac3349d Kostas Papadimitriou
        self.assertEqual(body['name'], commission_request['name'])
195 1ac3349d Kostas Papadimitriou
196 1ac3349d Kostas Papadimitriou
        r = client.get(u('service_quotas?user=' + user.uuid), **s1_headers)
197 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
198 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
199 1ac3349d Kostas Papadimitriou
        user_quota = body[user.uuid]
200 1ac3349d Kostas Papadimitriou
        system_quota = user_quota['system']
201 1ac3349d Kostas Papadimitriou
        r11 = system_quota[resource11['name']]
202 1ac3349d Kostas Papadimitriou
        self.assertEqual(r11['usage'], 3)
203 1ac3349d Kostas Papadimitriou
        self.assertEqual(r11['pending'], 3)
204 1ac3349d Kostas Papadimitriou
205 1ac3349d Kostas Papadimitriou
        # resolve pending commissions
206 1ac3349d Kostas Papadimitriou
        resolve_data = {
207 1ac3349d Kostas Papadimitriou
            "accept": [1, 3],
208 1ac3349d Kostas Papadimitriou
            "reject": [2, 3, 4],
209 1ac3349d Kostas Papadimitriou
        }
210 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(resolve_data)
211 1ac3349d Kostas Papadimitriou
212 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions/action'), post_data,
213 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
214 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
215 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
216 1ac3349d Kostas Papadimitriou
        self.assertEqual(body['accepted'], [1])
217 1ac3349d Kostas Papadimitriou
        self.assertEqual(body['rejected'], [2])
218 1ac3349d Kostas Papadimitriou
        failed = body['failed']
219 1ac3349d Kostas Papadimitriou
        self.assertEqual(len(failed), 2)
220 1ac3349d Kostas Papadimitriou
221 1ac3349d Kostas Papadimitriou
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
222 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
223 1ac3349d Kostas Papadimitriou
224 1ac3349d Kostas Papadimitriou
        # auto accept
225 1ac3349d Kostas Papadimitriou
        commission_request = {
226 1ac3349d Kostas Papadimitriou
            "auto_accept": True,
227 1ac3349d Kostas Papadimitriou
            "name": "my commission",
228 1ac3349d Kostas Papadimitriou
            "provisions": [
229 1ac3349d Kostas Papadimitriou
                {
230 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
231 1ac3349d Kostas Papadimitriou
                    "source": "system",
232 1ac3349d Kostas Papadimitriou
                    "resource": resource11['name'],
233 1ac3349d Kostas Papadimitriou
                    "quantity": 1
234 1ac3349d Kostas Papadimitriou
                },
235 1ac3349d Kostas Papadimitriou
                {
236 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
237 1ac3349d Kostas Papadimitriou
                    "source": "system",
238 1ac3349d Kostas Papadimitriou
                    "resource": resource12['name'],
239 1ac3349d Kostas Papadimitriou
                    "quantity": 100
240 1ac3349d Kostas Papadimitriou
                }]}
241 1ac3349d Kostas Papadimitriou
242 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
243 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
244 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
245 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 201)
246 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
247 1ac3349d Kostas Papadimitriou
        serial = body['serial']
248 1ac3349d Kostas Papadimitriou
        self.assertEqual(serial, 4)
249 1ac3349d Kostas Papadimitriou
250 1ac3349d Kostas Papadimitriou
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
251 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
252 1ac3349d Kostas Papadimitriou
253 1ac3349d Kostas Papadimitriou
        # malformed
254 1ac3349d Kostas Papadimitriou
        commission_request = {
255 1ac3349d Kostas Papadimitriou
            "auto_accept": True,
256 1ac3349d Kostas Papadimitriou
            "name": "my commission",
257 1ac3349d Kostas Papadimitriou
            "provisions": [
258 1ac3349d Kostas Papadimitriou
                {
259 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
260 1ac3349d Kostas Papadimitriou
                    "source": "system",
261 1ac3349d Kostas Papadimitriou
                    "resource": resource11['name'],
262 1ac3349d Kostas Papadimitriou
                }
263 1ac3349d Kostas Papadimitriou
            ]}
264 1ac3349d Kostas Papadimitriou
265 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
266 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
267 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
268 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 400)
269 1ac3349d Kostas Papadimitriou
270 1ac3349d Kostas Papadimitriou
        commission_request = {
271 1ac3349d Kostas Papadimitriou
            "auto_accept": True,
272 1ac3349d Kostas Papadimitriou
            "name": "my commission",
273 1ac3349d Kostas Papadimitriou
            "provisions": "dummy"}
274 1ac3349d Kostas Papadimitriou
275 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
276 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
277 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
278 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 400)
279 1ac3349d Kostas Papadimitriou
280 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), commission_request,
281 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
282 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 400)
283 1ac3349d Kostas Papadimitriou
284 1ac3349d Kostas Papadimitriou
        # no holding
285 1ac3349d Kostas Papadimitriou
        commission_request = {
286 1ac3349d Kostas Papadimitriou
            "auto_accept": True,
287 1ac3349d Kostas Papadimitriou
            "name": "my commission",
288 1ac3349d Kostas Papadimitriou
            "provisions": [
289 1ac3349d Kostas Papadimitriou
                {
290 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
291 1ac3349d Kostas Papadimitriou
                    "source": "system",
292 1ac3349d Kostas Papadimitriou
                    "resource": "non existent",
293 1ac3349d Kostas Papadimitriou
                    "quantity": 1
294 1ac3349d Kostas Papadimitriou
                },
295 1ac3349d Kostas Papadimitriou
                {
296 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
297 1ac3349d Kostas Papadimitriou
                    "source": "system",
298 1ac3349d Kostas Papadimitriou
                    "resource": resource12['name'],
299 1ac3349d Kostas Papadimitriou
                    "quantity": 100
300 1ac3349d Kostas Papadimitriou
                }]}
301 1ac3349d Kostas Papadimitriou
302 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
303 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
304 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
305 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
306 1ac3349d Kostas Papadimitriou
307 1ac3349d Kostas Papadimitriou
        # release
308 1ac3349d Kostas Papadimitriou
        commission_request = {
309 1ac3349d Kostas Papadimitriou
            "provisions": [
310 1ac3349d Kostas Papadimitriou
                {
311 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
312 1ac3349d Kostas Papadimitriou
                    "source": "system",
313 1ac3349d Kostas Papadimitriou
                    "resource": resource11['name'],
314 1ac3349d Kostas Papadimitriou
                    "quantity": -1
315 1ac3349d Kostas Papadimitriou
                }
316 1ac3349d Kostas Papadimitriou
            ]}
317 1ac3349d Kostas Papadimitriou
318 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
319 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
320 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
321 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 201)
322 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
323 1ac3349d Kostas Papadimitriou
        serial = body['serial']
324 1ac3349d Kostas Papadimitriou
325 1ac3349d Kostas Papadimitriou
        accept_data = {'accept': ""}
326 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(accept_data)
327 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
328 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
329 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
330 1ac3349d Kostas Papadimitriou
331 1ac3349d Kostas Papadimitriou
        reject_data = {'reject': ""}
332 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(accept_data)
333 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
334 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
335 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
336 1ac3349d Kostas Papadimitriou
337 1ac3349d Kostas Papadimitriou
        # force
338 1ac3349d Kostas Papadimitriou
        commission_request = {
339 1ac3349d Kostas Papadimitriou
            "force": True,
340 1ac3349d Kostas Papadimitriou
            "provisions": [
341 1ac3349d Kostas Papadimitriou
                {
342 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
343 1ac3349d Kostas Papadimitriou
                    "source": "system",
344 1ac3349d Kostas Papadimitriou
                    "resource": resource11['name'],
345 1ac3349d Kostas Papadimitriou
                    "quantity": 100
346 1ac3349d Kostas Papadimitriou
                }]}
347 1ac3349d Kostas Papadimitriou
348 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
349 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
350 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
351 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 201)
352 1ac3349d Kostas Papadimitriou
353 1ac3349d Kostas Papadimitriou
        commission_request = {
354 1ac3349d Kostas Papadimitriou
            "force": True,
355 1ac3349d Kostas Papadimitriou
            "provisions": [
356 1ac3349d Kostas Papadimitriou
                {
357 1ac3349d Kostas Papadimitriou
                    "holder": user.uuid,
358 1ac3349d Kostas Papadimitriou
                    "source": "system",
359 1ac3349d Kostas Papadimitriou
                    "resource": resource11['name'],
360 1ac3349d Kostas Papadimitriou
                    "quantity": -200
361 1ac3349d Kostas Papadimitriou
                }]}
362 1ac3349d Kostas Papadimitriou
363 1ac3349d Kostas Papadimitriou
        post_data = json.dumps(commission_request)
364 1ac3349d Kostas Papadimitriou
        r = client.post(u('commissions'), post_data,
365 1ac3349d Kostas Papadimitriou
                        content_type='application/json', **s1_headers)
366 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 413)
367 1ac3349d Kostas Papadimitriou
368 1ac3349d Kostas Papadimitriou
        r = client.get(u('quotas'), **headers)
369 1ac3349d Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
370 1ac3349d Kostas Papadimitriou
        body = json.loads(r.content)
371 1ac3349d Kostas Papadimitriou
        system_quota = body['system']
372 1ac3349d Kostas Papadimitriou
        r11 = system_quota[resource11['name']]
373 1ac3349d Kostas Papadimitriou
        self.assertEqual(r11['usage'], 102)
374 1ac3349d Kostas Papadimitriou
        self.assertEqual(r11['pending'], 101)
375 7ac2131c Sofia Papagiannaki
376 7ac2131c Sofia Papagiannaki
377 7ac2131c Sofia Papagiannaki
class TokensApiTest(TestCase):
378 7ac2131c Sofia Papagiannaki
    def setUp(self):
379 ab7ca50a Sofia Papagiannaki
        backend = activation_backends.get_backend()
380 ab7ca50a Sofia Papagiannaki
381 ab7ca50a Sofia Papagiannaki
        self.user1 = AstakosUser.objects.create(
382 ab7ca50a Sofia Papagiannaki
            email='test1', email_verified=True, moderated=True,
383 ab7ca50a Sofia Papagiannaki
            is_rejected=False)
384 ab7ca50a Sofia Papagiannaki
        backend.activate_user(self.user1)
385 ab7ca50a Sofia Papagiannaki
        assert self.user1.is_active is True
386 ab7ca50a Sofia Papagiannaki
387 ab7ca50a Sofia Papagiannaki
        self.user2 = AstakosUser.objects.create(
388 ab7ca50a Sofia Papagiannaki
            email='test2', email_verified=True, moderated=True,
389 ab7ca50a Sofia Papagiannaki
            is_rejected=False)
390 ab7ca50a Sofia Papagiannaki
        backend.activate_user(self.user2)
391 ab7ca50a Sofia Papagiannaki
        assert self.user2.is_active is True
392 7ac2131c Sofia Papagiannaki
393 7ac2131c Sofia Papagiannaki
        Service(name='service1', url='http://localhost/service1',
394 f870efe2 Sofia Papagiannaki
                api_url='http://localhost/api/service1',
395 f870efe2 Sofia Papagiannaki
                type='service1').save()
396 7ac2131c Sofia Papagiannaki
        Service(name='service2', url='http://localhost/service2',
397 f870efe2 Sofia Papagiannaki
                api_url='http://localhost/api/service2',
398 f870efe2 Sofia Papagiannaki
                type='service2').save()
399 7ac2131c Sofia Papagiannaki
        Service(name='service3', url='http://localhost/service3',
400 f870efe2 Sofia Papagiannaki
                api_url='http://localhost/api/service3',
401 f870efe2 Sofia Papagiannaki
                type='service3').save()
402 7ac2131c Sofia Papagiannaki
403 f870efe2 Sofia Papagiannaki
    def test_authenticate(self):
404 7ac2131c Sofia Papagiannaki
        client = Client()
405 7ac2131c Sofia Papagiannaki
406 f870efe2 Sofia Papagiannaki
        # Check not allowed method
407 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
408 f870efe2 Sofia Papagiannaki
        r = client.get(url, post_data={})
409 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
410 f870efe2 Sofia Papagiannaki
411 f870efe2 Sofia Papagiannaki
        # Malformed request
412 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
413 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data={})
414 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
415 f870efe2 Sofia Papagiannaki
416 f870efe2 Sofia Papagiannaki
        # Check unsupported xml input
417 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
418 f870efe2 Sofia Papagiannaki
        post_data = """
419 f870efe2 Sofia Papagiannaki
            <?xml version="1.0" encoding="UTF-8"?>
420 f870efe2 Sofia Papagiannaki
                <auth xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
421 f870efe2 Sofia Papagiannaki
                 xmlns="http://docs.openstack.org/identity/api/v2.0"
422 f870efe2 Sofia Papagiannaki
                 tenantName="%s">
423 f870efe2 Sofia Papagiannaki
                  <passwordCredentials username="%s" password="%s"/>
424 f870efe2 Sofia Papagiannaki
                </auth>""" % (self.user1.uuid, self.user1.uuid,
425 f870efe2 Sofia Papagiannaki
                              self.user1.auth_token)
426 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/xml')
427 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
428 f870efe2 Sofia Papagiannaki
        body = json.loads(r.content)
429 f870efe2 Sofia Papagiannaki
        self.assertEqual(body['badRequest']['message'],
430 f870efe2 Sofia Papagiannaki
                         "Unsupported Content-type: 'application/xml'")
431 f870efe2 Sofia Papagiannaki
432 f870efe2 Sofia Papagiannaki
        # Check malformed request: missing password
433 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
434 f870efe2 Sofia Papagiannaki
        post_data = """{"auth":{"passwordCredentials":{"username":"%s"},
435 f870efe2 Sofia Papagiannaki
                                "tenantName":"%s"}}""" % (
436 f870efe2 Sofia Papagiannaki
            self.user1.uuid, self.user1.uuid)
437 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/json')
438 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
439 f870efe2 Sofia Papagiannaki
        body = json.loads(r.content)
440 f870efe2 Sofia Papagiannaki
        self.assertEqual(body['badRequest']['message'],
441 f870efe2 Sofia Papagiannaki
                         'Malformed request')
442 f870efe2 Sofia Papagiannaki
443 f870efe2 Sofia Papagiannaki
        # Check malformed request: missing username
444 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
445 f870efe2 Sofia Papagiannaki
        post_data = """{"auth":{"passwordCredentials":{"password":"%s"},
446 f870efe2 Sofia Papagiannaki
                                "tenantName":"%s"}}""" % (
447 f870efe2 Sofia Papagiannaki
            self.user1.auth_token, self.user1.uuid)
448 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/json')
449 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
450 f870efe2 Sofia Papagiannaki
        body = json.loads(r.content)
451 f870efe2 Sofia Papagiannaki
        self.assertEqual(body['badRequest']['message'],
452 f870efe2 Sofia Papagiannaki
                         'Malformed request')
453 f870efe2 Sofia Papagiannaki
454 f870efe2 Sofia Papagiannaki
        # Check invalid pass
455 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
456 f870efe2 Sofia Papagiannaki
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
457 f870efe2 Sofia Papagiannaki
                                                       "password":"%s"},
458 f870efe2 Sofia Papagiannaki
                                "tenantName":"%s"}}""" % (
459 f870efe2 Sofia Papagiannaki
            self.user1.uuid, '', self.user1.uuid)
460 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/json')
461 7ac2131c Sofia Papagiannaki
        self.assertEqual(r.status_code, 401)
462 f870efe2 Sofia Papagiannaki
        body = json.loads(r.content)
463 f870efe2 Sofia Papagiannaki
        self.assertEqual(body['unauthorized']['message'],
464 f870efe2 Sofia Papagiannaki
                         'Invalid token')
465 f870efe2 Sofia Papagiannaki
466 f870efe2 Sofia Papagiannaki
        # Check inconsistent pass
467 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
468 f870efe2 Sofia Papagiannaki
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
469 f870efe2 Sofia Papagiannaki
                                                       "password":"%s"},
470 f870efe2 Sofia Papagiannaki
                                "tenantName":"%s"}}""" % (
471 49005665 Sofia Papagiannaki
            self.user1.uuid, self.user2.auth_token, self.user2.uuid)
472 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/json')
473 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 401)
474 f870efe2 Sofia Papagiannaki
        body = json.loads(r.content)
475 f870efe2 Sofia Papagiannaki
        self.assertEqual(body['unauthorized']['message'],
476 f870efe2 Sofia Papagiannaki
                         'Invalid credentials')
477 f870efe2 Sofia Papagiannaki
478 f870efe2 Sofia Papagiannaki
        # Check invalid json data
479 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
480 f870efe2 Sofia Papagiannaki
        r = client.post(url, "not json", content_type='application/json')
481 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
482 f870efe2 Sofia Papagiannaki
        body = json.loads(r.content)
483 f870efe2 Sofia Papagiannaki
        self.assertEqual(body['badRequest']['message'], 'Invalid JSON data')
484 f870efe2 Sofia Papagiannaki
485 f870efe2 Sofia Papagiannaki
        # Check auth with token
486 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
487 f870efe2 Sofia Papagiannaki
        post_data = """{"auth":{"token": {"id":"%s"},
488 f870efe2 Sofia Papagiannaki
                        "tenantName":"%s"}}""" % (
489 f870efe2 Sofia Papagiannaki
            self.user1.auth_token, self.user1.uuid)
490 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/json')
491 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
492 f870efe2 Sofia Papagiannaki
        self.assertTrue(r['Content-Type'].startswith('application/json'))
493 f870efe2 Sofia Papagiannaki
        try:
494 f870efe2 Sofia Papagiannaki
            body = json.loads(r.content)
495 f870efe2 Sofia Papagiannaki
        except Exception, e:
496 f870efe2 Sofia Papagiannaki
            self.fail(e)
497 f870efe2 Sofia Papagiannaki
498 f870efe2 Sofia Papagiannaki
        # Check successful json response
499 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
500 f870efe2 Sofia Papagiannaki
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
501 f870efe2 Sofia Papagiannaki
                                                       "password":"%s"},
502 f870efe2 Sofia Papagiannaki
                                "tenantName":"%s"}}""" % (
503 f870efe2 Sofia Papagiannaki
            self.user1.uuid, self.user1.auth_token, self.user1.uuid)
504 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/json')
505 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
506 f870efe2 Sofia Papagiannaki
        self.assertTrue(r['Content-Type'].startswith('application/json'))
507 f870efe2 Sofia Papagiannaki
        try:
508 f870efe2 Sofia Papagiannaki
            body = json.loads(r.content)
509 f870efe2 Sofia Papagiannaki
        except Exception, e:
510 f870efe2 Sofia Papagiannaki
            self.fail(e)
511 f870efe2 Sofia Papagiannaki
512 f870efe2 Sofia Papagiannaki
        try:
513 f870efe2 Sofia Papagiannaki
            token = body['token']['id']
514 f870efe2 Sofia Papagiannaki
            user = body['user']['id']
515 f870efe2 Sofia Papagiannaki
            service_catalog = body['serviceCatalog']
516 f870efe2 Sofia Papagiannaki
        except KeyError:
517 f870efe2 Sofia Papagiannaki
            self.fail('Invalid response')
518 f870efe2 Sofia Papagiannaki
519 f870efe2 Sofia Papagiannaki
        self.assertEqual(token, self.user1.auth_token)
520 f870efe2 Sofia Papagiannaki
        self.assertEqual(user, self.user1.uuid)
521 f870efe2 Sofia Papagiannaki
        self.assertEqual(len(service_catalog), 3)
522 f870efe2 Sofia Papagiannaki
523 f870efe2 Sofia Papagiannaki
        # Check successful xml response
524 f870efe2 Sofia Papagiannaki
        url = '/astakos/api/tokens'
525 f870efe2 Sofia Papagiannaki
        headers = {'HTTP_ACCEPT': 'application/xml'}
526 f870efe2 Sofia Papagiannaki
        post_data = """{"auth":{"passwordCredentials":{"username":"%s",
527 f870efe2 Sofia Papagiannaki
                                                       "password":"%s"},
528 f870efe2 Sofia Papagiannaki
                                "tenantName":"%s"}}""" % (
529 f870efe2 Sofia Papagiannaki
            self.user1.uuid, self.user1.auth_token, self.user1.uuid)
530 f870efe2 Sofia Papagiannaki
        r = client.post(url, post_data, content_type='application/json',
531 f870efe2 Sofia Papagiannaki
                        **headers)
532 f870efe2 Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
533 f870efe2 Sofia Papagiannaki
        self.assertTrue(r['Content-Type'].startswith('application/xml'))
534 49005665 Sofia Papagiannaki
#        try:
535 49005665 Sofia Papagiannaki
#            body = minidom.parseString(r.content)
536 49005665 Sofia Papagiannaki
#        except Exception, e:
537 49005665 Sofia Papagiannaki
#            self.fail(e)
538 f870efe2 Sofia Papagiannaki
539 f870efe2 Sofia Papagiannaki
    def test_get_endpoints(self):
540 f870efe2 Sofia Papagiannaki
        client = Client()
541 7ac2131c Sofia Papagiannaki
542 ab7ca50a Sofia Papagiannaki
        # Check in active user token
543 ab7ca50a Sofia Papagiannaki
        inactive_user = AstakosUser.objects.create(email='test3')
544 ab7ca50a Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints' % quote(
545 ab7ca50a Sofia Papagiannaki
            inactive_user.auth_token)
546 ab7ca50a Sofia Papagiannaki
        r = client.get(url)
547 ab7ca50a Sofia Papagiannaki
        self.assertEqual(r.status_code, 401)
548 ab7ca50a Sofia Papagiannaki
549 ab7ca50a Sofia Papagiannaki
        # Check invalid user token in path
550 ab7ca50a Sofia Papagiannaki
        url = '/astakos/api/tokens/nouser/endpoints'
551 ab7ca50a Sofia Papagiannaki
        r = client.get(url)
552 ab7ca50a Sofia Papagiannaki
        self.assertEqual(r.status_code, 401)
553 ab7ca50a Sofia Papagiannaki
554 ab7ca50a Sofia Papagiannaki
        # Check forbidden
555 ab7ca50a Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
556 ab7ca50a Sofia Papagiannaki
        headers = {'HTTP_X_AUTH_TOKEN': AstakosUser.objects.create(
557 ab7ca50a Sofia Papagiannaki
            email='test4').auth_token}
558 ab7ca50a Sofia Papagiannaki
        r = client.get(url, **headers)
559 ab7ca50a Sofia Papagiannaki
        self.assertEqual(r.status_code, 401)
560 ab7ca50a Sofia Papagiannaki
561 7ac2131c Sofia Papagiannaki
        # Check bad request method
562 7ac2131c Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
563 7ac2131c Sofia Papagiannaki
        r = client.post(url)
564 7ac2131c Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
565 7ac2131c Sofia Papagiannaki
566 7ac2131c Sofia Papagiannaki
        # Check forbidden
567 7ac2131c Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
568 7ac2131c Sofia Papagiannaki
        headers = {'HTTP_X_AUTH_TOKEN': self.user2.auth_token}
569 7ac2131c Sofia Papagiannaki
        r = client.get(url, **headers)
570 7ac2131c Sofia Papagiannaki
        self.assertEqual(r.status_code, 403)
571 7ac2131c Sofia Papagiannaki
572 bd93595d Sofia Papagiannaki
        # Check belongsTo BadRequest
573 bd93595d Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints?belongsTo=%s' % (
574 bd93595d Sofia Papagiannaki
            quote(self.user1.auth_token), quote(self.user2.uuid))
575 bd93595d Sofia Papagiannaki
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
576 bd93595d Sofia Papagiannaki
        r = client.get(url, **headers)
577 bd93595d Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
578 bd93595d Sofia Papagiannaki
579 bd93595d Sofia Papagiannaki
        # Check successful request
580 7ac2131c Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
581 7ac2131c Sofia Papagiannaki
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
582 7ac2131c Sofia Papagiannaki
        r = client.get(url, **headers)
583 7ac2131c Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
584 7ac2131c Sofia Papagiannaki
        self.assertEqual(r['Content-Type'], 'application/json; charset=UTF-8')
585 7ac2131c Sofia Papagiannaki
        try:
586 7ac2131c Sofia Papagiannaki
            body = json.loads(r.content)
587 7ac2131c Sofia Papagiannaki
        except:
588 7ac2131c Sofia Papagiannaki
            self.fail('json format expected')
589 7ac2131c Sofia Papagiannaki
        endpoints = body.get('endpoints')
590 7ac2131c Sofia Papagiannaki
        self.assertEqual(len(endpoints), 3)
591 7ac2131c Sofia Papagiannaki
592 7ac2131c Sofia Papagiannaki
         # Check xml serialization
593 7ac2131c Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints?format=xml' %\
594 7ac2131c Sofia Papagiannaki
            quote(self.user1.auth_token)
595 7ac2131c Sofia Papagiannaki
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
596 7ac2131c Sofia Papagiannaki
        r = client.get(url, **headers)
597 7ac2131c Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
598 7ac2131c Sofia Papagiannaki
        self.assertEqual(r['Content-Type'], 'application/xml; charset=UTF-8')
599 7ac2131c Sofia Papagiannaki
#        try:
600 7ac2131c Sofia Papagiannaki
#            body = minidom.parseString(r.content)
601 7ac2131c Sofia Papagiannaki
#        except Exception, e:
602 7ac2131c Sofia Papagiannaki
#            self.fail('xml format expected')
603 7ac2131c Sofia Papagiannaki
        endpoints = body.get('endpoints')
604 7ac2131c Sofia Papagiannaki
        self.assertEqual(len(endpoints), 3)
605 7ac2131c Sofia Papagiannaki
606 7ac2131c Sofia Papagiannaki
        # Check limit
607 7ac2131c Sofia Papagiannaki
        url = '/astakos/api/tokens/%s/endpoints?limit=2' %\
608 7ac2131c Sofia Papagiannaki
            quote(self.user1.auth_token)
609 7ac2131c Sofia Papagiannaki
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
610 7ac2131c Sofia Papagiannaki
        r = client.get(url, **headers)
611 7ac2131c Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
612 7ac2131c Sofia Papagiannaki
        body = json.loads(r.content)
613 7ac2131c Sofia Papagiannaki
        endpoints = body.get('endpoints')
614 7ac2131c Sofia Papagiannaki
        self.assertEqual(len(endpoints), 2)
615 7ac2131c Sofia Papagiannaki
616 7ac2131c Sofia Papagiannaki
        endpoint_link = body.get('endpoint_links', [])[0]
617 7ac2131c Sofia Papagiannaki
        next = endpoint_link.get('href')
618 7ac2131c Sofia Papagiannaki
        p = urlparse(next)
619 7ac2131c Sofia Papagiannaki
        params = parse_qs(p.query)
620 7ac2131c Sofia Papagiannaki
        self.assertTrue('limit' in params)
621 7ac2131c Sofia Papagiannaki
        self.assertTrue('marker' in params)
622 7ac2131c Sofia Papagiannaki
        self.assertEqual(params['marker'][0], '2')
623 7ac2131c Sofia Papagiannaki
624 7ac2131c Sofia Papagiannaki
        # Check marker
625 7ac2131c Sofia Papagiannaki
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
626 7ac2131c Sofia Papagiannaki
        r = client.get(next, **headers)
627 7ac2131c Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
628 7ac2131c Sofia Papagiannaki
        body = json.loads(r.content)
629 7ac2131c Sofia Papagiannaki
        endpoints = body.get('endpoints')
630 7ac2131c Sofia Papagiannaki
        self.assertEqual(len(endpoints), 1)