Merge lp:~fgallina/rnr-server/django16 into lp:rnr-server

Proposed by Fabián Ezequiel Gallina
Status: Merged
Approved by: Fabián Ezequiel Gallina
Approved revision: 263
Merged at revision: 254
Proposed branch: lp:~fgallina/rnr-server/django16
Merge into: lp:rnr-server
Diff against target: 854 lines (+348/-160)
18 files modified
.bzrignore (+5/-0)
django_project/config_dev/config/main.cfg (+4/-0)
django_project/manage.py (+10/-16)
fabtasks/bootstrap.py (+26/-3)
requirements.txt (+0/-5)
src/clickreviews/tests/__init__.py (+0/-11)
src/clickreviews/tests/factory.py (+7/-2)
src/clickreviews/tests/test_handlers.py (+60/-55)
src/reviewsapp/migrations/0016_update_permissions.py (+186/-0)
src/reviewsapp/models/reviews.py (+1/-1)
src/reviewsapp/preflight.py (+4/-3)
src/reviewsapp/schema.py (+1/-1)
src/reviewsapp/tests/__init__.py (+0/-37)
src/reviewsapp/tests/factory.py (+4/-0)
src/reviewsapp/tests/helpers.py (+26/-1)
src/reviewsapp/tests/test_handlers.py (+3/-1)
src/reviewsapp/tests/test_middleware.py (+0/-24)
src/reviewsapp/tests/test_wsgi.py (+11/-0)
To merge this branch: bzr merge lp:~fgallina/rnr-server/django16
Reviewer Review Type Date Requested Status
Matias Bordese (community) Approve
Review via email: mp+228332@code.launchpad.net

Commit message

Upgrade to Django 1.6.5

To post a comment you must log in.
Revision history for this message
Matias Bordese (matiasb) wrote :

LGTM

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (60.4 KiB)

The attempt to merge lp:~fgallina/rnr-server/django16 into lp:rnr-server failed. Below is the output from the failed tests.

[localhost] local: /usr/bin/python /usr/bin/virtualenv --no-site-packages virtualenv
The --no-site-packages flag is deprecated; it is now the default behavior.
New python executable in virtualenv/bin/python
Installing distribute.............................................................................................................................................................................................done.
Installing pip...............done.
[localhost] local: virtualenv/bin/pip install -r requirements.txt
Downloading/unpacking http://corey-projects.googlecode.com/files/linux_metrics-0.1.0.tar.gz (from -r requirements.txt (line 9))
  Downloading linux_metrics-0.1.0.tar.gz
  Running setup.py egg_info for package from http://corey-projects.googlecode.com/files/linux_metrics-0.1.0.tar.gz

Downloading/unpacking bzr (from -r requirements.txt (line 5))
  Running setup.py egg_info for package bzr
    No Cython, trying Pyrex...

    The python package 'Pyrex' is not available. If the .c files are available,
    they will be built, but modifying the .pyx files will not rebuild them.

Downloading/unpacking coverage (from -r requirements.txt (line 6))
  Running setup.py egg_info for package coverage

    warning: no previously-included files matching '*.pyc' found anywhere in distribution
Downloading/unpacking django-pgtools==0.1 (from -r requirements.txt (line 7))
  Running setup.py egg_info for package django-pgtools

Downloading/unpacking django-factory==0.11 (from -r requirements.txt (line 8))
  Downloading django_factory-0.11.tar.gz
  Running setup.py egg_info for package django-factory

    warning: no previously-included files matching '*.pyc' found anywhere in distribution
Downloading/unpacking httplib2==0.6.0 (from -r requirements.txt (line 10))
  Running setup.py egg_info for package httplib2

Downloading/unpacking launchpadlib==1.9.12 (from -r requirements.txt (line 11))
  Running setup.py egg_info for package launchpadlib

Downloading/unpacking lazr.restfulclient==0.12.0 (from -r requirements.txt (line 12))
  Running setup.py egg_info for package lazr.restfulclient

Downloading/unpacking mechanize (from -r requirements.txt (line 13))
  Running setup.py egg_info for package mechanize

Downloading/unpacking mock (from -r requirements.txt (line 14))
  Running setup.py egg_info for package mock

    warning: no files found matching '*.png' under directory 'docs'
    warning: no files found matching '*.css' under directory 'docs'
    warning: no files found matching '*.html' under directory 'docs'
    warning: no files found matching '*.js' under directory 'docs'
Downloading/unpacking oauthlib (from -r requirements.txt (line 15))
  Running setup.py egg_info for package oauthlib

Downloading/unpacking oops==0.0.13 (from -r requirements.txt (line 16))
  Downloading oops-0.0.13.tar.gz
  Running setup.py egg_info for package oops

Downloading/unpacking oops-datedir-repo==0.0.21 (from -r requirements.txt (line 17))
  Downloading oops_datedir_repo-0.0.21.tar.gz
...

lp:~fgallina/rnr-server/django16 updated
263. By Fabián Ezequiel Gallina

Fixes for sqlite based test runs

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2014-07-11 19:05:55 +0000
3+++ .bzrignore 2014-07-25 17:44:55 +0000
4@@ -11,7 +11,12 @@
5 django_project/rnrclient.py
6 django_project/mockssoservice
7 django_project/canonical
8+django_project/configglue
9+django_project/django
10+django_project/django_openid_auth
11+django_project/preflight
12 django_project/piston
13+django_project/south
14 django_project/oops_dictconfig
15 django_project/oops_wsgi
16 django_project/adminaudit
17
18=== modified file 'django_project/config_dev/config/main.cfg'
19--- django_project/config_dev/config/main.cfg 2014-07-11 19:05:55 +0000
20+++ django_project/config_dev/config/main.cfg 2014-07-25 17:44:55 +0000
21@@ -64,8 +64,12 @@
22
23 root_urlconf = urls
24
25+session_serializer = django.contrib.sessions.serializers.PickleSerializer
26+
27 template_dirs = ./django_project/templates/
28
29+test_runner = django.test.runner.DiscoverRunner
30+
31 installed_apps = adminaudit
32 django.contrib.admin
33 django.contrib.auth
34
35=== modified file 'django_project/manage.py'
36--- django_project/manage.py 2011-03-17 10:19:07 +0000
37+++ django_project/manage.py 2014-07-25 17:44:55 +0000
38@@ -1,17 +1,11 @@
39 #!/usr/bin/env python
40-
41-from django.core.management import execute_manager
42-try:
43- import settings # Assumed to be in a directory on the path.
44-except ImportError:
45- import sys
46- sys.stderr.write(
47- "Error: Can't find the file 'settings.py' within the "
48- "django_project. It appears you've customized things.\n"
49- "You'll have to run django-admin.py, passing it your "
50- "settings module.\n(If the file settings.py does indeed "
51- "exist, it's causing an ImportError somehow.)\n")
52- sys.exit(1)
53-
54-if __name__ == "__main__":
55- execute_manager(settings)
56+import os
57+import sys
58+
59+
60+if __name__ == '__main__':
61+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
62+
63+ from django_configglue.management import execute_from_command_line
64+
65+ execute_from_command_line(sys.argv)
66
67=== modified file 'fabtasks/bootstrap.py'
68--- fabtasks/bootstrap.py 2014-07-11 19:05:55 +0000
69+++ fabtasks/bootstrap.py 2014-07-25 17:44:55 +0000
70@@ -113,21 +113,44 @@
71 "django_project/txstatsd")
72
73 _get_or_pull_bzr_branch(
74- "lp:~ubuntuone-hackers/django-configglue/trunk",
75- "django-configglue")
76+ "lp:~configglue/configglue/trunk", "configglue", revision=112)
77+ _symlink("branches/configglue/configglue", "django_project/configglue")
78+
79+ _get_or_pull_bzr_branch(
80+ "lp:django-configglue", "django-configglue", revision=79)
81 _symlink(
82 "branches/django-configglue/django_configglue",
83 "django_project/django_configglue")
84
85 _get_or_pull_bzr_branch(
86+ "lp:~ubuntuone-pqm-team/django/stable", "django", revision="1.6.5")
87+ _symlink("branches/django/django", "django_project/django")
88+
89+ _get_or_pull_bzr_branch(
90+ "lp:~ubuntuone-pqm-team/django-openid-auth/stable",
91+ "django-openid-auth", revision=104)
92+ _symlink(
93+ "branches/django-openid-auth/django_openid_auth",
94+ "django_project/django_openid_auth")
95+
96+ _get_or_pull_bzr_branch(
97+ "lp:~canonical-isd-hackers/django-preflight/trunk",
98+ "django-preflight", revision=30)
99+ _symlink("branches/django-preflight/preflight", "django_project/preflight")
100+
101+ _get_or_pull_bzr_branch(
102 "lp:~ubuntuone-pqm-team/django-piston/stable",
103 "django-piston",
104- revision=4)
105+ revision=5)
106 _symlink(
107 "branches/django-piston/piston",
108 "django_project/piston")
109
110 _get_or_pull_bzr_branch(
111+ "lp:~ubuntuone-hackers/django-south/trunk", "django-south", revision=5)
112+ _symlink("branches/django-south/south", "django_project/south")
113+
114+ _get_or_pull_bzr_branch(
115 "lp:~canonical-isd-hackers/django-adminaudit/trunk",
116 "django-adminaudit",
117 revision=53)
118
119=== modified file 'requirements.txt'
120--- requirements.txt 2014-07-22 12:32:55 +0000
121+++ requirements.txt 2014-07-25 17:44:55 +0000
122@@ -3,12 +3,8 @@
123 -f http://code.google.com/p/httplib2/downloads/list
124 -f https://launchpad.net/django-pgtools/+download
125 bzr
126-configglue==1.0.1
127 coverage
128-django-openid-auth==0.2
129 django-pgtools==0.1
130-django-preflight
131-django==1.5.1
132 django_factory==0.11
133 http://corey-projects.googlecode.com/files/linux_metrics-0.1.0.tar.gz
134 httplib2==0.6.0
135@@ -25,7 +21,6 @@
136 python-openid
137 pytz
138 setuptools
139-south==0.7.6
140 storm
141 testtools
142 wsgi_intercept==0.4
143
144=== modified file 'src/clickreviews/tests/__init__.py'
145--- src/clickreviews/tests/__init__.py 2014-06-23 20:12:52 +0000
146+++ src/clickreviews/tests/__init__.py 2014-07-25 17:44:55 +0000
147@@ -1,11 +0,0 @@
148-from clickreviews.tests.test_utilities import VerifyPackageTestCase
149-from clickreviews.tests.test_handlers import (
150- ClickReviewsHandlerGetTestCase,
151- ClickReviewsHandlerPostTestCase,
152- ClickReviewsStatsHandlerTestCase,
153-)
154-from clickreviews.tests.test_forms import ClickPackageReviewFormTestCase
155-from clickreviews.tests.test_models import (
156- ClickPackageModelTestCase,
157- ClickPackageReviewModelTestCase,
158-)
159
160=== modified file 'src/clickreviews/tests/factory.py'
161--- src/clickreviews/tests/factory.py 2014-06-24 11:10:39 +0000
162+++ src/clickreviews/tests/factory.py 2014-07-25 17:44:55 +0000
163@@ -40,7 +40,8 @@
164 def makeClickPackageReview(
165 self, reviewer=None, click_package=None, version=None, rating="5",
166 summary=None, review_text=None, date_created=None, language=None,
167- hide=False, num_flags=0, architecture='i386', deleted=False):
168+ hide=False, num_flags=0, architecture='i386',
169+ usefulness_wilson_rating=None, deleted=False):
170 if reviewer is None:
171 reviewer = self.makeUser()
172 if click_package is None:
173@@ -60,6 +61,8 @@
174 date_deleted = datetime.now(pytz.utc)
175 else:
176 date_deleted = None
177+ if usefulness_wilson_rating is None:
178+ usefulness_wilson_rating = 0.0
179
180 architecture, created = Architecture.objects.get_or_create(
181 tag=architecture)
182@@ -69,7 +72,9 @@
183 version=version, rating=rating, summary=summary,
184 review_text=review_text, language=language,
185 hide=hide, date_created=date_created,
186- architecture=architecture, date_deleted=date_deleted)
187+ architecture=architecture,
188+ usefulness_wilson_rating=usefulness_wilson_rating,
189+ date_deleted=date_deleted)
190
191 review.click_package.update_stats()
192
193
194=== modified file 'src/clickreviews/tests/test_handlers.py'
195--- src/clickreviews/tests/test_handlers.py 2014-07-03 17:57:21 +0000
196+++ src/clickreviews/tests/test_handlers.py 2014-07-25 17:44:55 +0000
197@@ -6,18 +6,16 @@
198 from datetime import datetime
199 from io import BytesIO
200
201-from django.contrib.auth.models import User
202 from django.conf import settings
203 from django.core.cache import cache
204 from django.core.serializers.json import DateTimeAwareJSONEncoder
205 from django.core.urlresolvers import reverse
206-from django_factory import TestCase
207
208 from clickreviews.models import ClickPackage, ClickPackageReview
209 from clickreviews.tests.factory import TestCaseWithFactory
210
211
212-class ClickReviewsHandlerPostTestCase(TestCase):
213+class ClickReviewsHandlerPostTestCase(TestCaseWithFactory):
214
215 def setUp(self):
216 super(ClickReviewsHandlerPostTestCase, self).setUp()
217@@ -38,6 +36,7 @@
218
219 def make_data(self, package_name='com.ubuntu.dev.uname.pkgid',
220 rating=5):
221+ self.factory.makeArch('i386')
222 return {
223 'package_name': package_name,
224 'summary': 'Excellent',
225@@ -51,9 +50,8 @@
226 def _post_new_review(self, data, user=None, verify_result=True):
227 # Post a review as an authenticated user.
228 url = reverse('click-api-reviews')
229-
230 if user is None:
231- user = self.factory.make_one(User)
232+ user = self.factory.makeUser()
233 self.client.login(username=user.username, password='test')
234
235 response = self.client.post(
236@@ -125,19 +123,23 @@
237 self.assertEqual(5, click_package.ratings_average)
238
239
240-class ClickReviewsHandlerGetTestCase(TestCase):
241+class ClickReviewsHandlerGetTestCase(TestCaseWithFactory):
242
243 def _get_reviews(self, data=None):
244 url = reverse('click-api-reviews')
245 kwargs = {}
246 if data is not None:
247 kwargs['data'] = data
248- return self.client.get(url, **kwargs)
249+ is_authenticated_method = (
250+ 'reviewsapp.auth.SSOOAuthAuthentication.is_authenticated')
251+ with mock.patch(is_authenticated_method) as mock_is_authenticated:
252+ mock_is_authenticated.return_value = False
253+ return self.client.get(url, **kwargs)
254
255 def test_get_multiple_reviews_for_package(self):
256- package = self.factory.make_one(ClickPackage)
257- reviews = self.factory.make(5, ClickPackageReview,
258- click_package=package)
259+ package = self.factory.makeClickPackage()
260+ for _ in range(5):
261+ self.factory.makeClickPackageReview(click_package=package)
262
263 json_result = self._get_reviews(data={
264 'package_name': package.package_name,
265@@ -148,10 +150,10 @@
266 self.assertEqual(5, len(result))
267
268 def test_get_reviews_contains_correct_data(self):
269- package = self.factory.make_one(ClickPackage,
270- package_name="com.example.me.myapp")
271- review = self.factory.make_one(
272- ClickPackageReview, click_package=package, language='en',
273+ package = self.factory.makeClickPackage(
274+ package_name="com.example.me.myapp")
275+ review = self.factory.makeClickPackageReview(
276+ click_package=package, language='en',
277 rating=5, summary='Best app', review_text='Unlimited fun!',
278 version='0.1.1', date_created=datetime(
279 2014, 1, 15, 11, 13, 55, 123456, tzinfo=pytz.UTC))
280@@ -163,7 +165,7 @@
281 result = json.loads(json_result.content)
282 self.assertEqual(1, len(result))
283 result_review = result[0]
284- testme = DateTimeAwareJSONEncoder().encode(
285+ DateTimeAwareJSONEncoder().encode(
286 review.date_created).strip('"')
287 self.assertEqual({
288 'id': review.id,
289@@ -190,10 +192,10 @@
290 json.loads(result.content)['errors'].keys())
291
292 def test_doesnt_include_deleted(self):
293- package = self.factory.make_one(ClickPackage)
294- review = self.factory.make_one(ClickPackageReview,
295- click_package=package,
296- date_deleted=datetime.now(pytz.UTC))
297+ package = self.factory.makeClickPackage()
298+ self.factory.makeClickPackageReview(
299+ click_package=package,
300+ deleted=True)
301
302 json_result = self._get_reviews(data={
303 'package_name': package.package_name,
304@@ -203,11 +205,12 @@
305 self.assertEqual(0, len(result))
306
307 def test_ordered_by_wilson_rating(self):
308- package = self.factory.make_one(ClickPackage)
309+ package = self.factory.makeClickPackage()
310 wilson_ratings = [-1.5, 0, -2.5, 5.5]
311 reviews = [
312- self.factory.make_one(ClickPackageReview, click_package=package,
313- usefulness_wilson_rating=wilson_rating)
314+ self.factory.makeClickPackageReview(
315+ click_package=package,
316+ usefulness_wilson_rating=wilson_rating)
317 for wilson_rating in wilson_ratings
318 ]
319 expected_review_ids = [
320@@ -233,6 +236,29 @@
321 super(ClickReviewsStatsHandlerTestCase, self).setUp()
322 self.clear_cache()
323
324+ def make_stats_response(
325+ self, pk=1, package_name='org.some.package',
326+ histogram='[0, 0, 0, 0, 1]', ratings_total=1,
327+ ratings_average='5.00'):
328+
329+ # XXX: To be cleaned up once support for sqlite is dropped.
330+ # Using sqlite does not honor the settings for the
331+ # ratings_average DecimalField spec, ignoring max_digits and
332+ # decimal_places when returning the formatted value.
333+ db_engine = settings.DATABASES['default']['ENGINE']
334+ if db_engine == 'django.db.backends.sqlite3':
335+ ratings_average = ratings_average.rstrip('0')
336+ if ratings_average.endswith('.'):
337+ ratings_average = ratings_average[0:-1]
338+
339+ return {
340+ 'id': pk,
341+ 'package_name': package_name,
342+ 'histogram': histogram,
343+ 'ratings_total': ratings_total,
344+ 'ratings_average': ratings_average,
345+ }
346+
347 def clear_cache(self):
348 cache._cache.clear()
349 cache._expire_info.clear()
350@@ -260,19 +286,11 @@
351 foo = foo_review.click_package
352 bar = bar_review.click_package
353 self.assertEqual(2, len(reviews))
354- self.assertEqual(reviews, [{
355- 'id': foo.pk,
356- 'package_name': foo.package_name,
357- 'histogram': '[0, 0, 0, 0, 1]',
358- 'ratings_total': 1,
359- 'ratings_average': '5',
360- }, {
361- 'id': bar.pk,
362- 'package_name': bar.package_name,
363- 'histogram': '[0, 0, 0, 0, 1]',
364- 'ratings_total': 1,
365- 'ratings_average': '5',
366- }])
367+ self.assertEqual(reviews, [
368+ self.make_stats_response(
369+ pk=foo.pk, package_name=foo.package_name),
370+ self.make_stats_response(
371+ pk=bar.pk, package_name=bar.package_name)])
372
373 def test_read_for_package(self):
374 foo_review = self.factory.makeClickPackageReview(
375@@ -286,13 +304,8 @@
376 reviews = json.loads(response.content)
377
378 foo = foo_review.click_package
379- self.assertEqual(reviews, {
380- 'id': foo.pk,
381- 'package_name': foo.package_name,
382- 'histogram': '[0, 0, 0, 0, 1]',
383- 'ratings_total': 1,
384- 'ratings_average': '5',
385- })
386+ self.assertEqual(reviews, self.make_stats_response(
387+ pk=foo.pk, package_name=foo.package_name))
388
389 def test_read_for_missing_package(self):
390 response = self._request_stats(package_name='not_found')
391@@ -343,19 +356,11 @@
392
393 foo = foo_review.click_package
394 bar = bar_review.click_package
395- self.assertEqual(reviews, [{
396- 'id': foo.pk,
397- 'package_name': foo.package_name,
398- 'histogram': '[0, 0, 0, 0, 1]',
399- 'ratings_total': 1,
400- 'ratings_average': '5',
401- }, {
402- 'id': bar.pk,
403- 'package_name': bar.package_name,
404- 'histogram': '[0, 0, 0, 0, 1]',
405- 'ratings_total': 1,
406- 'ratings_average': '5',
407- }])
408+ self.assertEqual(reviews, [
409+ self.make_stats_response(
410+ pk=foo.pk, package_name=foo.package_name),
411+ self.make_stats_response(
412+ pk=bar.pk, package_name=bar.package_name)])
413
414 def test_vary_headers(self):
415 response = self._request_stats()
416
417=== added file 'src/reviewsapp/migrations/0016_update_permissions.py'
418--- src/reviewsapp/migrations/0016_update_permissions.py 1970-01-01 00:00:00 +0000
419+++ src/reviewsapp/migrations/0016_update_permissions.py 2014-07-25 17:44:55 +0000
420@@ -0,0 +1,186 @@
421+# -*- coding: utf-8 -*-
422+from django.contrib.auth.management import create_permissions
423+from django.db import transaction
424+from django.db.models import get_app, get_models
425+from south.v2 import DataMigration
426+
427+
428+class Migration(DataMigration):
429+
430+ def forwards(self, orm):
431+ """Ensures that all Permission objects for models are up to date.
432+
433+ Given this is Django a version updgrade, and there's a South
434+ bug[0] that won't let it track the permissions Meta for
435+ models, we need to ensure all of them get synced correctly for
436+ all installed apps.
437+
438+ [0] http://south.aeracode.org/ticket/211
439+ """
440+ models = get_models()
441+ apps = [get_app(model._meta.app_label) for model in models]
442+ for app in apps:
443+ # Safeguard for sqlite. See: http://bit.ly/1rRHC9Y
444+ with transaction.autocommit():
445+ create_permissions(app, models, verbosity=0)
446+
447+ models = {
448+ u'auth.group': {
449+ 'Meta': {'object_name': 'Group'},
450+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
451+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
452+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
453+ },
454+ u'auth.permission': {
455+ 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
456+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
457+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
458+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
459+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
460+ },
461+ u'auth.user': {
462+ 'Meta': {'object_name': 'User'},
463+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
464+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
465+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
466+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
467+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
468+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
469+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
470+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
471+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
472+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
473+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
474+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
475+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
476+ },
477+ u'contenttypes.contenttype': {
478+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
479+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
480+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
481+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
482+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
483+ },
484+ 'reviewsapp.architecture': {
485+ 'Meta': {'object_name': 'Architecture'},
486+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
487+ 'tag': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '16'})
488+ },
489+ 'reviewsapp.consumer': {
490+ 'Meta': {'object_name': 'Consumer'},
491+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
492+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
493+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
494+ 'secret': ('django.db.models.fields.CharField', [], {'default': "'aVPDdxZfSorFGKwCrQKmArDJpMiQrq'", 'max_length': '255', 'blank': 'True'}),
495+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
496+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'oauth_consumer'", 'unique': 'True', 'to': u"orm['auth.User']"})
497+ },
498+ 'reviewsapp.nonce': {
499+ 'Meta': {'object_name': 'Nonce'},
500+ 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Consumer']"}),
501+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
502+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
503+ 'nonce': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
504+ 'token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Token']"})
505+ },
506+ 'reviewsapp.repository': {
507+ 'Meta': {'object_name': 'Repository'},
508+ 'distroseries': ('django.db.models.fields.SlugField', [], {'max_length': '25'}),
509+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
510+ 'origin': ('django.db.models.fields.SlugField', [], {'max_length': '100'})
511+ },
512+ 'reviewsapp.review': {
513+ 'Meta': {'object_name': 'Review'},
514+ 'app_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100', 'blank': 'True'}),
515+ 'architecture': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Architecture']"}),
516+ 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 7, 25, 0, 0)'}),
517+ 'date_deleted': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
518+ 'hide': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
519+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
520+ 'language': ('django.db.models.fields.SlugField', [], {'max_length': '10'}),
521+ 'rating': ('reviewsapp.fields.IntegerRangeField', [], {}),
522+ 'repository': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Repository']"}),
523+ 'review_text': ('django.db.models.fields.CharField', [], {'max_length': '5000'}),
524+ 'reviewer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
525+ 'softwareitem': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.SoftwareItem']"}),
526+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
527+ 'usefulness_favorable': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
528+ 'usefulness_percentage': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
529+ 'usefulness_total': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
530+ 'usefulness_wilson_rating': ('django.db.models.fields.FloatField', [], {'default': '0.0'}),
531+ 'version': ('reviewsapp.fields.DebVersionField', [], {'max_length': '100', 'db_index': 'True'})
532+ },
533+ 'reviewsapp.reviewmoderation': {
534+ 'Meta': {'object_name': 'ReviewModeration'},
535+ 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 7, 25, 0, 0)'}),
536+ 'date_moderated': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
537+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
538+ 'moderation_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
539+ 'moderator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
540+ 'review': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Review']"}),
541+ 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'})
542+ },
543+ 'reviewsapp.reviewmoderationflag': {
544+ 'Meta': {'ordering': "['-date_created']", 'object_name': 'ReviewModerationFlag'},
545+ 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 7, 25, 0, 0)'}),
546+ 'description': ('django.db.models.fields.TextField', [], {}),
547+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
548+ 'review_moderation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.ReviewModeration']"}),
549+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
550+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True'})
551+ },
552+ 'reviewsapp.rnrsettings': {
553+ 'Meta': {'object_name': 'RNRSettings'},
554+ 'blacklist_words': ('django.db.models.fields.TextField', [], {'default': "''"}),
555+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
556+ 'moderation_mode': ('django.db.models.fields.CharField', [], {'default': "'passive'", 'max_length': '8'})
557+ },
558+ 'reviewsapp.softwareitem': {
559+ 'Meta': {'object_name': 'SoftwareItem'},
560+ 'date_ratings_updated': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 7, 25, 0, 0)'}),
561+ 'histogram': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
562+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
563+ 'package_name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
564+ 'ratings_average': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '3', 'decimal_places': '2'}),
565+ 'ratings_total': ('django.db.models.fields.IntegerField', [], {'default': '0'})
566+ },
567+ 'reviewsapp.softwareiteminorigin': {
568+ 'Meta': {'unique_together': "(('softwareitem', 'origin'),)", 'object_name': 'SoftwareItemInOrigin'},
569+ 'date_ratings_updated': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 7, 25, 0, 0)'}),
570+ 'histogram': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
571+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
572+ 'origin': ('django.db.models.fields.SlugField', [], {'max_length': '100'}),
573+ 'ratings_average': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '3', 'decimal_places': '2'}),
574+ 'ratings_total': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
575+ 'softwareitem': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.SoftwareItem']"})
576+ },
577+ 'reviewsapp.softwareiteminrepository': {
578+ 'Meta': {'unique_together': "(('softwareitem', 'repository'),)", 'object_name': 'SoftwareItemInRepository'},
579+ 'date_ratings_updated': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 7, 25, 0, 0)'}),
580+ 'histogram': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
581+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
582+ 'ratings_average': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '3', 'decimal_places': '2'}),
583+ 'ratings_total': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
584+ 'repository': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Repository']"}),
585+ 'softwareitem': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.SoftwareItem']"})
586+ },
587+ 'reviewsapp.token': {
588+ 'Meta': {'object_name': 'Token'},
589+ 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Consumer']"}),
590+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
591+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
592+ 'token': ('django.db.models.fields.CharField', [], {'default': "'TLaXclobaNdHsvKHbaNzyQOqCpmMIZxlDXxmFPXlgEWMTLQUCM'", 'max_length': '50', 'primary_key': 'True'}),
593+ 'token_secret': ('django.db.models.fields.CharField', [], {'default': "'JpBcFHPeJycAHuRJQFueAPjWmIirzaXhGkyULCemxhyTVHsqSc'", 'max_length': '50'}),
594+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
595+ },
596+ 'reviewsapp.usefulness': {
597+ 'Meta': {'object_name': 'Usefulness'},
598+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
599+ 'review': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviewsapp.Review']"}),
600+ 'useful': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
601+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
602+ }
603+ }
604+
605+ complete_apps = ['reviewsapp']
606+ symmetrical = True
607
608=== modified file 'src/reviewsapp/models/reviews.py'
609--- src/reviewsapp/models/reviews.py 2014-06-23 20:19:03 +0000
610+++ src/reviewsapp/models/reviews.py 2014-07-25 17:44:55 +0000
611@@ -445,7 +445,7 @@
612 class Usefulness(models.Model):
613 review = models.ForeignKey(Review, db_index=True)
614 user = models.ForeignKey(User)
615- useful = models.BooleanField(db_index=True)
616+ useful = models.BooleanField(db_index=True, default=False)
617
618 def username(self):
619 return self.user.username
620
621=== modified file 'src/reviewsapp/preflight.py'
622--- src/reviewsapp/preflight.py 2014-07-22 12:32:55 +0000
623+++ src/reviewsapp/preflight.py 2014-07-25 17:44:55 +0000
624@@ -27,9 +27,9 @@
625 import launchpadlib
626 import openid
627 import piston.utils
628+import preflight
629 import south
630 from django.conf import settings
631-from preflight import Preflight, register
632
633 import reviewsapp
634 from reviewsapp.utilities import web_services
635@@ -38,7 +38,7 @@
636 logger = logging.getLogger(__name__)
637
638
639-class RNRPreflight(Preflight):
640+class RNRPreflight(preflight.Preflight):
641
642 def versions(self):
643 return [
644@@ -47,6 +47,7 @@
645 {'name': 'openid', 'version': openid.__version__},
646 {'name': 'launchpadlib', 'version': launchpadlib.__version__},
647 {'name': 'piston', 'version': piston.utils.__version__},
648+ {'name': 'preflight', 'version': preflight.__version__},
649 {'name': 'South', 'version': south.__version__},
650 ]
651
652@@ -102,4 +103,4 @@
653 return type(pubs) == dict
654
655
656-register(RNRPreflight)
657+preflight.register(RNRPreflight)
658
659=== modified file 'src/reviewsapp/schema.py'
660--- src/reviewsapp/schema.py 2014-07-18 11:17:57 +0000
661+++ src/reviewsapp/schema.py 2014-07-25 17:44:55 +0000
662@@ -28,7 +28,7 @@
663 from django_configglue.schema import schemas
664 from oops_dictconfig.configglue_options import OopsOption
665
666-DjangoSchema = schemas.get(django.get_version())
667+DjangoSchema = schemas.get('1.6')
668
669
670 class RnRSchema(DjangoSchema):
671
672=== modified file 'src/reviewsapp/tests/__init__.py'
673--- src/reviewsapp/tests/__init__.py 2012-10-22 14:18:20 +0000
674+++ src/reviewsapp/tests/__init__.py 2014-07-25 17:44:55 +0000
675@@ -1,37 +0,0 @@
676-# This file is part of Software Center Ratings and Reviews
677-# Copyright (C) 2010 Canonical Ltd.
678-#
679-# This program is free software: you can redistribute it and/or modify
680-# it under the terms of the GNU Affero General Public License as
681-# published by the Free Software Foundation, either version 3 of the
682-# License, or (at your option) any later version.
683-#
684-# This program is distributed in the hope that it will be useful,
685-# but WITHOUT ANY WARRANTY; without even the implied warranty of
686-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
687-# GNU Affero General Public License for more details.
688-#
689-# You should have received a copy of the GNU Affero General Public License
690-# along with this program. If not, see <http://www.gnu.org/licenses/>.
691-
692-"""Pull in the different test cases so that Django's test runner finds them.
693-
694-Note: each module should define __all__ to ensure we're not importing more
695-than intended.
696-"""
697-
698-from __future__ import absolute_import
699-
700-from reviewsapp.tests.test_auth import *
701-from reviewsapp.tests.test_command_populate import *
702-from reviewsapp.tests.test_command_update_stats import *
703-from reviewsapp.tests.test_decorators import *
704-from reviewsapp.tests.test_handlers import *
705-from reviewsapp.tests.test_middleware import *
706-from reviewsapp.tests.test_models import *
707-from reviewsapp.tests.test_rnrclient import *
708-from reviewsapp.tests.test_preflight import *
709-from reviewsapp.tests.test_utilities import *
710-from reviewsapp.tests.test_views import *
711-from reviewsapp.tests.test_wsgi import *
712-from reviewsapp.tests.test_pep8 import *
713
714=== modified file 'src/reviewsapp/tests/factory.py'
715--- src/reviewsapp/tests/factory.py 2014-07-16 16:02:40 +0000
716+++ src/reviewsapp/tests/factory.py 2014-07-25 17:44:55 +0000
717@@ -81,6 +81,10 @@
718 prefix = "generic-string"
719 return prefix + str(self.getUniqueInteger())
720
721+ def makeArch(self, tag='i386'):
722+ """Gets or create an Arch with provided tag."""
723+ return Architecture.objects.get_or_create(tag=tag)
724+
725 def makeOAuthTokenAndConsumer(
726 self, user=None, consumer_secret=None, token_string=None,
727 token_secret=None, save=True):
728
729=== modified file 'src/reviewsapp/tests/helpers.py'
730--- src/reviewsapp/tests/helpers.py 2014-06-23 20:19:03 +0000
731+++ src/reviewsapp/tests/helpers.py 2014-07-25 17:44:55 +0000
732@@ -27,15 +27,39 @@
733 from contextlib import contextmanager
734 from unittest import TestCase
735
736+from django.db import (
737+ close_connection,
738+ close_old_connections,
739+ connection,
740+)
741 from django.conf import settings
742+from django.core import signals
743 from wsgi_intercept import add_wsgi_intercept, remove_wsgi_intercept
744 from wsgi_intercept.httplib2_intercept import install, uninstall
745+from wsgi_intercept.urllib2_intercept import install_opener, uninstall_opener
746
747
748 class WSGIInterceptedTestCase(TestCase):
749- def setUp(self, callbacks):
750+ def setUp(self, callbacks=None):
751 super(WSGIInterceptedTestCase, self).setUp()
752+ if callbacks is None:
753+ callbacks = {}
754+
755+ # Django 1.6 changed the way db connections are managed in the
756+ # request cycle, now it cleans up connections at request start
757+ # and end by detecting if the are usable or not. Because the
758+ # current connection in tests generates outside of the patched
759+ # wsgi request, such connections are closed and therefore
760+ # tests fail. This code prevents that:
761+ signals.request_started.disconnect(close_old_connections)
762+ signals.request_finished.disconnect(close_old_connections)
763+ self.addCleanup(
764+ signals.request_started.connect, close_old_connections)
765+ self.addCleanup(
766+ signals.request_finished.connect, close_old_connections)
767+
768 self.intercepted = []
769+ install_opener()
770 install()
771
772 for key, callback in callbacks.items():
773@@ -48,6 +72,7 @@
774 def tearDown(self):
775 for host, port in self.intercepted:
776 remove_wsgi_intercept(host, port)
777+ uninstall_opener()
778 uninstall()
779 super(WSGIInterceptedTestCase, self).tearDown()
780
781
782=== modified file 'src/reviewsapp/tests/test_handlers.py'
783--- src/reviewsapp/tests/test_handlers.py 2014-07-03 17:57:21 +0000
784+++ src/reviewsapp/tests/test_handlers.py 2014-07-25 17:44:55 +0000
785@@ -888,7 +888,9 @@
786
787
788 class SubmitReviewHandlerTestCase(TestCaseWithFactory):
789+
790 def setUp(self):
791+ super(SubmitReviewHandlerTestCase, self).setUp()
792 self.required_data = {
793 'package_name': 'inkscape',
794 'summary': 'Excellent',
795@@ -900,7 +902,7 @@
796 'language': 'en',
797 'arch_tag': 'i386',
798 }
799- super(SubmitReviewHandlerTestCase, self).setUp()
800+ self.factory.makeArch('i386')
801
802 def _post_new_review(self, data, user=None, verify_result=True):
803 # Post a review as an authenticated user.
804
805=== modified file 'src/reviewsapp/tests/test_middleware.py'
806--- src/reviewsapp/tests/test_middleware.py 2014-01-03 15:37:31 +0000
807+++ src/reviewsapp/tests/test_middleware.py 2014-07-25 17:44:55 +0000
808@@ -88,27 +88,3 @@
809
810 key = '.exceptions.ZeroDivisionError'
811 self.assert_stat_sent(key, mock_send)
812-
813-
814-class SoftTimeoutMiddlewareTestCase(TestCase):
815- @patch('django.test.client.RequestFactory._base_environ')
816- def test_delay_triggers_oops_report(self, mock_environ):
817- environ = {
818- 'REQUEST_METHOD': 'GET',
819- 'SERVER_NAME': 'testserver',
820- 'SERVER_PORT': '80',
821- 'wsgi.input': ''
822- }
823-
824- def get_environ(**request):
825- environ.update(request)
826- return environ
827- mock_environ.side_effect = get_environ
828- # soft_request_timeout is an IntConfigOption, but a float works too
829- with patch_settings(ENABLE_ARTIFICIAL_OOPS=True,
830- SOFT_REQUEST_TIMEOUT=0.1):
831- reload(reviewsapp.urls)
832- self.client.get('/reviews/delay/0.1/')
833-
834- reload(reviewsapp.urls)
835- self.assertTrue('dump-oops' in environ)
836
837=== modified file 'src/reviewsapp/tests/test_wsgi.py'
838--- src/reviewsapp/tests/test_wsgi.py 2014-01-03 15:53:10 +0000
839+++ src/reviewsapp/tests/test_wsgi.py 2014-07-25 17:44:55 +0000
840@@ -97,3 +97,14 @@
841 self.assertEqual(oops.get('type'), 'ZeroDivisionError')
842 self.assertIn('tb_text', oops)
843 self.assertTrue(oops['tb_text'].startswith(' File '))
844+
845+ def test_delay_triggers_an_oops(self):
846+ self.environ['PATH_INFO'] = '/reviews/delay/0.1/'
847+
848+ with patch_settings(SOFT_TIMEOUT_MILLISECONDS=1):
849+ self.request_wsgi_response(self.environ)
850+
851+ oops_content = self.read_oops_from_disk()
852+ self.assertEqual('SoftRequestTimeout', oops_content['type'])
853+ expected = u'Start_response over timeout 1.'
854+ self.assertEqual(expected, oops_content['value'])

Subscribers

People subscribed via source and target branches