Merge pull request #121 from pennyfx/broken_packages_fix

Broken packages fix
This commit is contained in:
Arron Schaar 2012-02-14 15:49:37 -08:00
Родитель 15ae4a0343 1402416e36
Коммит 20db544f7d
3 изменённых файлов: 104 добавлений и 73 удалений

Просмотреть файл

@ -1536,25 +1536,25 @@ class Package(BaseModel, SearchMixin):
return self.save(iteration=iteration, **kwargs)
# a common error here is "Full Name and Author already exists"
elif ('__all__' in err and
'Package with this Author and Name already exists.' in err['__all__']):
elif ('__all__' in err.message_dict and
'Package with this Author and Name already exists.' in err.message_dict['__all__']):
log.warning('[save] name conflict (%s), trying again with new name'
% self.name)
self.full_name = None
self.name = None
return self.save()
else:
return self.save()
else:
log.error('[save] Save package validation error: %s', str(err))
raise
except IntegrityError, err:
# if id_number exists we should try again
if 'id_number' in err[1]:
self.id_number = str(int(self.id_number) + 1)
iteration += 1
log.debug('[save] IntegrityError - new id_number %s' % self.id_number)
return self.save(iteration=iteration, **kwargs)
return self.save(iteration=iteration, **kwargs)
else:
log.error('[save] Save package IntegrityError error: %s', str(err))
raise
@ -1748,7 +1748,7 @@ class Package(BaseModel, SearchMixin):
"""
if self.full_name:
return
username = self.author.username
if self.author.get_profile():
username = self.author.get_profile().nickname or username

Просмотреть файл

@ -49,9 +49,13 @@ class PackageTest(TestCase):
author=self.author,
type='a',
full_name=package.name)
self.assertRaises(ValidationError, Package.objects.create,
author=self.author, type='a', full_name=package.name)
p = Package.objects.create(author=self.author, type='a', full_name=package.name)
#test package name iteration
eq_('john-1', p.name)
eq_('john', package.name)
def test_addon_creation_with_nickname(self):
"""In production if you log in with an AMO user, the username
is set to a number and the nickname on the profile is set to the
@ -59,32 +63,32 @@ class PackageTest(TestCase):
profile = self.author.get_profile()
profile.nickname = 'Gordon'
profile.save()
package = Package(
author=self.author,
type='a'
)
package.save()
eq_(package.full_name, 'Gordon')
def test_library_creation_with_nickname(self):
profile = self.author.get_profile()
profile.nickname = 'Samuel'
profile.save()
package = Package(
author=self.author,
type='l'
)
package.save()
eq_(package.full_name, 'Samuel-lib')
def test_package_sanitization(self):
bad_text = 'Te$t"><script src="google.com"></script>!#'
good_text = 'Te$tscript srcgoogle.com/script!#'
package = Package(
author=self.author,
type='a',
@ -93,11 +97,11 @@ class PackageTest(TestCase):
version_name=bad_text
)
package.save()
eq_(package.full_name, good_text)
eq_(package.description, good_text)
eq_(package.version_name, good_text)
def test_automatic_numbering(self):
Package(
author=self.author,
@ -110,7 +114,7 @@ class PackageTest(TestCase):
)
package.save()
self.assertEqual(package.full_name, '%s (1)' % self.author.username)
def test_ordering(self):
" Newest is first "
addon1 = Package(author=self.author, type='a')
@ -124,41 +128,41 @@ class PackageTest(TestCase):
names = (addon1.full_name, addon2.full_name)
self.failUnless('%s (1)' % self.author.username in names)
self.failUnless('%s' % self.author.username in names)
def test_manager_filtering(self):
Package(author=self.author, type='a').save()
Package(author=self.author, type='a').save()
Package(author=self.author, type='l').save()
self.assertEqual(Package.objects.addons().count(), 2)
self.assertEqual(Package.objects.libraries().count(), 3)
def test_manager_sort_recently_active(self):
p1 = Package(author=self.author, type='a')
p1.save()
p2 = Package(author=self.author, type='a')
p2.save()
Package(author=self.author, type='l').save()
p1rev2 = PackageRevision(author=self.author, revision_number=2)
p1.revisions.add(p1rev2)
p1rev2.created_at = datetime.datetime.now() - datetime.timedelta(60)
super(PackageRevision, p1rev2).save()
p2rev = p2.revisions.all()[0]
p2rev.save() #makes a new revision
qs = Package.objects.sort_recently_active().filter(type='a')
eq_(qs.count(), 2)
eq_(p2.id, qs[0].id)
eq_(qs[0].rev_count, 2)
eq_(qs[1].rev_count, 1)
def test_related_name(self):
Package(author=self.author, type='a').save()
self.assertEqual(self.author.packages_originated.count(), 1)
def test_create_adddon_from_archive(self):
path_addon = os.path.join(
settings.ROOT, 'apps/jetpack/tests/sample_addon.zip')
@ -171,7 +175,7 @@ class PackageTest(TestCase):
'main' in [m.filename for m in addon.latest.modules.all()])
self.failUnless(('attachment', 'txt') in [(a.filename, a.ext)
for a in addon.latest.attachments.all()])
def test_create_library_from_archive(self):
path_library = os.path.join(
settings.ROOT, 'apps/jetpack/tests/sample_library.zip')
@ -184,7 +188,7 @@ class PackageTest(TestCase):
for m in library.latest.modules.all()])
self.failUnless(('attachment', 'txt') in [(a.filename, a.ext)
for a in library.latest.attachments.all()])
def test_create_addon_from_xpi(self):
path_xpi = os.path.join(
settings.ROOT, 'apps/jetpack/tests/sample_addon.xpi')
@ -197,7 +201,7 @@ class PackageTest(TestCase):
'main' in [m.filename for m in addon.latest.modules.all()])
self.failUnless(('attachment', 'txt') in [(a.filename, a.ext)
for a in addon.latest.attachments.all()])
def test_update_addon_from_xpi(self):
path_xpi = os.path.join(
settings.ROOT, 'apps/jetpack/tests/sample_addon.xpi')
@ -205,13 +209,13 @@ class PackageTest(TestCase):
addon = create_package_from_xpi(path_xpi, self.author)
self.failUnless(addon)
eq_(addon.revisions.count(), 2)
def test_create_addon_from_xpi_with_libs(self):
libs = ['sample_library']
path_xpi = os.path.join(
settings.ROOT, 'apps/jetpack/tests/sample_addon_with_libs.xpi')
addon = create_package_from_xpi(path_xpi, self.author, libs=libs)
eq_(len(addon.latest.dependencies.all()), 1)
lib = addon.latest.dependencies.all()[0]
self.failUnless(lib.package.name in libs)
@ -220,7 +224,7 @@ class PackageTest(TestCase):
eq_(('attachment', 'txt'), (att.filename, att.ext))
self.failUnless(os.path.isfile(
os.path.join(settings.UPLOAD_DIR, att.path)))
def test_disable(self):
addon = Package.objects.create(author=self.author, type='a')
# disabling addon
@ -228,13 +232,13 @@ class PackageTest(TestCase):
eq_(Package.objects.active().filter(type='a').count(), 0)
eq_(Package.objects.active(viewer=self.author).filter(type='a').count(), 1)
return addon
def test_enable(self):
addon = self.test_disable()
addon.enable()
eq_(Package.objects.active().filter(type='a').count(), 1)
def test_delete(self):
addon = Package.objects.create(author=self.author, type='a')
# deleting addon
@ -242,7 +246,7 @@ class PackageTest(TestCase):
eq_(Package.objects.active().filter(type='a').count(), 0)
eq_(Package.objects.active(viewer=self.author).filter(type='a').count(), 0)
eq_(PackageRevision.objects.filter(package=addon).count(), 0)
def test_delete_with_a_copy(self):
addon = Package.objects.create(author=self.author, type='a')
addon_copy = addon.copy(self.author)
@ -254,7 +258,7 @@ class PackageTest(TestCase):
eq_(Package.objects.active(viewer=self.author).addons().count(), 1)
eq_(PackageRevision.objects.filter(package=addon).count(), 0)
eq_(PackageRevision.objects.filter(package=addon_copy).count(), 1)
def test_delete_with_dependency(self):
addon = Package.objects.create(author=self.author, type='a')
lib = Package.objects.create(author=self.author, type='l')
@ -263,70 +267,70 @@ class PackageTest(TestCase):
lib.delete()
eq_(Package.objects.addons().active().count(), 1)
eq_(Package.objects.libraries().active().filter(author=self.author).count(), 0)
def test_get_outdated_dependencies(self):
addon = Package.objects.create(author=self.author, type='a')
lib = Package.objects.create(author=self.author, type='l')
addon.latest.dependency_add(lib.latest)
lib.latest.module_create(author=self.author, filename='test', code='foo')
out_of_date = addon.latest.get_outdated_dependency_versions()
eq_(len(out_of_date), 1)
def test_outdated_dependencies_with_conflicts(self):
addon = Package.objects.create(author=self.author, type='a')
lib = Package.objects.create(author=self.author, type='l')
addon.latest.dependency_add(lib.latest)
jan = User.objects.get(username='jan')
jan_lib = Package(author=jan, type='l', full_name='janjanjan')
jan_lib.save()
dupe_lib = Package(author=jan, type='l', full_name=lib.full_name)
dupe_lib.save()
addon.latest.dependency_add(jan_lib.latest)
jan_lib.latest.dependency_add(dupe_lib.latest)
out_of_date = addon.latest.get_outdated_dependency_versions()
eq_(len(out_of_date), 0)
def test_update_dependency_version(self):
addon = Package.objects.create(author=self.author, type='a')
lib = Package.objects.create(author=self.author, type='l')
addon.latest.dependency_add(lib.latest)
lib.latest.module_create(author=self.author, filename='test', code='foo')
previous_addon = addon.latest.pk
addon.latest.dependency_update(lib.latest)
self.assertNotEqual(addon.latest.pk, previous_addon)
eq_(addon.latest.dependencies.get(package=lib), lib.latest)
def test_update_invalid_dependency(self):
addon = Package.objects.create(author=self.author, type='a')
lib = Package.objects.create(author=self.author, type='l')
self.assertRaises(DependencyException,
addon.latest.dependency_update,
lib.latest)
def test_package_copy(self):
addon = Package.objects.create(author=self.author, type='a')
addon_copy = addon.copy(author=self.author)
assert "(copy 1)" in addon_copy.full_name
addon_copy = addon.copy(author=self.author)
assert "(copy 1)" not in addon_copy.full_name
assert "(copy 2)" in addon_copy.full_name
addon_copy = addon.copy(author=self.author)
assert "(copy 1)" not in addon_copy.full_name
assert "(copy 2)" not in addon_copy.full_name
assert "(copy 3)" in addon_copy.full_name
def test_create_anew_id_number_if_current_exists(self):
full_clean = Package.full_clean
Package.full_clean = Mock()
@ -335,7 +339,7 @@ class PackageTest(TestCase):
addon2.id_number = addon.id_number
addon2.save()
Package.full_clean = full_clean
def test_description_characters(self):
addon = Package.objects.create(author=self.author, type='a')
description = "abcdefghijklmnoprstuwxyz!@#$%^&*(){}[]:',./?"
@ -343,43 +347,43 @@ class PackageTest(TestCase):
addon.save()
addon_saved = Package.objects.get(author=self.author, type='a')
eq_(addon_saved.description, description)
def test_activity_rating_calculation_one_year(self):
addon = Package.objects.create(author=self.author, type='a')
eq_(0, addon.calc_activity_rating())
now = datetime.datetime.now()
for i in range(1, 366):
r = addon.revisions.create(author=self.author, revision_number=i)
r.created_at = now-datetime.timedelta(i)
super(PackageRevision, r).save()
#created packages, including initial
eq_(366, addon.revisions.count())
eq_(Decimal('1'), addon.calc_activity_rating())
def test_activity_rating_calculation_first_week(self):
addon = Package.objects.create(type='a', author=self.author)
eq_(0, addon.calc_activity_rating())
now = datetime.datetime.now()
# Create 1 weeks worth of revisions... should equal .30 of score
# see models.py def Packages for weights
for i in range(1, 8):
r = addon.revisions.create(author=self.author, revision_number=i)
r.created_at = now-datetime.timedelta(i)
super(PackageRevision, r).save()
eq_(8, addon.revisions.count())
eq_(Decimal('0.300'), addon.calc_activity_rating())
def test_duplicate_packages_integrity_error(self):
# duplicate packages are denied on MySQL level
author = User.objects.get(username='john')
@ -394,3 +398,29 @@ class PackageTest(TestCase):
author=author, type='a')
self.assertRaises(IntegrityError, addon2.save)
Package.full_clean = backup
def test_duplicate_packages_name_interation(self):
# duplicate packages are denied on MySQL level
author = User.objects.get(username='john')
addon = Package(
full_name='Integrity Error',
author=author, type='a')
addon.save()
eq_(addon.latest.name, 'integrity-error')
addon2 = Package(
full_name='Integrity Error',
author=author, type='a')
addon2.save()
eq_(addon2.latest.name, 'john')
addon3 = Package(
full_name='Integrity Error',
author=author, type='a')
addon3.save()
eq_(addon3.latest.name, 'john-1')

Просмотреть файл

@ -0,0 +1 @@
ALTER TABLE jetpack_package ADD UNIQUE INDEX full_name_author_id (full_name, author_id);