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
=== modified file 'src/webcatalog/admin.py'
--- src/webcatalog/admin.py 2012-06-06 17:42:04 +0000
+++ src/webcatalog/admin.py 2012-06-28 13:32:29 +0000
@@ -42,8 +42,8 @@
42 list_display = ('package_name', 'name', 'comment', 'distroseries',42 list_display = ('package_name', 'name', 'comment', 'distroseries',
43 'wilson_score')43 'wilson_score')
44 search_fields = ('package_name', 'name', 'comment')44 search_fields = ('package_name', 'name', 'comment')
45 list_filter = ('distroseries', 'for_purchase', 'is_latest', 'departments')45 list_filter = ('distroseries', 'imported_from_sca', 'is_latest',
46 exclude = ('for_purchase', 'archive_id')46 'departments')
4747
4848
49class MachineAdmin(admin.ModelAdmin):49class MachineAdmin(admin.ModelAdmin):
5050
=== modified file 'src/webcatalog/forms.py'
--- src/webcatalog/forms.py 2012-06-20 07:48:28 +0000
+++ src/webcatalog/forms.py 2012-06-28 13:32:29 +0000
@@ -62,7 +62,7 @@
6262
63 class Meta:63 class Meta:
64 model = Application64 model = Application
65 exclude = ('for_purchase', 'archive_id', 'price', 'version')65 exclude = ('imported_from_sca', 'archive_id', 'price', 'version')
6666
67 @classmethod67 @classmethod
68 def get_form_from_desktop_data(cls, str_data, distroseries):68 def get_form_from_desktop_data(cls, str_data, distroseries):
@@ -142,7 +142,7 @@
142 def from_api_data(cls, app_data, distroseries):142 def from_api_data(cls, app_data, distroseries):
143 app_data = app_data.copy()143 app_data = app_data.copy()
144 app_data['distroseries'] = distroseries.id144 app_data['distroseries'] = distroseries.id
145 app_data['for_purchase'] = True145 app_data['imported_from_sca'] = True
146 if 'description' in app_data:146 if 'description' in app_data:
147 tagline, _, description = app_data['description'].partition('\n')147 tagline, _, description = app_data['description'].partition('\n')
148 app_data['comment'] = tagline148 app_data['comment'] = tagline
@@ -150,21 +150,11 @@
150 if 'debtags' in app_data and app_data['debtags']:150 if 'debtags' in app_data and app_data['debtags']:
151 app_data['debtags'] = json.dumps([get_hw_short_description(x)151 app_data['debtags'] = json.dumps([get_hw_short_description(x)
152 for x in app_data['debtags']])152 for x in app_data['debtags']])
153 app_data['application_id'] = app_data.get('id')
154153
155 try:154 try:
156 # XXX 2012-05-03 michaeln bug=993813 We can update to use155 instance = Application.objects.get(
157 # application_id only below once an import runs on production156 package_name=app_data['package_name'],
158 # setting the application_ids.157 distroseries=distroseries)
159 archive_id = app_data.get('archive_id')
160 if archive_id:
161 instance = Application.objects.get(
162 archive_id=archive_id,
163 distroseries=distroseries)
164 else:
165 instance = Application.objects.get(
166 application_id=app_data['application_id'],
167 distroseries=distroseries)
168 except Application.DoesNotExist:158 except Application.DoesNotExist:
169 instance = None159 instance = None
170160
171161
=== added file 'src/webcatalog/migrations/0024_remove_application_id_and_rename_for_purchase.py'
--- src/webcatalog/migrations/0024_remove_application_id_and_rename_for_purchase.py 1970-01-01 00:00:00 +0000
+++ src/webcatalog/migrations/0024_remove_application_id_and_rename_for_purchase.py 2012-06-28 13:32:29 +0000
@@ -0,0 +1,169 @@
1# encoding: utf-8
2from south.db import db
3from south.v2 import SchemaMigration
4
5class Migration(SchemaMigration):
6
7 def forwards(self, orm):
8 # Deleting field 'Application.application_id'
9 db.delete_column('webcatalog_application', 'application_id')
10
11 # Renaming field 'Application.for_purchase'
12 db.rename_column('webcatalog_application', 'for_purchase', 'imported_from_sca')
13
14 def backwards(self, orm):
15 # Adding field 'Application.application_id'
16 db.add_column('webcatalog_application', 'application_id',
17 self.gf('django.db.models.fields.IntegerField')(
18 null=True, blank=True), keep_default=False)
19
20 # Renaming field 'Application.for_purchase'
21 db.rename_column('webcatalog_application', 'imported_from_sca', 'for_purchase')
22
23 models = {
24 'auth.group': {
25 'Meta': {'object_name': 'Group'},
26 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
27 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
28 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
29 },
30 'auth.permission': {
31 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
32 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
33 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
34 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
35 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
36 },
37 'auth.user': {
38 'Meta': {'object_name': 'User'},
39 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
40 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
41 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
42 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
43 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
44 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
45 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
46 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
47 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
48 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
49 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
50 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
51 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
52 },
53 'contenttypes.contenttype': {
54 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
55 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
56 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
57 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
58 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
59 },
60 'webcatalog.application': {
61 'Meta': {'ordering': "('-wilson_score', 'name')", 'unique_together': "(('distroseries', 'archive_id'),)", 'object_name': 'Application'},
62 'app_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
63 'architectures': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
64 'archive_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '64', 'null': 'True', 'blank': 'True'}),
65 'categories': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
66 'channel': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
67 'comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
68 'debtags': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
69 'departments': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['webcatalog.Department']", 'symmetrical': 'False', 'blank': 'True'}),
70 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
71 'distroseries': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.DistroSeries']"}),
72 'icon': ('django.db.models.fields.files.ImageField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
73 'icon_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
74 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
75 'imported_from_sca': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
76 'is_latest': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
77 'keywords': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
78 'license': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
79 'mimetype': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
80 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
81 'package_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
82 'popcon': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
83 'price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '7', 'decimal_places': '2', 'blank': 'True'}),
84 'ratings_average': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '3', 'decimal_places': '2', 'blank': 'True'}),
85 'ratings_histogram': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
86 'ratings_total': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
87 'section': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
88 'version': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
89 'wilson_score': ('django.db.models.fields.FloatField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
90 },
91 'webcatalog.applicationmedia': {
92 'Meta': {'ordering': "('url',)", 'unique_together': "(('application', 'url'),)", 'object_name': 'ApplicationMedia'},
93 'application': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Application']"}),
94 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
95 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
96 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
97 },
98 'webcatalog.consumer': {
99 'Meta': {'object_name': 'Consumer'},
100 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
101 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
102 'key': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
103 'secret': ('django.db.models.fields.CharField', [], {'default': "'hyPFlJHgDizTUdnTNWGRLtVITxkCXv'", 'max_length': '255', 'blank': 'True'}),
104 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
105 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'oauth_consumer'", 'unique': 'True', 'to': "orm['auth.User']"})
106 },
107 'webcatalog.department': {
108 'Meta': {'object_name': 'Department'},
109 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
110 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
111 'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Department']", 'null': 'True', 'blank': 'True'}),
112 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
113 },
114 'webcatalog.distroseries': {
115 'Meta': {'object_name': 'DistroSeries'},
116 'code_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20', 'db_index': 'True'}),
117 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
118 'prerelease': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
119 'version': ('django.db.models.fields.CharField', [], {'max_length': '10', 'blank': 'True'})
120 },
121 'webcatalog.exhibit': {
122 'Meta': {'object_name': 'Exhibit'},
123 'banner_url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
124 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
125 'display': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
126 'distroseries': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['webcatalog.DistroSeries']", 'symmetrical': 'False'}),
127 'html': ('django.db.models.fields.TextField', [], {}),
128 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
129 'package_names': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
130 'published': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
131 'sca_id': ('django.db.models.fields.IntegerField', [], {}),
132 'weight': ('django.db.models.fields.IntegerField', [], {'default': '0'})
133 },
134 'webcatalog.machine': {
135 'Meta': {'unique_together': "(('owner', 'uuid'),)", 'object_name': 'Machine'},
136 'hostname': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
137 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
138 'logo_checksum': ('django.db.models.fields.CharField', [], {'max_length': '56', 'blank': 'True'}),
139 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
140 'package_list': ('django.db.models.fields.TextField', [], {}),
141 'packages_checksum': ('django.db.models.fields.CharField', [], {'max_length': '56'}),
142 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'})
143 },
144 'webcatalog.nonce': {
145 'Meta': {'object_name': 'Nonce'},
146 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Consumer']"}),
147 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
148 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
149 'nonce': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
150 'token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Token']"})
151 },
152 'webcatalog.reviewstatsimport': {
153 'Meta': {'object_name': 'ReviewStatsImport'},
154 'distroseries': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.DistroSeries']", 'unique': 'True'}),
155 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
156 'last_import': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
157 },
158 'webcatalog.token': {
159 'Meta': {'object_name': 'Token'},
160 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['webcatalog.Consumer']"}),
161 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
162 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
163 'token': ('django.db.models.fields.CharField', [], {'default': "'jfRUKQyKMbFDEhdHVnneCWnhZtSCSALtPMdkMsVgDZgpYnjpme'", 'max_length': '50', 'primary_key': 'True'}),
164 'token_secret': ('django.db.models.fields.CharField', [], {'default': "'lwXqDRKNlctQNbzZSQkHyKccayMHZlFtpbPngazmvxMKywrNKS'", 'max_length': '50'}),
165 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
166 }
167 }
168
169 complete_apps = ['webcatalog']
0170
=== modified file 'src/webcatalog/models/applications.py'
--- src/webcatalog/models/applications.py 2012-06-26 09:08:44 +0000
+++ src/webcatalog/models/applications.py 2012-06-28 13:32:29 +0000
@@ -87,13 +87,12 @@
87 icon_name = models.CharField(max_length=255, blank=True)87 icon_name = models.CharField(max_length=255, blank=True)
88 icon = models.ImageField(88 icon = models.ImageField(
89 upload_to='icons/%Y/%m', max_length=200, null=True, blank=True)89 upload_to='icons/%Y/%m', max_length=200, null=True, blank=True)
90 for_purchase = models.BooleanField(default=False)90 imported_from_sca = models.BooleanField(default=False)
91 archive_id = models.CharField(91 archive_id = models.CharField(
92 max_length=64, null=True, db_index=True, blank=True)92 max_length=64, null=True, db_index=True, blank=True)
93 price = models.DecimalField(93 price = models.DecimalField(
94 max_digits=7, decimal_places=2, null=True,94 max_digits=7, decimal_places=2, null=True,
95 blank=True, help_text="For-purchase applications (in US Dollars).")95 blank=True, help_text="For-purchase applications (in US Dollars).")
96 application_id = models.IntegerField(null=True, blank=True)
9796
98 ratings_total = models.IntegerField(null=True, blank=True)97 ratings_total = models.IntegerField(null=True, blank=True)
99 ratings_average = models.DecimalField(98 ratings_average = models.DecimalField(
10099
=== modified file 'src/webcatalog/tests/factory.py'
--- src/webcatalog/tests/factory.py 2012-06-26 09:18:42 +0000
+++ src/webcatalog/tests/factory.py 2012-06-28 13:32:29 +0000
@@ -103,8 +103,8 @@
103 ratings_average=None, ratings_total=None,103 ratings_average=None, ratings_total=None,
104 ratings_histogram='', screenshot_url='',104 ratings_histogram='', screenshot_url='',
105 archive_id=None, version='', is_latest=False,105 archive_id=None, version='', is_latest=False,
106 wilson_score=0.0, debtags=[], application_id=None,106 wilson_score=0.0, debtags=[], departments=None,
107 departments=None, license='', price=None):107 license='', price=None):
108 if name is None:108 if name is None:
109 name = self.get_unique_string(prefix='Readable Name')109 name = self.get_unique_string(prefix='Readable Name')
110 if package_name is None:110 if package_name is None:
@@ -124,7 +124,7 @@
124 ratings_histogram=ratings_histogram,124 ratings_histogram=ratings_histogram,
125 archive_id=archive_id, version=version, is_latest=is_latest,125 archive_id=archive_id, version=version, is_latest=is_latest,
126 wilson_score=wilson_score, debtags=debtags,126 wilson_score=wilson_score, debtags=debtags,
127 application_id=application_id, license=license, price=price)127 license=license, price=price)
128128
129 if departments is not None:129 if departments is not None:
130 for d in departments:130 for d in departments:
131131
=== modified file 'src/webcatalog/tests/test_commands.py'
--- src/webcatalog/tests/test_commands.py 2012-06-26 09:00:21 +0000
+++ src/webcatalog/tests/test_commands.py 2012-06-28 13:32:29 +0000
@@ -577,17 +577,18 @@
577 self.mock_urlopen.side_effect = mock_urlopen_fn577 self.mock_urlopen.side_effect = mock_urlopen_fn
578 self.addCleanup(self.patch_urlopen.stop)578 self.addCleanup(self.patch_urlopen.stop)
579579
580 def test_app_for_purchase_is_found(self):580 def test_app_imported_from_sca_is_found(self):
581 apps_for_purchase = Application.objects.filter(for_purchase=True)581 apps_imported_from_sca = Application.objects.filter(
582 self.assertEqual(0, len(apps_for_purchase))582 imported_from_sca=True)
583 self.assertEqual(0, len(apps_imported_from_sca))
583584
584 call_command('import_for_purchase_apps')585 call_command('import_for_purchase_apps')
585586
586 app_for_purchase = Application.objects.get(name='MyApp',587 app = Application.objects.get(name='MyApp',
587 distroseries=self.natty)588 distroseries=self.natty)
588 self.assertEqual(True, app_for_purchase.for_purchase)589 self.assertEqual(True, app.imported_from_sca)
589 self.assertTrue(app_for_purchase.description.find('hello') > -1)590 self.assertTrue(app.description.find('hello') > -1)
590 self.assertEqual("Proprietary", app_for_purchase.license)591 self.assertEqual("Proprietary", app.license)
591592
592 def test_app_gets_distroseries(self):593 def test_app_gets_distroseries(self):
593 with patch_settings(UBUNTU_SERIES_FOR_VERSIONS=TEST_VERSIONS):594 with patch_settings(UBUNTU_SERIES_FOR_VERSIONS=TEST_VERSIONS):
@@ -613,13 +614,11 @@
613 distroseries=self.natty)614 distroseries=self.natty)
614 self.assertEqual(Decimal('2.50'), app.price)615 self.assertEqual(Decimal('2.50'), app.price)
615616
616 def test_existing_app_gets_updated_by_archive_id(self):617 def test_existing_app_gets_updated_by_package_name(self):
617 self.factory.make_application(618 self.factory.make_application(
618 archive_id='launchpad_zematynnad2/myppa',619 package_name='hello', distroseries=self.maverick)
619 package_name='somethingelse', distroseries=self.maverick)620 self.factory.make_application(
620 self.factory.make_application(621 package_name='hello', distroseries=self.natty)
621 archive_id='launchpad_zematynnad2/myppa',
622 package_name='somethingelse', distroseries=self.natty)
623 apps = Application.objects.filter(622 apps = Application.objects.filter(
624 distroseries__in=(self.natty, self.maverick)).count()623 distroseries__in=(self.natty, self.maverick)).count()
625 self.assertEqual(2, apps)624 self.assertEqual(2, apps)
@@ -631,8 +630,7 @@
631 distroseries__in=(self.natty, self.maverick))630 distroseries__in=(self.natty, self.maverick))
632 self.assertEqual(2, actual_apps.count())631 self.assertEqual(2, actual_apps.count())
633 for app in actual_apps:632 for app in actual_apps:
634 self.assertEqual('launchpad_zematynnad2/myppa', app.archive_id)633 self.assertTrue(app.imported_from_sca)
635 self.assertEqual('hello', app.package_name)
636634
637 def test_app_gets_icon(self):635 def test_app_gets_icon(self):
638 call_command('import_for_purchase_apps')636 call_command('import_for_purchase_apps')
639637
=== modified file 'src/webcatalog/tests/test_forms.py'
--- src/webcatalog/tests/test_forms.py 2012-06-13 08:53:46 +0000
+++ src/webcatalog/tests/test_forms.py 2012-06-28 13:32:29 +0000
@@ -176,7 +176,7 @@
176176
177 def test_from_api_data_shortens_debtag(self):177 def test_from_api_data_shortens_debtag(self):
178 app = self.factory.make_application()178 app = self.factory.make_application()
179 data = {'debtags': ['hardware::storage:cd-writer']}179 data = self.make_valid_data(debtags=['hardware::storage:cd-writer'])
180180
181 form = ForPurchaseApplicationForm.from_api_data(data, app.distroseries)181 form = ForPurchaseApplicationForm.from_api_data(data, app.distroseries)
182182
@@ -252,28 +252,6 @@
252 data.update(**kwargs)252 data.update(**kwargs)
253 return data253 return data
254254
255 def test_archive_id_none_uses_application_id(self):
256 precise = self.factory.make_distroseries(code_name='precise')
257 existing_app = self.factory.make_application(
258 archive_id=None, application_id=21, distroseries=precise)
259
260 data = self.make_valid_data(archive_id=None, id=21)
261 form = ForPurchaseApplicationForm.from_api_data(data, precise)
262
263 self.assertEqual(existing_app, form.instance)
264
265 def test_updates_application_id(self):
266 precise = self.factory.make_distroseries(code_name='precise')
267 existing_app = self.factory.make_application(
268 archive_id='foo/bar', application_id=None, distroseries=precise)
269
270 data = self.make_valid_data(archive_id='foo/bar', id=21)
271 form = ForPurchaseApplicationForm.from_api_data(data, precise)
272 form.save()
273
274 app_reloaded = Application.objects.get(id=existing_app.id)
275 self.assertEqual(21, app_reloaded.application_id)
276
277 def test_archive_id_is_set_to_none_when_supplied_as_empty_str(self):255 def test_archive_id_is_set_to_none_when_supplied_as_empty_str(self):
278 """Check that bug 1010655 is not happening again."""256 """Check that bug 1010655 is not happening again."""
279 precise = self.factory.make_distroseries(code_name='precise')257 precise = self.factory.make_distroseries(code_name='precise')
280258
=== modified file 'src/webcatalog/tests/test_managers.py'
--- src/webcatalog/tests/test_managers.py 2012-06-06 18:00:26 +0000
+++ src/webcatalog/tests/test_managers.py 2012-06-28 13:32:29 +0000
@@ -50,14 +50,14 @@
50 self.assertEqual(expected.id, retrieved.id)50 self.assertEqual(expected.id, retrieved.id)
5151
52 def test_check_latest(self):52 def test_check_latest(self):
53 for code_name in ['lucid', 'maverick', 'natty', 'oneiric']:53 for version in ['10.04', '10.10', '11.04', '11.10']:
54 dseries = self.factory.make_distroseries(code_name=code_name)54 dseries = self.factory.make_distroseries(version=version)
55 self.factory.make_application(55 self.factory.make_application(
56 package_name='foobar', distroseries=dseries)56 package_name='foobar', distroseries=dseries)
5757
58 Application.objects.check_latest('foobar')58 Application.objects.check_latest('foobar')
5959
60 retrieved = Application.objects.filter(package_name='foobar').order_by(60 retrieved = Application.objects.filter(package_name='foobar').order_by(
61 '-distroseries__code_name')61 '-distroseries__version')
62 self.assertEqual([True, False, False, False],62 self.assertEqual([True, False, False, False],
63 [app.is_latest for app in retrieved])63 [app.is_latest for app in retrieved])
6464
=== modified file 'src/webcatalog/tests/test_views.py'
--- src/webcatalog/tests/test_views.py 2012-06-26 09:40:37 +0000
+++ src/webcatalog/tests/test_views.py 2012-06-28 13:32:29 +0000
@@ -91,7 +91,7 @@
91 def get_app_and_response(self, code_name='natty', version='11.04',91 def get_app_and_response(self, code_name='natty', version='11.04',
92 arch='x86_64', name=None, comment=None,92 arch='x86_64', name=None, comment=None,
93 description=None, detail_distro=None,93 description=None, detail_distro=None,
94 detail_package=None, for_purchase=False,94 detail_package=None, imported_from_sca=False,
95 screenshot_url='', useragent=UBUNTU_USERAGENT):95 screenshot_url='', useragent=UBUNTU_USERAGENT):
96 series, created = DistroSeries.objects.get_or_create(96 series, created = DistroSeries.objects.get_or_create(
97 code_name=code_name, version=version)97 code_name=code_name, version=version)
@@ -100,8 +100,8 @@
100 name=name, comment=comment,100 name=name, comment=comment,
101 description=description,101 description=description,
102 screenshot_url=screenshot_url)102 screenshot_url=screenshot_url)
103 if for_purchase:103 if imported_from_sca:
104 app.for_purchase = True104 app.imported_from_sca = True
105 app.save()105 app.save()
106 if not detail_distro:106 if not detail_distro:
107 detail_distro = app.distroseries.code_name107 detail_distro = app.distroseries.code_name
@@ -168,7 +168,7 @@
168168
169 def test_button_for_non_puchase_app(self):169 def test_button_for_non_puchase_app(self):
170 self.factory.make_application(package_name='pkgfoo',170 self.factory.make_application(package_name='pkgfoo',
171 price=None)171 price=None)
172172
173 response = self.get_package_details_response('pkgfoo')173 response = self.get_package_details_response('pkgfoo')
174174
@@ -178,7 +178,7 @@
178178
179 def test_button_for_for_puchase_app(self):179 def test_button_for_for_puchase_app(self):
180 self.factory.make_application(package_name='pkgfoo',180 self.factory.make_application(package_name='pkgfoo',
181 price=Decimal('12.99'))181 price=Decimal('12.99'))
182182
183 response = self.get_package_details_response('pkgfoo')183 response = self.get_package_details_response('pkgfoo')
184184

Subscribers

People subscribed via source and target branches