1
|
|
|
# Copyright 2013 Netherlands eScience Center |
2
|
|
|
# |
3
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
4
|
|
|
# you may not use this file except in compliance with the License. |
5
|
|
|
# You may obtain a copy of the License at |
6
|
|
|
# |
7
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0 |
8
|
|
|
# |
9
|
|
|
# Unless required by applicable law or agreed to in writing, software |
10
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, |
11
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12
|
|
|
# See the License for the specific language governing permissions and |
13
|
|
|
# limitations under the License. |
14
|
|
|
|
15
|
1 |
|
from UserList import UserList |
16
|
1 |
|
from datetime import datetime, timedelta |
17
|
1 |
|
from decimal import Decimal |
18
|
1 |
|
import unittest |
19
|
1 |
|
from iso8601.iso8601 import UTC |
20
|
1 |
|
from mock import Mock, ANY |
21
|
1 |
|
from pyramid import testing |
22
|
1 |
|
import annotation.views as views |
23
|
1 |
|
import annotation |
24
|
1 |
|
from annotation.uploads import UploadViews |
25
|
1 |
|
from pyramid.httpexceptions import HTTPFound |
26
|
|
|
|
27
|
|
|
|
28
|
1 |
|
class ConnectTests(unittest.TestCase): |
29
|
1 |
|
pass |
30
|
|
|
|
31
|
|
|
|
32
|
1 |
|
class ViewTests(unittest.TestCase): |
33
|
1 |
|
def setUp(self): |
34
|
1 |
|
self.config = testing.setUp() |
35
|
|
|
|
36
|
1 |
|
def tearDown(self): |
37
|
1 |
|
testing.tearDown() |
38
|
|
|
|
39
|
1 |
|
def test_home(self): |
40
|
1 |
|
request = testing.DummyRequest() |
41
|
1 |
|
response = views.home(request) |
42
|
1 |
|
self.assertEqual(response, {}) |
43
|
|
|
|
44
|
1 |
|
def test_trackers(self): |
45
|
1 |
|
request = testing.DummyRequest() |
46
|
1 |
|
cursor = UserList([{'id': 355}]) |
47
|
1 |
|
cursor.execute = Mock() |
48
|
1 |
|
request.db = Mock() |
49
|
1 |
|
request.db.cursor.return_value = cursor |
50
|
|
|
|
51
|
1 |
|
response = views.trackers(request) |
52
|
|
|
|
53
|
1 |
|
expected = {'trackers': [{'id': 355}]} |
54
|
1 |
|
self.assertEquals(response, expected) |
55
|
1 |
|
expected_sql = """ |
56
|
|
|
SELECT DISTINCT device_info_serial as id |
57
|
|
|
FROM gps.ee_tracker_limited |
58
|
|
|
JOIN gps.ee_track_session_limited USING (device_info_serial) |
59
|
|
|
ORDER BY device_info_serial |
60
|
|
|
""" |
61
|
1 |
|
cursor.execute.assert_called_with(expected_sql) |
62
|
|
|
|
63
|
1 |
|
def test_tracker(self): |
64
|
1 |
|
request = testing.DummyRequest() |
65
|
1 |
|
request.db = Mock() |
66
|
1 |
|
cursor = Mock() |
67
|
1 |
|
request.db.cursor.return_value = cursor |
68
|
1 |
|
request.matchdict = {'id': '355', |
69
|
|
|
'start': '2010-06-28T00:00:00Z', |
70
|
|
|
'end': '2010-06-29T00:00:00Z'} |
71
|
|
|
|
72
|
1 |
|
views.tracker(request) |
73
|
|
|
|
74
|
1 |
|
binds = (20.0, |
75
|
|
|
355, |
76
|
|
|
'2010-06-28T00:00:00+00:00', |
77
|
|
|
'2010-06-29T00:00:00+00:00', |
78
|
|
|
355, |
79
|
|
|
'2010-06-28T00:00:00+00:00', |
80
|
|
|
'2010-06-29T00:00:00+00:00') |
81
|
1 |
|
cursor.execute.assert_called_with(ANY, binds) |
82
|
|
|
|
83
|
|
|
|
84
|
1 |
|
class AnnotationTests(unittest.TestCase): |
85
|
1 |
|
def setUp(self): |
86
|
1 |
|
self.config = testing.setUp() |
87
|
1 |
|
self.request = testing.DummyRequest() |
88
|
|
|
|
89
|
1 |
|
def tearDown(self): |
90
|
1 |
|
testing.tearDown() |
91
|
|
|
|
92
|
1 |
|
def test_datetime_adaptor(self): |
93
|
1 |
|
obj = datetime(2010, 6, 28, 0, 0, 0, 0, UTC) |
94
|
1 |
|
result = annotation.datetime_adaptor(obj, self.request) |
95
|
1 |
|
self.assertEquals(result, '2010-06-28T00:00:00+00:00') |
96
|
|
|
|
97
|
1 |
|
def test_timedelta_adaptor(self): |
98
|
1 |
|
obj = timedelta(seconds=65) |
99
|
1 |
|
result = annotation.timedelta_adaptor(obj, self.request) |
100
|
1 |
|
self.assertEquals(result, '0:01:05') |
101
|
|
|
|
102
|
1 |
|
def test_decimal_adaptor(self): |
103
|
1 |
|
obj = Decimal('0.1234') |
104
|
1 |
|
result = annotation.decimal_adaptor(obj, self.request) |
105
|
1 |
|
self.assertEquals(result, 0.1234) |
106
|
|
|
|
107
|
1 |
|
def test_cursor_adaptor(self): |
108
|
1 |
|
obj = (1, 2, 3) |
109
|
1 |
|
result = annotation.cursor_adaptor(obj, self.request) |
110
|
1 |
|
self.assertEquals(result, [1, 2, 3]) |
111
|
|
|
|
112
|
|
|
|
113
|
1 |
|
class UploadViewsTest(unittest.TestCase): |
114
|
1 |
|
def setUp(self): |
115
|
1 |
|
self.config = testing.setUp() |
116
|
1 |
|
self.request = testing.DummyRequest() |
117
|
1 |
|
self.request.db = Mock() |
118
|
1 |
|
self.cursor = Mock() |
119
|
1 |
|
self.request.db.cursor.return_value = self.cursor |
120
|
|
|
|
121
|
1 |
|
def tearDown(self): |
122
|
1 |
|
testing.tearDown() |
123
|
|
|
|
124
|
1 |
|
def test_constructor_nourlparameters_tableIsEmpty(self): |
|
|
|
|
125
|
1 |
|
views = UploadViews(self.request) |
126
|
|
|
|
127
|
1 |
|
self.assertEquals(views.table, '') |
128
|
|
|
|
129
|
1 |
|
def test_constructor_url_parameters_trackerAndTableFilled(self): |
|
|
|
|
130
|
1 |
|
self.request.matchdict['table'] = 'mytable' |
131
|
|
|
|
132
|
1 |
|
views = UploadViews(self.request) |
133
|
|
|
|
134
|
1 |
|
self.assertEquals(views.table, 'mytable') |
135
|
|
|
|
136
|
1 |
|
def test_uploads_notableselected(self): |
137
|
1 |
|
views = UploadViews(self.request) |
138
|
|
|
|
139
|
1 |
|
response = views.uploads() |
140
|
|
|
|
141
|
1 |
|
expected_response = {'trackers': [], 'table': ''} |
142
|
1 |
|
self.assertEqual(response, expected_response) |
143
|
|
|
|
144
|
1 |
View Code Duplication |
def test_uploads_selectedtable_listsoftrackers(self): |
|
|
|
|
145
|
1 |
|
self.request.params['table'] = 'mytable' |
146
|
1 |
|
views = UploadViews(self.request) |
147
|
1 |
|
rows = [{ |
148
|
|
|
'id': 355, |
149
|
|
|
'start': datetime(2010, 6, 28, 0, 0, 0, 0, UTC), |
150
|
|
|
'end': datetime(2010, 6, 28, 12, 0, 0, 0, UTC), |
151
|
|
|
'count:': 1, |
152
|
|
|
}] |
153
|
1 |
|
self.cursor.fetchall.return_value = rows |
154
|
1 |
|
self.cursor.fetchone.return_value = {'date_time': datetime(2010, 6, 28, 10, 0, 0, 0, UTC), 'count': 1} |
|
|
|
|
155
|
|
|
|
156
|
1 |
|
response = views.uploads() |
157
|
|
|
|
158
|
1 |
|
expected = {'table': 'mytable', |
159
|
|
|
'trackers': [{'count:': 1, |
160
|
|
|
'end': datetime(2010, 6, 28, 12, 0, 0, 0, UTC), |
|
|
|
|
161
|
|
|
'first_page': datetime(2010, 6, 28, 10, 0, 0, 0, UTC), |
|
|
|
|
162
|
|
|
'id': 355, |
163
|
|
|
'last_page': datetime(2010, 6, 28, 10, 0, 0, 0, UTC), |
|
|
|
|
164
|
|
|
'page_size': 500, |
165
|
|
|
'size': 1, |
166
|
|
|
'start': datetime(2010, 6, 28, 0, 0, 0, 0, UTC) |
|
|
|
|
167
|
|
|
}] |
168
|
|
|
} |
169
|
1 |
|
self.assertEqual(response, expected) |
170
|
|
|
|
171
|
1 |
View Code Duplication |
def test_uploads_windowtoosmall_listsoftrackers(self): |
|
|
|
|
172
|
1 |
|
self.request.params['table'] = 'mytable' |
173
|
1 |
|
views = UploadViews(self.request) |
174
|
1 |
|
rows = [{ |
175
|
|
|
'id': 355, |
176
|
|
|
'start': datetime(2010, 6, 28, 0, 0, 0, 0, UTC), |
177
|
|
|
'end': datetime(2010, 6, 28, 12, 0, 0, 0, UTC), |
178
|
|
|
'count:': 1, |
179
|
|
|
}] |
180
|
1 |
|
self.cursor.fetchall.return_value = rows |
181
|
1 |
|
views.track_size = Mock(return_value=1) |
182
|
1 |
|
self.cursor.fetchone.return_value = None |
183
|
|
|
|
184
|
1 |
|
response = views.uploads() |
185
|
|
|
|
186
|
1 |
|
expected = {'table': 'mytable', |
187
|
|
|
'trackers': [{'count:': 1, |
188
|
|
|
'end': datetime(2010, 6, 28, 12, 0, 0, 0, UTC), |
|
|
|
|
189
|
|
|
'first_page': datetime(2010, 6, 28, 12, 0, 0, 0, UTC), |
|
|
|
|
190
|
|
|
'id': 355, |
191
|
|
|
'last_page': datetime(2010, 6, 28, 0, 0, 0, 0, UTC), |
|
|
|
|
192
|
|
|
'page_size': 500, |
193
|
|
|
'size': 1, |
194
|
|
|
'start': datetime(2010, 6, 28, 0, 0, 0, 0, UTC) |
|
|
|
|
195
|
|
|
}] |
196
|
|
|
} |
197
|
1 |
|
self.assertEqual(response, expected) |
198
|
|
|
|
199
|
|
|
|
200
|
1 |
View Code Duplication |
def test_upload(self): |
|
|
|
|
201
|
1 |
|
self.request.matchdict['table'] = 'mytable' |
202
|
1 |
|
self.request.params['id'] = '355' |
203
|
1 |
|
self.request.params['start'] = '2010-06-27T00:00:00+00:00' |
204
|
1 |
|
self.request.params['end'] = '2010-06-29T00:00:00+00:00' |
205
|
1 |
|
self.config.add_route('annotations.csv', '/uploads/{table}/annotations.csv') |
|
|
|
|
206
|
1 |
|
views = UploadViews(self.request) |
207
|
1 |
|
rows = [{ |
208
|
|
|
'id': 3, |
209
|
|
|
'label': 'flying', |
210
|
|
|
'color': 'rgb(0,0,255)', |
211
|
|
|
}] |
212
|
1 |
|
self.cursor.fetchall.return_value = rows |
213
|
|
|
|
214
|
1 |
|
response = views.upload() |
215
|
|
|
|
216
|
1 |
|
expected_response = {'annotations_url': '/uploads/mytable/annotations.csv', |
|
|
|
|
217
|
|
|
'classes': '[{"color": "rgb(0,0,255)", "id": 3, "label": "flying"}]', |
|
|
|
|
218
|
|
|
'end': '2010-06-29T00:00:00+00:00', |
219
|
|
|
'start': '2010-06-27T00:00:00+00:00', |
220
|
|
|
'tracker_id': 355, |
221
|
|
|
} |
222
|
1 |
|
self.assertEqual(response, expected_response) |
223
|
|
|
|
224
|
1 |
|
def test_upload_withoutselection(self): |
225
|
1 |
|
self.request.matchdict['table'] = 'mytable' |
226
|
1 |
|
self.config.add_route('uploads.html', '/uploads.html') |
227
|
1 |
|
views = UploadViews(self.request) |
228
|
|
|
|
229
|
1 |
|
response = views.upload() |
230
|
|
|
|
231
|
1 |
|
expected_response = HTTPFound('/uploads.html?table=mytable') |
232
|
1 |
|
self.assertIsInstance(response, HTTPFound) |
233
|
1 |
|
self.assertEqual(response.location, expected_response.location) |
234
|
|
|
|
235
|
1 |
View Code Duplication |
def test_annotations_as_csv(self): |
|
|
|
|
236
|
1 |
|
self.request.matchdict['table'] = 'mytable' |
237
|
1 |
|
self.request.params['id'] = '355' |
238
|
1 |
|
self.request.params['start'] = '2010-06-27T00:00:00+00:00' |
239
|
1 |
|
self.request.params['end'] = '2010-06-29T00:00:00+00:00' |
240
|
1 |
|
views = UploadViews(self.request) |
241
|
1 |
|
rows = [{ |
242
|
|
|
'device_info_serial': 355, |
243
|
|
|
'date_time': datetime(2010, 6, 28, 0, 0, 0, 0, UTC), |
244
|
|
|
'class_id': 3 |
245
|
|
|
}] |
246
|
1 |
|
self.cursor.fetchall.return_value = rows |
247
|
|
|
|
248
|
1 |
|
response = views.annotations_as_csv() |
249
|
|
|
|
250
|
1 |
|
expected_body = 'device_info_serial,date_time,class_id\n355,2010-06-28T00:00:00+00:00Z,3\n' |
|
|
|
|
251
|
|
|
self.assertEqual(response.body, expected_body) |
252
|
|
|
|
This check looks for invalid names for a range of different identifiers.
You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.
If your project includes a Pylint configuration file, the settings contained in that file take precedence.
To find out more about Pylint, please refer to their site.