def test_approve(self, review_helper_mock, statsd_incr_mock): command = auto_approve.Command() command.approve(self.version) assert review_helper_mock.call_count == 1 assert review_helper_mock.call_args == ((), { 'addon': self.addon, 'version': self.version }) assert review_helper_mock().handler.process_public.call_count == 1 assert statsd_incr_mock.call_count == 1 assert statsd_incr_mock.call_args == (( 'reviewers.auto_approve.approve.success', ), {})
def test_fetch_candidates(self): # Create the candidates and extra addons & versions that should not be # considered for auto-approval. expected = self.create_candidates() # Gather the candidates. command = auto_approve.Command() command.post_review = True qs = command.fetch_candidates() # Test that they are all present. assert [(version.addon, version) for version in qs] == expected
def test_fetch_candidates(self): # We already have an add-on with a version awaiting review that should # be considered. Make sure its nomination date is in the past to test # ordering. self.version.update(nomination=self.days_ago(1)) # Add reviewer flags disabling auto-approval for this add-on. It would # still be fetched as a candidate, just rejected later on when # calculating the verdict. AddonReviewerFlags.objects.create(addon=self.addon, auto_approval_disabled=True) # Add nominated add-on: it should be considered. new_addon = addon_factory(status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) new_addon_version = new_addon.versions.all()[0] new_addon_version.update(nomination=self.days_ago(2)) # Even add an empty reviewer flags instance, that should not matter. AddonReviewerFlags.objects.create(addon=new_addon) # Add langpack: it should be considered. langpack = addon_factory(type=amo.ADDON_LPAPP, status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) langpack_version = langpack.versions.all()[0] langpack_version.update(nomination=self.days_ago(3)) # Add a dictionary: it should also be considered. dictionary = addon_factory(type=amo.ADDON_DICT, status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) dictionary_version = dictionary.versions.all()[0] dictionary_version.update(nomination=self.days_ago(4)) # search engine plugins are considered now search_addon = addon_factory(type=amo.ADDON_SEARCH) version_factory(addon=search_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }, nomination=self.days_ago(5)) # Some recommended add-ons - one nominated and one update. # They should be considered by fetch_candidate(), so that they get a # weight assigned etc - they will not be auto-approved but that's # handled at a later stage, when calculating the verdict. recommendable_addon_nominated = addon_factory( status=amo.STATUS_NOMINATED, version_kw={ 'recommendation_approved': True, 'nomination': self.days_ago(6) }, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }, ) recommended_addon = version_factory(addon=addon_factory(), recommendation_approved=True, nomination=self.days_ago(7), file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }).addon DiscoveryItem.objects.create(recommendable=True, addon=recommendable_addon_nominated) DiscoveryItem.objects.create(recommendable=True, addon=recommended_addon) # --------------------------------------------------------------------- # Add a bunch of add-ons in various states that should not be returned. # Public add-on with no updates. addon_factory(file_kw={'is_webextension': True}) # Disabled add-on with updates. disabled_addon = addon_factory(disabled_by_user=True) version_factory(addon=disabled_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Add-on with deleted version. addon_with_deleted_version = addon_factory() deleted_version = version_factory(addon=addon_with_deleted_version, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) deleted_version.delete() # Add-on with a non-webextension update. non_webext_addon = addon_factory() version_factory(addon=non_webext_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Add-on with 3 versions: # - one webext, listed, public. # - one non-listed webext version # - one listed non-webext awaiting review. complex_addon = addon_factory(file_kw={'is_webextension': True}) version_factory(addon=complex_addon, channel=amo.RELEASE_CHANNEL_UNLISTED, file_kw={'is_webextension': True}) version_factory(addon=complex_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Finally, add a second file to self.version to test the distinct(). file_factory(version=self.version, status=amo.STATUS_AWAITING_REVIEW, is_webextension=True) # Add-on with an already public version and an unlisted webext # still awaiting review complex_addon_2 = addon_factory(file_kw={'is_webextension': True}) version_factory(addon=complex_addon_2, channel=amo.RELEASE_CHANNEL_UNLISTED, file_kw={ 'is_webextension': True, 'status': amo.STATUS_AWAITING_REVIEW }) # --------------------------------------------------------------------- # Gather the candidates. command = auto_approve.Command() command.post_review = True qs = command.fetch_candidates() # 5 versions should be found. Because of the nomination date, # search_version should be first (its nomination date is the # oldest) followed etc. assert len(qs) == 7 assert [v.addon.pk for v in qs] == [ a.pk for a in ( recommended_addon, recommendable_addon_nominated, search_addon, dictionary, langpack, new_addon, self.addon, ) ]
def test_fetch_candidates(self): # Add nominated add-on: it should be considered. self.version.update(nomination=self.days_ago(1)) new_addon = addon_factory(status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) new_addon_version = new_addon.versions.all()[0] new_addon_version.update(nomination=self.days_ago(2)) # Add langpack: it should also be considered. langpack = addon_factory(type=amo.ADDON_LPAPP, status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) langpack_version = langpack.versions.all()[0] langpack_version.update(nomination=self.days_ago(3)) # Add a bunch of add-ons in various states that should not be returned. # Public add-on with no updates. addon_factory(file_kw={'is_webextension': True}) # Non-extension with updates. search_addon = addon_factory(type=amo.ADDON_SEARCH) version_factory(addon=search_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Disabled add-on with updates. disabled_addon = addon_factory(disabled_by_user=True) version_factory(addon=disabled_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Add-on with deleted version. addon_with_deleted_version = addon_factory() deleted_version = version_factory(addon=addon_with_deleted_version, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) deleted_version.delete() # Add-on with a non-webextension update. non_webext_addon = addon_factory() version_factory(addon=non_webext_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Add-on with 3 versions: # - one webext, listed, public. # - one non-listed webext version # - one listed non-webext awaiting review. complex_addon = addon_factory(file_kw={'is_webextension': True}) version_factory(addon=complex_addon, channel=amo.RELEASE_CHANNEL_UNLISTED, file_kw={'is_webextension': True}) version_factory(addon=complex_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Finally, add a second file to self.version to test the distinct(). file_factory(version=self.version, status=amo.STATUS_AWAITING_REVIEW, is_webextension=True) # Gather the candidates. command = auto_approve.Command() command.post_review = True qs = command.fetch_candidates() # 3 versions should be found. Because of the nomination date, # langpack_version should be first (its nomination date is the oldest), # followed by new_addon_version and then self.version. assert len(qs) == 3 assert qs[0] == langpack_version assert qs[1] == new_addon_version assert qs[2] == self.version
def test_fetch_candidates(self): # We already have an add-on with a version awaiting review that should # be considered. Make sure its nomination date is in the past to test # ordering. self.version.update(nomination=self.days_ago(1)) # Add reviewer flags disabling auto-approval for this add-on. It would # still be fetched as a candidate, just rejected later on when # calculating the verdict. AddonReviewerFlags.objects.create(addon=self.addon, auto_approval_disabled=True) # Add nominated add-on: it should be considered. new_addon = addon_factory(status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) new_addon_version = new_addon.versions.all()[0] new_addon_version.update(nomination=self.days_ago(2)) # Even add an empty reviewer flags instance, that should not matter. AddonReviewerFlags.objects.create(addon=new_addon) # Add langpack: it should also be considered. langpack = addon_factory(type=amo.ADDON_LPAPP, status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) langpack_version = langpack.versions.all()[0] langpack_version.update(nomination=self.days_ago(3)) # Add a bunch of add-ons in various states that should not be returned. # Public add-on with no updates. addon_factory(file_kw={'is_webextension': True}) # Non-extension with updates. search_addon = addon_factory(type=amo.ADDON_SEARCH) version_factory(addon=search_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Disabled add-on with updates. disabled_addon = addon_factory(disabled_by_user=True) version_factory(addon=disabled_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Add-on with deleted version. addon_with_deleted_version = addon_factory() deleted_version = version_factory(addon=addon_with_deleted_version, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) deleted_version.delete() # Add-on with a non-webextension update. non_webext_addon = addon_factory() version_factory(addon=non_webext_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Add-on with 3 versions: # - one webext, listed, public. # - one non-listed webext version # - one listed non-webext awaiting review. complex_addon = addon_factory(file_kw={'is_webextension': True}) version_factory(addon=complex_addon, channel=amo.RELEASE_CHANNEL_UNLISTED, file_kw={'is_webextension': True}) version_factory(addon=complex_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Finally, add a second file to self.version to test the distinct(). file_factory(version=self.version, status=amo.STATUS_AWAITING_REVIEW, is_webextension=True) # Gather the candidates. command = auto_approve.Command() command.post_review = True qs = command.fetch_candidates() # 3 versions should be found. Because of the nomination date, # langpack_version should be first (its nomination date is the oldest), # followed by new_addon_version and then self.version. assert len(qs) == 3 assert qs[0] == langpack_version assert qs[1] == new_addon_version assert qs[2] == self.version
def test_fetch_candidates(self): # We already have an add-on with a version awaiting review that should # be considered. Make sure its nomination date is in the past to test # ordering. self.version.update(nomination=self.days_ago(1)) # Add a second file to self.version to test the distinct(). file_factory(version=self.version, status=amo.STATUS_AWAITING_REVIEW, is_webextension=True) # Add reviewer flags disabling auto-approval for this add-on. It would # still be fetched as a candidate, just rejected later on when # calculating the verdict. AddonReviewerFlags.objects.create(addon=self.addon, auto_approval_disabled=True) # Add nominated add-on: it should be considered. new_addon = addon_factory(name='New Addon', status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) new_addon_version = new_addon.versions.all()[0] new_addon_version.update(nomination=self.days_ago(2)) # Even add an empty reviewer flags instance, that should not matter. AddonReviewerFlags.objects.create(addon=new_addon) # Add langpack: it should be considered. langpack = addon_factory(name='Langpack', type=amo.ADDON_LPAPP, status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) langpack_version = langpack.versions.all()[0] langpack_version.update(nomination=self.days_ago(3)) # Add a dictionary: it should also be considered. dictionary = addon_factory(name='Dictionary', type=amo.ADDON_DICT, status=amo.STATUS_NOMINATED, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) dictionary_version = dictionary.versions.all()[0] dictionary_version.update(nomination=self.days_ago(4)) # search engine plugins are considered now search_addon = addon_factory(name='Search', type=amo.ADDON_SEARCH) search_addon_version = version_factory(addon=search_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }, nomination=self.days_ago(5)) # Some recommended add-ons - one nominated and one update. # They should be considered by fetch_candidate(), so that they get a # weight assigned etc - they will not be auto-approved but that's # handled at a later stage, when calculating the verdict. recommendable_addon_nominated = addon_factory( name='Recommendable Addon', status=amo.STATUS_NOMINATED, version_kw={ 'recommendation_approved': True, 'nomination': self.days_ago(6) }, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }, ) DiscoveryItem.objects.create(recommendable=True, addon=recommendable_addon_nominated) recommended_addon = addon_factory(name='Recommended Addon', ) recommended_addon_version = version_factory( addon=recommended_addon, recommendation_approved=True, nomination=self.days_ago(7), file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) DiscoveryItem.objects.create(recommendable=True, addon=recommended_addon) # Add-on with 3 versions: # - one webext, listed, public. # - one non-listed webext version awaiting review. # - one listed non-webext awaiting review (should be ignored) complex_addon = addon_factory(name='Complex Addon', file_kw={'is_webextension': True}) complex_addon_version = version_factory( nomination=self.days_ago(8), addon=complex_addon, channel=amo.RELEASE_CHANNEL_UNLISTED, file_kw={ 'is_webextension': True, 'status': amo.STATUS_AWAITING_REVIEW }) version_factory(nomination=self.days_ago(9), addon=complex_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Add-on with an already public version and an unlisted webext # awaiting review. complex_addon_2 = addon_factory(name='Second Complex Addon', file_kw={'is_webextension': True}) complex_addon_2_version = version_factory( addon=complex_addon_2, channel=amo.RELEASE_CHANNEL_UNLISTED, nomination=self.days_ago(10), file_kw={ 'is_webextension': True, 'status': amo.STATUS_AWAITING_REVIEW }) # Disabled version with a webext waiting review (Still has to be # considered because unlisted doesn't care about disabled by user # state. user_disabled_addon = addon_factory( name='Disabled by user waiting review', disabled_by_user=True) user_disabled_addon_version = version_factory( nomination=self.days_ago(11), channel=amo.RELEASE_CHANNEL_UNLISTED, addon=user_disabled_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Pure unlisted upload. Addon status is "incomplete" as a result, but # it should still be considered because unlisted versions don't care # about that. pure_unlisted = addon_factory(name='Pure unlisted', version_kw={ 'channel': amo.RELEASE_CHANNEL_UNLISTED, 'nomination': self.days_ago(12) }, file_kw={ 'is_webextension': True, 'status': amo.STATUS_AWAITING_REVIEW }, status=amo.STATUS_NULL) pure_unlisted_version = pure_unlisted.versions.get() # Unlisted static theme. unlisted_theme = addon_factory(name='Unlisted theme', version_kw={ 'channel': amo.RELEASE_CHANNEL_UNLISTED, 'nomination': self.days_ago(13) }, file_kw={ 'is_webextension': True, 'status': amo.STATUS_AWAITING_REVIEW }, status=amo.STATUS_NULL, type=amo.ADDON_STATICTHEME) unlisted_theme_version = unlisted_theme.versions.get() # --------------------------------------------------------------------- # Add a bunch of add-ons in various states that should not be returned. # Public add-on with no updates. addon_factory(name='Already Public', file_kw={'is_webextension': True}) # Mozilla Disabled add-on with updates. disabled_addon = addon_factory( name='Mozilla Disabled', status=amo.STATUS_DISABLED, ) version_factory(addon=disabled_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Add-on with deleted version. addon_with_deleted_version = addon_factory( name='With deleted version awaiting review') deleted_version = version_factory(addon=addon_with_deleted_version, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) deleted_version.delete() # Add-on with a non-webextension update. non_webext_addon = addon_factory(name='Non Webext waiting review') version_factory(addon=non_webext_addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW}) # Somehow deleted add-on with a file still waiting for review. deleted_addon = addon_factory( name='Deleted Awaiting Review Somehow', status=amo.STATUS_DELETED, ) version_factory(addon=deleted_addon, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # listed version belonging to an add-on disabled by user addon_factory(name='Listed Disabled by user', disabled_by_user=True, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Incomplete listed addon addon_factory(name='Incomplete listed', status=amo.STATUS_NULL, file_kw={ 'status': amo.STATUS_AWAITING_REVIEW, 'is_webextension': True }) # Listed static theme addon_factory(name='Listed theme', file_kw={ 'is_webextension': True, 'status': amo.STATUS_AWAITING_REVIEW }, status=amo.STATUS_NOMINATED, type=amo.ADDON_STATICTHEME) # --------------------------------------------------------------------- # Gather the candidates. command = auto_approve.Command() command.post_review = True qs = command.fetch_candidates() # We should find these versions, in this exact order. expected = [(version.addon, version) for version in [ unlisted_theme_version, pure_unlisted_version, user_disabled_addon_version, complex_addon_2_version, complex_addon_version, recommended_addon_version, recommendable_addon_nominated.current_version, search_addon_version, dictionary.current_version, langpack.current_version, new_addon.current_version, self.version, ]] assert [(version.addon, version) for version in qs] == expected