def test_approve(self, review_helper_mock, statsd_incr_mock):
     command = auto_approve.Command()
     command.approve(self.version)
     assert review_helper_mock.call_count == 1
     assert review_helper_mock.call_args == ((), {
         'addon': self.addon,
         'version': self.version
     })
     assert review_helper_mock().handler.process_public.call_count == 1
     assert statsd_incr_mock.call_count == 1
     assert statsd_incr_mock.call_args == ((
         'reviewers.auto_approve.approve.success', ), {})
    def test_fetch_candidates(self):
        # Create the candidates and extra addons & versions that should not be
        # considered for auto-approval.
        expected = self.create_candidates()

        # Gather the candidates.
        command = auto_approve.Command()
        command.post_review = True
        qs = command.fetch_candidates()

        # Test that they are all present.
        assert [(version.addon, version) for version in qs] == expected
    def test_fetch_candidates(self):
        # We already have an add-on with a version awaiting review that should
        # be considered. Make sure its nomination date is in the past to test
        # ordering.
        self.version.update(nomination=self.days_ago(1))
        # Add reviewer flags disabling auto-approval for this add-on. It would
        # still be fetched as a candidate, just rejected later on when
        # calculating the verdict.
        AddonReviewerFlags.objects.create(addon=self.addon,
                                          auto_approval_disabled=True)

        # Add nominated add-on: it should be considered.
        new_addon = addon_factory(status=amo.STATUS_NOMINATED,
                                  file_kw={
                                      'status': amo.STATUS_AWAITING_REVIEW,
                                      'is_webextension': True
                                  })
        new_addon_version = new_addon.versions.all()[0]
        new_addon_version.update(nomination=self.days_ago(2))
        # Even add an empty reviewer flags instance, that should not matter.
        AddonReviewerFlags.objects.create(addon=new_addon)

        # Add langpack: it should be considered.
        langpack = addon_factory(type=amo.ADDON_LPAPP,
                                 status=amo.STATUS_NOMINATED,
                                 file_kw={
                                     'status': amo.STATUS_AWAITING_REVIEW,
                                     'is_webextension': True
                                 })
        langpack_version = langpack.versions.all()[0]
        langpack_version.update(nomination=self.days_ago(3))

        # Add a dictionary: it should also be considered.
        dictionary = addon_factory(type=amo.ADDON_DICT,
                                   status=amo.STATUS_NOMINATED,
                                   file_kw={
                                       'status': amo.STATUS_AWAITING_REVIEW,
                                       'is_webextension': True
                                   })
        dictionary_version = dictionary.versions.all()[0]
        dictionary_version.update(nomination=self.days_ago(4))

        # search engine plugins are considered now
        search_addon = addon_factory(type=amo.ADDON_SEARCH)
        version_factory(addon=search_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        },
                        nomination=self.days_ago(5))

        # Some recommended add-ons - one nominated and one update.
        # They should be considered by fetch_candidate(), so that they get a
        # weight assigned etc - they will not be auto-approved but that's
        # handled at a later stage, when calculating the verdict.
        recommendable_addon_nominated = addon_factory(
            status=amo.STATUS_NOMINATED,
            version_kw={
                'recommendation_approved': True,
                'nomination': self.days_ago(6)
            },
            file_kw={
                'status': amo.STATUS_AWAITING_REVIEW,
                'is_webextension': True
            },
        )
        recommended_addon = version_factory(addon=addon_factory(),
                                            recommendation_approved=True,
                                            nomination=self.days_ago(7),
                                            file_kw={
                                                'status':
                                                amo.STATUS_AWAITING_REVIEW,
                                                'is_webextension': True
                                            }).addon
        DiscoveryItem.objects.create(recommendable=True,
                                     addon=recommendable_addon_nominated)
        DiscoveryItem.objects.create(recommendable=True,
                                     addon=recommended_addon)

        # ---------------------------------------------------------------------
        # Add a bunch of add-ons in various states that should not be returned.
        # Public add-on with no updates.
        addon_factory(file_kw={'is_webextension': True})

        # Disabled add-on with updates.
        disabled_addon = addon_factory(disabled_by_user=True)
        version_factory(addon=disabled_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        })

        # Add-on with deleted version.
        addon_with_deleted_version = addon_factory()
        deleted_version = version_factory(addon=addon_with_deleted_version,
                                          file_kw={
                                              'status':
                                              amo.STATUS_AWAITING_REVIEW,
                                              'is_webextension': True
                                          })
        deleted_version.delete()

        # Add-on with a non-webextension update.
        non_webext_addon = addon_factory()
        version_factory(addon=non_webext_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Add-on with 3 versions:
        # - one webext, listed, public.
        # - one non-listed webext version
        # - one listed non-webext awaiting review.
        complex_addon = addon_factory(file_kw={'is_webextension': True})
        version_factory(addon=complex_addon,
                        channel=amo.RELEASE_CHANNEL_UNLISTED,
                        file_kw={'is_webextension': True})
        version_factory(addon=complex_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Finally, add a second file to self.version to test the distinct().
        file_factory(version=self.version,
                     status=amo.STATUS_AWAITING_REVIEW,
                     is_webextension=True)

        # Add-on with an already public version and an unlisted webext
        # still awaiting review
        complex_addon_2 = addon_factory(file_kw={'is_webextension': True})
        version_factory(addon=complex_addon_2,
                        channel=amo.RELEASE_CHANNEL_UNLISTED,
                        file_kw={
                            'is_webextension': True,
                            'status': amo.STATUS_AWAITING_REVIEW
                        })

        # ---------------------------------------------------------------------
        # Gather the candidates.
        command = auto_approve.Command()
        command.post_review = True
        qs = command.fetch_candidates()

        # 5 versions should be found. Because of the nomination date,
        # search_version should be first (its nomination date is the
        # oldest) followed etc.
        assert len(qs) == 7
        assert [v.addon.pk for v in qs] == [
            a.pk for a in (
                recommended_addon,
                recommendable_addon_nominated,
                search_addon,
                dictionary,
                langpack,
                new_addon,
                self.addon,
            )
        ]
    def test_fetch_candidates(self):
        # Add nominated add-on: it should be considered.
        self.version.update(nomination=self.days_ago(1))
        new_addon = addon_factory(status=amo.STATUS_NOMINATED,
                                  file_kw={
                                      'status': amo.STATUS_AWAITING_REVIEW,
                                      'is_webextension': True
                                  })
        new_addon_version = new_addon.versions.all()[0]
        new_addon_version.update(nomination=self.days_ago(2))

        # Add langpack: it should also be considered.
        langpack = addon_factory(type=amo.ADDON_LPAPP,
                                 status=amo.STATUS_NOMINATED,
                                 file_kw={
                                     'status': amo.STATUS_AWAITING_REVIEW,
                                     'is_webextension': True
                                 })
        langpack_version = langpack.versions.all()[0]
        langpack_version.update(nomination=self.days_ago(3))

        # Add a bunch of add-ons in various states that should not be returned.
        # Public add-on with no updates.
        addon_factory(file_kw={'is_webextension': True})

        # Non-extension with updates.
        search_addon = addon_factory(type=amo.ADDON_SEARCH)
        version_factory(addon=search_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        })

        # Disabled add-on with updates.
        disabled_addon = addon_factory(disabled_by_user=True)
        version_factory(addon=disabled_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        })

        # Add-on with deleted version.
        addon_with_deleted_version = addon_factory()
        deleted_version = version_factory(addon=addon_with_deleted_version,
                                          file_kw={
                                              'status':
                                              amo.STATUS_AWAITING_REVIEW,
                                              'is_webextension': True
                                          })
        deleted_version.delete()

        # Add-on with a non-webextension update.
        non_webext_addon = addon_factory()
        version_factory(addon=non_webext_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Add-on with 3 versions:
        # - one webext, listed, public.
        # - one non-listed webext version
        # - one listed non-webext awaiting review.
        complex_addon = addon_factory(file_kw={'is_webextension': True})
        version_factory(addon=complex_addon,
                        channel=amo.RELEASE_CHANNEL_UNLISTED,
                        file_kw={'is_webextension': True})
        version_factory(addon=complex_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Finally, add a second file to self.version to test the distinct().
        file_factory(version=self.version,
                     status=amo.STATUS_AWAITING_REVIEW,
                     is_webextension=True)

        # Gather the candidates.
        command = auto_approve.Command()
        command.post_review = True
        qs = command.fetch_candidates()

        # 3 versions should be found. Because of the nomination date,
        # langpack_version should be first (its nomination date is the oldest),
        # followed by new_addon_version and then self.version.
        assert len(qs) == 3
        assert qs[0] == langpack_version
        assert qs[1] == new_addon_version
        assert qs[2] == self.version
    def test_fetch_candidates(self):
        # We already have an add-on with a version awaiting review that should
        # be considered. Make sure its nomination date is in the past to test
        # ordering.
        self.version.update(nomination=self.days_ago(1))
        # Add reviewer flags disabling auto-approval for this add-on. It would
        # still be fetched as a candidate, just rejected later on when
        # calculating the verdict.
        AddonReviewerFlags.objects.create(addon=self.addon,
                                          auto_approval_disabled=True)

        # Add nominated add-on: it should be considered.
        new_addon = addon_factory(status=amo.STATUS_NOMINATED,
                                  file_kw={
                                      'status': amo.STATUS_AWAITING_REVIEW,
                                      'is_webextension': True
                                  })
        new_addon_version = new_addon.versions.all()[0]
        new_addon_version.update(nomination=self.days_ago(2))
        # Even add an empty reviewer flags instance, that should not matter.
        AddonReviewerFlags.objects.create(addon=new_addon)

        # Add langpack: it should also be considered.
        langpack = addon_factory(type=amo.ADDON_LPAPP,
                                 status=amo.STATUS_NOMINATED,
                                 file_kw={
                                     'status': amo.STATUS_AWAITING_REVIEW,
                                     'is_webextension': True
                                 })
        langpack_version = langpack.versions.all()[0]
        langpack_version.update(nomination=self.days_ago(3))

        # Add a bunch of add-ons in various states that should not be returned.
        # Public add-on with no updates.
        addon_factory(file_kw={'is_webextension': True})

        # Non-extension with updates.
        search_addon = addon_factory(type=amo.ADDON_SEARCH)
        version_factory(addon=search_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        })

        # Disabled add-on with updates.
        disabled_addon = addon_factory(disabled_by_user=True)
        version_factory(addon=disabled_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        })

        # Add-on with deleted version.
        addon_with_deleted_version = addon_factory()
        deleted_version = version_factory(addon=addon_with_deleted_version,
                                          file_kw={
                                              'status':
                                              amo.STATUS_AWAITING_REVIEW,
                                              'is_webextension': True
                                          })
        deleted_version.delete()

        # Add-on with a non-webextension update.
        non_webext_addon = addon_factory()
        version_factory(addon=non_webext_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Add-on with 3 versions:
        # - one webext, listed, public.
        # - one non-listed webext version
        # - one listed non-webext awaiting review.
        complex_addon = addon_factory(file_kw={'is_webextension': True})
        version_factory(addon=complex_addon,
                        channel=amo.RELEASE_CHANNEL_UNLISTED,
                        file_kw={'is_webextension': True})
        version_factory(addon=complex_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Finally, add a second file to self.version to test the distinct().
        file_factory(version=self.version,
                     status=amo.STATUS_AWAITING_REVIEW,
                     is_webextension=True)

        # Gather the candidates.
        command = auto_approve.Command()
        command.post_review = True
        qs = command.fetch_candidates()

        # 3 versions should be found. Because of the nomination date,
        # langpack_version should be first (its nomination date is the oldest),
        # followed by new_addon_version and then self.version.
        assert len(qs) == 3
        assert qs[0] == langpack_version
        assert qs[1] == new_addon_version
        assert qs[2] == self.version
Beispiel #6
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 a second file to self.version to test the distinct().
        file_factory(version=self.version,
                     status=amo.STATUS_AWAITING_REVIEW,
                     is_webextension=True)
        # Add reviewer flags disabling auto-approval for this add-on. It would
        # still be fetched as a candidate, just rejected later on when
        # calculating the verdict.
        AddonReviewerFlags.objects.create(addon=self.addon,
                                          auto_approval_disabled=True)

        # Add nominated add-on: it should be considered.
        new_addon = addon_factory(name='New Addon',
                                  status=amo.STATUS_NOMINATED,
                                  file_kw={
                                      'status': amo.STATUS_AWAITING_REVIEW,
                                      'is_webextension': True
                                  })
        new_addon_version = new_addon.versions.all()[0]
        new_addon_version.update(nomination=self.days_ago(2))
        # Even add an empty reviewer flags instance, that should not matter.
        AddonReviewerFlags.objects.create(addon=new_addon)

        # Add langpack: it should be considered.
        langpack = addon_factory(name='Langpack',
                                 type=amo.ADDON_LPAPP,
                                 status=amo.STATUS_NOMINATED,
                                 file_kw={
                                     'status': amo.STATUS_AWAITING_REVIEW,
                                     'is_webextension': True
                                 })
        langpack_version = langpack.versions.all()[0]
        langpack_version.update(nomination=self.days_ago(3))

        # Add a dictionary: it should also be considered.
        dictionary = addon_factory(name='Dictionary',
                                   type=amo.ADDON_DICT,
                                   status=amo.STATUS_NOMINATED,
                                   file_kw={
                                       'status': amo.STATUS_AWAITING_REVIEW,
                                       'is_webextension': True
                                   })
        dictionary_version = dictionary.versions.all()[0]
        dictionary_version.update(nomination=self.days_ago(4))

        # search engine plugins are considered now
        search_addon = addon_factory(name='Search', type=amo.ADDON_SEARCH)
        search_addon_version = version_factory(addon=search_addon,
                                               file_kw={
                                                   'status':
                                                   amo.STATUS_AWAITING_REVIEW,
                                                   'is_webextension': True
                                               },
                                               nomination=self.days_ago(5))

        # Some recommended add-ons - one nominated and one update.
        # They should be considered by fetch_candidate(), so that they get a
        # weight assigned etc - they will not be auto-approved but that's
        # handled at a later stage, when calculating the verdict.
        recommendable_addon_nominated = addon_factory(
            name='Recommendable Addon',
            status=amo.STATUS_NOMINATED,
            version_kw={
                'recommendation_approved': True,
                'nomination': self.days_ago(6)
            },
            file_kw={
                'status': amo.STATUS_AWAITING_REVIEW,
                'is_webextension': True
            },
        )
        DiscoveryItem.objects.create(recommendable=True,
                                     addon=recommendable_addon_nominated)

        recommended_addon = addon_factory(name='Recommended Addon', )
        recommended_addon_version = version_factory(
            addon=recommended_addon,
            recommendation_approved=True,
            nomination=self.days_ago(7),
            file_kw={
                'status': amo.STATUS_AWAITING_REVIEW,
                'is_webextension': True
            })
        DiscoveryItem.objects.create(recommendable=True,
                                     addon=recommended_addon)

        # Add-on with 3 versions:
        # - one webext, listed, public.
        # - one non-listed webext version awaiting review.
        # - one listed non-webext awaiting review (should be ignored)
        complex_addon = addon_factory(name='Complex Addon',
                                      file_kw={'is_webextension': True})
        complex_addon_version = version_factory(
            nomination=self.days_ago(8),
            addon=complex_addon,
            channel=amo.RELEASE_CHANNEL_UNLISTED,
            file_kw={
                'is_webextension': True,
                'status': amo.STATUS_AWAITING_REVIEW
            })
        version_factory(nomination=self.days_ago(9),
                        addon=complex_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Add-on with an already public version and an unlisted webext
        # awaiting review.
        complex_addon_2 = addon_factory(name='Second Complex Addon',
                                        file_kw={'is_webextension': True})
        complex_addon_2_version = version_factory(
            addon=complex_addon_2,
            channel=amo.RELEASE_CHANNEL_UNLISTED,
            nomination=self.days_ago(10),
            file_kw={
                'is_webextension': True,
                'status': amo.STATUS_AWAITING_REVIEW
            })

        # Disabled version with a webext waiting review (Still has to be
        # considered because unlisted doesn't care about disabled by user
        # state.
        user_disabled_addon = addon_factory(
            name='Disabled by user waiting review', disabled_by_user=True)
        user_disabled_addon_version = version_factory(
            nomination=self.days_ago(11),
            channel=amo.RELEASE_CHANNEL_UNLISTED,
            addon=user_disabled_addon,
            file_kw={
                'status': amo.STATUS_AWAITING_REVIEW,
                'is_webextension': True
            })

        # Pure unlisted upload. Addon status is "incomplete" as a result, but
        # it should still be considered because unlisted versions don't care
        # about that.
        pure_unlisted = addon_factory(name='Pure unlisted',
                                      version_kw={
                                          'channel':
                                          amo.RELEASE_CHANNEL_UNLISTED,
                                          'nomination': self.days_ago(12)
                                      },
                                      file_kw={
                                          'is_webextension': True,
                                          'status': amo.STATUS_AWAITING_REVIEW
                                      },
                                      status=amo.STATUS_NULL)
        pure_unlisted_version = pure_unlisted.versions.get()

        # Unlisted static theme.
        unlisted_theme = addon_factory(name='Unlisted theme',
                                       version_kw={
                                           'channel':
                                           amo.RELEASE_CHANNEL_UNLISTED,
                                           'nomination': self.days_ago(13)
                                       },
                                       file_kw={
                                           'is_webextension': True,
                                           'status': amo.STATUS_AWAITING_REVIEW
                                       },
                                       status=amo.STATUS_NULL,
                                       type=amo.ADDON_STATICTHEME)
        unlisted_theme_version = unlisted_theme.versions.get()

        # ---------------------------------------------------------------------
        # Add a bunch of add-ons in various states that should not be returned.
        # Public add-on with no updates.
        addon_factory(name='Already Public', file_kw={'is_webextension': True})

        # Mozilla Disabled add-on with updates.
        disabled_addon = addon_factory(
            name='Mozilla Disabled',
            status=amo.STATUS_DISABLED,
        )
        version_factory(addon=disabled_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        })

        # Add-on with deleted version.
        addon_with_deleted_version = addon_factory(
            name='With deleted version awaiting review')
        deleted_version = version_factory(addon=addon_with_deleted_version,
                                          file_kw={
                                              'status':
                                              amo.STATUS_AWAITING_REVIEW,
                                              'is_webextension': True
                                          })
        deleted_version.delete()

        # Add-on with a non-webextension update.
        non_webext_addon = addon_factory(name='Non Webext waiting review')
        version_factory(addon=non_webext_addon,
                        file_kw={'status': amo.STATUS_AWAITING_REVIEW})

        # Somehow deleted add-on with a file still waiting for review.
        deleted_addon = addon_factory(
            name='Deleted Awaiting Review Somehow',
            status=amo.STATUS_DELETED,
        )
        version_factory(addon=deleted_addon,
                        file_kw={
                            'status': amo.STATUS_AWAITING_REVIEW,
                            'is_webextension': True
                        })

        # listed version belonging to an add-on disabled by user
        addon_factory(name='Listed Disabled by user',
                      disabled_by_user=True,
                      file_kw={
                          'status': amo.STATUS_AWAITING_REVIEW,
                          'is_webextension': True
                      })

        # Incomplete listed addon
        addon_factory(name='Incomplete listed',
                      status=amo.STATUS_NULL,
                      file_kw={
                          'status': amo.STATUS_AWAITING_REVIEW,
                          'is_webextension': True
                      })

        # Listed static theme
        addon_factory(name='Listed theme',
                      file_kw={
                          'is_webextension': True,
                          'status': amo.STATUS_AWAITING_REVIEW
                      },
                      status=amo.STATUS_NOMINATED,
                      type=amo.ADDON_STATICTHEME)

        # ---------------------------------------------------------------------
        # Gather the candidates.
        command = auto_approve.Command()
        command.post_review = True
        qs = command.fetch_candidates()

        # We should find these versions, in this exact order.
        expected = [(version.addon, version) for version in [
            unlisted_theme_version,
            pure_unlisted_version,
            user_disabled_addon_version,
            complex_addon_2_version,
            complex_addon_version,
            recommended_addon_version,
            recommendable_addon_nominated.current_version,
            search_addon_version,
            dictionary.current_version,
            langpack.current_version,
            new_addon.current_version,
            self.version,
        ]]

        assert [(version.addon, version) for version in qs] == expected