Merge lp:~michael.nelson/ubuntu-webcatalog/1025679-diffs-with-client into lp:ubuntu-webcatalog

Proposed by Michael Nelson
Status: Merged
Approved by: Łukasz Czyżykowski
Approved revision: 178
Merged at revision: 165
Proposed branch: lp:~michael.nelson/ubuntu-webcatalog/1025679-diffs-with-client
Merge into: lp:ubuntu-webcatalog
Diff against target: 812 lines (+317/-231)
7 files modified
src/webcatalog/department_filters.py (+1/-0)
src/webcatalog/fixtures/initial_data.json (+251/-224)
src/webcatalog/management/commands/import_sca_apps.py (+2/-1)
src/webcatalog/models/applications.py (+21/-6)
src/webcatalog/tests/test_commands.py (+8/-0)
src/webcatalog/tests/test_data/sca_apps.txt (+3/-0)
src/webcatalog/tests/test_models.py (+31/-0)
To merge this branch: bzr merge lp:~michael.nelson/ubuntu-webcatalog/1025679-diffs-with-client
Reviewer Review Type Date Requested Status
Łukasz Czyżykowski (community) Approve
Review via email: mp+120530@code.launchpad.net

Description of the change

Overview
========

This branch ensures exported departments on the SCA api are used to populate the departments when importing sca apps. Particularly, to ensure all the books and magazines exported from SCA are listed under the correct dept.

Additionally, it updates a few icons, as per the related bug (see screenshots there).

Details
=======

I got the current dump of departments from production, then added the "Books & Magazines", to make sure we're not overwriting any existing relationships with departments.

Note: Some pdf's are still published on the sca api with only the dept 'Education' (ie. without "Books & Magazines"):
 * 'LinuxUser Ausgabe ...
 * ADMIN-Magazin Ausgabe ...
 * Ubuntu User Ausgabe ...
 * Android User Ausgabe...
 * Others - just look for the department "Education" in the api, if it's a book/magazine it should include "Books & Magazines" :) ).

`fab test`

You can test locally by adding this to your local.cfg:

{{{
[webcatalog]
sca_api_url = http://software-center.ubuntu.com/api/2.0/
}}}
then running:
 * fab manage:import_from_sca
 * fab run
and checking the UI. You'll see this:

http://people.canonical.com/~michaeln/tmp/1025679-books-magazines.png

What becomes immediately apparent is that we should also be storing the published date or something to allow us to present these with the most recently published first?

To post a comment you must log in.
178. By Michael Nelson

REFACTOR: Don't use lists in method args :/.

Revision history for this message
Łukasz Czyżykowski (lukasz-czyzykowski) :
review: Approve
179. By Michael Nelson

Merged trunk and resolved conflict.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/webcatalog/department_filters.py'
2--- src/webcatalog/department_filters.py 2012-07-02 21:25:30 +0000
3+++ src/webcatalog/department_filters.py 2012-08-21 13:59:20 +0000
4@@ -53,6 +53,7 @@
5
6 department_filters = {
7 'Accessories': [category_filter(set(['Utility', 'System']))],
8+ 'Books & Magazines': [],
9 'Education': [category_filter(set(['Education']))],
10 'Fonts': [package_name_filter(r'[to]tf-.*')],
11 'Games': [category_filter(set(['Game', 'Sports']))],
12
13=== modified file 'src/webcatalog/fixtures/initial_data.json'
14--- src/webcatalog/fixtures/initial_data.json 2012-04-17 16:56:44 +0000
15+++ src/webcatalog/fixtures/initial_data.json 2012-08-21 13:59:20 +0000
16@@ -1,407 +1,434 @@
17 [
18 {
19- "pk": 1,
20- "model": "webcatalog.department",
21+ "pk": 1,
22+ "model": "webcatalog.department",
23 "fields": {
24- "name": "Games",
25- "parent": null,
26+ "name": "Games",
27+ "parent": null,
28 "slug": "games"
29 }
30- },
31+ },
32 {
33- "pk": 2,
34- "model": "webcatalog.department",
35+ "pk": 2,
36+ "model": "webcatalog.department",
37 "fields": {
38- "name": "Office",
39- "parent": null,
40+ "name": "Office",
41+ "parent": null,
42 "slug": "office"
43 }
44- },
45+ },
46 {
47- "pk": 3,
48- "model": "webcatalog.department",
49+ "pk": 3,
50+ "model": "webcatalog.department",
51 "fields": {
52- "name": "Sound & Video",
53- "parent": null,
54+ "name": "Sound & Video",
55+ "parent": null,
56 "slug": "sound-video"
57 }
58- },
59+ },
60 {
61- "pk": 4,
62- "model": "webcatalog.department",
63+ "pk": 4,
64+ "model": "webcatalog.department",
65 "fields": {
66- "name": "Developer Tools",
67- "parent": null,
68+ "name": "Developer Tools",
69+ "parent": null,
70 "slug": "developer-tools"
71 }
72- },
73+ },
74 {
75- "pk": 5,
76- "model": "webcatalog.department",
77+ "pk": 5,
78+ "model": "webcatalog.department",
79 "fields": {
80- "name": "Science & Engineering",
81- "parent": null,
82+ "name": "Science & Engineering",
83+ "parent": null,
84 "slug": "science-engineering"
85 }
86- },
87+ },
88 {
89- "pk": 6,
90- "model": "webcatalog.department",
91+ "pk": 6,
92+ "model": "webcatalog.department",
93 "fields": {
94- "name": "Education",
95- "parent": null,
96+ "name": "Education",
97+ "parent": null,
98 "slug": "education"
99 }
100- },
101+ },
102 {
103- "pk": 7,
104- "model": "webcatalog.department",
105+ "pk": 7,
106+ "model": "webcatalog.department",
107 "fields": {
108- "name": "Biology",
109- "parent": 5,
110+ "name": "Biology",
111+ "parent": 5,
112 "slug": "biology"
113 }
114- },
115+ },
116 {
117- "pk": 8,
118- "model": "webcatalog.department",
119+ "pk": 8,
120+ "model": "webcatalog.department",
121 "fields": {
122- "name": "Accessories",
123- "parent": null,
124+ "name": "Accessories",
125+ "parent": null,
126 "slug": "accessories"
127 }
128- },
129+ },
130 {
131- "pk": 9,
132- "model": "webcatalog.department",
133+ "pk": 9,
134+ "model": "webcatalog.department",
135 "fields": {
136- "name": "Role-Playing",
137- "parent": 1,
138+ "name": "Role-Playing",
139+ "parent": 1,
140 "slug": "role-playing"
141 }
142- },
143+ },
144 {
145- "pk": 10,
146- "model": "webcatalog.department",
147+ "pk": 10,
148+ "model": "webcatalog.department",
149 "fields": {
150- "name": "Geography",
151- "parent": 5,
152+ "name": "Geography",
153+ "parent": 5,
154 "slug": "geography"
155 }
156- },
157+ },
158 {
159- "pk": 13,
160- "model": "webcatalog.department",
161+ "pk": 13,
162+ "model": "webcatalog.department",
163 "fields": {
164- "name": "Graphics",
165- "parent": null,
166+ "name": "Graphics",
167+ "parent": null,
168 "slug": "graphics"
169 }
170- },
171+ },
172 {
173- "pk": 12,
174- "model": "webcatalog.department",
175+ "pk": 12,
176+ "model": "webcatalog.department",
177 "fields": {
178- "name": "Viewers",
179- "parent": 13,
180+ "name": "Viewers",
181+ "parent": 13,
182 "slug": "viewers"
183 }
184- },
185+ },
186 {
187- "pk": 14,
188- "model": "webcatalog.department",
189+ "pk": 14,
190+ "model": "webcatalog.department",
191 "fields": {
192- "name": "Themes & Tweaks",
193- "parent": null,
194+ "name": "Themes & Tweaks",
195+ "parent": null,
196 "slug": "themes-tweaks"
197 }
198- },
199+ },
200 {
201- "pk": 15,
202- "model": "webcatalog.department",
203+ "pk": 15,
204+ "model": "webcatalog.department",
205 "fields": {
206- "name": "Internet",
207- "parent": null,
208+ "name": "Internet",
209+ "parent": null,
210 "slug": "internet"
211 }
212- },
213+ },
214 {
215- "pk": 16,
216- "model": "webcatalog.department",
217+ "pk": 16,
218+ "model": "webcatalog.department",
219 "fields": {
220- "name": "Debugging",
221- "parent": 4,
222+ "name": "Debugging",
223+ "parent": 4,
224 "slug": "debugging"
225 }
226- },
227+ },
228 {
229- "pk": 17,
230- "model": "webcatalog.department",
231+ "pk": 17,
232+ "model": "webcatalog.department",
233 "fields": {
234- "name": "Profiling",
235- "parent": 4,
236+ "name": "Profiling",
237+ "parent": 4,
238 "slug": "profiling"
239 }
240- },
241+ },
242 {
243- "pk": 18,
244- "model": "webcatalog.department",
245+ "pk": 18,
246+ "model": "webcatalog.department",
247 "fields": {
248- "name": "Chat",
249- "parent": 15,
250+ "name": "Chat",
251+ "parent": 15,
252 "slug": "chat"
253 }
254- },
255+ },
256 {
257- "pk": 19,
258- "model": "webcatalog.department",
259+ "pk": 19,
260+ "model": "webcatalog.department",
261 "fields": {
262- "name": "IDEs",
263- "parent": 4,
264+ "name": "IDEs",
265+ "parent": 4,
266 "slug": "ides"
267 }
268- },
269+ },
270 {
271- "pk": 20,
272- "model": "webcatalog.department",
273+ "pk": 20,
274+ "model": "webcatalog.department",
275 "fields": {
276- "name": "3D",
277- "parent": 13,
278+ "name": "3D",
279+ "parent": 13,
280 "slug": "3d"
281 }
282- },
283+ },
284 {
285- "pk": 21,
286- "model": "webcatalog.department",
287+ "pk": 21,
288+ "model": "webcatalog.department",
289 "fields": {
290- "name": "Engineering",
291- "parent": 5,
292+ "name": "Engineering",
293+ "parent": 5,
294 "slug": "engineering"
295 }
296- },
297+ },
298 {
299- "pk": 22,
300- "model": "webcatalog.department",
301+ "pk": 22,
302+ "model": "webcatalog.department",
303 "fields": {
304- "name": "Electronics",
305- "parent": 5,
306+ "name": "Electronics",
307+ "parent": 5,
308 "slug": "electronics"
309 }
310- },
311+ },
312 {
313- "pk": 23,
314- "model": "webcatalog.department",
315+ "pk": 23,
316+ "model": "webcatalog.department",
317 "fields": {
318- "name": "Web Browsers",
319- "parent": 15,
320+ "name": "Web Browsers",
321+ "parent": 15,
322 "slug": "web-browsers"
323 }
324- },
325+ },
326 {
327- "pk": 24,
328- "model": "webcatalog.department",
329+ "pk": 24,
330+ "model": "webcatalog.department",
331 "fields": {
332- "name": "Mathematics",
333- "parent": 5,
334+ "name": "Mathematics",
335+ "parent": 5,
336 "slug": "mathematics"
337 }
338- },
339+ },
340 {
341- "pk": 25,
342- "model": "webcatalog.department",
343+ "pk": 25,
344+ "model": "webcatalog.department",
345 "fields": {
346- "name": "Chemistry",
347- "parent": 5,
348+ "name": "Chemistry",
349+ "parent": 5,
350 "slug": "chemistry"
351 }
352- },
353+ },
354 {
355- "pk": 26,
356- "model": "webcatalog.department",
357+ "pk": 26,
358+ "model": "webcatalog.department",
359 "fields": {
360- "name": "Physics",
361- "parent": 5,
362+ "name": "Physics",
363+ "parent": 5,
364 "slug": "physics"
365 }
366- },
367+ },
368 {
369- "pk": 28,
370- "model": "webcatalog.department",
371+ "pk": 28,
372+ "model": "webcatalog.department",
373 "fields": {
374- "name": "Mail",
375- "parent": 15,
376+ "name": "Mail",
377+ "parent": 15,
378 "slug": "mail"
379 }
380- },
381+ },
382 {
383- "pk": 29,
384- "model": "webcatalog.department",
385+ "pk": 29,
386+ "model": "webcatalog.department",
387 "fields": {
388- "name": "Computing & Robotics",
389- "parent": 5,
390+ "name": "Computing & Robotics",
391+ "parent": 5,
392 "slug": "computing-robotics"
393 }
394- },
395+ },
396 {
397- "pk": 30,
398- "model": "webcatalog.department",
399+ "pk": 30,
400+ "model": "webcatalog.department",
401 "fields": {
402- "name": "Web Development",
403- "parent": 4,
404+ "name": "Web Development",
405+ "parent": 4,
406 "slug": "web-development"
407 }
408- },
409+ },
410 {
411- "pk": 31,
412- "model": "webcatalog.department",
413+ "pk": 31,
414+ "model": "webcatalog.department",
415 "fields": {
416- "name": "Graphic Interface Design",
417- "parent": 4,
418+ "name": "Graphic Interface Design",
419+ "parent": 4,
420 "slug": "graphic-interface-design"
421 }
422- },
423+ },
424 {
425- "pk": 32,
426- "model": "webcatalog.department",
427+ "pk": 32,
428+ "model": "webcatalog.department",
429 "fields": {
430- "name": "Version Control",
431- "parent": 4,
432+ "name": "Version Control",
433+ "parent": 4,
434 "slug": "version-control"
435 }
436- },
437+ },
438 {
439- "pk": 33,
440- "model": "webcatalog.department",
441+ "pk": 33,
442+ "model": "webcatalog.department",
443 "fields": {
444- "name": "Photography",
445- "parent": 13,
446+ "name": "Photography",
447+ "parent": 13,
448 "slug": "photography"
449 }
450- },
451+ },
452 {
453- "pk": 34,
454- "model": "webcatalog.department",
455+ "pk": 34,
456+ "model": "webcatalog.department",
457 "fields": {
458- "name": "Astronomy",
459- "parent": 5,
460+ "name": "Astronomy",
461+ "parent": 5,
462 "slug": "astronomy"
463 }
464- },
465+ },
466 {
467- "pk": 35,
468- "model": "webcatalog.department",
469+ "pk": 35,
470+ "model": "webcatalog.department",
471 "fields": {
472- "name": "Universal Access",
473- "parent": null,
474+ "name": "Universal Access",
475+ "parent": null,
476 "slug": "universal-access"
477 }
478- },
479+ },
480 {
481- "pk": 36,
482- "model": "webcatalog.department",
483+ "pk": 36,
484+ "model": "webcatalog.department",
485 "fields": {
486- "name": "Drawing",
487- "parent": 13,
488+ "name": "Drawing",
489+ "parent": 13,
490 "slug": "drawing"
491 }
492- },
493+ },
494 {
495- "pk": 37,
496- "model": "webcatalog.department",
497+ "pk": 37,
498+ "model": "webcatalog.department",
499 "fields": {
500- "name": "Painting",
501- "parent": 13,
502+ "name": "Painting",
503+ "parent": 13,
504 "slug": "painting"
505 }
506- },
507+ },
508 {
509- "pk": 38,
510- "model": "webcatalog.department",
511+ "pk": 38,
512+ "model": "webcatalog.department",
513 "fields": {
514- "name": "Publishing",
515- "parent": 13,
516+ "name": "Publishing",
517+ "parent": 13,
518 "slug": "publishing"
519 }
520- },
521+ },
522 {
523- "pk": 39,
524- "model": "webcatalog.department",
525+ "pk": 39,
526+ "model": "webcatalog.department",
527 "fields": {
528- "name": "Localization",
529- "parent": 4,
530+ "name": "Localization",
531+ "parent": 4,
532 "slug": "localization"
533 }
534- },
535+ },
536 {
537- "pk": 40,
538- "model": "webcatalog.department",
539+ "pk": 40,
540+ "model": "webcatalog.department",
541 "fields": {
542- "name": "Scanning & OCR",
543- "parent": 13,
544+ "name": "Scanning & OCR",
545+ "parent": 13,
546 "slug": "scanning-ocr"
547 }
548- },
549+ },
550 {
551- "pk": 41,
552- "model": "webcatalog.department",
553+ "pk": 41,
554+ "model": "webcatalog.department",
555 "fields": {
556- "name": "Geology",
557- "parent": 5,
558+ "name": "Geology",
559+ "parent": 5,
560 "slug": "geology"
561 }
562- },
563+ },
564 {
565- "pk": 42,
566- "model": "webcatalog.department",
567+ "pk": 42,
568+ "model": "webcatalog.department",
569 "fields": {
570- "name": "Board Games",
571- "parent": 1,
572+ "name": "Board Games",
573+ "parent": 1,
574 "slug": "board-games"
575 }
576- },
577+ },
578 {
579- "pk": 43,
580- "model": "webcatalog.department",
581+ "pk": 43,
582+ "model": "webcatalog.department",
583 "fields": {
584- "name": "Puzzles",
585- "parent": 1,
586+ "name": "Puzzles",
587+ "parent": 1,
588 "slug": "puzzles"
589 }
590- },
591+ },
592 {
593- "pk": 44,
594- "model": "webcatalog.department",
595+ "pk": 44,
596+ "model": "webcatalog.department",
597 "fields": {
598- "name": "File Sharing",
599- "parent": 15,
600+ "name": "File Sharing",
601+ "parent": 15,
602 "slug": "file-sharing"
603 }
604- },
605+ },
606 {
607- "pk": 45,
608- "model": "webcatalog.department",
609+ "pk": 45,
610+ "model": "webcatalog.department",
611 "fields": {
612- "name": "Sports",
613- "parent": 1,
614+ "name": "Sports",
615+ "parent": 1,
616 "slug": "sports"
617 }
618- },
619+ },
620 {
621- "pk": 46,
622- "model": "webcatalog.department",
623+ "pk": 46,
624+ "model": "webcatalog.department",
625 "fields": {
626- "name": "Card Games",
627- "parent": 1,
628+ "name": "Card Games",
629+ "parent": 1,
630 "slug": "card-games"
631 }
632- },
633+ },
634 {
635- "pk": 47,
636- "model": "webcatalog.department",
637+ "pk": 47,
638+ "model": "webcatalog.department",
639 "fields": {
640- "name": "Fonts",
641- "parent": null,
642+ "name": "Fonts",
643+ "parent": null,
644 "slug": "fonts"
645 }
646+ },
647+ {
648+ "pk": 48,
649+ "model": "webcatalog.department",
650+ "fields": {
651+ "name": "Java",
652+ "parent": 4,
653+ "slug": "java"
654+ }
655+ },
656+ {
657+ "pk": 49,
658+ "model": "webcatalog.department",
659+ "fields": {
660+ "name": "Python",
661+ "parent": 4,
662+ "slug": "python"
663+ }
664+ },
665+ {
666+ "pk": 50,
667+ "model": "webcatalog.department",
668+ "fields": {
669+ "name": "Books & Magazines",
670+ "parent": null,
671+ "slug": "books-magazines"
672+ }
673 }
674 ]
675
676=== modified file 'src/webcatalog/management/commands/import_sca_apps.py'
677--- src/webcatalog/management/commands/import_sca_apps.py 2012-08-20 09:17:36 +0000
678+++ src/webcatalog/management/commands/import_sca_apps.py 2012-08-21 13:59:20 +0000
679@@ -97,7 +97,8 @@
680 app_data, distroseries)
681 if form.is_valid():
682 app = form.save()
683- app.update_departments()
684+ department_names = app_data.get('department', [])
685+ app.update_departments(department_names)
686 self.add_icon_to_app(app, data=icon_data)
687 self.output(u"{0} created.\n".format(app.name).encode('utf-8'), 1)
688 return app.package_name
689
690=== modified file 'src/webcatalog/models/applications.py'
691--- src/webcatalog/models/applications.py 2012-08-20 15:37:31 +0000
692+++ src/webcatalog/models/applications.py 2012-08-21 13:59:20 +0000
693@@ -153,17 +153,32 @@
694 .filter(application__package_name=self.package_name)
695 .distinct().order_by('-code_name'))
696
697- def update_departments(self):
698+ def update_departments(self, department_names=None):
699 """Update the list of departments for this app"""
700+ department_names = department_names or []
701+
702+ def get_dept(dept_name):
703+ dept, created = Department.objects.get_or_create(
704+ name=dept_name, defaults={'slug': slugify(dept_name)})
705+ if created:
706+ logging.warn("Department %s automatically created!" %
707+ dept_name)
708+ return dept
709+
710+ if self.imported_from_sca:
711+ if department_names:
712+ for dept_name in department_names:
713+ dept = get_dept(dept_name)
714+ self.departments.add(dept)
715+ return
716+ elif self.departments.all():
717+ return
718+
719 self.departments.clear()
720 for dept_name, dept_filters in department_filters.items():
721 for dept_filter in dept_filters:
722 if dept_filter(self):
723- dept, created = Department.objects.get_or_create(
724- name=dept_name, defaults={'slug': slugify(dept_name)})
725- if created:
726- logging.warn("Department %s automatically created!" %
727- dept_name)
728+ dept = get_dept(dept_name)
729 self.departments.add(dept)
730 break
731
732
733=== added file 'src/webcatalog/static/images/dept_icons/books-magazines.png'
734Binary files src/webcatalog/static/images/dept_icons/books-magazines.png 1970-01-01 00:00:00 +0000 and src/webcatalog/static/images/dept_icons/books-magazines.png 2012-08-21 13:59:20 +0000 differ
735=== modified file 'src/webcatalog/static/images/dept_icons/java.png'
736Binary files src/webcatalog/static/images/dept_icons/java.png 2012-05-07 14:13:45 +0000 and src/webcatalog/static/images/dept_icons/java.png 2012-08-21 13:59:20 +0000 differ
737=== added file 'src/webcatalog/static/images/dept_icons/python.png'
738Binary files src/webcatalog/static/images/dept_icons/python.png 1970-01-01 00:00:00 +0000 and src/webcatalog/static/images/dept_icons/python.png 2012-08-21 13:59:20 +0000 differ
739=== modified file 'src/webcatalog/tests/test_commands.py'
740--- src/webcatalog/tests/test_commands.py 2012-08-21 12:51:48 +0000
741+++ src/webcatalog/tests/test_commands.py 2012-08-21 13:59:20 +0000
742@@ -682,6 +682,14 @@
743 arb_apps = Application.objects.filter(package_name='eg_arb_app')
744 self.assertEqual(2, arb_apps.count())
745
746+ def test_import_sca_apps_updates_depts(self):
747+ call_command('import_for_purchase_apps')
748+
749+ app = Application.objects.get(package_name='hello',
750+ distroseries=self.natty)
751+ self.assertEqual(['Books & Magazines'],
752+ [dept.name for dept in app.departments.all()])
753+
754 def test_no_longer_existing_apps_are_removed(self):
755 precise = self.factory.make_distroseries(code_name='precise')
756 old_app = self.factory.make_application(
757
758=== modified file 'src/webcatalog/tests/test_data/sca_apps.txt'
759--- src/webcatalog/tests/test_data/sca_apps.txt 2012-06-26 09:00:21 +0000
760+++ src/webcatalog/tests/test_data/sca_apps.txt 2012-08-21 13:59:20 +0000
761@@ -14,6 +14,9 @@
762 "http://localhost:8000/screenshot_1.png",
763 "http://localhost:8000/screenshot_2.png"
764 ],
765+ "department": [
766+ "Books & Magazines"
767+ ],
768 "archive_root": "",
769 "tos_url": "",
770 "icon_url": "http://localhost:8000/site_media/icons/2011/06/eg_64x64.png",
771
772=== modified file 'src/webcatalog/tests/test_models.py'
773--- src/webcatalog/tests/test_models.py 2012-08-20 15:36:56 +0000
774+++ src/webcatalog/tests/test_models.py 2012-08-21 13:59:20 +0000
775@@ -61,6 +61,37 @@
776 self.assertEqual(1, app.departments.count())
777 self.assertEqual('Games', app.departments.get().name)
778
779+ def test_update_departments_for_sca_doesnt_clear(self):
780+ dept_names = ['dept1', 'dept2']
781+ departments = [
782+ self.factory.make_department(name) for name in dept_names]
783+ app = self.factory.make_application(imported_from_sca=True,
784+ departments=departments)
785+
786+ app.update_departments()
787+
788+ self.assertEqual(dept_names,
789+ [dept.name for dept in app.departments.all()])
790+
791+ def test_update_departments_for_sca_from_categories(self):
792+ # If an sca-imported app doesn't have any departments, it
793+ # should be updated as per the categories.
794+ app = self.factory.make_application(imported_from_sca=True)
795+ app.categories = 'Game;'
796+
797+ app.update_departments()
798+
799+ self.assertEqual(1, app.departments.count())
800+ self.assertEqual('Games', app.departments.get().name)
801+
802+ def test_update_departments_for_sca_from_departments(self):
803+ app = self.factory.make_application(imported_from_sca=True)
804+
805+ app.update_departments(['Books & Magazines'])
806+
807+ self.assertEqual(1, app.departments.count())
808+ self.assertEqual('Books & Magazines', app.departments.get().name)
809+
810 def test_crumbs_no_department(self):
811 app = self.factory.make_application()
812 app_url = reverse('wc-package-detail',

Subscribers

People subscribed via source and target branches