Merge lp:~elachuni/ubuntu-webcatalog/departments into lp:ubuntu-webcatalog
- departments
- Merge into trunk
Proposed by
Anthony Lenton
Status: | Merged |
---|---|
Approved by: | Michael Nelson |
Approved revision: | 9 |
Merged at revision: | 8 |
Proposed branch: | lp:~elachuni/ubuntu-webcatalog/departments |
Merge into: | lp:ubuntu-webcatalog |
Diff against target: |
764 lines (+663/-8) 8 files modified
src/webcatalog/admin.py (+6/-2) src/webcatalog/department_filters.py (+116/-0) src/webcatalog/fixtures/initial_data.json (+370/-0) src/webcatalog/management/commands/import_app_install_data.py (+3/-2) src/webcatalog/models.py (+37/-4) src/webcatalog/tests/__init__.py (+2/-0) src/webcatalog/tests/test_department_filters.py (+69/-0) src/webcatalog/tests/test_models.py (+60/-0) |
To merge this branch: | bzr merge lp:~elachuni/ubuntu-webcatalog/departments |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Nelson (community) | Approve | ||
Review via email: mp+57424@code.launchpad.net |
Commit message
Description of the change
Overview
========
Add a Department model to loosely group applications.
Details
=======
This is needed to allow simple browsing of the site, to have apps grouped into departments like the software-center does.
A few tiny bugs were fixed while I was there, to fix failures I was getting when importing app data locally:
- Encoded unicode strings when writing to stdout in import_
- Changed Application.
- Extended max_length for Application.
- Allowed blank Application.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/webcatalog/admin.py' |
2 | --- src/webcatalog/admin.py 2011-04-08 12:25:25 +0000 |
3 | +++ src/webcatalog/admin.py 2011-04-13 02:40:59 +0000 |
4 | @@ -22,7 +22,10 @@ |
5 | with_statement, |
6 | ) |
7 | from django.contrib import admin |
8 | -from webcatalog.models import Application |
9 | +from webcatalog.models import ( |
10 | + Application, |
11 | + Department, |
12 | + ) |
13 | |
14 | __metaclass__ = type |
15 | __all__ = [ |
16 | @@ -33,6 +36,7 @@ |
17 | class ApplicationAdmin(admin.ModelAdmin): |
18 | list_display = ('package_name', 'name', 'comment') |
19 | search_fields = ('package_name', 'name', 'comment') |
20 | - |
21 | + list_filter = ('departments',) |
22 | |
23 | admin.site.register(Application, ApplicationAdmin) |
24 | +admin.site.register(Department) |
25 | |
26 | === added file 'src/webcatalog/department_filters.py' |
27 | --- src/webcatalog/department_filters.py 1970-01-01 00:00:00 +0000 |
28 | +++ src/webcatalog/department_filters.py 2011-04-13 02:40:59 +0000 |
29 | @@ -0,0 +1,116 @@ |
30 | +# -*- coding: utf-8 -*- |
31 | +# This file is part of the Ubuntu Web Catalog |
32 | +# Copyright (C) 2011 Canonical Ltd. |
33 | +# |
34 | +# This program is free software: you can redistribute it and/or modify |
35 | +# it under the terms of the GNU Affero General Public License as |
36 | +# published by the Free Software Foundation, either version 3 of the |
37 | +# License, or (at your option) any later version. |
38 | +# |
39 | +# This program is distributed in the hope that it will be useful, |
40 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
41 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
42 | +# GNU Affero General Public License for more details. |
43 | +# |
44 | +# You should have received a copy of the GNU Affero General Public License |
45 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
46 | + |
47 | +"""Department filters.""" |
48 | + |
49 | +from __future__ import ( |
50 | + absolute_import, |
51 | + with_statement, |
52 | + ) |
53 | + |
54 | +import re |
55 | + |
56 | +from django.db import models |
57 | + |
58 | +__metaclass__ = type |
59 | +__all__ = [ |
60 | + 'department_filters', |
61 | + ] |
62 | + |
63 | + |
64 | +def category_filter(categories_set): |
65 | + """Returns a filter func that checks an app for certain categories.""" |
66 | + def filter_func(app): |
67 | + return bool(app.categories_set.intersection(categories_set)) |
68 | + return filter_func |
69 | + |
70 | +def package_name_filter(name_regex): |
71 | + """Returns a filter func that checks if an app's name matches a regex""" |
72 | + def filter_func(app): |
73 | + return re.match(name_regex, app.package_name) is not None |
74 | + return filter_func |
75 | + |
76 | +def section_filter(sections): |
77 | + """Returns a filter that checks if an app is in certain sections.""" |
78 | + def filter_func(app): |
79 | + return app.section in sections |
80 | + return filter_func |
81 | + |
82 | +# Taken from https://wiki.ubuntu.com/SoftwareCenter#line-793 |
83 | + |
84 | +department_filters = { |
85 | + 'Accessories': [category_filter(set(['Utility', 'System']))], |
86 | + 'Education': [category_filter(set(['Education']))], |
87 | + 'Fonts': [package_name_filter(r'[to]tf-.*')], |
88 | + 'Games': [category_filter(set(['Game', 'Sports']))], |
89 | + 'Board Games': [category_filter(set(['BoardGame']))], |
90 | + 'Card Games': [category_filter(set(['CardGame']))], |
91 | + 'Puzzles': [category_filter(set(['LogicGame']))], |
92 | + 'Role-Playing': [category_filter(set(['RolePlaying']))], |
93 | + 'Sports': [category_filter(set(['SportsGame']))], |
94 | + 'Graphics': [category_filter(set(['Graphics']))], |
95 | + '3D': [category_filter(set(['3DGraphics']))], |
96 | + 'Drawing': [category_filter(set(['VectorGraphics']))], |
97 | + 'Painting': [category_filter(set(['RasterGraphics']))], |
98 | + 'Photography': [category_filter(set(['Photography']))], |
99 | + 'Publishing': [category_filter(set(['Publishing']))], |
100 | + 'Scanning & OCR': [category_filter(set(['Scanning', 'OCR']))], |
101 | + 'Viewers': [category_filter(set(['Viewer']))], |
102 | + 'Internet': [category_filter(set(['Network']))], |
103 | + 'Chat': [category_filter(set(['InstantMessaging', 'IRCClient']))], |
104 | + 'File Sharing': [category_filter(set(['FileTransfer']))], |
105 | + 'Mail': [category_filter(set(['Email']))], |
106 | + 'Web Browsers': [category_filter(set(['WebBrowser']))], |
107 | + 'Office': [category_filter(set(['Office']))], |
108 | + 'Science & Engineering': [category_filter(set(['Science'])), |
109 | + section_filter(['science'])], |
110 | + 'Astronomy': [category_filter(set(['Astronomy']))], |
111 | + 'Biology': [category_filter(set(['Biology']))], |
112 | + 'Chemistry': [category_filter(set(['Chemistry']))], |
113 | + 'Computing & Robotics': [category_filter(set(['ArtificialIntelligence', |
114 | + 'ComputerScience', 'Robotics']))], |
115 | + 'Electronics': [category_filter(set(['Electronics']))], |
116 | + 'Engineering': [category_filter(set(['Engineering']))], |
117 | + 'Geography': [category_filter(set(['Geography']))], |
118 | + 'Geology': [category_filter(set(['Geology', 'Geoscience']))], |
119 | + 'Mathematics': [category_filter(set(['DataVisualization', 'Math', |
120 | + 'NumericalAnalysis'])), section_filter(['math', 'gnu-r'])], |
121 | + 'Medicine': [category_filter(set(['MedicalSoftware']))], |
122 | + 'Physics': [category_filter(set(['Electricity', 'Physics']))], |
123 | + 'Sound & Video': [category_filter(set(['AudioVideo', 'Audio', 'Video']))], |
124 | + 'Themes & Tweaks': [category_filter(set(['Settings']))], |
125 | + 'Universal Access': [category_filter(set(['Accessibility']))], |
126 | + 'Developer Tools': [category_filter(set(['Development'])), |
127 | + section_filter(['devel'])], |
128 | + 'Debugging': [category_filter(set(['Debugger']))], |
129 | + 'Graphic Interface Design': [category_filter(set(['GUIDesigner']))], |
130 | + 'Haskell': [section_filter(['haskell'])], |
131 | + 'IDEs': [category_filter(set(['IDE']))], |
132 | + 'Java': [section_filter(['java'])], |
133 | + 'Libraries': [section_filter(['libdevel'])], |
134 | + 'Lisp': [section_filter(['lisp'])], |
135 | + 'Localization': [category_filter(set(['Translation']))], |
136 | + 'Mono/CLI': [section_filter(['cli-mono'])], |
137 | + 'OCaml': [section_filter(['ocaml'])], |
138 | + 'Perl': [section_filter(['perl'])], |
139 | + 'Profiling': [category_filter(set(['Profiling']))], |
140 | + 'Python': [section_filter(['python'])], |
141 | + 'Ruby': [section_filter(['ruby'])], |
142 | + 'Version Control': [category_filter(set(['RevisionControl'])), |
143 | + section_filter(['vcs'])], |
144 | + 'Web Development': [category_filter(set(['WebDevelopment']))], |
145 | +} |
146 | |
147 | === added directory 'src/webcatalog/fixtures' |
148 | === added file 'src/webcatalog/fixtures/initial_data.json' |
149 | --- src/webcatalog/fixtures/initial_data.json 1970-01-01 00:00:00 +0000 |
150 | +++ src/webcatalog/fixtures/initial_data.json 2011-04-13 02:40:59 +0000 |
151 | @@ -0,0 +1,370 @@ |
152 | +[ |
153 | + { |
154 | + "pk": 1, |
155 | + "model": "webcatalog.department", |
156 | + "fields": { |
157 | + "name": "Games", |
158 | + "parent": null |
159 | + } |
160 | + }, |
161 | + { |
162 | + "pk": 2, |
163 | + "model": "webcatalog.department", |
164 | + "fields": { |
165 | + "name": "Office", |
166 | + "parent": null |
167 | + } |
168 | + }, |
169 | + { |
170 | + "pk": 3, |
171 | + "model": "webcatalog.department", |
172 | + "fields": { |
173 | + "name": "Sound & Video", |
174 | + "parent": null |
175 | + } |
176 | + }, |
177 | + { |
178 | + "pk": 4, |
179 | + "model": "webcatalog.department", |
180 | + "fields": { |
181 | + "name": "Developer Tools", |
182 | + "parent": null |
183 | + } |
184 | + }, |
185 | + { |
186 | + "pk": 5, |
187 | + "model": "webcatalog.department", |
188 | + "fields": { |
189 | + "name": "Science & Engineering", |
190 | + "parent": null |
191 | + } |
192 | + }, |
193 | + { |
194 | + "pk": 6, |
195 | + "model": "webcatalog.department", |
196 | + "fields": { |
197 | + "name": "Education", |
198 | + "parent": null |
199 | + } |
200 | + }, |
201 | + { |
202 | + "pk": 7, |
203 | + "model": "webcatalog.department", |
204 | + "fields": { |
205 | + "name": "Biology", |
206 | + "parent": 5 |
207 | + } |
208 | + }, |
209 | + { |
210 | + "pk": 8, |
211 | + "model": "webcatalog.department", |
212 | + "fields": { |
213 | + "name": "Accessories", |
214 | + "parent": null |
215 | + } |
216 | + }, |
217 | + { |
218 | + "pk": 9, |
219 | + "model": "webcatalog.department", |
220 | + "fields": { |
221 | + "name": "Role-Playing", |
222 | + "parent": 1 |
223 | + } |
224 | + }, |
225 | + { |
226 | + "pk": 10, |
227 | + "model": "webcatalog.department", |
228 | + "fields": { |
229 | + "name": "Geography", |
230 | + "parent": 5 |
231 | + } |
232 | + }, |
233 | + { |
234 | + "pk": 11, |
235 | + "model": "webcatalog.department", |
236 | + "fields": { |
237 | + "name": "Medicine", |
238 | + "parent": 5 |
239 | + } |
240 | + }, |
241 | + { |
242 | + "pk": 12, |
243 | + "model": "webcatalog.department", |
244 | + "fields": { |
245 | + "name": "Viewers", |
246 | + "parent": 13 |
247 | + } |
248 | + }, |
249 | + { |
250 | + "pk": 13, |
251 | + "model": "webcatalog.department", |
252 | + "fields": { |
253 | + "name": "Graphics", |
254 | + "parent": null |
255 | + } |
256 | + }, |
257 | + { |
258 | + "pk": 14, |
259 | + "model": "webcatalog.department", |
260 | + "fields": { |
261 | + "name": "Themes & Tweaks", |
262 | + "parent": null |
263 | + } |
264 | + }, |
265 | + { |
266 | + "pk": 15, |
267 | + "model": "webcatalog.department", |
268 | + "fields": { |
269 | + "name": "Internet", |
270 | + "parent": null |
271 | + } |
272 | + }, |
273 | + { |
274 | + "pk": 16, |
275 | + "model": "webcatalog.department", |
276 | + "fields": { |
277 | + "name": "Debugging", |
278 | + "parent": 4 |
279 | + } |
280 | + }, |
281 | + { |
282 | + "pk": 17, |
283 | + "model": "webcatalog.department", |
284 | + "fields": { |
285 | + "name": "Profiling", |
286 | + "parent": 4 |
287 | + } |
288 | + }, |
289 | + { |
290 | + "pk": 18, |
291 | + "model": "webcatalog.department", |
292 | + "fields": { |
293 | + "name": "Chat", |
294 | + "parent": 15 |
295 | + } |
296 | + }, |
297 | + { |
298 | + "pk": 19, |
299 | + "model": "webcatalog.department", |
300 | + "fields": { |
301 | + "name": "IDEs", |
302 | + "parent": 4 |
303 | + } |
304 | + }, |
305 | + { |
306 | + "pk": 20, |
307 | + "model": "webcatalog.department", |
308 | + "fields": { |
309 | + "name": "3D", |
310 | + "parent": 13 |
311 | + } |
312 | + }, |
313 | + { |
314 | + "pk": 21, |
315 | + "model": "webcatalog.department", |
316 | + "fields": { |
317 | + "name": "Engineering", |
318 | + "parent": 5 |
319 | + } |
320 | + }, |
321 | + { |
322 | + "pk": 22, |
323 | + "model": "webcatalog.department", |
324 | + "fields": { |
325 | + "name": "Electronics", |
326 | + "parent": 5 |
327 | + } |
328 | + }, |
329 | + { |
330 | + "pk": 23, |
331 | + "model": "webcatalog.department", |
332 | + "fields": { |
333 | + "name": "Web Browsers", |
334 | + "parent": 15 |
335 | + } |
336 | + }, |
337 | + { |
338 | + "pk": 24, |
339 | + "model": "webcatalog.department", |
340 | + "fields": { |
341 | + "name": "Mathematics", |
342 | + "parent": 5 |
343 | + } |
344 | + }, |
345 | + { |
346 | + "pk": 25, |
347 | + "model": "webcatalog.department", |
348 | + "fields": { |
349 | + "name": "Chemistry", |
350 | + "parent": 5 |
351 | + } |
352 | + }, |
353 | + { |
354 | + "pk": 26, |
355 | + "model": "webcatalog.department", |
356 | + "fields": { |
357 | + "name": "Physics", |
358 | + "parent": 5 |
359 | + } |
360 | + }, |
361 | + { |
362 | + "pk": 27, |
363 | + "model": "webcatalog.department", |
364 | + "fields": { |
365 | + "name": "FileSharing", |
366 | + "parent": null |
367 | + } |
368 | + }, |
369 | + { |
370 | + "pk": 28, |
371 | + "model": "webcatalog.department", |
372 | + "fields": { |
373 | + "name": "Mail", |
374 | + "parent": 15 |
375 | + } |
376 | + }, |
377 | + { |
378 | + "pk": 29, |
379 | + "model": "webcatalog.department", |
380 | + "fields": { |
381 | + "name": "Computing & Robotics", |
382 | + "parent": 5 |
383 | + } |
384 | + }, |
385 | + { |
386 | + "pk": 30, |
387 | + "model": "webcatalog.department", |
388 | + "fields": { |
389 | + "name": "Web Development", |
390 | + "parent": 4 |
391 | + } |
392 | + }, |
393 | + { |
394 | + "pk": 31, |
395 | + "model": "webcatalog.department", |
396 | + "fields": { |
397 | + "name": "Graphic Interface Design", |
398 | + "parent": 4 |
399 | + } |
400 | + }, |
401 | + { |
402 | + "pk": 32, |
403 | + "model": "webcatalog.department", |
404 | + "fields": { |
405 | + "name": "Version Control", |
406 | + "parent": 4 |
407 | + } |
408 | + }, |
409 | + { |
410 | + "pk": 33, |
411 | + "model": "webcatalog.department", |
412 | + "fields": { |
413 | + "name": "Photography", |
414 | + "parent": 13 |
415 | + } |
416 | + }, |
417 | + { |
418 | + "pk": 34, |
419 | + "model": "webcatalog.department", |
420 | + "fields": { |
421 | + "name": "Astronomy", |
422 | + "parent": 5 |
423 | + } |
424 | + }, |
425 | + { |
426 | + "pk": 35, |
427 | + "model": "webcatalog.department", |
428 | + "fields": { |
429 | + "name": "Universal Access", |
430 | + "parent": null |
431 | + } |
432 | + }, |
433 | + { |
434 | + "pk": 36, |
435 | + "model": "webcatalog.department", |
436 | + "fields": { |
437 | + "name": "Drawing", |
438 | + "parent": 13 |
439 | + } |
440 | + }, |
441 | + { |
442 | + "pk": 37, |
443 | + "model": "webcatalog.department", |
444 | + "fields": { |
445 | + "name": "Painting", |
446 | + "parent": 13 |
447 | + } |
448 | + }, |
449 | + { |
450 | + "pk": 38, |
451 | + "model": "webcatalog.department", |
452 | + "fields": { |
453 | + "name": "Publishing", |
454 | + "parent": 13 |
455 | + } |
456 | + }, |
457 | + { |
458 | + "pk": 39, |
459 | + "model": "webcatalog.department", |
460 | + "fields": { |
461 | + "name": "Localization", |
462 | + "parent": 4 |
463 | + } |
464 | + }, |
465 | + { |
466 | + "pk": 40, |
467 | + "model": "webcatalog.department", |
468 | + "fields": { |
469 | + "name": "Scanning & OCR", |
470 | + "parent": 13 |
471 | + } |
472 | + }, |
473 | + { |
474 | + "pk": 41, |
475 | + "model": "webcatalog.department", |
476 | + "fields": { |
477 | + "name": "Geology", |
478 | + "parent": 5 |
479 | + } |
480 | + }, |
481 | + { |
482 | + "pk": 42, |
483 | + "model": "webcatalog.department", |
484 | + "fields": { |
485 | + "name": "Board Games", |
486 | + "parent": 1 |
487 | + } |
488 | + }, |
489 | + { |
490 | + "pk": 43, |
491 | + "model": "webcatalog.department", |
492 | + "fields": { |
493 | + "name": "Puzzles", |
494 | + "parent": 1 |
495 | + } |
496 | + }, |
497 | + { |
498 | + "pk": 44, |
499 | + "model": "webcatalog.department", |
500 | + "fields": { |
501 | + "name": "File Sharing", |
502 | + "parent": 15 |
503 | + } |
504 | + }, |
505 | + { |
506 | + "pk": 45, |
507 | + "model": "webcatalog.department", |
508 | + "fields": { |
509 | + "name": "Sports", |
510 | + "parent": 1 |
511 | + } |
512 | + }, |
513 | + { |
514 | + "pk": 46, |
515 | + "model": "webcatalog.department", |
516 | + "fields": { |
517 | + "name": "Card Games", |
518 | + "parent": 1 |
519 | + } |
520 | + } |
521 | +] |
522 | \ No newline at end of file |
523 | |
524 | === modified file 'src/webcatalog/management/commands/import_app_install_data.py' |
525 | --- src/webcatalog/management/commands/import_app_install_data.py 2011-04-12 15:55:30 +0000 |
526 | +++ src/webcatalog/management/commands/import_app_install_data.py 2011-04-13 02:40:59 +0000 |
527 | @@ -86,11 +86,12 @@ |
528 | |
529 | if form.is_valid(): |
530 | app = form.save() |
531 | + app.update_departments() |
532 | if self.verbosity > 0: |
533 | self.stdout.write( |
534 | - u"{0} created.\n".format(app.name)) |
535 | + u"{0} created.\n".format(app.name).encode('utf-8')) |
536 | else: |
537 | if self.verbosity > 0: |
538 | self.stdout.write( |
539 | u"Skipping {0} as input failed validation: {1}.\n".format( |
540 | - member.name, form.errors)) |
541 | + member.name, form.errors).encode('utf-8')) |
542 | |
543 | === modified file 'src/webcatalog/models.py' |
544 | --- src/webcatalog/models.py 2011-04-12 15:22:54 +0000 |
545 | +++ src/webcatalog/models.py 2011-04-13 02:40:59 +0000 |
546 | @@ -21,8 +21,13 @@ |
547 | absolute_import, |
548 | with_statement, |
549 | ) |
550 | + |
551 | +import logging |
552 | + |
553 | from django.db import models |
554 | |
555 | +from webcatalog.department_filters import department_filters |
556 | + |
557 | __metaclass__ = type |
558 | __all__ = [ |
559 | 'Application', |
560 | @@ -37,19 +42,20 @@ |
561 | # at runtime instead. |
562 | |
563 | # The following fields are extracted from app-install-data. |
564 | - package_name = models.SlugField(max_length=100) |
565 | + package_name = models.CharField(max_length=100) |
566 | name = models.CharField(max_length=255) |
567 | comment = models.CharField(max_length=255, blank=True) |
568 | popcon = models.IntegerField() |
569 | channel = models.CharField(max_length=255, blank=True) |
570 | screenshot_url = models.URLField(blank=True, |
571 | help_text="Only use this if it is other than the normal screenshot url.") |
572 | - mimetype = models.CharField(max_length=255, blank=True) |
573 | + mimetype = models.CharField(max_length=2048, blank=True) |
574 | architectures = models.CharField(max_length=255, blank=True) |
575 | keywords = models.CharField(max_length=255, blank=True) |
576 | - app_type = models.CharField(max_length=32) |
577 | + app_type = models.CharField(max_length=32, blank=True) |
578 | section = models.CharField(max_length=32) |
579 | - categories = models.CharField(max_length=255) |
580 | + categories = models.CharField(max_length=255, blank=True) |
581 | + departments = models.ManyToManyField('Department', blank=True) |
582 | |
583 | # Other desktop fields used by s-c |
584 | gnome_full_name = models.CharField(max_length=255, blank=True) |
585 | @@ -64,3 +70,30 @@ |
586 | |
587 | def __unicode__(self): |
588 | return u"{0} ({1})".format(self.name, self.package_name) |
589 | + |
590 | + @property |
591 | + def categories_set(self): |
592 | + """Return the set of categories for this app""" |
593 | + stripped = [x.strip() for x in self.categories.split(';')] |
594 | + return set(x for x in stripped if x) |
595 | + |
596 | + def update_departments(self): |
597 | + """Update the list of departments for this app""" |
598 | + self.departments.clear() |
599 | + for dept_name, dept_filters in department_filters.items(): |
600 | + for dept_filter in dept_filters: |
601 | + if dept_filter(self): |
602 | + dept, created = Department.objects.get_or_create( |
603 | + name=dept_name) |
604 | + if created: |
605 | + logging.warn("Department %s automatically created!" % |
606 | + dept_name) |
607 | + self.departments.add(dept) |
608 | + break |
609 | + |
610 | +class Department(models.Model): |
611 | + parent = models.ForeignKey('self', blank=True, null=True) |
612 | + name = models.CharField(max_length=64) |
613 | + |
614 | + def __unicode__(self): |
615 | + return self.name |
616 | |
617 | === modified file 'src/webcatalog/tests/__init__.py' |
618 | --- src/webcatalog/tests/__init__.py 2011-04-12 12:54:38 +0000 |
619 | +++ src/webcatalog/tests/__init__.py 2011-04-13 02:40:59 +0000 |
620 | @@ -19,3 +19,5 @@ |
621 | from .test_forms import * |
622 | from .test_commands import * |
623 | from .test_views import * |
624 | +from .test_department_filters import * |
625 | +from .test_models import * |
626 | |
627 | === added file 'src/webcatalog/tests/test_department_filters.py' |
628 | --- src/webcatalog/tests/test_department_filters.py 1970-01-01 00:00:00 +0000 |
629 | +++ src/webcatalog/tests/test_department_filters.py 2011-04-13 02:40:59 +0000 |
630 | @@ -0,0 +1,69 @@ |
631 | +# -*- coding: utf-8 -*- |
632 | +# This file is part of the Ubuntu Web Catalog |
633 | +# Copyright (C) 2011 Canonical Ltd. |
634 | +# |
635 | +# This program is free software: you can redistribute it and/or modify |
636 | +# it under the terms of the GNU Affero General Public License as |
637 | +# published by the Free Software Foundation, either version 3 of the |
638 | +# License, or (at your option) any later version. |
639 | +# |
640 | +# This program is distributed in the hope that it will be useful, |
641 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
642 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
643 | +# GNU Affero General Public License for more details. |
644 | +# |
645 | +# You should have received a copy of the GNU Affero General Public License |
646 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
647 | + |
648 | +"""Test cases for department filters.""" |
649 | + |
650 | +from __future__ import ( |
651 | + absolute_import, |
652 | + with_statement, |
653 | + ) |
654 | + |
655 | + |
656 | +from webcatalog.tests.factory import TestCaseWithFactory |
657 | +from webcatalog.department_filters import ( |
658 | + category_filter, |
659 | + package_name_filter, |
660 | + section_filter |
661 | + ) |
662 | + |
663 | +__metaclass__ = type |
664 | +__all__ = [ |
665 | + 'DepartmentFilterTestCase', |
666 | + ] |
667 | + |
668 | + |
669 | +class DepartmentFilterTestCase(TestCaseWithFactory): |
670 | + def test_package_name_filter(self): |
671 | + dept_filter = package_name_filter('a*$') |
672 | + app1 = self.factory.make_application(package_name='aaaaa') |
673 | + self.assertTrue(dept_filter(app1)) |
674 | + |
675 | + app2 = self.factory.make_application(package_name='aaabaa') |
676 | + self.assertFalse(dept_filter(app2)) |
677 | + |
678 | + def test_category_filter(self): |
679 | + dept_filter = category_filter(['foo', 'bar']) |
680 | + app = self.factory.make_application() |
681 | + self.assertFalse(dept_filter(app)) |
682 | + app.categories = 'foo;bin' |
683 | + self.assertTrue(dept_filter(app)) |
684 | + app.categories = 'foobin' |
685 | + self.assertFalse(dept_filter(app)) |
686 | + app.categories = '' |
687 | + self.assertFalse(dept_filter(app)) |
688 | + |
689 | + def test_section_filter(self): |
690 | + dept_filter = section_filter(['foo', 'bar']) |
691 | + app = self.factory.make_application() |
692 | + |
693 | + self.assertFalse(dept_filter(app)) |
694 | + app.section = 'foo' |
695 | + self.assertTrue(dept_filter(app)) |
696 | + app.section = 'foobin' |
697 | + self.assertFalse(dept_filter(app)) |
698 | + app.section = '' |
699 | + self.assertFalse(dept_filter(app)) |
700 | |
701 | === added file 'src/webcatalog/tests/test_models.py' |
702 | --- src/webcatalog/tests/test_models.py 1970-01-01 00:00:00 +0000 |
703 | +++ src/webcatalog/tests/test_models.py 2011-04-13 02:40:59 +0000 |
704 | @@ -0,0 +1,60 @@ |
705 | +# -*- coding: utf-8 -*- |
706 | +# This file is part of the Ubuntu Web Catalog |
707 | +# Copyright (C) 2011 Canonical Ltd. |
708 | +# |
709 | +# This program is free software: you can redistribute it and/or modify |
710 | +# it under the terms of the GNU Affero General Public License as |
711 | +# published by the Free Software Foundation, either version 3 of the |
712 | +# License, or (at your option) any later version. |
713 | +# |
714 | +# This program is distributed in the hope that it will be useful, |
715 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
716 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
717 | +# GNU Affero General Public License for more details. |
718 | +# |
719 | +# You should have received a copy of the GNU Affero General Public License |
720 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
721 | + |
722 | +"""Test cases for models.""" |
723 | + |
724 | +from __future__ import ( |
725 | + absolute_import, |
726 | + with_statement, |
727 | + ) |
728 | + |
729 | + |
730 | +from webcatalog.tests.factory import TestCaseWithFactory |
731 | +from webcatalog.models import Application |
732 | + |
733 | +__metaclass__ = type |
734 | +__all__ = [ |
735 | + 'ApplicationTestCase', |
736 | + ] |
737 | + |
738 | + |
739 | +class ApplicationTestCase(TestCaseWithFactory): |
740 | + def test_categories_set(self): |
741 | + app = self.factory.make_application() |
742 | + app.categories = 'foo;;;; bar ' |
743 | + self.assertEqual(set(['foo', 'bar']), app.categories_set) |
744 | + |
745 | + def test_empty_category_set(self): |
746 | + app = self.factory.make_application() |
747 | + app.categories = '' |
748 | + self.assertEqual(set(), app.categories_set) |
749 | + |
750 | + def test_update_empty_departments(self): |
751 | + app = self.factory.make_application() |
752 | + |
753 | + app.update_departments() |
754 | + |
755 | + self.assertEqual(0, app.departments.count()) |
756 | + |
757 | + def test_update_departments(self): |
758 | + app = self.factory.make_application() |
759 | + app.categories = 'Game;' |
760 | + |
761 | + app.update_departments() |
762 | + |
763 | + self.assertEqual(1, app.departments.count()) |
764 | + self.assertEqual('Games', app.departments.get().name) |
Excellent Anthony! I'll assume that you're also working on the ui aspect of this and grab something else this morning.
Thanks for the small import fixes too.