def test_signing_error_roll_back(self, sign_file_mock):
        sign_file_mock.side_effect = [SigningError, None]
        call_command('auto_approve')
        # Make sure that the AutoApprovalSummary created for the first add-on
        # was rolled back because of the signing error, and that it didn't
        # affect the approval of the second one.
        assert sign_file_mock.call_count == 2

        for file_ in self.files:
            file_.reload()
        for addon in self.addons:
            addon.reload()

        assert not AutoApprovalSummary.objects.filter(
            version=self.versions[0]).exists()
        assert self.addons[0].status == amo.STATUS_APPROVED  # It already was.
        assert self.files[0].status == amo.STATUS_AWAITING_REVIEW
        assert not self.files[0].reviewed

        assert AutoApprovalSummary.objects.get(version=self.versions[1])
        assert self.addons[1].status == amo.STATUS_APPROVED
        assert self.files[1].status == amo.STATUS_APPROVED
        assert self.files[1].reviewed

        assert len(mail.outbox) == 1

        assert get_reviewing_cache(self.addons[0].pk) is None
        assert get_reviewing_cache(self.addons[1].pk) is None

        self._check_stats({'total': 2, 'error': 1, 'is_locked': 0,
                           'has_auto_approval_disabled': 0,
                           'auto_approved': 1, 'is_recommendable': 0,
                           'should_be_delayed': 0})
    def test_signing_error_roll_back(self, sign_file_mock):
        sign_file_mock.side_effect = [SigningError, None]
        call_command('auto_approve')
        # Make sure that the AutoApprovalSummary created for the first add-on
        # was rolled back because of the signing error, and that it didn't
        # affect the approval of the second one.
        assert sign_file_mock.call_count == 2

        for file_ in self.files:
            file_.reload()
        for addon in self.addons:
            addon.reload()

        assert not AutoApprovalSummary.objects.filter(
            version=self.versions[0]).exists()
        assert self.addons[0].status == amo.STATUS_APPROVED  # It already was.
        assert self.files[0].status == amo.STATUS_AWAITING_REVIEW
        assert not self.files[0].reviewed

        assert AutoApprovalSummary.objects.get(version=self.versions[1])
        assert self.addons[1].status == amo.STATUS_APPROVED
        assert self.files[1].status == amo.STATUS_APPROVED
        assert self.files[1].reviewed

        assert len(mail.outbox) == 1

        assert get_reviewing_cache(self.addons[0].pk) is None
        assert get_reviewing_cache(self.addons[1].pk) is None

        self._check_stats({'total': 2, 'error': 1, 'is_locked': 0,
                           'has_auto_approval_disabled': 0,
                           'auto_approved': 1})
 def test_no_validation_result(self, create_summary_for_version_mock):
     create_summary_for_version_mock.side_effect = (
         AutoApprovalNoValidationResultError)
     call_command('auto_approve')
     assert get_reviewing_cache(self.addon.pk) is None
     assert create_summary_for_version_mock.call_count == 1
     self._check_stats({'total': 1, 'error': 1})
 def test_not_enough_files_error(self, create_summary_for_version_mock):
     create_summary_for_version_mock.side_effect = (
         AutoApprovalNotEnoughFilesError)
     call_command('auto_approve')
     assert get_reviewing_cache(self.addon.pk) is None
     assert create_summary_for_version_mock.call_count == 1
     self._check_stats({'total': 1, 'error': 1})
 def test_signing_error(self, sign_file_mock):
     sign_file_mock.side_effect = SigningError
     call_command('auto_approve')
     assert sign_file_mock.call_count == 1
     assert get_reviewing_cache(self.addon.pk) is None
     self._check_stats({'total': 1, 'error': 1, 'is_locked': 0,
                        'has_auto_approval_disabled': 0})
Exemple #6
0
 def process_addon(self, *, addon, now):
     latest_version = addon.find_latest_version(
         channel=amo.RELEASE_CHANNEL_LISTED)
     if (latest_version and latest_version.is_unreviewed
             and not latest_version.pending_rejection):
         # If latest version is unreviewed and not pending
         # rejection, we want to put the delayed rejection of all
         # versions of this addon on hold until a decision has been
         # made by reviewers on the latest one.
         log.info(
             'Skipping rejections for add-on %s until version %s '
             'has been reviewed', addon.pk, latest_version.pk)
         return
     versions = self.fetch_version_candidates_for_addon(addon=addon,
                                                        now=now)
     if not versions.exists():
         log.info('Somehow no versions to auto-reject for add-on %s',
                  addon.pk)
         return
     locked_by = get_reviewing_cache(addon.pk)
     if locked_by:
         # Don't auto-reject something that has been locked, even by the
         # task user - wait until it's free to avoid any conflicts.
         log.info(
             'Skipping rejections for add-on %s until lock from user %s '
             'has expired', addon.pk, locked_by)
         return
         set_reviewing_cache(addon.pk, settings.TASK_USER_ID)
     try:
         self.reject_versions(addon=addon,
                              versions=versions,
                              latest_version=latest_version)
     finally:
         # Always clear our lock no matter what happens.
         clear_reviewing_cache(addon.pk)
 def test_no_validation_result(self, create_summary_for_version_mock):
     create_summary_for_version_mock.side_effect = (
         AutoApprovalNoValidationResultError)
     call_command('auto_approve')
     assert get_reviewing_cache(self.addon.pk) is None
     assert create_summary_for_version_mock.call_count == 1
     self._check_stats({'total': 1, 'error': 1})
 def test_signing_error(self, sign_file_mock):
     sign_file_mock.side_effect = SigningError
     call_command('auto_approve')
     assert sign_file_mock.call_count == 1
     assert get_reviewing_cache(self.addon.pk) is None
     self._check_stats({'total': 1, 'error': 1, 'is_locked': 0,
                        'has_auto_approval_disabled': 0})
 def test_not_enough_files_error(self, create_summary_for_version_mock):
     create_summary_for_version_mock.side_effect = (
         AutoApprovalNotEnoughFilesError)
     call_command('auto_approve')
     assert get_reviewing_cache(self.addon.pk) is None
     assert create_summary_for_version_mock.call_count == 1
     self._check_stats({'total': 1, 'error': 1})
 def test_successful_verdict_dry_run(
         self, create_summary_for_version_mock, approve_mock):
     create_summary_for_version_mock.return_value = (
         AutoApprovalSummary(verdict=amo.WOULD_HAVE_BEEN_AUTO_APPROVED), {})
     call_command('auto_approve', '--dry-run')
     assert approve_mock.call_count == 0
     assert create_summary_for_version_mock.call_args == (
         (self.version, ), {'dry_run': True})
     assert get_reviewing_cache(self.addon.pk) is None
     self._check_stats({'total': 1, 'auto_approved': 1})
 def test_successful_verdict_dry_run(
         self, create_summary_for_version_mock, approve_mock):
     create_summary_for_version_mock.return_value = (
         AutoApprovalSummary(verdict=amo.WOULD_HAVE_BEEN_AUTO_APPROVED), {})
     call_command('auto_approve', '--dry-run')
     assert approve_mock.call_count == 0
     assert create_summary_for_version_mock.call_args == (
         (self.version, ), {'dry_run': True})
     assert get_reviewing_cache(self.addon.pk) is None
     self._check_stats({'total': 1, 'auto_approved': 1})
 def test_failed_verdict(self, create_summary_for_version_mock,
                         approve_mock):
     fake_verdict_info = {'is_locked': True}
     create_summary_for_version_mock.return_value = (AutoApprovalSummary(
         verdict=amo.NOT_AUTO_APPROVED), fake_verdict_info)
     call_command('auto_approve')
     assert approve_mock.call_count == 0
     assert create_summary_for_version_mock.call_args == ((self.version, ),
                                                          {
                                                              'dry_run':
                                                              False
                                                          })
     assert get_reviewing_cache(self.addon.pk) is None
     self._check_stats({
         'total': 1,
         'is_locked': 1,
     })
 def test_failed_verdict(
         self, create_summary_for_version_mock, approve_mock):
     fake_verdict_info = {
         'is_locked': True
     }
     create_summary_for_version_mock.return_value = (
         AutoApprovalSummary(verdict=amo.NOT_AUTO_APPROVED),
         fake_verdict_info)
     call_command('auto_approve')
     assert approve_mock.call_count == 0
     assert create_summary_for_version_mock.call_args == (
         (self.version, ), {'dry_run': False})
     assert get_reviewing_cache(self.addon.pk) is None
     self._check_stats({
         'total': 1,
         'is_locked': 1,
     })
Exemple #14
0
def review_viewing(request):
    if 'addon_id' not in request.POST:
        return {}

    addon_id = request.POST['addon_id']
    user_id = request.user.id
    current_name = ''
    is_user = 0
    key = get_reviewing_cache_key(addon_id)
    user_key = '%s:review_viewing_user:%s' % (settings.CACHE_PREFIX, user_id)
    interval = amo.REVIEWER_VIEWING_INTERVAL

    # Check who is viewing.
    currently_viewing = get_reviewing_cache(addon_id)

    # If nobody is viewing or current user is, set current user as viewing
    if not currently_viewing or currently_viewing == user_id:
        # Get a list of all the reviews this user is locked on.
        review_locks = cache.get_many(cache.get(user_key, {}))
        can_lock_more_reviews = (
            len(review_locks) < amo.REVIEWER_REVIEW_LOCK_LIMIT
            or acl.action_allowed(request,
                                  amo.permissions.REVIEWER_ADMIN_TOOLS_VIEW))
        if can_lock_more_reviews or currently_viewing == user_id:
            set_reviewing_cache(addon_id, user_id)
            # Give it double expiry just to be safe.
            cache.set(user_key, set(review_locks) | {key}, interval * 4)
            currently_viewing = user_id
            current_name = request.user.name
            is_user = 1
        else:
            currently_viewing = settings.TASK_USER_ID
            current_name = ugettext('Review lock limit reached')
            is_user = 2
    else:
        current_name = UserProfile.objects.get(pk=currently_viewing).name

    return {
        'current': currently_viewing,
        'current_name': current_name,
        'is_user': is_user,
        'interval_seconds': interval
    }
Exemple #15
0
def review_viewing(request):
    if 'addon_id' not in request.POST:
        return {}

    addon_id = request.POST['addon_id']
    user_id = request.user.id
    current_name = ''
    is_user = 0
    key = get_reviewing_cache_key(addon_id)
    user_key = '%s:review_viewing_user:%s' % (settings.CACHE_PREFIX, user_id)
    interval = amo.REVIEWER_VIEWING_INTERVAL

    # Check who is viewing.
    currently_viewing = get_reviewing_cache(addon_id)

    # If nobody is viewing or current user is, set current user as viewing
    if not currently_viewing or currently_viewing == user_id:
        # Get a list of all the reviews this user is locked on.
        review_locks = cache.get_many(cache.get(user_key, {}))
        can_lock_more_reviews = (
            len(review_locks) < amo.REVIEWER_REVIEW_LOCK_LIMIT or
            acl.action_allowed(request,
                               amo.permissions.REVIEWS_ADMIN))
        if can_lock_more_reviews or currently_viewing == user_id:
            set_reviewing_cache(addon_id, user_id)
            # Give it double expiry just to be safe.
            cache.set(user_key, set(review_locks) | {key}, interval * 4)
            currently_viewing = user_id
            current_name = request.user.name
            is_user = 1
        else:
            currently_viewing = settings.TASK_USER_ID
            current_name = ugettext('Review lock limit reached')
            is_user = 2
    else:
        current_name = UserProfile.objects.get(pk=currently_viewing).name

    return {'current': currently_viewing, 'current_name': current_name,
            'is_user': is_user, 'interval_seconds': interval}
    def test_full(self, sign_file_mock):
        # Simple integration test with as few mocks as possible.
        assert not AutoApprovalSummary.objects.exists()
        assert not self.file.reviewed
        ActivityLog.objects.all().delete()
        self.author = user_factory()
        self.addon.addonuser_set.create(user=self.author)

        # Delete the add-on current version and approval info, leaving it
        # nominated. Set its nomination date in the past and it should be
        # picked up and auto-approved.
        AddonApprovalsCounter.objects.filter(addon=self.addon).get().delete()
        self.addon.current_version.delete()
        self.version.update(nomination=self.days_ago(2))
        self.addon.update_status()

        call_command('auto_approve', '--dry-run')
        call_command('auto_approve')

        self.addon.reload()
        self.file.reload()
        assert AutoApprovalSummary.objects.count() == 1
        assert AutoApprovalSummary.objects.get(version=self.version)
        assert get_reviewing_cache(self.addon.pk) is None
        assert self.addon.status == amo.STATUS_APPROVED
        assert self.file.status == amo.STATUS_APPROVED
        assert self.file.reviewed
        assert ActivityLog.objects.count()
        activity_log = ActivityLog.objects.latest('pk')
        assert activity_log.action == amo.LOG.APPROVE_VERSION.id
        assert sign_file_mock.call_count == 1
        assert sign_file_mock.call_args[0][0] == self.file
        assert len(mail.outbox) == 1
        msg = mail.outbox[0]
        assert msg.to == [self.author.email]
        assert msg.from_email == settings.ADDONS_EMAIL
        assert msg.subject == 'Mozilla Add-ons: %s %s Approved' % (str(
            self.addon.name), self.version.version)
    def test_full(self, sign_file_mock):
        # Simple integration test with as few mocks as possible.
        assert not AutoApprovalSummary.objects.exists()
        assert not self.file.reviewed
        ActivityLog.objects.all().delete()
        self.author = user_factory()
        self.addon.addonuser_set.create(user=self.author)

        # Delete the add-on current version and approval info, leaving it
        # nominated. Because we're in post-review we should pick it up and
        # approve it anyway.
        AddonApprovalsCounter.objects.filter(addon=self.addon).get().delete()
        self.addon.current_version.delete()
        self.addon.update_status()

        call_command('auto_approve', '--dry-run')
        call_command('auto_approve')

        self.addon.reload()
        self.file.reload()
        assert AutoApprovalSummary.objects.count() == 1
        assert AutoApprovalSummary.objects.get(version=self.version)
        assert get_reviewing_cache(self.addon.pk) is None
        assert self.addon.status == amo.STATUS_APPROVED
        assert self.file.status == amo.STATUS_APPROVED
        assert self.file.reviewed
        assert ActivityLog.objects.count()
        activity_log = ActivityLog.objects.latest('pk')
        assert activity_log.action == amo.LOG.APPROVE_VERSION.id
        assert sign_file_mock.call_count == 1
        assert sign_file_mock.call_args[0][0] == self.file
        assert len(mail.outbox) == 1
        msg = mail.outbox[0]
        assert msg.to == [self.author.email]
        assert msg.from_email == settings.ADDONS_EMAIL
        assert msg.subject == 'Mozilla Add-ons: %s %s Approved' % (
            six.text_type(self.addon.name), self.version.version)