Bug 976835: Only offer fully reviewed versions as updates to fully reviewed versions.

This commit is contained in:
Kris Maglione 2014-02-20 13:19:55 -08:00 коммит произвёл Mathieu Agopian
Родитель ec9c7c8036
Коммит ed74601fcf
3 изменённых файлов: 83 добавлений и 71 удалений

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

@ -609,10 +609,9 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
return self.versions.no_cache().filter(**fltr).extra(
where=["""
NOT EXISTS (
SELECT 1 FROM versions as v2
INNER JOIN files AS f2 ON (f2.version_id = v2.id)
WHERE v2.id = versions.id
AND f2.status NOT IN (%s))
SELECT 1 FROM files AS f2
WHERE f2.version_id = versions.id AND
f2.status NOT IN (%s))
""" % status_list])[0]
except (IndexError, Version.DoesNotExist):

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

@ -37,20 +37,6 @@ class TestDataValidate(amo.tests.TestCase):
up.cursor = connection.cursor()
return up
def test_beta(self):
data = self.good_data.copy()
for good in ['1.0a', '1.0beta2', '1.0 beta2']:
data['version'] = good
form = self.get(data)
assert form.is_valid()
assert form.is_beta_version
for bad in ['1.0', 'beta 1.0', '1.0 beta 2']:
data['version'] = bad
form = self.get(data)
assert form.is_valid()
assert not form.is_beta_version
def test_app_os(self):
data = self.good_data.copy()
data['appOS'] = 'something %s penguin' % amo.PLATFORM_LINUX.api_name
@ -363,16 +349,32 @@ class TestLookup(amo.tests.TestCase):
def test_file_preliminary_addon(self):
"""
If the addon is in prelim. review, show the highest file with
public., which in this case is 1.2.1
prelim, which in this case is 1.2.1
"""
for status in amo.LITE_STATUSES:
self.addon.update(status=status)
# Since we're asking for an update from version 1.2, and
# we want to serve a prelim update, 1.2 needs to be
# prelim as well.
self.change_status(self.version_1_2_0, amo.STATUS_LITE)
self.change_status(self.version_1_2_1, amo.STATUS_LITE)
version, file = self.get('1.2', self.version_int,
self.app, amo.PLATFORM_LINUX)
eq_(version, self.version_1_2_1)
def test_file_preliminary_ex_full_addon(self):
"""
If the addon is in prelim. review, user has a full reviewed version.
Show the most recent full reviewed version.
"""
self.addon.update(status=amo.STATUS_LITE)
self.change_status(self.version_1_2_2, amo.STATUS_LITE)
version, file = self.get('1.2', self.version_int,
self.app, amo.PLATFORM_LINUX)
eq_(version, self.version_1_2_1)
class TestDefaultToCompat(amo.tests.TestCase):
"""
@ -663,6 +665,10 @@ class TestResponse(amo.tests.TestCase):
version.version = beta_version
version.save()
# Changing the status of the only reviewed file resets the
# add-on status to UNREVIEWED. Change it back to public.
version.addon.update(status=amo.STATUS_PUBLIC)
data = self.good_data.copy()
up = self.get(data)
up.is_valid()

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

@ -95,8 +95,6 @@ class Update(object):
self.conn, self.cursor = None, None
self.data = data.copy()
self.data['row'] = {}
self.flags = {'use_version': False, 'multiple_status': False}
self.is_beta_version = False
self.version_int = 0
self.compat_mode = compat_mode
@ -140,48 +138,14 @@ class Update(object):
else:
data['appOS'] = None
self.is_beta_version = base.VERSION_BETA.search(data['version'])
return True
def get_beta(self):
data = self.data
data['status'] = base.STATUS_PUBLIC
if data['addon_status'] == base.STATUS_PUBLIC:
# Beta channel looks at the addon name to see if it's beta.
if self.is_beta_version:
# For beta look at the status of the existing files.
sql = """
SELECT versions.id, status
FROM files INNER JOIN versions
ON files.version_id = versions.id
WHERE versions.addon_id = %(id)s
AND versions.version = %(version)s LIMIT 1;"""
self.cursor.execute(sql, data)
result = self.cursor.fetchone()
# Only change the status if there are files.
if result is not None:
status = result[1]
# If it's in Beta or Public, then we should be looking
# for similar. If not, find something public.
if status in (base.STATUS_BETA, base.STATUS_PUBLIC):
data['status'] = status
else:
data.update(STATUSES_PUBLIC)
self.flags['multiple_status'] = True
elif data['addon_status'] in (base.STATUS_LITE,
base.STATUS_LITE_AND_NOMINATED):
data['status'] = base.STATUS_LITE
else:
# Otherwise then we'll keep the update within the current version.
data['status'] = base.STATUS_NULL
self.flags['use_version'] = True
def get_update(self):
self.get_beta()
data = self.data
data.update(STATUSES_PUBLIC)
data['STATUS_BETA'] = base.STATUS_BETA
sql = ["""
SELECT
addons.guid as guid, addons.addontype_id as type,
@ -212,17 +176,60 @@ class Update(object):
if data.get('appOS'):
sql.append(' OR files.platform_id = %(appOS)s')
if self.flags['use_version']:
sql.append(') WHERE files.status > %(status)s AND '
'versions.version = %(version)s ')
else:
if self.flags['multiple_status']:
# Note that getting this properly escaped is a pain.
# Suggestions for improvement welcome.
sql.append(') WHERE files.status in (%(STATUS_PUBLIC)s,'
'%(STATUS_LITE)s,%(STATUS_LITE_AND_NOMINATED)s) ')
else:
sql.append(') WHERE files.status = %(status)s ')
sql.append("""
)
-- Find a reference to the user's current version, if it exists.
-- These should never be inner joins. We need results even if we
-- can't find the current version.
LEFT JOIN versions curver
ON curver.addon_id = addons.id AND curver.version = %(version)s
LEFT JOIN files curfile
ON curfile.version_id = curver.id
WHERE
-- Note that the WHEN clauses here will evaluate to the same
-- thing for each row we examine. The JOINs above narrow the
-- rows matched by the WHERE clause to versions of a specific
-- add-on, and the ORDER BY and LIMIT 1 clauses below make it
-- unlikely that we'll be examining a large number of rows,
-- so this is fairly cheap.
CASE
WHEN curfile.status = %(STATUS_BETA)s
THEN
-- User's current version is a known beta version.
--
-- Serve only beta updates. Serving a full version here
-- will forever kick users out of the beta update channel.
--
-- If the add-on does not have full review, serve no
-- updates.
addons.status = %(STATUS_PUBLIC)s AND
files.status = %(STATUS_BETA)s
WHEN addons.status IN (%(STATUS_LITE)s,
%(STATUS_LITE_AND_NOMINATED)s)
AND (curfile.id IS NULL OR curfile.status = %(STATUS_LITE)s)
THEN
-- Add-on is prelim, and user's current version is either a
-- known prelim, or an unknown version.
--
-- Serve only prelim versions. Serving a full version here
-- will prevent users from receiving further updates until
-- the add-on achieves full review.
files.status = %(STATUS_LITE)s
ELSE
-- Anything else, including:
--
-- * Add-on has full review
-- * User's current version has full review, regardless
-- of add-on status
--
-- Serve only full-reviewed updates.
files.status = %(STATUS_PUBLIC)s
END
""")
sql.append('AND appmin.version_int <= %(version_int)s ')
@ -272,8 +279,8 @@ class Update(object):
'version', 'premium_type'],
list(result)))
row['type'] = base.ADDON_SLUGS_UPDATE[row['type']]
row['url'] = get_mirror(self.data['addon_status'],
self.data['id'], row)
row['url'] = get_mirror(data['addon_status'],
data['id'], row)
data['row'] = row
return True