test_project_repository.py
14.6 KB
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
# -*- coding: utf8 -*-
# This file is part of PyBossa.
#
# Copyright (C) 2015 SciFabric LTD.
#
# PyBossa is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyBossa is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with PyBossa. If not, see <http://www.gnu.org/licenses/>.
# Cache global variables for timeouts
from default import Test, db
from nose.tools import assert_raises
from factories import ProjectFactory, CategoryFactory
from pybossa.repositories import ProjectRepository
from pybossa.exc import WrongObjectError, DBIntegrityError
class TestProjectRepositoryForProjects(Test):
def setUp(self):
super(TestProjectRepositoryForProjects, self).setUp()
self.project_repo = ProjectRepository(db)
def test_get_return_none_if_no_project(self):
"""Test get method returns None if there is no project with the
specified id"""
project = self.project_repo.get(2)
assert project is None, project
def test_get_returns_project(self):
"""Test get method returns a project if exists"""
project = ProjectFactory.create()
retrieved_project = self.project_repo.get(project.id)
assert project == retrieved_project, retrieved_project
def test_get_by_shortname_return_none_if_no_project(self):
"""Test get_by_shortname returns None when a project with the specified
short_name does not exist"""
project = self.project_repo.get_by_shortname('thisprojectdoesnotexist')
assert project is None, project
def test_get_by_shortname_returns_the_project(self):
"""Test get_by_shortname returns a project if exists"""
project = ProjectFactory.create()
retrieved_project = self.project_repo.get_by_shortname(project.short_name)
assert project == retrieved_project, retrieved_project
def test_get_by(self):
"""Test get_by returns a project with the specified attribute"""
project = ProjectFactory.create(name='My Project', short_name='myproject')
retrieved_project = self.project_repo.get_by(name=project.name)
assert project == retrieved_project, retrieved_project
def test_get_by_returns_none_if_no_project(self):
"""Test get_by returns None if no project matches the query"""
ProjectFactory.create(name='My Project', short_name='myproject')
project = self.project_repo.get_by(name='no_name')
assert project is None, project
def get_all_returns_list_of_all_projects(self):
"""Test get_all returns a list of all the existing projects"""
projects = ProjectFactory.create_batch(3)
retrieved_projects = self.project_repo.get_all()
assert isinstance(retrieved_projects, list)
assert len(retrieved_projects) == len(projects), retrieved_projects
for project in retrieved_projects:
assert project in projects, project
def test_filter_by_no_matches(self):
"""Test filter_by returns an empty list if no projects match the query"""
ProjectFactory.create(name='My Project', short_name='myproject')
retrieved_projects = self.project_repo.filter_by(name='no_name')
assert isinstance(retrieved_projects, list)
assert len(retrieved_projects) == 0, retrieved_projects
def test_filter_by_one_condition(self):
"""Test filter_by returns a list of projects that meet the filtering
condition"""
ProjectFactory.create_batch(3, allow_anonymous_contributors=False)
should_be_missing = ProjectFactory.create(allow_anonymous_contributors=True)
retrieved_projects = self.project_repo.filter_by(allow_anonymous_contributors=False)
assert len(retrieved_projects) == 3, retrieved_projects
assert should_be_missing not in retrieved_projects, retrieved_projects
def test_filter_by_multiple_conditions(self):
"""Test filter_by supports multiple-condition queries"""
ProjectFactory.create_batch(2, allow_anonymous_contributors=False, featured=False)
project = ProjectFactory.create(allow_anonymous_contributors=False, featured=True)
retrieved_projects = self.project_repo.filter_by(
allow_anonymous_contributors=False,
featured=True)
assert len(retrieved_projects) == 1, retrieved_projects
assert project in retrieved_projects, retrieved_projects
def test_filter_by_limit_offset(self):
"""Test that filter_by supports limit and offset options"""
ProjectFactory.create_batch(4)
all_projects = self.project_repo.filter_by()
first_two = self.project_repo.filter_by(limit=2)
last_two = self.project_repo.filter_by(limit=2, offset=2)
assert len(first_two) == 2, first_two
assert len(last_two) == 2, last_two
assert first_two == all_projects[:2]
assert last_two == all_projects[2:]
def test_save(self):
"""Test save persist the project"""
project = ProjectFactory.build()
assert self.project_repo.get(project.id) is None
self.project_repo.save(project)
assert self.project_repo.get(project.id) == project, "Project not saved"
def test_save_fails_if_integrity_error(self):
"""Test save raises a DBIntegrityError if the instance to be saved lacks
a required value"""
project = ProjectFactory.build(name=None)
assert_raises(DBIntegrityError, self.project_repo.save, project)
def test_save_only_saves_projects(self):
"""Test save raises a WrongObjectError when an object which is not
a Project instance is saved"""
bad_object = dict()
assert_raises(WrongObjectError, self.project_repo.save, bad_object)
def test_update(self):
"""Test update persists the changes made to the project"""
project = ProjectFactory.create(description='this is a project')
project.description = 'the description has changed'
self.project_repo.update(project)
updated_project = self.project_repo.get(project.id)
assert updated_project.description == 'the description has changed', updated_project
def test_update_fails_if_integrity_error(self):
"""Test update raises a DBIntegrityError if the instance to be updated
lacks a required value"""
project = ProjectFactory.create()
project.name = None
assert_raises(DBIntegrityError, self.project_repo.update, project)
def test_update_only_updates_projects(self):
"""Test update raises a WrongObjectError when an object which is not
a Project instance is updated"""
bad_object = dict()
assert_raises(WrongObjectError, self.project_repo.update, bad_object)
def test_delete(self):
"""Test delete removes the project instance"""
project = ProjectFactory.create()
self.project_repo.delete(project)
deleted = self.project_repo.get(project.id)
assert deleted is None, deleted
def test_delete_also_removes_dependant_resources(self):
"""Test delete removes project tasks and taskruns too"""
from factories import TaskFactory, TaskRunFactory, BlogpostFactory
from pybossa.repositories import TaskRepository, BlogRepository
project = ProjectFactory.create()
task = TaskFactory.create(project=project)
taskrun = TaskRunFactory.create(task=task)
blogpost = BlogpostFactory.create(project=project)
self.project_repo.delete(project)
deleted_task = TaskRepository(db).get_task(task.id)
deleted_taskrun = TaskRepository(db).get_task_run(taskrun.id)
deleted_blogpost = BlogRepository(db).get(blogpost.id)
assert deleted_task is None, deleted_task
assert deleted_taskrun is None, deleted_taskrun
def test_delete_only_deletes_projects(self):
"""Test delete raises a WrongObjectError if is requested to delete other
than a project"""
bad_object = dict()
assert_raises(WrongObjectError, self.project_repo.delete, bad_object)
class TestProjectRepositoryForCategories(Test):
def setUp(self):
super(TestProjectRepositoryForCategories, self).setUp()
self.project_repo = ProjectRepository(db)
def test_get_category_return_none_if_no_category(self):
"""Test get_category method returns None if there is no category with
the specified id"""
category = self.project_repo.get_category(200)
assert category is None, category
def test_get_category_returns_category(self):
"""Test get_category method returns a category if exists"""
category = CategoryFactory.create()
retrieved_category = self.project_repo.get_category(category.id)
assert category == retrieved_category, retrieved_category
def test_get_category_by(self):
"""Test get_category returns a category with the specified attribute"""
category = CategoryFactory.create(name='My Cat', short_name='mycat')
retrieved_category = self.project_repo.get_category_by(name=category.name)
assert category == retrieved_category, retrieved_category
def test_get_category_by_returns_none_if_no_category(self):
"""Test get_category returns None if no category matches the query"""
CategoryFactory.create(name='My Project', short_name='mycategory')
category = self.project_repo.get_by(name='no_name')
assert category is None, category
def get_all_returns_list_of_all_categories(self):
"""Test get_all_categories returns a list of all the existing categories"""
categories = CategoryFactory.create_batch(3)
retrieved_categories = self.project_repo.get_all_categories()
assert isinstance(retrieved_categories, list)
assert len(retrieved_categories) == len(categories), retrieved_categories
for category in retrieved_categories:
assert category in categories, category
def test_filter_categories_by_no_matches(self):
"""Test filter_categories_by returns an empty list if no categories
match the query"""
CategoryFactory.create(name='My Project', short_name='mycategory')
retrieved_categories = self.project_repo.filter_categories_by(name='no_name')
assert isinstance(retrieved_categories, list)
assert len(retrieved_categories) == 0, retrieved_categories
def test_filter_categories_by_one_condition(self):
"""Test filter_categories_by returns a list of categories that meet
the filtering condition"""
CategoryFactory.create_batch(3, description='generic category')
should_be_missing = CategoryFactory.create(description='other category')
retrieved_categories = (self.project_repo
.filter_categories_by(description='generic category'))
assert len(retrieved_categories) == 3, retrieved_categories
assert should_be_missing not in retrieved_categories, retrieved_categories
def test_filter_categories_by_limit_offset(self):
"""Test that filter_categories_by supports limit and offset options"""
CategoryFactory.create_batch(4)
all_categories = self.project_repo.filter_categories_by()
first_two = self.project_repo.filter_categories_by(limit=2)
last_two = self.project_repo.filter_categories_by(limit=2, offset=2)
assert len(first_two) == 2, first_two
assert len(last_two) == 2, last_two
assert first_two == all_categories[:2]
assert last_two == all_categories[2:]
def test_save_category(self):
"""Test save_category persist the category"""
category = CategoryFactory.build()
assert self.project_repo.get(category.id) is None
self.project_repo.save_category(category)
assert self.project_repo.get_category(category.id) == category, "Category not saved"
def test_save_category_fails_if_integrity_error(self):
"""Test save_category raises a DBIntegrityError if the instance to be
saved lacks a required value"""
category = CategoryFactory.build(name=None)
assert_raises(DBIntegrityError, self.project_repo.save_category, category)
def test_save_category_only_saves_categories(self):
"""Test save_category raises a WrongObjectError when an object which is
not a Category instance is saved"""
bad_object = ProjectFactory.build()
assert_raises(WrongObjectError, self.project_repo.save_category, bad_object)
def test_update_category(self):
"""Test update_category persists the changes made to the category"""
category = CategoryFactory.create(description='this is a category')
category.description = 'the description has changed'
self.project_repo.update_category(category)
updated_category = self.project_repo.get_category(category.id)
assert updated_category.description == 'the description has changed', updated_category
def test_update_category_fails_if_integrity_error(self):
"""Test update raises a DBIntegrityError if the instance to be updated
lacks a required value"""
category = CategoryFactory.create()
category.name = None
assert_raises(DBIntegrityError, self.project_repo.update_category, category)
def test_update_category_only_updates_categories(self):
"""Test update_category raises a WrongObjectError when an object which is
not a Category instance is updated"""
bad_object = ProjectFactory.build()
assert_raises(WrongObjectError, self.project_repo.update_category, bad_object)
def test_delete_category(self):
"""Test delete_category removes the category instance"""
category = CategoryFactory.create()
self.project_repo.delete_category(category)
deleted = self.project_repo.get_category(category.id)
assert deleted is None, deleted
def test_delete_category_only_deletes_categories(self):
"""Test delete_category raises a WrongObjectError if is requested to
delete other than a category"""
bad_object = dict()
assert_raises(WrongObjectError, self.project_repo.delete_category, bad_object)