Ejemplo n.º 1
0
 def test_compatible_version(self):
     addon = addon_factory()
     version = version_factory(addon=addon, version='99')
     version_factory(
         addon=addon, version='100',
         channel=amo.RELEASE_CHANNEL_UNLISTED)
     assert find_compatible_version(addon, amo.FIREFOX.id) == version
Ejemplo n.º 2
0
    def test_all_versions_shown_for_admin(self):
        self.login_as_admin()
        listed_ver = version_factory(
            addon=self.addon, channel=amo.RELEASE_CHANNEL_LISTED,
            version='4.0', created=self.days_ago(1))
        unlisted_ver = version_factory(
            addon=self.addon, channel=amo.RELEASE_CHANNEL_UNLISTED,
            version='5.0')
        assert self.addon.versions.count() == 3
        res = self.client.get(self.file_url())
        doc = pq(res.content)

        left_select = doc('#id_left')
        assert left_select('optgroup').attr('label') == self.version.version
        file_options = left_select('option.status-public')
        assert len(file_options) == 3, left_select.html()
        # Check the files in the list are the two we added and the default.
        assert file_options.eq(0).attr('value') == str(
            unlisted_ver.all_files[0].pk)
        assert file_options.eq(1).attr('value') == str(
            listed_ver.all_files[0].pk)
        assert file_options.eq(2).attr('value') == str(self.file.pk)
        # Check there are prefixes on the labels for the channels
        assert file_options.eq(0).text().endswith('[Self]')
        assert file_options.eq(1).text().endswith('[AMO]')
        assert file_options.eq(2).text().endswith('[AMO]')
Ejemplo n.º 3
0
    def test_count_stats_for_date(self):
        # Add a listed add-on, it should show up in "addon_count_new".
        listed_addon = addon_factory()

        # Add an unlisted version to that add-on, it should *not* increase the
        # "version_count_new" count.
        version_factory(
            addon=listed_addon, channel=amo.RELEASE_CHANNEL_UNLISTED)

        # Add an unlisted add-on, it should not show up in either
        # "addon_count_new" or "version_count_new".
        addon_factory(version_kw={
            'channel': amo.RELEASE_CHANNEL_UNLISTED
        })

        date = datetime.date.today()
        job = 'addon_count_new'
        tasks.update_global_totals(job, date)
        global_stat = GlobalStat.objects.no_cache().get(date=date, name=job)
        assert global_stat.count == 1

        job = 'version_count_new'
        tasks.update_global_totals(job, date)
        global_stat = GlobalStat.objects.no_cache().get(date=date, name=job)
        assert global_stat.count == 1
Ejemplo n.º 4
0
    def test_version_detail(self):
        version = version_factory(addon=self.addon, version='2.0')
        version.update(created=self.days_ago(2))
        version = version_factory(addon=self.addon, version='2.1b',
                                  file_kw={'status': amo.STATUS_BETA})
        version.update(created=self.days_ago(1))
        version_factory(addon=self.addon, version='2.2b',
                        file_kw={'status': amo.STATUS_BETA})
        urls = [(v.version, reverse('addons.versions',
                                    args=[self.addon.slug, v.version]))
                for v in self.addon.versions.all()]

        version, url = urls[0]
        assert version == '2.2b'
        r = self.client.get(url, follow=True)
        self.assert3xx(r, self.url_list_betas + '?page=1#version-%s' % version)

        version, url = urls[1]
        assert version == '2.1b'
        r = self.client.get(url, follow=True)
        self.assert3xx(r, self.url_list_betas + '?page=2#version-%s' % version)

        version, url = urls[2]
        assert version == '2.0'
        r = self.client.get(url, follow=True)
        self.assert3xx(r, self.url_list + '?page=1#version-%s' % version)

        version, url = urls[3]
        assert version == '1.0'
        r = self.client.get(url, follow=True)
        self.assert3xx(r, self.url_list + '?page=2#version-%s' % version)
Ejemplo n.º 5
0
    def test_extract_version_and_files(self):
        version = self.addon.current_version
        file_factory(version=version, platform=PLATFORM_MAC.id)
        current_beta_version = version_factory(
            addon=self.addon,
            file_kw={
                'status': amo.STATUS_BETA,
                'is_webextension': True,
                'is_mozilla_signed_extension': True,
            })
        # Give one of the versions some webext permissions to test that.
        WebextPermission.objects.create(
            file=current_beta_version.all_files[0],
            permissions=['bookmarks', 'random permission']
        )
        unlisted_version = version_factory(
            addon=self.addon, channel=amo.RELEASE_CHANNEL_UNLISTED)
        extracted = self._extract()

        assert extracted['current_version']
        assert extracted['current_version']['id'] == version.pk
        # Because strict_compatibility is False, the max version we record in
        # the index is an arbitrary super high version.
        assert extracted['current_version']['compatible_apps'] == {
            FIREFOX.id: {
                'min': 2000000200100L,
                'max': 9999000000200100,
                'max_human': '4.0',
                'min_human': '2.0',
            }
        }
Ejemplo n.º 6
0
 def test_review_files(self):
     version_factory(addon=self.addon,
                     created=self.version.created - timedelta(days=1),
                     file_kw={'status': amo.STATUS_PUBLIC})
     for status in REVIEW_FILES_STATUSES:
         self.setup_data(status=status)
         assert self.helper.handler.__class__ == ReviewFiles
Ejemplo n.º 7
0
def test_get_diff_newline_both_no_newline():
    addon = addon_factory(file_kw={'filename': 'webextension_no_id.xpi'})

    original_version = addon.current_version

    AddonGitRepository.extract_and_commit_from_version(original_version)

    parent_version = version_factory(
        addon=addon, file_kw={'filename': 'webextension_no_id.xpi'})

    repo = AddonGitRepository.extract_and_commit_from_version(parent_version)

    # Let's remove the newline
    apply_changes(repo, parent_version, '{"id": "random"}', 'manifest.json')

    version = version_factory(
        addon=addon, file_kw={'filename': 'webextension_no_id.xpi'})

    repo = AddonGitRepository.extract_and_commit_from_version(version)

    # Now we're adding it again
    apply_changes(repo, version, '{"id": "new random id"}', 'manifest.json')

    changes = repo.get_diff(
        commit=version.git_hash,
        parent=parent_version.git_hash)

    assert len(changes) == 1

    assert changes[0]['new_ending_new_line'] is False
    assert changes[0]['old_ending_new_line'] is False
Ejemplo n.º 8
0
    def test_count_stats_for_date(self):
        # Add a listed add-on, it should show up in "addon_count_new".
        listed_addon = addon_factory(created=datetime.datetime.now())

        # Add an unlisted version to that add-on, it should *not* increase the
        # "version_count_new" count.
        version_factory(
            addon=listed_addon, channel=amo.RELEASE_CHANNEL_UNLISTED)

        # Add an unlisted add-on, it should not show up in either
        # "addon_count_new" or "version_count_new".
        addon_factory(version_kw={
            'channel': amo.RELEASE_CHANNEL_UNLISTED
        })

        date = datetime.date.today()
        job = 'addon_count_new'
        tasks.update_global_totals(job, date)
        global_stat = GlobalStat.objects.get(date=date, name=job)
        assert global_stat.count == 1

        # Should still work if the date is passed as a datetime string (what
        # celery serialization does).
        job = 'version_count_new'
        tasks.update_global_totals(job, datetime.datetime.now().isoformat())
        global_stat = GlobalStat.objects.get(date=date, name=job)
        assert global_stat.count == 1
Ejemplo n.º 9
0
    def test_through_cron(self):
        # Yesterday, create some stuff.
        with freeze_time(datetime.datetime.now() - datetime.timedelta(days=1)):
            yesterday = datetime.date.today()

            # Add a listed add-on, it should show up in "addon_count_new".
            listed_addon = addon_factory(created=datetime.datetime.now())

            # Add an unlisted version to that add-on, it should *not* increase
            # the "version_count_new" count.
            version_factory(
                addon=listed_addon, channel=amo.RELEASE_CHANNEL_UNLISTED)

            # Add an unlisted add-on, it should not show up in either
            # "addon_count_new" or "version_count_new".
            addon_factory(version_kw={
                'channel': amo.RELEASE_CHANNEL_UNLISTED
            })

        # Launch the cron.
        cron.update_global_totals()

        job = 'addon_count_new'
        global_stat = GlobalStat.objects.get(date=yesterday, name=job)
        assert global_stat.count == 1

        job = 'version_count_new'
        global_stat = GlobalStat.objects.get(date=yesterday, name=job)
        assert global_stat.count == 1
Ejemplo n.º 10
0
 def setUp(self):
     user_factory(
         id=settings.TASK_USER_ID, username='******',
         email='*****@*****.**')
     self.addons = [
         addon_factory(average_daily_users=666, users=[user_factory()]),
         addon_factory(average_daily_users=999, users=[user_factory()]),
     ]
     self.versions = [
         version_factory(
             addon=self.addons[0], file_kw={
                 'status': amo.STATUS_AWAITING_REVIEW,
                 'is_webextension': True}),
         version_factory(
             addon=self.addons[1], file_kw={
                 'status': amo.STATUS_AWAITING_REVIEW,
                 'is_webextension': True}),
     ]
     self.files = [
         self.versions[0].all_files[0],
         self.versions[1].all_files[0],
     ]
     self.versions[0].update(nomination=days_ago(1))
     FileValidation.objects.create(
         file=self.versions[0].all_files[0], validation=u'{}')
     FileValidation.objects.create(
         file=self.versions[1].all_files[0], validation=u'{}')
     super(TestAutoApproveCommandTransactions, self).setUp()
Ejemplo n.º 11
0
    def test_only_consider_beta_for_downgrade_error_if_uploading_a_beta(self):
        """Make sure we don't raise the webextension downgrade error when
        uploading a public legacy version we have a beta webext."""
        # Create a beta webext with a version number higher than the existing
        # legacy, but lower than the legacy we're about to upload...
        version_factory(addon=self.addon, version='1.0b1', file_kw={
            'is_webextension': True, 'status': amo.STATUS_BETA,
        })
        file_ = amo.tests.AMOPaths().file_fixture_path(
            'delicious_bookmarks-2.1.106-fx.xpi')
        upload = FileUpload.objects.create(path=file_, addon=self.addon)
        tasks.validate(upload, listed=True)
        upload.refresh_from_db()
        assert upload.processed_validation['errors'] == 0
        assert upload.valid

        # Do consider previous betas when uploading a beta, though.
        file_ = amo.tests.AMOPaths().file_fixture_path(
            'beta-extension.xpi')
        upload = FileUpload.objects.create(path=file_, addon=self.addon)
        tasks.validate(upload, listed=True)
        upload.refresh_from_db()
        assert not upload.valid
        expected = ['validation', 'messages', 'webext_downgrade']
        assert upload.processed_validation['messages'][0]['id'] == expected
        assert upload.processed_validation['messages'][0]['type'] == 'error'
Ejemplo n.º 12
0
    def test_version_detail(self):
        version = version_factory(addon=self.addon, version='2.0')
        version.update(created=self.days_ago(2))
        version = version_factory(addon=self.addon, version='2.1')
        version.update(created=self.days_ago(1))
        urls = [(v.version, reverse('addons.versions',
                                    args=[self.addon.slug, v.version]))
                for v in self.addon.versions.all()]

        version, url = urls[0]
        assert version == '2.1'
        response = self.client.get(url, follow=True)
        self.assert3xx(
            response, self.url_list + '?page=1#version-%s' % version)

        version, url = urls[1]
        assert version == '2.0'
        response = self.client.get(url, follow=True)
        self.assert3xx(
            response, self.url_list + '?page=2#version-%s' % version)

        version, url = urls[2]
        assert version == '1.0'
        response = self.client.get(url, follow=True)
        self.assert3xx(
            response, self.url_list + '?page=3#version-%s' % version)
Ejemplo n.º 13
0
 def test_version_list_doesnt_show_unreviewed_versions_public_addon(self):
     version = self.addon.current_version.version
     version_factory(
         addon=self.addon, file_kw={'status': amo.STATUS_AWAITING_REVIEW},
         version='2.1')
     doc = self.get_content()
     assert len(doc('.version')) == 1
     assert doc('.version').attr('id') == 'version-%s' % version
Ejemplo n.º 14
0
 def test_review_unlisted_while_a_listed_version_is_awaiting_review(self):
     self.make_addon_unlisted(self.addon)
     self.version.reload()
     version_factory(
         addon=self.addon, channel=amo.RELEASE_CHANNEL_LISTED,
         file_kw={'status': amo.STATUS_AWAITING_REVIEW})
     self.addon.update(status=amo.STATUS_NOMINATED)
     assert self.get_helper()
Ejemplo n.º 15
0
 def test_version_list_does_not_show_betas_by_default(self):
     version = self.addon.current_version.version
     version_factory(
         addon=self.addon, file_kw={'status': amo.STATUS_BETA},
         version='2.1b')
     doc = self.get_content()
     assert len(doc('.version')) == 1
     assert doc('.version').attr('id') == 'version-%s' % version
Ejemplo n.º 16
0
def addon(transactional_db, create_superuser, pytestconfig):
    """Creates a custom addon named 'Ui-Addon'.

    This addon will be a featured addon and will have a featured collecton
    attatched to it. It will belong to the user created by the
    'create_superuser' fixture.

    It has 1 preview, 5 reviews, and 2 authors. The second author is named
    'ui-tester2'. It has a version number as well as a beta version.
    """
    if not pytestconfig.option.usingliveserver:
        return

    default_icons = [x[0] for x in icons() if x[0].startswith('icon/')]
    addon = addon_factory(
        status=STATUS_PUBLIC,
        type=ADDON_EXTENSION,
        average_daily_users=5567,
        users=[UserProfile.objects.get(username='******')],
        average_rating=5,
        description=u'My Addon description',
        file_kw={
            'hash': 'fakehash',
            'platform': amo.PLATFORM_ALL.id,
            'size': 42,
        },
        guid=generate_addon_guid(),
        homepage=u'https://www.example.org/',
        icon_type=random.choice(default_icons),
        name=u'Ui-Addon',
        public_stats=True,
        slug='ui-test',
        summary=u'My Addon summary',
        support_email=u'*****@*****.**',
        support_url=u'https://support.example.org/support/ui-test-addon/',
        tags=['some_tag', 'another_tag', 'ui-testing',
              'selenium', 'python'],
        total_reviews=888,
        weekly_downloads=2147483647,
        developer_comments='This is a testing addon, used within pytest.',
        is_experimental=True,
    )
    Preview.objects.create(addon=addon, position=1)
    Review.objects.create(addon=addon, rating=5, user=user_factory())
    Review.objects.create(addon=addon, rating=3, user=user_factory())
    Review.objects.create(addon=addon, rating=2, user=user_factory())
    Review.objects.create(addon=addon, rating=1, user=user_factory())
    addon.reload()
    AddonUser.objects.create(user=user_factory(username='******'),
                             addon=addon, listed=True)
    version_factory(addon=addon, file_kw={'status': amo.STATUS_BETA},
                    version='1.1beta')
    addon.save()
    generate_collection(addon, app=FIREFOX)
    print('Created addon {0} for testing successfully'.format(addon.name))
    return addon
Ejemplo n.º 17
0
 def test_valid_versions(self):
     addon = Addon.objects.get(id=3615)
     additional_version = version_factory(
         addon=addon, version='0.1')
     amo.tests.file_factory(version=additional_version)
     version_factory(
         addon=addon, version='0.2',
         file_kw={'status': amo.STATUS_DISABLED})
     assert list(
         Version.objects.valid()) == [additional_version, self.version]
Ejemplo n.º 18
0
    def test_validity_still_valid_if_new_version_in_different_channel(self):
        version_factory(addon=self.addon, channel=amo.RELEASE_CHANNEL_UNLISTED)
        assert self.version == self.addon.find_latest_version(
            channel=amo.RELEASE_CHANNEL_LISTED)

        # The token isn't expired.
        assert not self.token.is_expired()
        # It's also still valid, since our version is still the latest listed
        # one.
        assert self.token.is_valid()
Ejemplo n.º 19
0
    def test_basic(self):
        # These add-ons should be disabled completely since they only have a
        # single legacy file.
        should_be_fully_disabled = [
            addon_factory(),
            addon_factory(type=amo.ADDON_LPAPP),
            addon_factory(type=amo.ADDON_THEME),
        ]

        # This one has a legacy and a non-legacy version, so only the legacy
        # File & Version should be disabled.
        should_have_old_version_disabled = [
            addon_factory(created=self.days_ago(42),
                          version_kw={'created': self.days_ago(42)}),
        ]
        version_factory(
            addon=should_have_old_version_disabled[0],
            file_kw={'is_webextension': True})

        # These should *not* have any File instance disabled, they should be
        # kept intact.
        should_be_kept_intact = [
            addon_factory(file_kw={'is_webextension': True}),
            addon_factory(file_kw={'is_mozilla_signed_extension': True}),
            addon_factory(file_kw={'is_mozilla_signed_extension': True,
                                   'is_webextension': True}),
            addon_factory(type=amo.ADDON_DICT),
            addon_factory(type=amo.ADDON_SEARCH),
        ]

        call_command('process_addons', task='disable_legacy_files')

        for addon in should_be_fully_disabled:
            addon.reload()
            assert addon.status == amo.STATUS_NULL  # No public version left.
            assert addon.current_version is None
            file_ = addon.versions.all()[0].files.all()[0]
            assert file_.status == amo.STATUS_DISABLED

        for addon in should_have_old_version_disabled:
            addon.reload()
            assert addon.status == amo.STATUS_PUBLIC
            assert addon.current_version
            file_ = addon.current_version.files.all()[0]
            assert file_.status == amo.STATUS_PUBLIC
            file_ = addon.versions.exclude(
                pk=addon.current_version.pk)[0].files.all()[0]
            assert file_.status == amo.STATUS_DISABLED

        for addon in should_be_kept_intact:
            addon.reload()
            assert addon.status == amo.STATUS_PUBLIC
            assert addon.current_version
            file_ = addon.versions.all()[0].all_files[0]
            assert file_.status == amo.STATUS_PUBLIC
Ejemplo n.º 20
0
    def test_latest_unlisted_version(self):
        self.addon = addon_factory()
        version_factory(
            addon=self.addon, channel=amo.RELEASE_CHANNEL_UNLISTED,
            version='1.1')
        assert self.addon.latest_unlisted_version

        result = self.serialize()
        # In this serializer latest_unlisted_version is omitted even if there
        # is one, because it's limited to users with specific rights.
        assert 'latest_unlisted_version' not in result
Ejemplo n.º 21
0
    def create_featured_addon_with_version(self):
        """Creates a custom addon named 'Ui-Addon'.

        This addon will be a featured addon and will have a featured collecton
        attatched to it. It will belong to the user uitest.

        It has 1 preview, 5 reviews, and 2 authors. The second author is named
        'ui-tester2'. It has a version number as well as a beta version.

        """
        default_icons = [x[0] for x in icons() if x[0].startswith('icon/')]
        addon = addon_factory(
            status=STATUS_PUBLIC,
            type=ADDON_EXTENSION,
            average_daily_users=5000,
            users=[UserProfile.objects.get(username='******')],
            average_rating=5,
            description=u'My Addon description',
            file_kw={
                'hash': 'fakehash',
                'platform': amo.PLATFORM_ALL.id,
                'size': 42,
            },
            guid=generate_addon_guid(),
            icon_type=random.choice(default_icons),
            name=u'Ui-Addon',
            public_stats=True,
            slug='ui-test-2',
            summary=u'My Addon summary',
            tags=['some_tag', 'another_tag', 'ui-testing',
                  'selenium', 'python'],
            total_ratings=500,
            weekly_downloads=9999999,
            developer_comments='This is a testing addon.',
        )
        Preview.objects.create(addon=addon, position=1)
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        Rating.objects.create(addon=addon, rating=5, user=user_factory())
        AddonUser.objects.create(user=user_factory(username='******'),
                                 addon=addon, listed=True)
        version_factory(addon=addon, file_kw={'status': amo.STATUS_BETA},
                        version='1.1beta')
        addon.save()
        generate_collection(addon, app=FIREFOX)
        print(
            'Created addon {0} for testing successfully'
            .format(addon.name))
Ejemplo n.º 22
0
 def test_rejected_can_request_review(self):
     self.addon.update(status=amo.STATUS_NULL)
     latest_version = self.addon.find_latest_version(
         channel=amo.RELEASE_CHANNEL_LISTED)
     for file_ in latest_version.files.all():
         file_.update(status=amo.STATUS_DISABLED)
     version_factory(addon=self.addon,
                     file_kw={'status': amo.STATUS_DISABLED})
     doc = pq(self.client.get(self.url).content)
     buttons = doc('.version-status-actions form button')
     # We should only show the links for one of the disabled versions.
     assert buttons.length == 1
     assert buttons.text() == u'Request Review'
Ejemplo n.º 23
0
    def test_channel_prefix_not_shown_when_no_mixed_channels(self):
        self.login_as_admin()
        version_factory(addon=self.addon, channel=amo.RELEASE_CHANNEL_LISTED)
        assert self.addon.versions.count() == 2
        res = self.client.get(self.file_url())
        doc = pq(res.content)

        left_select = doc('#id_left')
        assert left_select('optgroup').attr('label') == self.version.version
        # Check there are NO prefixes on the labels for the channels
        file_options = left_select('option.status-public')
        assert not file_options.eq(0).text().endswith('[Self]')
        assert not file_options.eq(1).text().endswith('[AMO]')
        assert not file_options.eq(2).text().endswith('[AMO]')
Ejemplo n.º 24
0
 def test_is_compatible_by_default_type(self):
     # Types in NO_COMPAT are compatible by default.
     addon = Addon.objects.get(id=3615)
     version = version_factory(addon=addon)
     addon.update(type=amo.ADDON_PERSONA)
     assert version.is_compatible_by_default
     assert version.is_compatible_app(amo.FIREFOX)
Ejemplo n.º 25
0
 def test_is_compatible_by_default(self):
     # Base test for fixture before the rest. Should be compatible by
     # default.
     addon = Addon.objects.get(id=3615)
     version = version_factory(addon=addon)
     assert version.is_compatible_by_default
     assert version.is_compatible_app(amo.FIREFOX)
Ejemplo n.º 26
0
 def test_show_latest_unlisted_version_unlisted(self):
     unlisted_version = version_factory(
         addon=self.addon, channel=amo.RELEASE_CHANNEL_UNLISTED)
     unlisted_version.update(created=self.days_ago(1))
     result = self._test_url()
     assert result['latest_unlisted_version']
     assert result['latest_unlisted_version']['id'] == unlisted_version.pk
Ejemplo n.º 27
0
    def test_latest_unlisted_version_with_rights(self):
        self.serializer_class = self.serializer_class_with_unlisted_data

        self.addon = addon_factory()
        version_factory(
            addon=self.addon, channel=amo.RELEASE_CHANNEL_UNLISTED,
            version='1.1')
        assert self.addon.latest_unlisted_version

        result = self.serialize()
        # In this serializer latest_unlisted_version is present.
        assert result['latest_unlisted_version']
        self._test_version(
            self.addon.latest_unlisted_version,
            result['latest_unlisted_version'])
        assert result['latest_unlisted_version']['url'] == absolutify('')
Ejemplo n.º 28
0
def test_get_raw_diff_cache():
    addon = addon_factory(file_kw={'filename': 'webextension_no_id.xpi'})

    original_version = addon.current_version

    AddonGitRepository.extract_and_commit_from_version(original_version)

    version = version_factory(
        addon=addon, file_kw={'filename': 'webextension_no_id.xpi'})

    repo = AddonGitRepository.extract_and_commit_from_version(version)

    # Let's a file
    apply_changes(repo, version, '', 'manifest.json', delete=True)

    with mock.patch('olympia.lib.git.pygit2.Repository.diff') as mocked_diff:
        repo.get_diff(
            commit=version.git_hash,
            parent=original_version.git_hash)

        repo.get_diff(
            commit=version.git_hash,
            parent=original_version.git_hash)

        mocked_diff.assert_called_once()

    assert (version.git_hash, original_version.git_hash) in repo._diff_cache
Ejemplo n.º 29
0
    def setUp(self):
        # Create File objects for version 1.0 and 1.1.
        self.addon = addon_factory(
            guid='test-desktop@nowhere', slug='test-amo-addon',
            version_kw={'version': '1.0'})
        self.version = self.addon.current_version
        self.file = self.version.files.get()
        self.version_1_1 = version_factory(addon=self.addon, version='1.1')
        self.file_1_1 = self.version_1_1.files.get()

        # Creating the files and versions above resets this.
        self.addon.update(status=amo.STATUS_PUBLIC)

        # Create a FileUpload object for an XPI containing version 1.1.
        path = os.path.join(settings.ROOT,
                            'src/olympia/devhub/tests/addons/desktop.xpi')
        self.file_upload = FileUpload.objects.create(path=path)
        self.xpi_version = '1.1'

        # Patch validation tasks that we expect the validator to call.
        self.patchers = []
        self.save_file = self.patch(
            'olympia.devhub.tasks.handle_file_validation_result').subtask
        self.save_upload = self.patch(
            'olympia.devhub.tasks.handle_upload_validation_result').subtask

        self.validate_file = self.patch(
            'olympia.devhub.tasks.validate_file').subtask
        self.validate_upload = self.patch(
            'olympia.devhub.tasks.validate_file_path').subtask
Ejemplo n.º 30
0
    def test_no_upgrade_annotation_no_version(self):
        """Make sure there's no workaround the downgrade error."""
        self.addon.update(guid='guid@xpi')

        file_ = amo.tests.AMOPaths().file_fixture_path(
            'delicious_bookmarks-no-version.xpi')

        self.update_files(is_webextension=True)

        deleted_version = version_factory(
            addon=self.addon, file_kw={'is_webextension': False})
        deleted_version.delete()

        upload = FileUpload.objects.create(path=file_, addon=self.addon)
        upload.addon.version = None
        upload.addon.save()
        upload.save(update_fields=('version',))
        upload.refresh_from_db()

        tasks.validate(upload, listed=True)
        upload.refresh_from_db()

        expected = [u'testcases_installrdf', u'_test_rdf', u'missing_addon']

        validation = upload.processed_validation

        assert validation['messages'][0]['id'] == expected
        assert validation['messages'][0]['type'] == 'error'
Ejemplo n.º 31
0
    def test_get_results_with_good_blocked_versions(self):
        self.create_switch('enable-scanner-results-api', active=True)
        # Result labelled as "good" because auto-approve has been confirmed.
        version_1 = version_factory(addon=addon_factory())
        result_1 = ScannerResult.objects.create(scanner=CUSTOMS,
                                                version=version_1)
        VersionLog.objects.create(
            activity_log=ActivityLog.create(
                action=amo.LOG.CONFIRM_AUTO_APPROVED,
                version=version_1,
                user=self.user,
            ),
            version=version_1,
        )
        # Oh noes! The version has been blocked.
        block_1 = Block.objects.create(guid=version_1.addon.guid,
                                       updated_by=self.user)
        block_activity_log_save(block_1, change=False)

        response = self.client.get(self.url)
        results = self.assert_json_results(response, expected_results=1)
        assert results[0]['id'] == result_1.id
        assert results[0]['label'] == LABEL_BAD
Ejemplo n.º 32
0
 def test_version_pagination(self):
     addon = addon_factory(users=[user_factory()])
     first_file = addon.current_version.all_files[0]
     [version_factory(addon=addon) for i in range(0, 30)]
     self.detail_url = reverse('admin:addons_addon_change',
                               args=(addon.pk, ))
     user = user_factory(email='*****@*****.**')
     self.grant_permission(user, 'Addons:Edit')
     self.grant_permission(user, 'Admin:Advanced')
     self.client.login(email=user.email)
     response = self.client.get(self.detail_url, follow=True)
     assert response.status_code == 200
     assert addon.guid in response.content.decode('utf-8')
     assert len(pq(response.content)('.field-version__version')) == 30
     next_url = self.detail_url + '?page=2'
     assert next_url in response.content.decode('utf-8')
     response = self.client.get(next_url, follow=True)
     assert response.status_code == 200
     assert addon.guid in response.content.decode('utf-8')
     assert len(pq(response.content)('.field-version__version')) == 1
     assert pq(
         response.content)('#id_files-0-id')[0].attrib['value'] == (str(
             first_file.id))
Ejemplo n.º 33
0
    def test_only_affects_auto_approved_and_unconfirmed(self):
        # Non auto-approved add-on, should not be considered.
        addon_factory()

        # Non auto-approved add-on that has an AutoApprovalSummary entry,
        # should not be considered.
        AutoApprovalSummary.objects.create(
            version=addon_factory().current_version,
            verdict=amo.NOT_AUTO_APPROVED)

        # Add-on with the current version not auto-approved, should not be
        # considered.
        extra_addon = addon_factory()
        AutoApprovalSummary.objects.create(version=extra_addon.current_version,
                                           verdict=amo.AUTO_APPROVED)
        extra_addon.current_version.update(created=self.days_ago(1))
        version_factory(addon=extra_addon)

        # Add-on that was auto-approved but already confirmed, should not be
        # considered, it's too late.
        already_confirmed_addon = addon_factory()
        AutoApprovalSummary.objects.create(
            version=already_confirmed_addon.current_version,
            verdict=amo.AUTO_APPROVED,
            confirmed=True)

        # Add-on that should be considered because it's current version is
        # auto-approved.
        auto_approved_addon = addon_factory()
        AutoApprovalSummary.objects.create(
            version=auto_approved_addon.current_version,
            verdict=amo.AUTO_APPROVED)
        # Add some extra versions that should not have an impact.
        version_factory(addon=auto_approved_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})
        version_factory(addon=auto_approved_addon,
                        channel=amo.RELEASE_CHANNEL_UNLISTED)

        with count_subtask_calls(
                process_addons.recalculate_post_review_weight) as calls:
            call_command('process_addons',
                         task='recalculate_post_review_weight')

        assert len(calls) == 1
        assert calls[0]['kwargs']['args'] == [[auto_approved_addon.pk]]
Ejemplo n.º 34
0
    def test_webextension_cannot_be_downgraded_ignore_deleted_version(self):
        """Make sure even deleting the previous version does not prevent
        the downgrade error."""
        file_ = amo.tests.AMOPaths().file_fixture_path(
            'delicious_bookmarks-2.1.106-fx.xpi')

        self.update_files(is_webextension=True)

        deleted_version = version_factory(
            addon=self.addon, file_kw={'is_webextension': False})
        deleted_version.delete()

        upload = FileUpload.objects.create(path=file_, addon=self.addon)

        tasks.validate(upload, listed=True)
        upload.refresh_from_db()

        expected = ['validation', 'messages', 'legacy_addons_unsupported']

        validation = upload.processed_validation

        assert validation['messages'][0]['id'] == expected
        assert validation['messages'][0]['type'] == 'error'
Ejemplo n.º 35
0
    def test_current_beta_version(self):
        self.addon = addon_factory()

        self.beta_version = version_factory(
            addon=self.addon,
            file_kw={'status': amo.STATUS_BETA},
            version='1.1beta')

        result = self.serialize()
        assert result['current_beta_version']
        self._test_version(
            self.beta_version,
            result['current_beta_version'],
        )
        assert result['current_beta_version']['url'] == absolutify(
            reverse('addons.versions',
                    args=[self.addon.slug, self.beta_version.version]))

        # Just in case, test that current version is still present & different.
        assert result['current_version']
        assert result['current_version'] != result['current_beta_version']
        self._test_version(self.addon.current_version,
                           result['current_version'])
Ejemplo n.º 36
0
    def test_reject_multiple_versions(self):
        old_version = self.version
        self.version = version_factory(addon=self.addon, version='3.0')
        # An extra file should not change anything.
        file_factory(version=self.version, platform=amo.PLATFORM_LINUX.id)
        self.setup_data(amo.STATUS_PUBLIC, file_status=amo.STATUS_PUBLIC)

        # Safeguards.
        assert isinstance(self.helper.handler, ReviewFiles)
        assert self.addon.status == amo.STATUS_PUBLIC
        assert self.file.status == amo.STATUS_PUBLIC
        assert self.addon.current_version.is_public()

        data = self.get_data().copy()
        data['versions'] = self.addon.versions.all()
        self.helper.set_data(data)
        self.helper.handler.reject_multiple_versions()

        self.addon.reload()
        self.file.reload()
        assert self.addon.status == amo.STATUS_NULL
        assert self.addon.current_version is None
        assert list(self.addon.versions.all()) == [self.version, old_version]
        assert self.file.status == amo.STATUS_DISABLED

        assert len(mail.outbox) == 1
        assert mail.outbox[0].to == [self.addon.authors.all()[0].email]
        assert mail.outbox[0].subject == (
            u"Mozilla Add-ons: One or more versions of Delicious Bookmarks "
            u"didn't pass review")
        assert ('Version(s) affected and disabled:\n3.0, 2.1.072'
                in mail.outbox[0].body)
        log_token = ActivityLogToken.objects.get()
        assert log_token.uuid.hex in mail.outbox[0].reply_to[0]

        assert self.check_log_count(amo.LOG.REJECT_VERSION.id) == 2
        assert self.check_log_count(amo.LOG.REJECT_CONTENT.id) == 0
Ejemplo n.º 37
0
    def _handle_version(self, data):
        if (self.addon.versions(manager='unfiltered_for_relations').filter(
                version=data['version']).exists()):
            print('Skipping %s (version already exists' % data['version'])
            return

        file_data = data['file']
        file_kw = {
            'hash':
            file_data['hash'],
            'filename':
            basename(urlparse(file_data['url']).path),
            'status':
            amo.STATUS_CHOICES_API_LOOKUP[file_data['status']],
            'size':
            file_data['size'],
            'is_mozilla_signed_extension':
            (file_data['is_mozilla_signed_extension']),
            'strict_compatibility': (data['is_strict_compatibility_enabled']),
        }

        version_kw = {
            'version': data['version'],
            # FIXME: maybe reviewed/created would make sense at least, to
            # get more or less the correct ordering ?
            # Everything else we don't really care about at the moment.
        }

        print('Creating version %s' % data['version'])
        with atomic():
            version = version_factory(addon=self.addon,
                                      file_kw=file_kw,
                                      **version_kw)

            # Download the file to the right path.
            print('Downloading file for version %s' % data['version'])
            self._download_file(file_data['url'], version.file)
Ejemplo n.º 38
0
    def test_extract_addon_with_more_versions_than_batch_size(self):
        version_1 = self.addon.current_version
        version_2 = version_factory(
            addon=self.addon,
            file_kw={
                'filename': 'webextension_no_id.xpi',
            },
        )
        repo = AddonGitRepository(self.addon)
        entry = GitExtractionEntry.objects.create(addon=self.addon)

        assert not version_1.git_hash
        assert not version_2.git_hash
        assert not repo.is_extracted

        # First execution of the CRON task.
        self.command.extract_addon(entry, batch_size=1)
        version_1.refresh_from_db()
        version_2.refresh_from_db()
        entry.refresh_from_db()

        assert repo.is_extracted
        assert version_1.git_hash
        # We only git-extracted the first version because of batch_size=1.
        assert not version_2.git_hash
        # We keep the entry and we set `in_progress` to `False` because we
        # still need to extract the second version.
        assert not entry.in_progress
        assert GitExtractionEntry.objects.filter(pk=entry.pk).exists()

        # Second execution of the CRON task.
        self.command.extract_addon(entry, batch_size=1)
        version_2.refresh_from_db()

        assert repo.is_extracted
        assert version_2.git_hash
        assert not GitExtractionEntry.objects.filter(pk=entry.pk).exists()
Ejemplo n.º 39
0
    def test_serialize_deleted_file(self):
        expected_filename = 'manifest.json'
        parent_version = self.addon.current_version
        new_version = version_factory(addon=self.addon,
                                      file_kw={
                                          'filename': 'webextension_no_id.xpi',
                                          'is_webextension': True,
                                      })

        repo = AddonGitRepository.extract_and_commit_from_version(new_version)
        apply_changes(repo, new_version, '', expected_filename, delete=True)

        file = self.addon.current_version.current_file
        data = self.serialize(file, parent_version=parent_version)

        assert data['download_url'] is None
        # We deleted the selected file, so there should be a diff.
        assert data['diff'] is not None
        assert data['diff']['mode'] == 'D'
        assert data['mimetype'] == 'application/json'
        assert data['sha256'] is None
        assert data['size'] is None
        assert data['mime_category'] is None
        assert data['filename'] == expected_filename
Ejemplo n.º 40
0
    def test_addon_mixed_channels(self):
        first_version = self.addon.current_version
        second_version = version_factory(addon=self.addon,
                                         channel=amo.RELEASE_CHANNEL_UNLISTED)
        response = self.client.get(self.url)
        assert response.status_code == 200
        doc = pq(response.content)

        first_expected_review_link = reverse('editors.review',
                                             args=(self.addon.slug, ))
        elms = doc('a[href="%s"]' % first_expected_review_link)
        assert len(elms) == 1
        assert elms[0].attrib['title'] == str(first_version.pk)
        assert elms[0].text == first_version.version

        second_expected_review_link = reverse('editors.review',
                                              args=(
                                                  'unlisted',
                                                  self.addon.slug,
                                              ))
        elms = doc('a[href="%s"]' % second_expected_review_link)
        assert len(elms) == 1
        assert elms[0].attrib['title'] == str(second_version.pk)
        assert elms[0].text == second_version.version
Ejemplo n.º 41
0
    def test_cant_reply_to_old_version(self):
        old_version = self.addon.find_latest_version(channel=amo.RELEASE_CHANNEL_LISTED)
        old_version.update(created=self.days_ago(1))
        new_version = version_factory(addon=self.addon)
        assert new_version == self.addon.find_latest_version(
            channel=amo.RELEASE_CHANNEL_LISTED
        )
        self.user = user_factory()
        self.grant_permission(self.user, 'Addons:Review')
        self.client.login_api(self.user)

        # First check we can reply to new version
        new_url = reverse_ns(
            'version-reviewnotes-list',
            kwargs={'addon_pk': self.addon.pk, 'version_pk': new_version.pk},
        )
        response = self.client.post(new_url, {'comments': 'comménty McCómm€nt'})
        assert response.status_code == 201
        assert self.get_review_activity_queryset().count() == 1

        # The check we can't reply to the old version
        response = self._post_reply()
        assert response.status_code == 400
        assert self.get_review_activity_queryset().count() == 1
Ejemplo n.º 42
0
    def test_public_to_public_already_had_webextension_tag(self):
        self.file.update(is_webextension=True)
        Tag(tag_text='firefox57').save_tag(self.addon)
        assert (set(self.addon.tags.all().values_list(
            'tag_text', flat=True)) == set(['firefox57']))
        self.addon.current_version.update(created=self.days_ago(1))
        self.version = version_factory(
            addon=self.addon,
            channel=amo.RELEASE_CHANNEL_LISTED,
            version='3.0.42',
            file_kw={'status': amo.STATUS_AWAITING_REVIEW})
        self.file = self.version.files.all()[0]
        self.setup_data(amo.STATUS_PUBLIC)

        # Safeguards.
        assert isinstance(self.helper.handler, helpers.ReviewFiles)
        assert self.addon.status == amo.STATUS_PUBLIC
        assert self.file.status == amo.STATUS_AWAITING_REVIEW
        assert self.addon.current_version.files.all()[0].status == (
            amo.STATUS_PUBLIC)

        self.helper.handler.process_public()
        assert (set(self.addon.tags.all().values_list(
            'tag_text', flat=True)) == set(['firefox57']))
Ejemplo n.º 43
0
 def test_known_ip_adresses(self):
     self.user.update(last_login_ip='127.1.2.3')
     Rating.objects.create(
         addon=addon_factory(), user=self.user, ip_address='127.1.2.3')
     dummy_addon = addon_factory()
     Rating.objects.create(
         addon=dummy_addon, version=dummy_addon.current_version,
         user=self.user, ip_address='128.1.2.3')
     Rating.objects.create(
         addon=dummy_addon, version=version_factory(addon=dummy_addon),
         user=self.user, ip_address='129.1.2.4')
     Rating.objects.create(
         addon=addon_factory(), user=self.user, ip_address='130.1.2.4')
     Rating.objects.create(
         addon=addon_factory(), user=self.user, ip_address='130.1.2.4')
     Rating.objects.create(
         addon=dummy_addon,
         user=user_factory(), ip_address='255.255.0.0')
     model_admin = UserAdmin(UserProfile, admin.site)
     doc = pq(model_admin.known_ip_adresses(self.user))
     result = doc('ul li').text().split()
     assert len(result) == 4
     assert (set(result) ==
             set(['130.1.2.4', '128.1.2.3', '129.1.2.4', '127.1.2.3']))
Ejemplo n.º 44
0
    def test_version_is_public(self):
        addon = Addon.objects.get(id=3615)
        version = version_factory(addon=addon)

        # Base test. Everything is in order, the version should be public.
        assert version.is_public()

        # Non-public file.
        self._reset_version(version)
        version.all_files[0].status = amo.STATUS_DISABLED
        assert not version.is_public()

        # Deleted version.
        self._reset_version(version)
        version.deleted = True
        assert not version.is_public()

        # Non-public addon.
        self._reset_version(version)

        is_public_path = 'olympia.addons.models.Addon.is_public'
        with mock.patch(is_public_path) as is_addon_public:
            is_addon_public.return_value = False
            assert not version.is_public()
Ejemplo n.º 45
0
    def test_only_affects_auto_approved(
            self, recalculate_post_review_weight_mock):
        # Non auto-approved add-on, should not be considered.
        addon_factory()

        # Non auto-approved add-on that has an AutoApprovalSummary entry,
        # should not be considered.
        AutoApprovalSummary.objects.create(
            version=addon_factory().current_version,
            verdict=amo.NOT_AUTO_APPROVED)

        # Add-on with the current version not auto-approved, should not be
        # considered.
        extra_addon = addon_factory()
        AutoApprovalSummary.objects.create(
            version=extra_addon.current_version, verdict=amo.AUTO_APPROVED)
        extra_addon.current_version.update(created=self.days_ago(1))
        version_factory(addon=extra_addon)

        # Add-on that should be considered because it's current version is
        # auto-approved.
        auto_approved_addon = addon_factory()
        AutoApprovalSummary.objects.create(
            version=auto_approved_addon.current_version,
            verdict=amo.AUTO_APPROVED)
        # Add some extra versions that should not have an impact.
        version_factory(
            addon=auto_approved_addon,
            file_kw={'status': amo.STATUS_AWAITING_REVIEW})
        version_factory(
            addon=auto_approved_addon, channel=amo.RELEASE_CHANNEL_UNLISTED)

        call_command(
            'process_addons', task='recalculate_post_review_weight')

        assert recalculate_post_review_weight_mock.call_count == 1
        recalculate_post_review_weight_mock.assert_called_with(
            args=[[auto_approved_addon.pk]], kwargs={})
Ejemplo n.º 46
0
 def test_source_upload_path_utf8_chars(self):
     addon = Addon.objects.get(id=3615)
     addon.update(slug=u'crosswarpex-확장')
     version = version_factory(addon=addon, version='0.1')
     uploaded_name = source_upload_path(version, 'crosswarpex-확장.tar.gz')
     assert uploaded_name.endswith(u'crosswarpex-확장-0.1-src.tar.gz')
Ejemplo n.º 47
0
 def test_source_upload_path(self):
     addon = Addon.objects.get(id=3615)
     version = version_factory(addon=addon, version='0.1')
     uploaded_name = source_upload_path(version, 'foo.tar.gz')
     assert uploaded_name.endswith(u'a3615-0.1-src.tar.gz')
Ejemplo n.º 48
0
 def test_invalidate_d2c_version_signals_on_save(self, inv_mock):
     addon = Addon.objects.get(pk=3615)
     version_factory(addon=addon)
     assert inv_mock.called
Ejemplo n.º 49
0
 def test_validity_version_out_of_date(self):
     version_factory(addon=self.addon, channel=amo.RELEASE_CHANNEL_LISTED)
     # The token isn't expired.
     assert not self.token.is_expired()
     # But is invalid, because the version isn't the latest version.
     assert not self.token.is_valid()
Ejemplo n.º 50
0
    def test_invalid_versions_not_accepted(self):
        user = user_factory()
        self.grant_permission(user, 'Admin:Tools')
        self.grant_permission(user, 'Reviews:Admin')
        self.client.login(email=user.email)

        self.addon.current_version.update(version='123.4b5')
        version_factory(addon=self.addon, version='678')
        # Update min_version in self.block to a version that doesn't exist
        self.block.update(min_version='444.4a')

        response = self.client.get(self.change_url, follow=True)
        content = response.content.decode('utf-8')
        doc = pq(content)
        ver_list = doc('#id_min_version option')
        assert len(ver_list) == 4
        assert ver_list.eq(0).attr['value'] == '444.4a'
        assert ver_list.eq(0).text() == '(invalid)'
        assert ver_list.eq(1).attr['value'] == '0'
        assert ver_list.eq(2).attr['value'] == '123.4b5'
        assert ver_list.eq(3).attr['value'] == '678'
        ver_list = doc('#id_max_version option')
        assert len(ver_list) == 3
        assert ver_list.eq(0).attr['value'] == '*'
        assert ver_list.eq(1).attr['value'] == '123.4b5'
        assert ver_list.eq(2).attr['value'] == '678'

        data = {
            'url': 'https://foo.baa',
            'reason': 'some other reason',
            'include_in_legacy': True,
            '_continue': 'Save and continue editing',
        }
        # Try saving the form with the same min_version
        response = self.client.post(
            self.change_url,
            dict(
                min_version='444.4a',  # current value, but not a version.
                max_version=self.addon.current_version.version,  # valid
                **data),
            follow=True)
        assert response.status_code == 200
        assert b'Invalid version' in response.content
        self.block = self.block.reload()
        assert self.block.min_version == '444.4a'  # not changed
        assert self.block.max_version == '*'  # not changed either.
        assert not ActivityLog.objects.for_addons(self.addon).exists()
        doc = pq(content)
        assert doc('#id_min_version option').eq(0).attr['value'] == '444.4a'

        # Change to a version that exists
        response = self.client.post(self.change_url,
                                    dict(min_version='123.4b5',
                                         max_version='*',
                                         **data),
                                    follow=True)
        assert response.status_code == 200
        assert b'Invalid version' not in response.content
        self.block = self.block.reload()
        assert self.block.min_version == '123.4b5'  # changed
        assert self.block.max_version == '*'
        assert ActivityLog.objects.for_addons(self.addon).exists()
        # the value shouldn't be in the list of versions either any longer.
        assert b'444.4a' not in response.content
Ejemplo n.º 51
0
    def test_add_single(self):
        user = user_factory()
        self.grant_permission(user, 'Admin:Tools')
        self.grant_permission(user, 'Reviews:Admin')
        self.client.login(email=user.email)

        addon = addon_factory(guid='guid@',
                              name='Danger Danger',
                              version_kw={'version': '1.2a'})
        first_version = addon.current_version
        second_version = version_factory(addon=addon, version='3')
        pending_version = version_factory(
            addon=addon,
            version='5.999',
            file_kw={'status': amo.STATUS_AWAITING_REVIEW})
        response = self.client.get(self.single_url + '?guid=guid@',
                                   follow=True)
        content = response.content.decode('utf-8')
        assert 'Add-on GUIDs (one per line)' not in content
        assert 'guid@' in content
        assert 'Danger Danger' in content
        assert str(addon.average_daily_users) in content
        assert Block.objects.count() == 0  # Check we didn't create it already
        assert 'Block History' in content

        # Create the block
        response = self.client.post(self.single_url + '?guid=guid@', {
            'min_version': '0',
            'max_version': addon.current_version.version,
            'url': 'dfd',
            'reason': 'some reason',
            '_continue': 'Save',
        },
                                    follow=True)
        assert response.status_code == 200
        assert Block.objects.count() == 1
        block = Block.objects.first()
        assert block.addon == addon
        log = ActivityLog.objects.for_addons(addon).last()
        assert log.action == amo.LOG.BLOCKLIST_BLOCK_ADDED.id
        assert log.arguments == [addon, addon.guid, block]
        assert log.details['min_version'] == '0'
        assert log.details['max_version'] == addon.current_version.version
        assert log.details['reason'] == 'some reason'
        block_log = ActivityLog.objects.for_block(block).filter(
            action=log.action).last()
        assert block_log == log
        block_log_by_guid = ActivityLog.objects.for_guidblock('guid@').filter(
            action=log.action).last()
        assert block_log_by_guid == log

        assert log == ActivityLog.objects.for_version(first_version).last()
        assert log == ActivityLog.objects.for_version(second_version).last()
        assert not ActivityLog.objects.for_version(pending_version).exists()

        content = response.content.decode('utf-8')
        todaysdate = datetime.datetime.now().date()
        assert f'<a href="dfd">{todaysdate}</a>' in content
        assert f'Block added by {user.name}: guid@' in content
        assert f'versions 0 - {addon.current_version.version}' in content
        assert f'Included in legacy blocklist' not in content
Ejemplo n.º 52
0
 def test_unlisted(self):
     addon = addon_factory()
     self.version = version_factory(addon=addon,
                                    channel=amo.RELEASE_CHANNEL_UNLISTED)
     result = self.serialize()
     assert result['channel'] == 'unlisted'
Ejemplo n.º 53
0
    def setup_data(self):
        user = user_factory()
        for idx in range(0, 5):
            addon_factory()
        # one version, 0 - *
        Block.objects.create(
            addon=addon_factory(file_kw={'is_signed': True, 'is_webextension': True}),
            updated_by=user,
        )
        # one version, 0 - 9999
        Block.objects.create(
            addon=addon_factory(
                version_kw={'version': '11.7'},
                file_kw={'is_signed': True, 'is_webextension': True},
            ),
            updated_by=user,
            max_version='9999',
        )
        # one version, 0 - *, unlisted
        Block.objects.create(
            addon=addon_factory(
                version_kw={'channel': amo.RELEASE_CHANNEL_UNLISTED},
                file_kw={'is_signed': True, 'is_webextension': True},
            ),
            updated_by=user,
        )
        # five versions, but only two within block (123.40, 123.5)
        self.five_ver_block = Block.objects.create(
            addon=addon_factory(
                version_kw={'version': '123.40'},
                file_kw={'is_signed': True, 'is_webextension': True},
            ),
            updated_by=user,
            max_version='123.45',
        )
        self.five_ver_123_40 = self.five_ver_block.addon.current_version
        self.five_ver_123_5 = version_factory(
            addon=self.five_ver_block.addon,
            version='123.5',
            deleted=True,
            file_kw={'is_signed': True, 'is_webextension': True},
        )
        self.five_ver_123_45_1 = version_factory(
            addon=self.five_ver_block.addon,
            version='123.45.1',
            file_kw={'is_signed': True, 'is_webextension': True},
        )
        # these two would be included if they were signed and webextensions
        self.not_signed_version = version_factory(
            addon=self.five_ver_block.addon,
            version='123.5.1',
            file_kw={'is_signed': False, 'is_webextension': True},
        )
        self.not_webext_version = version_factory(
            addon=self.five_ver_block.addon,
            version='123.5.2',
            file_kw={'is_signed': True, 'is_webextension': False},
        )
        # no matching versions (edge cases)
        self.over = Block.objects.create(
            addon=addon_factory(
                version_kw={'version': '0.1'},
                file_kw={'is_signed': True, 'is_webextension': True},
            ),
            updated_by=user,
            max_version='0',
        )
        self.under = Block.objects.create(
            addon=addon_factory(
                version_kw={'version': '9998.0'},
                file_kw={'is_signed': True, 'is_webextension': True},
            ),
            updated_by=user,
            min_version='9999',
        )

        # A blocked addon has been uploaded and deleted before
        reused_2_1_addon = addon_factory(
            # this a previous, superceeded, addon that should be included
            status=amo.STATUS_DELETED,  # they should all be deleted
            version_kw={'version': '2.1'},
            file_kw={'is_signed': True, 'is_webextension': True},
        )
        self.addon_deleted_before_2_1_ver = reused_2_1_addon.versions.all()[0]
        reused_2_5_addon = addon_factory(
            # And this is an earlier addon that should also be included
            status=amo.STATUS_DELETED,  # they should all be deleted
            version_kw={'version': '2.5'},
            file_kw={'is_signed': True, 'is_webextension': True},
        )
        self.addon_deleted_before_2_5_ver = reused_2_5_addon.versions.all()[0]
        current_addon = addon_factory(
            version_kw={'version': '2'},
            file_kw={'is_signed': True, 'is_webextension': True},
        )
        self.addon_deleted_before_unblocked_ver = current_addon.current_version
        self.addon_deleted_before_unsigned_ver = version_factory(
            addon=current_addon,
            version='2.1',
            # not signed, but shouldn't override the signed 2.1 version
            file_kw={'is_signed': False, 'is_webextension': True},
        )
        version_factory(
            addon=current_addon,
            version='3.0',
            file_kw={'is_signed': True, 'is_webextension': True},
        )
        reused_2_1_addon.update(guid=GUID_REUSE_FORMAT.format(current_addon.id))
        reused_2_5_addon.update(guid=GUID_REUSE_FORMAT.format(reused_2_1_addon.id))
        reused_2_1_addon.addonguid.update(guid=current_addon.guid)
        reused_2_5_addon.addonguid.update(guid=current_addon.guid)
        self.addon_deleted_before_block = Block.objects.create(
            guid=current_addon.guid, min_version='2.0.1', updated_by=user
        )
Ejemplo n.º 54
0
    def test_extract_version_and_files(self):
        version = self.addon.current_version
        file_factory(version=version, platform=PLATFORM_MAC.id)

        unlisted_version = version_factory(
            addon=self.addon, channel=amo.RELEASE_CHANNEL_UNLISTED, file_kw={
                'is_webextension': True,
            })
        # Give one of the versions some webext permissions to test that.
        WebextPermission.objects.create(
            file=unlisted_version.all_files[0],
            permissions=['bookmarks', 'random permission']
        )
        extracted = self._extract()

        assert extracted['current_version']
        assert extracted['current_version']['id'] == version.pk
        # Because strict_compatibility is False, the max version we record in
        # the index is an arbitrary super high version.
        assert extracted['current_version']['compatible_apps'] == {
            FIREFOX.id: {
                'min': 2000000200100,
                'max': 9999000000200100,
                'max_human': '4.0',
                'min_human': '2.0',
            }
        }
        assert extracted['current_version']['reviewed'] == version.reviewed
        assert extracted['current_version']['version'] == version.version
        for index, file_ in enumerate(version.all_files):
            extracted_file = extracted['current_version']['files'][index]
            assert extracted_file['id'] == file_.pk
            assert extracted_file['created'] == file_.created
            assert extracted_file['filename'] == file_.filename
            assert extracted_file['hash'] == file_.hash
            assert extracted_file['is_webextension'] == file_.is_webextension
            assert extracted_file['is_restart_required'] == (
                file_.is_restart_required)
            assert extracted_file['is_mozilla_signed_extension'] == (
                file_.is_mozilla_signed_extension)
            assert extracted_file['platform'] == file_.platform
            assert extracted_file['size'] == file_.size
            assert extracted_file['status'] == file_.status
            assert extracted_file['webext_permissions_list'] == []

        assert set(extracted['platforms']) == set([PLATFORM_MAC.id,
                                                   PLATFORM_ALL.id])

        version = unlisted_version
        assert extracted['latest_unlisted_version']
        assert extracted['latest_unlisted_version']['id'] == version.pk
        # Because strict_compatibility is False, the max version we record in
        # the index is an arbitrary super high version.
        assert extracted['latest_unlisted_version']['compatible_apps'] == {
            FIREFOX.id: {
                'min': 4009900200100,
                'max': 9999000000200100,
                'max_human': '5.0.99',
                'min_human': '4.0.99',
            }
        }
        assert (
            extracted['latest_unlisted_version']['version'] == version.version)
        for idx, file_ in enumerate(version.all_files):
            extracted_file = extracted['latest_unlisted_version']['files'][idx]
            assert extracted_file['id'] == file_.pk
            assert extracted_file['created'] == file_.created
            assert extracted_file['filename'] == file_.filename
            assert extracted_file['hash'] == file_.hash
            assert extracted_file['is_webextension'] == file_.is_webextension
            assert extracted_file['is_mozilla_signed_extension'] == (
                file_.is_mozilla_signed_extension)
            assert extracted_file['is_restart_required'] == (
                file_.is_restart_required)
            assert extracted_file['platform'] == file_.platform
            assert extracted_file['size'] == file_.size
            assert extracted_file['status'] == file_.status
            assert (extracted_file['webext_permissions_list'] ==
                    file_.webext_permissions_list ==
                    ['bookmarks', 'random permission'])
Ejemplo n.º 55
0
    def test_latest_public_compatible_with(self):
        # Add compatible add-ons. We're going to request versions compatible
        # with 58.0.
        compatible_pack1 = addon_factory(
            name='Spanish Language Pack',
            type=amo.ADDON_LPAPP,
            target_locale='es',
            file_kw={'strict_compatibility': True},
            version_kw={
                'min_app_version': '57.0',
                'max_app_version': '57.*'
            })
        compatible_pack1.current_version.update(created=self.days_ago(2))
        compatible_version1 = version_factory(
            addon=compatible_pack1,
            file_kw={'strict_compatibility': True},
            min_app_version='58.0',
            max_app_version='58.*')
        compatible_version1.update(created=self.days_ago(1))
        compatible_pack2 = addon_factory(
            name='French Language Pack',
            type=amo.ADDON_LPAPP,
            target_locale='fr',
            file_kw={'strict_compatibility': True},
            version_kw={
                'min_app_version': '58.0',
                'max_app_version': '58.*'
            })
        compatible_version2 = compatible_pack2.current_version
        compatible_version2.update(created=self.days_ago(2))
        version_factory(addon=compatible_pack2,
                        file_kw={'strict_compatibility': True},
                        min_app_version='59.0',
                        max_app_version='59.*')
        # Add a more recent version for both add-ons, that would be compatible
        # with 58.0, but is not public/listed so should not be returned.
        version_factory(addon=compatible_pack1,
                        file_kw={'strict_compatibility': True},
                        min_app_version='58.0',
                        max_app_version='58.*',
                        channel=amo.RELEASE_CHANNEL_UNLISTED)
        version_factory(addon=compatible_pack2,
                        file_kw={
                            'strict_compatibility': True,
                            'status': amo.STATUS_DISABLED
                        },
                        min_app_version='58.0',
                        max_app_version='58.*')
        # And for the first pack, add a couple of versions that are also
        # compatible. They are older so should appear after.
        extra_compatible_version_1 = version_factory(
            addon=compatible_pack1,
            file_kw={'strict_compatibility': True},
            min_app_version='58.0',
            max_app_version='58.*')
        extra_compatible_version_1.update(created=self.days_ago(3))
        extra_compatible_version_2 = version_factory(
            addon=compatible_pack1,
            file_kw={'strict_compatibility': True},
            min_app_version='58.0',
            max_app_version='58.*')
        extra_compatible_version_2.update(created=self.days_ago(4))

        # Add a few of incompatible add-ons.
        incompatible_pack1 = addon_factory(
            name='German Language Pack (incompatible with 58.0)',
            type=amo.ADDON_LPAPP,
            target_locale='fr',
            file_kw={'strict_compatibility': True},
            version_kw={
                'min_app_version': '56.0',
                'max_app_version': '56.*'
            })
        version_factory(addon=incompatible_pack1,
                        file_kw={'strict_compatibility': True},
                        min_app_version='59.0',
                        max_app_version='59.*')
        addon_factory(name='Italian Language Pack (incompatible with 58.0)',
                      type=amo.ADDON_LPAPP,
                      target_locale='it',
                      file_kw={'strict_compatibility': True},
                      version_kw={
                          'min_app_version': '59.0',
                          'max_app_version': '59.*'
                      })
        addon_factory(name='Thunderbird Polish Language Pack',
                      type=amo.ADDON_LPAPP,
                      target_locale='pl',
                      file_kw={'strict_compatibility': True},
                      version_kw={
                          'application': amo.THUNDERBIRD.id,
                          'min_app_version': '58.0',
                          'max_app_version': '58.*'
                      })
        # Even add a pack with a compatible version... not public. And another
        # one with a compatible version... not listed.
        incompatible_pack2 = addon_factory(
            name='Japanese Language Pack (public, but 58.0 version is not)',
            type=amo.ADDON_LPAPP,
            target_locale='ja',
            file_kw={'strict_compatibility': True},
            version_kw={
                'min_app_version': '57.0',
                'max_app_version': '57.*'
            })
        version_factory(addon=incompatible_pack2,
                        min_app_version='58.0',
                        max_app_version='58.*',
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'strict_compatibility': True
                        })
        incompatible_pack3 = addon_factory(
            name='Nederlands Language Pack (58.0 version is unlisted)',
            type=amo.ADDON_LPAPP,
            target_locale='ja',
            file_kw={'strict_compatibility': True},
            version_kw={
                'min_app_version': '57.0',
                'max_app_version': '57.*'
            })
        version_factory(addon=incompatible_pack3,
                        min_app_version='58.0',
                        max_app_version='58.*',
                        channel=amo.RELEASE_CHANNEL_UNLISTED,
                        file_kw={'strict_compatibility': True})

        appversions = {
            'min': version_int('58.0'),
            'max': version_int('58.0a'),
        }
        qs = Version.objects.latest_public_compatible_with(
            amo.FIREFOX.id, appversions)

        expected_versions = [
            compatible_version1, compatible_version2,
            extra_compatible_version_1, extra_compatible_version_2
        ]
        assert list(qs) == expected_versions
Ejemplo n.º 56
0
    def setUp(self):
        super(TestBrowseRedirect, self).setUp()

        self.version = version_factory(addon=addon_factory())
        self.browse_redirect_url = reverse('files.browse_redirect',
                                           args=[self.version.pk])
Ejemplo n.º 57
0
    def test_can_edit_with_discovery_edit_permission(self):
        addon = addon_factory()
        item = PromotedAddon.objects.create(addon=addon,
                                            group_id=RECOMMENDED.id)
        ver1 = addon.current_version
        ver1.update(version='1.111')
        ver2 = version_factory(addon=addon, version='1.222')
        ver3 = version_factory(addon=addon, version='1.333')
        item.reload()
        assert item.addon.current_version == ver3
        approvals = [
            PromotedApproval.objects.create(version=ver1,
                                            group_id=RECOMMENDED.id,
                                            application_id=amo.FIREFOX.id),
            PromotedApproval.objects.create(version=ver2,
                                            group_id=RECOMMENDED.id,
                                            application_id=amo.ANDROID.id),
            PromotedApproval.objects.create(version=ver2,
                                            group_id=LINE.id,
                                            application_id=amo.FIREFOX.id),
            PromotedApproval.objects.create(version=ver3,
                                            group_id=RECOMMENDED.id,
                                            application_id=amo.FIREFOX.id),
        ]
        approvals.reverse()  # we order by -version_id so match it.
        item.reload()
        assert item.approved_applications
        detail_url = reverse(self.detail_url_name, args=(item.pk, ))
        user = user_factory(email='*****@*****.**')
        self.grant_permission(user, 'Discovery:Edit')
        self.client.login(email=user.email)
        response = self.client.get(detail_url, follow=True)
        assert response.status_code == 200
        content = response.content.decode('utf-8')
        assert '1.111' in content
        assert '1.222' in content
        assert '1.333' in content

        response = self.client.post(
            detail_url,
            dict(
                self._get_approval_form(item, approvals),
                **self._get_heroform(''),
                **{
                    'group_id': LINE.id,  # change the group
                }),
            follow=True)
        assert response.status_code == 200
        assert 'errors' not in response.context_data, (
            response.context_data['errors'])
        item.reload()
        assert PromotedAddon.objects.count() == 1
        assert item.group == LINE
        assert PromotedApproval.objects.count() == 4  # same
        # now it's not promoted because the current_version isn't approved for
        # LINE group
        assert not item.approved_applications

        # Try to delete one of the approvals
        response = self.client.post(
            detail_url,
            dict(
                self._get_approval_form(item, approvals),
                **self._get_heroform(''),
                **{
                    'form-0-DELETE': 'on',  # delete the latest approval
                }),
            follow=True)
        assert response.status_code == 200
        assert 'errors' not in response.context_data, (
            response.context_data['errors'])
        assert PromotedAddon.objects.count() == 1
        assert PromotedApproval.objects.count() == 3
        assert PrimaryHero.objects.count() == 0  # check we didn't add
Ejemplo n.º 58
0
    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
Ejemplo n.º 59
0
    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,
            )
        ]
Ejemplo n.º 60
0
    def test_get(self):
        task_user = user_factory()
        # result labelled as "bad" because its state is TRUE_POSITIVE
        bad_version = version_factory(addon=addon_factory())
        bad_result = ScannerResult.objects.create(scanner=YARA,
                                                  version=bad_version,
                                                  state=TRUE_POSITIVE)
        # result without a version and state is UNKNOWN
        ScannerResult.objects.create(scanner=YARA)
        # true positive, but without a version
        ScannerResult.objects.create(scanner=YARA, state=TRUE_POSITIVE)
        # result labelled as "good" because it has been approved
        good_version_1 = version_factory(addon=addon_factory())
        good_result_1 = ScannerResult.objects.create(scanner=WAT,
                                                     version=good_version_1)
        ActivityLog.create(amo.LOG.APPROVE_VERSION,
                           good_version_1,
                           user=self.user)
        # result labelled as "good" because auto-approve has been confirmed
        good_version_2 = version_factory(addon=addon_factory())
        good_result_2 = ScannerResult.objects.create(scanner=CUSTOMS,
                                                     version=good_version_2)
        ActivityLog.create(amo.LOG.APPROVE_VERSION,
                           good_version_2,
                           user=task_user)
        ActivityLog.create(amo.LOG.CONFIRM_AUTO_APPROVED,
                           good_version_2,
                           user=self.user)
        # Simulate a reviewer who has confirmed auto-approval a second time. We
        # should not return duplicate results.
        ActivityLog.create(amo.LOG.CONFIRM_AUTO_APPROVED,
                           good_version_2,
                           user=self.user)
        # result NOT labelled as "good" because action is not correct.
        version_3 = version_factory(addon=addon_factory())
        ScannerResult.objects.create(scanner=YARA, version=version_3)
        ActivityLog.create(amo.LOG.REJECT_VERSION, version_3, user=self.user)
        # result NOT labelled as "good" because user is TASK_USER_ID
        version_4 = version_factory(addon=addon_factory())
        ScannerResult.objects.create(scanner=YARA, version=version_4)
        ActivityLog.create(amo.LOG.APPROVE_VERSION, version_4, user=task_user)

        with override_settings(TASK_USER_ID=task_user.pk):
            response = self.client.get(self.url)

        assert response.status_code == 200
        results = self.assert_json_results(response, expected_results=3)
        # Force a `label` value so that the serialized (expected) data is
        # accurate. This is needed because `label` is an annotated field
        # created in the QuerySet.
        good_result_2.label = 'good'
        assert results[0] == ScannerResultSerializer(
            instance=good_result_2).data
        # Force a `label` value so that the serialized (expected) data is
        # accurate. This is needed because `label` is an annotated field
        # created in the QuerySet.
        good_result_1.label = 'good'
        assert results[1] == ScannerResultSerializer(
            instance=good_result_1).data
        # Force a `label` value so that the serialized (expected) data is
        # accurate. This is needed because `label` is an annotated field
        # created in the QuerySet.
        bad_result.label = 'bad'
        assert results[2] == ScannerResultSerializer(instance=bad_result).data