1
- from django .test import TestCase
2
1
import json
3
2
import base64
3
+ import datetime
4
+ import unittest
5
+
6
+ from django .test import TestCase
7
+ from django .contrib .auth .models import User
8
+ from django_dynamic_fixture import get
9
+ from rest_framework import status
10
+ from rest_framework .test import APIClient
11
+
12
+ from readthedocs .builds .models import Build
4
13
5
14
6
15
super_auth = base64 .b64encode ('super:test' )
@@ -14,24 +23,121 @@ def test_make_build(self):
14
23
"""
15
24
Test that a superuser can use the API
16
25
"""
17
- post_data = {
18
- "project" : "/api/v1/project/1/" ,
19
- "version" : "/api/v1/version/1/" ,
20
- "success" : True ,
21
- "output" : "Test Output" ,
22
- "error" : "Test Error" ,
23
- }
24
- resp = self .client .post ('/api/v1/build/' , data = json .dumps (post_data ),
25
- content_type = 'application/json' ,
26
- HTTP_AUTHORIZATION = 'Basic %s' % super_auth )
27
- self .assertEqual (resp .status_code , 201 )
28
- self .assertEqual (resp ['location' ],
29
- 'http://testserver/api/v1/build/1/' )
30
- resp = self .client .get ('/api/v1/build/1/' , data = {'format' : 'json' },
31
- HTTP_AUTHORIZATION = 'Basic %s' % super_auth )
26
+ client = APIClient ()
27
+ client .login (username = 'super' , password = 'test' )
28
+ resp = client .post (
29
+ '/api/v2/build/' ,
30
+ {
31
+ 'project' : 1 ,
32
+ 'version' : 1 ,
33
+ 'success' : True ,
34
+ 'output' : 'Test Output' ,
35
+ 'error' : 'Test Error' ,
36
+ 'state' : 'cloning' ,
37
+ },
38
+ format = 'json' )
39
+ self .assertEqual (resp .status_code , status .HTTP_201_CREATED )
40
+ build = resp .data
41
+ self .assertEqual (build ['id' ], 1 )
42
+ self .assertEqual (build ['state_display' ], 'Cloning' )
43
+
44
+ resp = client .get ('/api/v2/build/1/' )
32
45
self .assertEqual (resp .status_code , 200 )
33
- obj = json .loads (resp .content )
34
- self .assertEqual (obj ['output' ], 'Test Output' )
46
+ build = resp .data
47
+ self .assertEqual (build ['output' ], 'Test Output' )
48
+ self .assertEqual (build ['state_display' ], 'Cloning' )
49
+
50
+ def test_make_build_without_permission (self ):
51
+ """Ensure anonymous/non-staff users cannot write the build endpoint"""
52
+ client = APIClient ()
53
+
54
+ def _try_post ():
55
+ resp = client .post (
56
+ '/api/v2/build/' ,
57
+ {
58
+ 'project' : 1 ,
59
+ 'version' : 1 ,
60
+ 'success' : True ,
61
+ 'output' : 'Test Output' ,
62
+ 'error' : 'Test Error' ,
63
+ },
64
+ format = 'json' )
65
+ self .assertEqual (resp .status_code , 403 )
66
+
67
+ _try_post ()
68
+
69
+ api_user = get (User , staff = False , password = 'test' )
70
+ assert api_user .is_staff == False
71
+ client .force_authenticate (user = api_user )
72
+ _try_post ()
73
+
74
+ def test_update_build_without_permission (self ):
75
+ """Ensure anonymous/non-staff users cannot update build endpoints"""
76
+ client = APIClient ()
77
+ api_user = get (User , staff = False , password = 'test' )
78
+ client .force_authenticate (user = api_user )
79
+ build = get (Build , project_id = 1 , version_id = 1 , state = 'cloning' )
80
+ resp = client .put (
81
+ '/api/v2/build/{0}/' .format (build .pk ),
82
+ {
83
+ 'project' : 1 ,
84
+ 'version' : 1 ,
85
+ 'state' : 'finished'
86
+ },
87
+ format = 'json' )
88
+ self .assertEqual (resp .status_code , 403 )
89
+
90
+ def test_make_build_protected_fields (self ):
91
+ """Ensure build api view delegates correct serializer
92
+
93
+ Super users should be able to read/write the `builder` property, but we
94
+ don't expose this to end users via the API
95
+ """
96
+ build = get (Build , project_id = 1 , version_id = 1 , builder = 'foo' )
97
+ client = APIClient ()
98
+
99
+ api_user = get (User , staff = False , password = 'test' )
100
+ client .force_authenticate (user = api_user )
101
+ resp = client .get ('/api/v2/build/{0}/' .format (build .pk ), format = 'json' )
102
+ self .assertEqual (resp .status_code , 403 )
103
+
104
+ client .force_authenticate (user = User .objects .get (username = 'super' ))
105
+ resp = client .get ('/api/v2/build/{0}/' .format (build .pk ), format = 'json' )
106
+ self .assertEqual (resp .status_code , 200 )
107
+ self .assertIn ('builder' , resp .data )
108
+
109
+ def test_make_build_commands (self ):
110
+ """Create build and build commands"""
111
+ client = APIClient ()
112
+ client .login (username = 'super' , password = 'test' )
113
+ resp = client .post (
114
+ '/api/v2/build/' ,
115
+ {
116
+ 'project' : 1 ,
117
+ 'version' : 1 ,
118
+ 'success' : True ,
119
+ },
120
+ format = 'json' )
121
+ self .assertEqual (resp .status_code , status .HTTP_201_CREATED )
122
+ build = resp .data
123
+ now = datetime .datetime .utcnow ()
124
+ resp = client .post (
125
+ '/api/v2/command/' ,
126
+ {
127
+ 'build' : build ['id' ],
128
+ 'command' : 'echo test' ,
129
+ 'description' : 'foo' ,
130
+ 'start_time' : str (now - datetime .timedelta (seconds = 5 )),
131
+ 'end_time' : str (now ),
132
+ },
133
+ format = 'json' )
134
+ self .assertEqual (resp .status_code , status .HTTP_201_CREATED )
135
+ resp = client .get ('/api/v2/build/1/' )
136
+ self .assertEqual (resp .status_code , 200 )
137
+ build = resp .data
138
+ self .assertEqual (len (build ['commands' ]), 1 )
139
+ self .assertEqual (build ['commands' ][0 ]['run_time' ], 5 )
140
+ self .assertEqual (build ['commands' ][0 ]['description' ], 'foo' )
35
141
36
142
37
143
class APITests (TestCase ):
0 commit comments