Merge lp:~michael.nelson/ubuntu-webcatalog/1015515-dont-create-new-app into lp:ubuntu-webcatalog

Proposed by Michael Nelson
Status: Merged
Approved by: Anthony Lenton
Approved revision: 168
Merged at revision: 152
Proposed branch: lp:~michael.nelson/ubuntu-webcatalog/1015515-dont-create-new-app
Merge into: lp:ubuntu-webcatalog
Prerequisite: lp:~michael.nelson/ubuntu-webcatalog/1015505-extras-not-propietary
Diff against target: 443 lines (+204/-70)
9 files modified
src/webcatalog/admin.py (+2/-2)
src/webcatalog/forms.py (+5/-15)
src/webcatalog/migrations/0024_remove_application_id_and_rename_for_purchase.py (+169/-0)
src/webcatalog/models/applications.py (+1/-2)
src/webcatalog/tests/factory.py (+3/-3)
src/webcatalog/tests/test_commands.py (+15/-17)
src/webcatalog/tests/test_forms.py (+1/-23)
src/webcatalog/tests/test_managers.py (+3/-3)
src/webcatalog/tests/test_views.py (+5/-5)
To merge this branch: bzr merge lp:~michael.nelson/ubuntu-webcatalog/1015515-dont-create-new-app
Reviewer Review Type Date Requested Status
Anthony Lenton (community) Approve
Review via email: mp+112131@code.launchpad.net

Commit message

Don't create new apps for the same distroseries and package_name.

Description of the change

Overview
========

Updates the form used to process sca app data so that we don't create new applications for the same distroseries just because they have different archive_ids.

Instead, if there's already an app in the same distroseries with the same package name, we update it.

I also fixed test_check_latest which was a false positive (it was passing if you ran all tests, but failing if I just ran the test case, because it was dependent on the alpha-ordering of the implicit versions being created by the test).

`fab test`

Notes: I'm currently left a little confused as to why we added application_id. We (I) added it with r116 as a way for us to distinguish apps imported from sca, given that we now had sca apps with archive_id=None. But this doesn't help distinguishing existing apps in the archive.

I don't know why we didn't go with package_name, or is package_name an issue because we may well *want* to have different versions of an app available in myapps. In which case, application_id still doesn't help, but checking for package_name+version+distroseries may.

Should we add some unique constraints for this? (unique_together=('distroseries', 'package_name', 'version') or similar.

RESOLVED after chatting with achuni:
 * Both application_id and for_purchase allow us to distinguish between sca_imported apps and archive imported (so we can remove one of them - I've deleted application_id and renamed for_purchase->imported_from_sca, as we only ever use the bool value - check with achuni).
 * We only ever want one package_name per distroseries, always preferring the sca imported data. Therefore we should add a unique_together on distroseries/packagename and a migration to ensure we have the DB in this state initially. I'll do this is the next branch (as well as ensuring that archive updates don't overwrite apps imported_from_sca).

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

Remove unnecessary exclude from admin form.

Revision history for this message
Anthony Lenton (elachuni) wrote :

Looks good! :)

+1 to remove application_id, and rename for_purchase -> imported_from_sca too.

review: Approve

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 2012-06-06 17:42:04 +0000
3+++ src/webcatalog/admin.py 2012-06-28 13:32:29 +0000
4@@ -42,8 +42,8 @@
5 list_display = ('package_name', 'name', 'comment', 'distroseries',
6 'wilson_score')
7 search_fields = ('package_name', 'name', 'comment')
8- list_filter = ('distroseries', 'for_purchase', 'is_latest', 'departments')
9- exclude = ('for_purchase', 'archive_id')
10+ list_filter = ('distroseries', 'imported_from_sca', 'is_latest',
11+ 'departments')
12
13
14 class MachineAdmin(admin.ModelAdmin):
15
16=== modified file 'src/webcatalog/forms.py'
17--- src/webcatalog/forms.py 2012-06-20 07:48:28 +0000
18+++ src/webcatalog/forms.py 2012-06-28 13:32:29 +0000
19@@ -62,7 +62,7 @@
20
21 class Meta:
22 model = Application
23- exclude = ('for_purchase', 'archive_id', 'price', 'version')
24+ exclude = ('imported_from_sca', 'archive_id', 'price', 'version')
25
26 @classmethod
27 def get_form_from_desktop_data(cls, str_data, distroseries):
28@@ -142,7 +142,7 @@
29 def from_api_data(cls, app_data, distroseries):
30 app_data = app_data.copy()
31 app_data['distroseries'] = distroseries.id
32- app_data['for_purchase'] = True
33+ app_data['imported_from_sca'] = True
34 if 'description' in app_data:
35 tagline, _, description = app_data['description'].partition('\n')
36 app_data['comment'] = tagline
37@@ -150,21 +150,11 @@
38 if 'debtags' in app_data and app_data['debtags']:
39 app_data['debtags'] = json.dumps([get_hw_short_description(x)
40 for x in app_data['debtags']])
41- app_data['application_id'] = app_data.get('id')
42
43 try:
44- # XXX 2012-05-03 michaeln bug=993813 We can update to use
45- # application_id only below once an import runs on production
46- # setting the application_ids.
47- archive_id = app_data.get('archive_id')
48- if archive_id:
49- instance = Application.objects.get(
50- archive_id=archive_id,
51- distroseries=distroseries)
52- else:
53- instance = Application.objects.get(
54- application_id=app_data['application_id'],
55- distroseries=distroseries)
56+ instance = Application.objects.get(
57+ package_name=app_data['package_name'],
58+ distroseries=distroseries)
59 except Application.DoesNotExist:
60 instance = None
61
62
63=== added file 'src/webcatalog/migrations/0024_remove_application_id_and_rename_for_purchase.py'
64--- src/webcatalog/migrations/0024_remove_application_id_and_rename_for_purchase.py 1970-01-01 00:00:00 +0000
65+++ src/webcatalog/migrations/0024_remove_application_id_and_rename_for_purchase.py 2012-06-28 13:32:29 +0000
66@@ -0,0 +1,169 @@
67+# encoding: utf-8
68+from south.db import db
69+from south.v2 import SchemaMigration
70+
71+class Migration(SchemaMigration):
72+
73+ def forwards(self, orm):
74+ # Deleting field 'Application.application_id'
75+ db.delete_column('webcatalog_application', 'application_id')
76+
77+ # Renaming field 'Application.for_purchase'
78+ db.rename_column('webcatalog_application', 'for_purchase', 'imported_from_sca')
79+
80+ def backwards(self, orm):
81+ # Adding field 'Application.application_id'
82+ db.add_column('webcatalog_application', 'application_id',
83+ self.gf('django.db.models.fields.IntegerField')(
84+ null=True, blank=True), keep_default=False)
85+
86+ # Renaming field 'Application.for_purchase'
87+ db.rename_column('webcatalog_application', 'imported_from_sca', 'for_purchase')
88+
89+ models = {
90+ 'auth.group': {
91+ 'Meta': {'object_name': 'Group'},
92+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
93+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
94+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
95+ },
96+ 'auth.permission': {
97+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
98+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
99+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
100+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
101+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
102+ },
103+ 'auth.user': {
104+ 'Meta': {'object_name': 'User'},
105+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
106+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
107+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
108+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
109+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
110+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
111+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
112+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
113+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
114+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
115+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
116+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
117+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
118+ },
119+ 'contenttypes.contenttype': {
120+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
121+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
122+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
123+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
124+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
125+ },
126+ 'webcatalog.application': {
127+ 'Meta': {'ordering': "('-wilson_score', 'name')", 'unique_together': "(('distroseries', 'archive_id'),)", 'object_name': 'Application'},
128+ 'app_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
129+ 'architectures': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
130+ 'archive_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '64', 'null': 'True', 'blank': 'True'}),
131+ 'categories': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
132+ 'channel': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
133+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
134+ 'debtags': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
135+ 'departments': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['webcatalog.Department']", 'symmetrical': 'False', 'blank': 'True'}),
136+ 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
137+ 'distroseries': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.DistroSeries']"}),
138+ 'icon': ('django.db.models.fields.files.ImageField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
139+ 'icon_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
140+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
141+ 'imported_from_sca': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
142+ 'is_latest': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
143+ 'keywords': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
144+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
145+ 'mimetype': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
146+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
147+ 'package_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
148+ 'popcon': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
149+ 'price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '7', 'decimal_places': '2', 'blank': 'True'}),
150+ 'ratings_average': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '3', 'decimal_places': '2', 'blank': 'True'}),
151+ 'ratings_histogram': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
152+ 'ratings_total': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
153+ 'section': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
154+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
155+ 'wilson_score': ('django.db.models.fields.FloatField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
156+ },
157+ 'webcatalog.applicationmedia': {
158+ 'Meta': {'ordering': "('url',)", 'unique_together': "(('application', 'url'),)", 'object_name': 'ApplicationMedia'},
159+ 'application': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Application']"}),
160+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
161+ 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
162+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
163+ },
164+ 'webcatalog.consumer': {
165+ 'Meta': {'object_name': 'Consumer'},
166+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
167+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
168+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
169+ 'secret': ('django.db.models.fields.CharField', [], {'default': "'hyPFlJHgDizTUdnTNWGRLtVITxkCXv'", 'max_length': '255', 'blank': 'True'}),
170+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
171+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'oauth_consumer'", 'unique': 'True', 'to': "orm['auth.User']"})
172+ },
173+ 'webcatalog.department': {
174+ 'Meta': {'object_name': 'Department'},
175+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
176+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
177+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Department']", 'null': 'True', 'blank': 'True'}),
178+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
179+ },
180+ 'webcatalog.distroseries': {
181+ 'Meta': {'object_name': 'DistroSeries'},
182+ 'code_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20', 'db_index': 'True'}),
183+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
184+ 'prerelease': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
185+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '10', 'blank': 'True'})
186+ },
187+ 'webcatalog.exhibit': {
188+ 'Meta': {'object_name': 'Exhibit'},
189+ 'banner_url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
190+ 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
191+ 'display': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
192+ 'distroseries': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['webcatalog.DistroSeries']", 'symmetrical': 'False'}),
193+ 'html': ('django.db.models.fields.TextField', [], {}),
194+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
195+ 'package_names': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
196+ 'published': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
197+ 'sca_id': ('django.db.models.fields.IntegerField', [], {}),
198+ 'weight': ('django.db.models.fields.IntegerField', [], {'default': '0'})
199+ },
200+ 'webcatalog.machine': {
201+ 'Meta': {'unique_together': "(('owner', 'uuid'),)", 'object_name': 'Machine'},
202+ 'hostname': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
203+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
204+ 'logo_checksum': ('django.db.models.fields.CharField', [], {'max_length': '56', 'blank': 'True'}),
205+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
206+ 'package_list': ('django.db.models.fields.TextField', [], {}),
207+ 'packages_checksum': ('django.db.models.fields.CharField', [], {'max_length': '56'}),
208+ 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'})
209+ },
210+ 'webcatalog.nonce': {
211+ 'Meta': {'object_name': 'Nonce'},
212+ 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Consumer']"}),
213+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
214+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
215+ 'nonce': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
216+ 'token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Token']"})
217+ },
218+ 'webcatalog.reviewstatsimport': {
219+ 'Meta': {'object_name': 'ReviewStatsImport'},
220+ 'distroseries': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.DistroSeries']", 'unique': 'True'}),
221+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
222+ 'last_import': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
223+ },
224+ 'webcatalog.token': {
225+ 'Meta': {'object_name': 'Token'},
226+ 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Consumer']"}),
227+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
228+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
229+ 'token': ('django.db.models.fields.CharField', [], {'default': "'jfRUKQyKMbFDEhdHVnneCWnhZtSCSALtPMdkMsVgDZgpYnjpme'", 'max_length': '50', 'primary_key': 'True'}),
230+ 'token_secret': ('django.db.models.fields.CharField', [], {'default': "'lwXqDRKNlctQNbzZSQkHyKccayMHZlFtpbPngazmvxMKywrNKS'", 'max_length': '50'}),
231+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
232+ }
233+ }
234+
235+ complete_apps = ['webcatalog']
236
237=== modified file 'src/webcatalog/models/applications.py'
238--- src/webcatalog/models/applications.py 2012-06-26 09:08:44 +0000
239+++ src/webcatalog/models/applications.py 2012-06-28 13:32:29 +0000
240@@ -87,13 +87,12 @@
241 icon_name = models.CharField(max_length=255, blank=True)
242 icon = models.ImageField(
243 upload_to='icons/%Y/%m', max_length=200, null=True, blank=True)
244- for_purchase = models.BooleanField(default=False)
245+ imported_from_sca = models.BooleanField(default=False)
246 archive_id = models.CharField(
247 max_length=64, null=True, db_index=True, blank=True)
248 price = models.DecimalField(
249 max_digits=7, decimal_places=2, null=True,
250 blank=True, help_text="For-purchase applications (in US Dollars).")
251- application_id = models.IntegerField(null=True, blank=True)
252
253 ratings_total = models.IntegerField(null=True, blank=True)
254 ratings_average = models.DecimalField(
255
256=== modified file 'src/webcatalog/tests/factory.py'
257--- src/webcatalog/tests/factory.py 2012-06-26 09:18:42 +0000
258+++ src/webcatalog/tests/factory.py 2012-06-28 13:32:29 +0000
259@@ -103,8 +103,8 @@
260 ratings_average=None, ratings_total=None,
261 ratings_histogram='', screenshot_url='',
262 archive_id=None, version='', is_latest=False,
263- wilson_score=0.0, debtags=[], application_id=None,
264- departments=None, license='', price=None):
265+ wilson_score=0.0, debtags=[], departments=None,
266+ license='', price=None):
267 if name is None:
268 name = self.get_unique_string(prefix='Readable Name')
269 if package_name is None:
270@@ -124,7 +124,7 @@
271 ratings_histogram=ratings_histogram,
272 archive_id=archive_id, version=version, is_latest=is_latest,
273 wilson_score=wilson_score, debtags=debtags,
274- application_id=application_id, license=license, price=price)
275+ license=license, price=price)
276
277 if departments is not None:
278 for d in departments:
279
280=== modified file 'src/webcatalog/tests/test_commands.py'
281--- src/webcatalog/tests/test_commands.py 2012-06-26 09:00:21 +0000
282+++ src/webcatalog/tests/test_commands.py 2012-06-28 13:32:29 +0000
283@@ -577,17 +577,18 @@
284 self.mock_urlopen.side_effect = mock_urlopen_fn
285 self.addCleanup(self.patch_urlopen.stop)
286
287- def test_app_for_purchase_is_found(self):
288- apps_for_purchase = Application.objects.filter(for_purchase=True)
289- self.assertEqual(0, len(apps_for_purchase))
290+ def test_app_imported_from_sca_is_found(self):
291+ apps_imported_from_sca = Application.objects.filter(
292+ imported_from_sca=True)
293+ self.assertEqual(0, len(apps_imported_from_sca))
294
295 call_command('import_for_purchase_apps')
296
297- app_for_purchase = Application.objects.get(name='MyApp',
298- distroseries=self.natty)
299- self.assertEqual(True, app_for_purchase.for_purchase)
300- self.assertTrue(app_for_purchase.description.find('hello') > -1)
301- self.assertEqual("Proprietary", app_for_purchase.license)
302+ app = Application.objects.get(name='MyApp',
303+ distroseries=self.natty)
304+ self.assertEqual(True, app.imported_from_sca)
305+ self.assertTrue(app.description.find('hello') > -1)
306+ self.assertEqual("Proprietary", app.license)
307
308 def test_app_gets_distroseries(self):
309 with patch_settings(UBUNTU_SERIES_FOR_VERSIONS=TEST_VERSIONS):
310@@ -613,13 +614,11 @@
311 distroseries=self.natty)
312 self.assertEqual(Decimal('2.50'), app.price)
313
314- def test_existing_app_gets_updated_by_archive_id(self):
315- self.factory.make_application(
316- archive_id='launchpad_zematynnad2/myppa',
317- package_name='somethingelse', distroseries=self.maverick)
318- self.factory.make_application(
319- archive_id='launchpad_zematynnad2/myppa',
320- package_name='somethingelse', distroseries=self.natty)
321+ def test_existing_app_gets_updated_by_package_name(self):
322+ self.factory.make_application(
323+ package_name='hello', distroseries=self.maverick)
324+ self.factory.make_application(
325+ package_name='hello', distroseries=self.natty)
326 apps = Application.objects.filter(
327 distroseries__in=(self.natty, self.maverick)).count()
328 self.assertEqual(2, apps)
329@@ -631,8 +630,7 @@
330 distroseries__in=(self.natty, self.maverick))
331 self.assertEqual(2, actual_apps.count())
332 for app in actual_apps:
333- self.assertEqual('launchpad_zematynnad2/myppa', app.archive_id)
334- self.assertEqual('hello', app.package_name)
335+ self.assertTrue(app.imported_from_sca)
336
337 def test_app_gets_icon(self):
338 call_command('import_for_purchase_apps')
339
340=== modified file 'src/webcatalog/tests/test_forms.py'
341--- src/webcatalog/tests/test_forms.py 2012-06-13 08:53:46 +0000
342+++ src/webcatalog/tests/test_forms.py 2012-06-28 13:32:29 +0000
343@@ -176,7 +176,7 @@
344
345 def test_from_api_data_shortens_debtag(self):
346 app = self.factory.make_application()
347- data = {'debtags': ['hardware::storage:cd-writer']}
348+ data = self.make_valid_data(debtags=['hardware::storage:cd-writer'])
349
350 form = ForPurchaseApplicationForm.from_api_data(data, app.distroseries)
351
352@@ -252,28 +252,6 @@
353 data.update(**kwargs)
354 return data
355
356- def test_archive_id_none_uses_application_id(self):
357- precise = self.factory.make_distroseries(code_name='precise')
358- existing_app = self.factory.make_application(
359- archive_id=None, application_id=21, distroseries=precise)
360-
361- data = self.make_valid_data(archive_id=None, id=21)
362- form = ForPurchaseApplicationForm.from_api_data(data, precise)
363-
364- self.assertEqual(existing_app, form.instance)
365-
366- def test_updates_application_id(self):
367- precise = self.factory.make_distroseries(code_name='precise')
368- existing_app = self.factory.make_application(
369- archive_id='foo/bar', application_id=None, distroseries=precise)
370-
371- data = self.make_valid_data(archive_id='foo/bar', id=21)
372- form = ForPurchaseApplicationForm.from_api_data(data, precise)
373- form.save()
374-
375- app_reloaded = Application.objects.get(id=existing_app.id)
376- self.assertEqual(21, app_reloaded.application_id)
377-
378 def test_archive_id_is_set_to_none_when_supplied_as_empty_str(self):
379 """Check that bug 1010655 is not happening again."""
380 precise = self.factory.make_distroseries(code_name='precise')
381
382=== modified file 'src/webcatalog/tests/test_managers.py'
383--- src/webcatalog/tests/test_managers.py 2012-06-06 18:00:26 +0000
384+++ src/webcatalog/tests/test_managers.py 2012-06-28 13:32:29 +0000
385@@ -50,14 +50,14 @@
386 self.assertEqual(expected.id, retrieved.id)
387
388 def test_check_latest(self):
389- for code_name in ['lucid', 'maverick', 'natty', 'oneiric']:
390- dseries = self.factory.make_distroseries(code_name=code_name)
391+ for version in ['10.04', '10.10', '11.04', '11.10']:
392+ dseries = self.factory.make_distroseries(version=version)
393 self.factory.make_application(
394 package_name='foobar', distroseries=dseries)
395
396 Application.objects.check_latest('foobar')
397
398 retrieved = Application.objects.filter(package_name='foobar').order_by(
399- '-distroseries__code_name')
400+ '-distroseries__version')
401 self.assertEqual([True, False, False, False],
402 [app.is_latest for app in retrieved])
403
404=== modified file 'src/webcatalog/tests/test_views.py'
405--- src/webcatalog/tests/test_views.py 2012-06-26 09:40:37 +0000
406+++ src/webcatalog/tests/test_views.py 2012-06-28 13:32:29 +0000
407@@ -91,7 +91,7 @@
408 def get_app_and_response(self, code_name='natty', version='11.04',
409 arch='x86_64', name=None, comment=None,
410 description=None, detail_distro=None,
411- detail_package=None, for_purchase=False,
412+ detail_package=None, imported_from_sca=False,
413 screenshot_url='', useragent=UBUNTU_USERAGENT):
414 series, created = DistroSeries.objects.get_or_create(
415 code_name=code_name, version=version)
416@@ -100,8 +100,8 @@
417 name=name, comment=comment,
418 description=description,
419 screenshot_url=screenshot_url)
420- if for_purchase:
421- app.for_purchase = True
422+ if imported_from_sca:
423+ app.imported_from_sca = True
424 app.save()
425 if not detail_distro:
426 detail_distro = app.distroseries.code_name
427@@ -168,7 +168,7 @@
428
429 def test_button_for_non_puchase_app(self):
430 self.factory.make_application(package_name='pkgfoo',
431- price=None)
432+ price=None)
433
434 response = self.get_package_details_response('pkgfoo')
435
436@@ -178,7 +178,7 @@
437
438 def test_button_for_for_puchase_app(self):
439 self.factory.make_application(package_name='pkgfoo',
440- price=Decimal('12.99'))
441+ price=Decimal('12.99'))
442
443 response = self.get_package_details_response('pkgfoo')
444

Subscribers

People subscribed via source and target branches