示例#1
0
class TestSuggestionsApi(ESTestCase):
    fixtures = fixture("webapp_337141")

    def setUp(self):
        self.url = reverse("suggestions-search-api")
        self.refresh("webapp")
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.save()
        self.app2 = app_factory(
            name=u"Second âpp", description=u"Second dèsc" * 25, icon_type="image/png", created=self.days_ago(3)
        )
        self.refresh("webapp")

    def tearDown(self):
        # Cleanup to remove these from the index.
        unindex_webapps([self.app1.id, self.app2.id])
        self.app1.delete()
        self.app2.delete()

    def test_suggestions(self):
        response = self.client.get(self.url, data={"lang": "en-US"})
        parsed = json.loads(response.content)
        eq_(parsed[0], "")
        self.assertSetEqual(parsed[1], [unicode(self.app1.name), unicode(self.app2.name)])
        self.assertSetEqual(parsed[2], [unicode(self.app1.description), unicode(truncate(self.app2.description))])
        self.assertSetEqual(parsed[3], [absolutify(self.app1.get_detail_url()), absolutify(self.app2.get_detail_url())])
        self.assertSetEqual(parsed[4], [self.app1.get_icon_url(64), self.app2.get_icon_url(64)])

    def test_suggestions_filtered(self):
        response = self.client.get(self.url, data={"q": "Second", "lang": "en-US"})
        parsed = json.loads(response.content)
        eq_(parsed[1], [unicode(self.app2.name)])
示例#2
0
 def test_owner_still_non_reviewer_access(self):
     user = Webapp.objects.get(pk=337141).authors.all()[0]
     access = Access.objects.create(
         key='test_oauth_key_owner', secret='super secret', user=user)
     client = RestOAuthClient(access)
     res = client.get(self.url)
     eq_(res.status_code, 403)
示例#3
0
 def test_owner_still_non_reviewer_access(self):
     user = Webapp.objects.get(pk=337141).authors.all()[0]
     access = Access.objects.create(
         key='test_oauth_key_owner', secret='super secret', user=user)
     client = RestOAuthClient(access)
     res = client.get(self.url)
     eq_(res.status_code, 403)
示例#4
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse('search-api')
     self.webapp = Webapp.objects.get(pk=337141)
     self.category = Category.objects.create(name='test', slug='test',
                                             type=amo.ADDON_WEBAPP)
     self.webapp.icon_hash = 'fakehash'
     self.webapp.save()
     self.refresh('webapp')
示例#5
0
 def test_admin_get(self):
     self.create_app()
     admin = UserProfile.objects.get(email="*****@*****.**")
     g = Group.objects.create(rules="*:*")
     GroupUser.objects.create(group=g, user=admin)
     ac = Access.objects.create(key="adminOauthKey", secret=generate(), user=admin.user)
     client = RestOAuthClient(ac)
     r = client.get(self.get_url)
     eq_(r.status_code, 200)
示例#6
0
 def test_reviewer_get(self):
     self.create_app()
     editor = UserProfile.objects.get(email="*****@*****.**")
     g = Group.objects.create(rules="Apps:Review,Reviews:Edit")
     GroupUser.objects.create(group=g, user=editor)
     ac = Access.objects.create(key="adminOauthKey", secret=generate(), user=editor.user)
     client = RestOAuthClient(ac)
     r = client.get(self.get_url)
     eq_(r.status_code, 200)
示例#7
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse('search-api')
     self.webapp = Webapp.objects.get(pk=337141)
     self.category = Category.objects.create(name='test',
                                             type=amo.ADDON_WEBAPP)
     # Pick a few common device features.
     self.profile = FeatureProfile(apps=True, audio=True, fullscreen=True,
                                   geolocation=True, indexeddb=True,
                                   sms=True).to_signature()
     self.qs = {'q': 'something', 'pro': self.profile, 'dev': 'firefoxos'}
示例#8
0
 def test_admin_get(self):
     self.create_app()
     admin = UserProfile.objects.get(email='*****@*****.**')
     g = Group.objects.create(rules='*:*')
     GroupUser.objects.create(group=g, user=admin)
     ac = Access.objects.create(key='adminOauthKey',
                                secret=generate(),
                                user=admin.user)
     client = RestOAuthClient(ac)
     r = client.get(self.get_url)
     eq_(r.status_code, 200)
示例#9
0
 def test_reviewer_get(self):
     self.create_app()
     editor = UserProfile.objects.get(email='*****@*****.**')
     g = Group.objects.create(rules='Apps:Review,Reviews:Edit')
     GroupUser.objects.create(group=g, user=editor)
     ac = Access.objects.create(key='adminOauthKey',
                                secret=generate(),
                                user=editor.user)
     client = RestOAuthClient(ac)
     r = client.get(self.get_url)
     eq_(r.status_code, 200)
示例#10
0
 def setUp(self):
     self.url = reverse('suggestions-search-api')
     self.refresh('webapp')
     self.client = RestOAuthClient(None)
     self.app1 = Webapp.objects.get(pk=337141)
     self.app1.save()
     self.app2 = app_factory(name=u'Second âpp',
                             description=u'Second dèsc' * 25,
                             icon_type='image/png',
                             created=self.days_ago(3))
     self.refresh('webapp')
示例#11
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse('search-api')
     self.webapp = Webapp.objects.get(pk=337141)
     self.webapp.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
     # Pick a few common device features.
     self.profile = FeatureProfile(apps=True,
                                   audio=True,
                                   fullscreen=True,
                                   geolocation=True,
                                   indexeddb=True,
                                   sms=True).to_signature()
     self.qs = {'q': 'something', 'pro': self.profile, 'dev': 'firefoxos'}
示例#12
0
 def setUp(self):
     self.url = reverse('rocketbar-search-api')
     self.refresh('webapp')
     self.client = RestOAuthClient(None)
     self.app1 = Webapp.objects.get(pk=337141)
     self.app1.save()
     self.app2 = app_factory(
         name=u'Second âpp',
         description=u'Second dèsc' * 25,
         icon_type='image/png',
         created=self.days_ago(3),
         manifest_url='http://testrocketbar.example.com')
     self.refresh('webapp')
示例#13
0
class TestSuggestionsApi(ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.url = reverse('suggestions-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.save()
        self.app2 = app_factory(name=u'Second âpp',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                created=self.days_ago(3))
        self.refresh('webapp')

    def tearDown(self):
        # Cleanup to remove these from the index.
        unindex_webapps([self.app1.id, self.app2.id])
        self.app1.delete()
        self.app2.delete()

    def test_suggestions(self):
        response = self.client.get(self.url, data={'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(parsed[0], '')
        self.assertSetEqual(parsed[1],
                            [unicode(self.app1.name),
                             unicode(self.app2.name)])
        self.assertSetEqual(parsed[2], [
            unicode(self.app1.description),
            unicode(truncate(self.app2.description))
        ])
        self.assertSetEqual(parsed[3], [
            absolutify(self.app1.get_detail_url()),
            absolutify(self.app2.get_detail_url())
        ])
        self.assertSetEqual(
            parsed[4],
            [self.app1.get_icon_url(64),
             self.app2.get_icon_url(64)])

    def test_suggestions_filtered(self):
        response = self.client.get(self.url,
                                   data={
                                       'q': 'Second',
                                       'lang': 'en-US'
                                   })
        parsed = json.loads(response.content)
        eq_(parsed[1], [unicode(self.app2.name)])
示例#14
0
class TestRocketbarApi(ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.save()
        self.app2 = app_factory(name=u'Second âpp',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                created=self.days_ago(3),
                                manifest_url='http://testrocketbar.example.com')
        self.refresh('webapp')

    def tearDown(self):
        # Cleanup to remove these from the index.
        unindex_webapps([self.app1.id, self.app2.id])
        self.app1.delete()
        self.app2.delete()

    def test_suggestions_filtered(self):
        response = self.client.get(self.url, data={'q': 'Second',
                                                   'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(parsed, [{'manifest_url': self.app2.get_manifest_url(),
                      'icon': self.app2.get_icon_url(64),
                      'name': unicode(self.app2.name),
                      'slug': self.app2.app_slug}])
示例#15
0
    def test_admin_get(self):
        app = self.create_app(privacy_policy=u'élolà')

        admin = UserProfile.objects.get(email='*****@*****.**')
        g = Group.objects.create(rules='*:*')
        GroupUser.objects.create(group=g, user=admin)
        ac = Access.objects.create(key='adminOauthKey', secret='admin secret',
                                   user=admin)
        client = RestOAuthClient(ac)
        r = client.get(self.get_url)
        eq_(r.status_code, 200)

        res = client.get(reverse('app-privacy-policy-detail',
                                 args=[app.pk]))
        eq_(r.status_code, 200)
        eq_(res.json['privacy_policy'], u'élolà')
示例#16
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse("search-api")
     self.webapp = Webapp.objects.get(pk=337141)
     self.category = Category.objects.create(name="test", slug="test", type=amo.ADDON_WEBAPP)
     self.webapp.save()
     self.refresh("webapp")
示例#17
0
    def test_admin_get(self):
        app = self.create_app()
        data = self.base_data()
        self.client.put(self.get_url, data=json.dumps(data))

        admin = UserProfile.objects.get(email="*****@*****.**")
        g = Group.objects.create(rules="*:*")
        GroupUser.objects.create(group=g, user=admin)
        ac = Access.objects.create(key="adminOauthKey", secret=generate(), user=admin)
        client = RestOAuthClient(ac)
        r = client.get(self.get_url)
        eq_(r.status_code, 200)

        res = client.get(reverse("app-privacy-policy-detail", args=[app.pk]))
        eq_(r.status_code, 200)
        eq_(res.json["privacy_policy"], data["privacy_policy"])
示例#18
0
    def test_admin_get(self):
        app = self.create_app(privacy_policy=u'élolà')

        admin = UserProfile.objects.get(email='*****@*****.**')
        g = Group.objects.create(rules='*:*')
        GroupUser.objects.create(group=g, user=admin)
        ac = Access.objects.create(key='adminOauthKey',
                                   secret='admin secret',
                                   user=admin)
        client = RestOAuthClient(ac)
        r = client.get(self.get_url)
        eq_(r.status_code, 200)

        res = client.get(reverse('app-privacy-policy-detail', args=[app.pk]))
        eq_(r.status_code, 200)
        eq_(res.json['privacy_policy'], u'élolà')
示例#19
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse('search-api')
     self.webapp = Webapp.objects.get(pk=337141)
     self.category = 'books'
     self.webapp.icon_hash = 'fakehash'
     self.webapp.save()
     self.refresh('webapp')
示例#20
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse("search-api")
     self.webapp = Webapp.objects.get(pk=337141)
     self.category = "books"
     self.webapp.icon_hash = "fakehash"
     self.webapp.save()
     self.refresh("webapp")
示例#21
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse("search-api")
     self.webapp = Webapp.objects.get(pk=337141)
     # Pick a few common device features.
     self.profile = FeatureProfile(
         apps=True, audio=True, fullscreen=True, geolocation=True, indexeddb=True, sms=True
     ).to_signature()
     self.qs = {"q": "something", "pro": self.profile, "dev": "firefoxos"}
示例#22
0
    def test_reviewer_get(self):
        app = self.create_app()
        data = self.base_data()
        self.client.put(self.get_url, data=json.dumps(data))

        editor = UserProfile.objects.get(email='*****@*****.**')
        g = Group.objects.create(rules='Apps:Review,Reviews:Edit')
        GroupUser.objects.create(group=g, user=editor)
        ac = Access.objects.create(key='adminOauthKey', secret=generate(),
                                   user=editor.user)
        client = RestOAuthClient(ac)
        r = client.get(self.get_url)
        eq_(r.status_code, 200)

        res = client.get(reverse('app-privacy-policy-detail',
                                 args=[app.pk]))
        eq_(r.status_code, 200)
        eq_(res.json['privacy_policy'], data['privacy_policy'])
示例#23
0
    def test_admin_get(self):
        app = self.create_app()
        data = self.base_data()
        self.client.put(self.get_url, data=json.dumps(data))

        admin = UserProfile.objects.get(email='*****@*****.**')
        g = Group.objects.create(rules='*:*')
        GroupUser.objects.create(group=g, user=admin)
        ac = Access.objects.create(key='adminOauthKey', secret=generate(),
                                   user=admin.user)
        client = RestOAuthClient(ac)
        r = client.get(self.get_url)
        eq_(r.status_code, 200)

        res = client.get(reverse('app-privacy-policy-detail',
                                 args=[app.pk]))
        eq_(r.status_code, 200)
        eq_(res.json['privacy_policy'], data['privacy_policy'])
示例#24
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse('search-api')
     self.webapp = Webapp.objects.get(pk=337141)
     # Pick a few common device features.
     self.profile = FeatureProfile(apps=True, audio=True, fullscreen=True,
                                   geolocation=True, indexeddb=True,
                                   sms=True).to_signature()
     self.qs = {'q': 'something', 'pro': self.profile, 'dev': 'firefoxos'}
示例#25
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse('search-api')
     self.webapp = Webapp.objects.get(pk=337141)
     self.category = Category.objects.create(name='Books', slug='books',
                                             type=amo.ADDON_WEBAPP)
     self.webapp.icon_hash = 'fakehash'
     self.webapp.save()
     self.refresh('webapp')
示例#26
0
class TestSuggestionsApi(ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.url = reverse('suggestions-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.save()
        self.app2 = app_factory(name=u'Second âpp',
                                description=u'Second dèsc' * 25,
                                created=self.days_ago(3))
        self.refresh('webapp')

    def tearDown(self):
        # Cleanup to remove these from the index.
        unindex_webapps([self.app1.id, self.app2.id])
        self.app1.delete()
        self.app2.delete()

    def test_suggestions(self):
        response = self.client.get(self.url, data={'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(parsed[0], '')
        self.assertSetEqual(
            parsed[1],
            [unicode(self.app1.name), unicode(self.app2.name)])
        self.assertSetEqual(
            parsed[2],
            [unicode(self.app1.description),
             unicode(truncate(self.app2.description))])
        self.assertSetEqual(
            parsed[3],
            [absolutify(self.app1.get_detail_url()),
             absolutify(self.app2.get_detail_url())])
        self.assertSetEqual(
            parsed[4],
            [self.app1.get_icon_url(64), self.app2.get_icon_url(64)])

    def test_suggestions_filtered(self):
        response = self.client.get(self.url, data={'q': 'Second',
                                                   'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(parsed[1], [unicode(self.app2.name)])
示例#27
0
 def setUp(self):
     self.url = reverse("suggestions-search-api")
     self.refresh("webapp")
     self.client = RestOAuthClient(None)
     self.app1 = Webapp.objects.get(pk=337141)
     self.app1.save()
     self.app2 = app_factory(
         name=u"Second âpp", description=u"Second dèsc" * 25, icon_type="image/png", created=self.days_ago(3)
     )
     self.refresh("webapp")
示例#28
0
 def setUp(self):
     self.url = reverse('suggestions-api')
     self.refresh('webapp')
     self.client = RestOAuthClient(None)
     self.app1 = Webapp.objects.get(pk=337141)
     self.app1.save()
     self.app2 = app_factory(name=u'Second âpp',
                             description=u'Second dèsc' * 25,
                             created=self.days_ago(3))
     self.refresh('webapp')
示例#29
0
    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.profile = UserProfile.objects.get(pk=2519)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app1.save()

        self.app2 = app_factory(name=u'Something Second Something Something',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                icon_hash='fakehash',
                                created=self.days_ago(3),
                                manifest_url='http://rocket.example.com')
        self.app2.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        # Add 2 installed records so this app is boosted higher than app1.
        Installed.objects.create(user=self.profile, addon=self.app2)
        Installed.objects.create(user=self.profile, addon=self.app2)
        self.app2.save()
        self.refresh('webapp')
示例#30
0
 def setUp(self):
     self.url = reverse('rocketbar-search-api')
     self.refresh('webapp')
     self.client = RestOAuthClient(None)
     self.app1 = Webapp.objects.get(pk=337141)
     self.app1.save()
     self.app2 = app_factory(name=u'Second âpp',
                             description=u'Second dèsc' * 25,
                             icon_type='image/png',
                             created=self.days_ago(3),
                             manifest_url='http://testrocketbar.example.com')
     self.refresh('webapp')
示例#31
0
 def setUp(self):
     self.client = RestOAuthClient(None)
     self.url = reverse('search-api')
     self.webapp = Webapp.objects.get(pk=337141)
     self.webapp.platform_set.create(platform_id=mkt.PLATFORM_FXOS.id)
     self.webapp.form_factor_set.create(form_factor_id=mkt.FORM_MOBILE.id)
     self.category = Category.objects.create(name='test',
                                             type=amo.ADDON_WEBAPP)
     # Pick a few common device features.
     self.profile = FeatureProfile(apps=True, audio=True, fullscreen=True,
                                   geolocation=True, indexeddb=True,
                                   sms=True).to_signature()
     self.qs = {'q': 'something', 'pro': self.profile,
                'platform': 'firefoxos', 'form_factor': 'mobile'}
示例#32
0
 def setUp(self):
     self.url = reverse("rocketbar-search-api")
     self.refresh("webapp")
     self.client = RestOAuthClient(None)
     self.app1 = Webapp.objects.get(pk=337141)
     self.app1.save()
     self.app2 = app_factory(
         name=u"Second âpp",
         description=u"Second dèsc" * 25,
         icon_type="image/png",
         created=self.days_ago(3),
         manifest_url="http://testrocketbar.example.com",
     )
     self.refresh("webapp")
示例#33
0
    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.platform_set.create(platform_id=mkt.PLATFORM_FXOS.id)
        self.app1.save()

        self.app2 = app_factory(name=u'Something Second Something Something',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                created=self.days_ago(3),
                                manifest_url='http://rocket.example.com')
        self.app2.platform_set.create(platform_id=mkt.PLATFORM_FXOS.id)
        self.app2.save()
        self.refresh('webapp')
示例#34
0
    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app1.save()

        self.app2 = app_factory(name=u'Something Second Something Something',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                created=self.days_ago(3),
                                manifest_url='http://rocket.example.com')
        self.app2.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app2.save()
        self.refresh('webapp')
示例#35
0
    def setUp(self):
        self.url = reverse("rocketbar-search-api")
        self.refresh("webapp")
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app1.save()

        self.app2 = app_factory(
            name=u"Something Second Something Something",
            description=u"Second dèsc" * 25,
            icon_type="image/png",
            icon_hash="fakehash",
            created=self.days_ago(3),
            manifest_url="http://rocket.example.com",
        )
        self.app2.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app2.save()
        self.refresh("webapp")
示例#36
0
class TestRocketbarApi(ESTestCase):
    fixtures = fixture("webapp_337141")

    def setUp(self):
        self.url = reverse("rocketbar-search-api")
        self.refresh("webapp")
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.save()
        self.app2 = app_factory(
            name=u"Second âpp",
            description=u"Second dèsc" * 25,
            icon_type="image/png",
            created=self.days_ago(3),
            manifest_url="http://testrocketbar.example.com",
        )
        self.refresh("webapp")

    def tearDown(self):
        # Cleanup to remove these from the index.
        unindex_webapps([self.app1.id, self.app2.id])
        self.app1.delete()
        self.app2.delete()

    def test_suggestions_filtered(self):
        response = self.client.get(self.url, data={"q": "Second", "lang": "en-US"})
        parsed = json.loads(response.content)
        eq_(
            parsed,
            [
                {
                    "manifest_url": self.app2.get_manifest_url(),
                    "icon": self.app2.get_icon_url(64),
                    "name": unicode(self.app2.name),
                    "slug": self.app2.app_slug,
                }
            ],
        )
示例#37
0
class TestRocketbarApi(ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.save()
        self.app2 = app_factory(
            name=u'Second âpp',
            description=u'Second dèsc' * 25,
            icon_type='image/png',
            created=self.days_ago(3),
            manifest_url='http://testrocketbar.example.com')
        self.refresh('webapp')

    def tearDown(self):
        # Cleanup to remove these from the index.
        unindex_webapps([self.app1.id, self.app2.id])
        self.app1.delete()
        self.app2.delete()

    def test_suggestions_filtered(self):
        response = self.client.get(self.url,
                                   data={
                                       'q': 'Second',
                                       'lang': 'en-US'
                                   })
        parsed = json.loads(response.content)
        eq_(parsed, [{
            'manifest_url': self.app2.get_manifest_url(),
            'icon': self.app2.get_icon_url(64),
            'name': unicode(self.app2.name),
            'slug': self.app2.app_slug
        }])
示例#38
0
class TestApi(RestOAuth, ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.client = RestOAuthClient(None)
        self.url = reverse('search-api')
        self.webapp = Webapp.objects.get(pk=337141)
        self.category = 'books'
        self.webapp.icon_hash = 'fakehash'
        self.webapp.save()
        self.refresh('webapp')

    def tearDown(self):
        for w in Webapp.objects.all():
            w.delete()
        unindex_webapps(list(Webapp.with_deleted.values_list('id', flat=True)))
        super(TestApi, self).tearDown()

    def test_verbs(self):
        self._allowed_verbs(self.url, ['get'])

    def test_has_cors(self):
        self.assertCORS(self.client.get(self.url), 'get')

    def test_meta(self):
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        eq_(set(res.json.keys()), set(['objects', 'meta']))
        eq_(res.json['meta']['total_count'], 1)

    @patch('mkt.search.utils.statsd.timer')
    def test_statsd(self, _mock):
        self.client.get(self.url)
        assert _mock.called

    def test_search_published_apps(self):
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 1)
        eq_(objs[0]['slug'], self.webapp.app_slug)

    def test_search_no_approved_apps(self):
        self.webapp.update(status=amo.STATUS_APPROVED)
        self.refresh('webapp')
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        eq_(res.json['objects'], [])

    def test_search_no_unlisted_apps(self):
        self.webapp.update(status=amo.STATUS_UNLISTED)
        self.refresh('webapp')
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        eq_(res.json['objects'], [])

    def test_wrong_category(self):
        res = self.client.get(self.url,
                              data={'cat': self.category + 'xq'})
        eq_(res.status_code, 400)
        eq_(res['Content-Type'], 'application/json')

    def test_wrong_sort(self):
        res = self.client.get(self.url, data={'sort': 'awesomeness'})
        eq_(res.status_code, 400)

    def test_sort(self):
        # Make sure elasticsearch is actually accepting the params.
        for api_sort, es_sort in DEFAULT_SORTING.items():
            res = self.client.get(self.url, [('sort', api_sort)])
            eq_(res.status_code, 200)

    def test_multiple_sort(self):
        res = self.client.get(self.url, [('sort', 'rating'),
                                         ('sort', 'created')])
        eq_(res.status_code, 200)

    def test_right_category(self):
        res = self.client.get(self.url, data={'cat': self.category})
        eq_(res.status_code, 200)
        eq_(res.json['objects'], [])

    def create(self):
        self.webapp.update(categories=[self.category])
        self.refresh('webapp')

    def test_right_category_present(self):
        self.create()
        res = self.client.get(self.url, data={'cat': self.category})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 1)

    def test_tarako_category(self):
        self.create()
        # tarako-lifestyle includes books.
        res = self.client.get(self.url, data={'cat': 'tarako-lifestyle'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 1)

        # tarako-games includes only games.
        res = self.client.get(self.url, data={'cat': 'tarako-games'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

        # tarako-tools includes multiple categories, but not books.
        res = self.client.get(self.url, data={'cat': 'tarako-tools'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

    def test_user_info_with_shared_secret(self):
        user = UserProfile.objects.all()[0]

        def fakeauth(auth, req, **kw):
            req.user = user
            req.user = user

        with patch('mkt.api.middleware.RestSharedSecretMiddleware'
                   '.process_request', fakeauth):
            with self.settings(SITE_URL=''):
                self.create()
            res = self.client.get(self.url, data={'cat': self.category})
            obj = res.json['objects'][0]
            assert 'user' in obj

    def test_dehydrate(self):
        with self.settings(SITE_URL='http://hy.fr'):
            self.create()
            res = self.client.get(self.url, data={'cat': self.category})
            eq_(res.status_code, 200)
            obj = res.json['objects'][0]
            content_ratings = obj['content_ratings']
            eq_(obj['absolute_url'],
                absolutify(self.webapp.get_absolute_url()))
            eq_(obj['app_type'], self.webapp.app_type)
            eq_(obj['categories'], [self.category])
            eq_(content_ratings['body'], 'generic')
            eq_(content_ratings['rating'], None)
            eq_(content_ratings['descriptors'], [])
            eq_(content_ratings['interactives'], [])
            eq_(obj['current_version'], u'1.0')
            eq_(obj['description'],
                {'en-US': self.webapp.description.localized_string})
            eq_(obj['icons']['128'], self.webapp.get_icon_url(128))
            ok_(obj['icons']['128'].endswith('?modified=fakehash'))
            eq_(obj['id'], long(self.webapp.id))
            eq_(obj['is_offline'], False)
            eq_(obj['manifest_url'], self.webapp.get_manifest_url())
            eq_(obj['package_path'], None)
            eq_(obj['payment_account'], None)
            self.assertApiUrlEqual(obj['privacy_policy'],
                                   '/apps/app/337141/privacy/')
            eq_(obj['public_stats'], self.webapp.public_stats)
            eq_(obj['ratings'], {'average': 0.0, 'count': 0})
            self.assertApiUrlEqual(obj['resource_uri'],
                                   '/apps/app/337141/')
            eq_(obj['slug'], self.webapp.app_slug)
            eq_(obj['supported_locales'], ['en-US', 'es', 'pt-BR'])
            eq_(obj['tags'], [])
            ok_('1.0' in obj['versions'])
            self.assertApiUrlEqual(obj['versions']['1.0'],
                                   '/apps/versions/1268829/')

        # These only exists if requested by a reviewer.
        ok_('latest_version' not in obj)
        ok_('reviewer_flags' not in obj)

    @patch('mkt.webapps.models.Webapp.get_excluded_region_ids')
    def test_upsell(self, get_excluded_region_ids):
        get_excluded_region_ids.return_value = []
        upsell = app_factory(premium_type=amo.ADDON_PREMIUM)
        AddonUpsell.objects.create(free=self.webapp, premium=upsell)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, {'premium_types': 'free'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 1)
        obj = res.json['objects'][0]
        eq_(obj['upsell']['id'], upsell.id)
        eq_(obj['upsell']['app_slug'], upsell.app_slug)
        eq_(obj['upsell']['name'], upsell.name)
        eq_(obj['upsell']['icon_url'], upsell.get_icon_url(128))
        self.assertApiUrlEqual(obj['upsell']['resource_uri'],
                               '/apps/app/%s/' % upsell.id)
        eq_(obj['upsell']['region_exclusions'], [])

        upsell.delete()
        unindex_webapps([upsell.id])

    def test_dehydrate_regions(self):
        self.webapp.addonexcludedregion.create(region=mkt.regions.BR.id)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        regions = obj['regions']
        ok_(mkt.regions.BR.slug not in [r['slug'] for r in regions])
        eq_(len(regions), len(mkt.regions.ALL_REGION_IDS) - 1)

    def test_region_filtering(self):
        self.webapp.addonexcludedregion.create(region=mkt.regions.BR.id)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data={'region': 'br'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

    def test_languages_filtering(self):
        # This webapp's supported_locales: [u'en-US', u'es', u'pt-BR']

        res = self.client.get(self.url, data={'languages': 'fr'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

        for lang in ('fr,pt-BR', 'es, pt-BR', 'es', 'pt-BR'):
            res = self.client.get(self.url, data={'languages': lang})
            eq_(res.status_code, 200)
            obj = res.json['objects'][0]
            eq_(obj['slug'], self.webapp.app_slug)

    def test_offline_filtering(self):
        def check(offline, visible):
            res = self.client.get(self.url, data={'offline': offline})
            eq_(res.status_code, 200)
            objs = res.json['objects']
            eq_(len(objs), int(visible))

        # Should NOT show up in offline.
        # Should show up in online.
        # Should show up everywhere if not filtered.
        check(offline='True', visible=False)
        check(offline='False', visible=True)
        check(offline='None', visible=True)

        # Mark that app is capable offline.
        self.webapp.update(is_packaged=True)
        self.refresh('webapp')

        # Should show up in offline.
        # Should NOT show up in online.
        # Should show up everywhere if not filtered.
        check(offline='True', visible=True)
        check(offline='False', visible=False)
        check(offline='None', visible=True)

    def test_q(self):
        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_q_num_requests(self):
        es = WebappIndexer.get_es()
        orig_search = es.search
        es.counter = 0

        def monkey_search(*args, **kwargs):
            es.counter += 1
            return orig_search(*args, **kwargs)

        es.search = monkey_search

        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        eq_(res.json['meta']['total_count'], 1)
        eq_(len(res.json['objects']), 1)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

        # Verify only one search call was made.
        eq_(es.counter, 1)

        es.search = orig_search

    def test_q_num_requests_no_results(self):
        es = WebappIndexer.get_es()
        orig_search = es.search
        es.counter = 0

        def monkey_search(*args, **kwargs):
            es.counter += 1
            return orig_search(*args, **kwargs)

        es.search = monkey_search

        res = self.client.get(self.url, data={'q': 'noresults'})
        eq_(res.status_code, 200)
        eq_(res.json['meta']['total_count'], 0)
        eq_(len(res.json['objects']), 0)

        # Verify only one search call was made.
        eq_(es.counter, 1)

        es.search = orig_search

    def test_q_exact(self):
        app1 = app_factory(name='test app test11')
        app2 = app_factory(name='test app test21')
        app3 = app_factory(name='test app test31')
        self.refresh('webapp')

        res = self.client.get(self.url, data={'q': 'test app test21'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 3)
        # app2 should be first since it's an exact match and is boosted higher.
        obj = res.json['objects'][0]
        eq_(obj['slug'], app2.app_slug)

        app1.delete()
        app2.delete()
        app3.delete()
        unindex_webapps([app1.id, app2.id, app3.id])

    def test_q_is_tag(self):
        Tag(tag_text='whatsupp').save_tag(self.webapp)
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'whatsupp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_q_is_tag_misspelled(self):
        Tag(tag_text='whatsapp').save_tag(self.webapp)
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'whatsupp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_fuzzy_match(self):
        res = self.client.get(self.url, data={'q': 'soemthing'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_icu_folding(self):
        self.webapp.name = {'es': 'Páginas Amarillos'}
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'paginas'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_camel_case_word_splitting(self):
        self.webapp.name = 'AirCombat'
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'air combat'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_phrase_slop(self):
        self.webapp.name = {'es': 'Metro de Santiago',
                            'en': None}
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'metro santiago'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_name_localized(self):
        # First test no ?lang parameter returns all localizations.
        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], {u'en-US': u'Something Something Steamcube!',
                          u'es': u'Algo Algo Steamcube!'})

        # Second test that adding ?lang returns only that localization.
        res = self.client.get(self.url,
                              data={'q': 'something', 'lang': 'es'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], u'Algo Algo Steamcube!')

    def test_other_localized(self):
        # Test fields that should be localized.
        translations = {'en-US': u'Test in English',
                        'es': u'Test in Español'}
        self.webapp.homepage = translations
        self.webapp.support_email = translations
        self.webapp.support_url = translations
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['homepage'], translations)
        eq_(obj['support_email'], translations)
        eq_(obj['support_url'], translations)

    def test_name_localized_to_default_locale(self):
        self.webapp.update(default_locale='es')
        self.refresh('webapp')

        # Make a request in another language that we know will fail.
        res = self.client.get(self.url,
                              data={'q': 'something', 'lang': 'de'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], u'Algo Algo Steamcube!')

    def test_device(self):
        AddonDeviceType.objects.create(
            addon=self.webapp, device_type=DEVICE_CHOICES_IDS['desktop'])
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'dev': 'desktop'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_no_flash_on_firefoxos(self):
        AddonDeviceType.objects.create(
            addon=self.webapp, device_type=DEVICE_CHOICES_IDS['firefoxos'])
        f = self.webapp.get_latest_file()
        f.uses_flash = True
        f.save()
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'dev': 'firefoxos'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 0)

    def test_premium_types(self):
        res = self.client.get(self.url,
                              data={'premium_types': 'free'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_premium_types_empty(self):
        res = self.client.get(self.url,
                              data={'premium_types': 'premium'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

    def test_multiple_premium_types(self):
        res = self.client.get(self.url,
                              data={'premium_types': ['free', 'premium']})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_app_type_hosted(self):
        res = self.client.get(self.url, data={'app_type': 'hosted'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['is_packaged'], False)
        eq_(obj['is_offline'], False)
        eq_(obj['package_path'], None)

    @override_settings(SITE_URL='http://hy.fr')
    def test_app_type_packaged(self):
        self.webapp.update(is_packaged=True)
        f = self.webapp.current_version.all_files[0]

        self.refresh('webapp')

        res = self.client.get(self.url, data={'app_type': 'packaged'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['is_packaged'], True)
        eq_(obj['is_offline'], True)
        eq_(obj['package_path'],
            '%s/downloads/file/%s/%s' % (settings.SITE_URL, f.id, f.filename))

    def test_app_type_privileged(self):
        # Override the class-decorated patch.
        with patch('mkt.versions.models.Version.is_privileged', True):
            self.webapp.update(is_packaged=True)
            self.refresh('webapp')

            res = self.client.get(self.url, data={'app_type': 'packaged'})
            eq_(res.status_code, 200)
            # Packaged also includes privileged, which is technically also a
            # packaged app.
            eq_(len(res.json['objects']), 1)
            obj = res.json['objects'][0]
            eq_(obj['slug'], self.webapp.app_slug)

            res = self.client.get(self.url,
                                  data={'app_type': 'privileged'})
            eq_(res.status_code, 200)
            eq_(len(res.json['objects']), 1)
            obj = res.json['objects'][0]
            eq_(obj['slug'], self.webapp.app_slug)

    def test_status_value_packaged(self):
        # When packaged and not a reviewer we exclude latest version status.
        self.webapp.update(is_packaged=True)
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['status'], amo.STATUS_PUBLIC)
        eq_('latest_version' in obj, False)

    def test_addon_type_anon(self):
        res = self.client.get(self.url, data={'type': 'app'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

        res = self.client.get(self.url, data={'type': 'vindaloo'})
        eq_(res.status_code, 400)
        error = res.json['detail']
        eq_(error.keys(), ['type'])

    def test_word_delimiter_preserves_original(self):
        self.webapp.description = {
            'en-US': 'This is testing word delimiting preservation in long '
                     'descriptions and here is what we want to find: WhatsApp'
        }
        self.webapp.save()
        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, data={'q': 'whatsapp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_pagination(self):
        Webapp.objects.get(pk=337141).delete()
        app1 = app_factory(name='test app test1')
        app2 = app_factory(name='test app test2')
        app3 = app_factory(name='test app test3')
        # Setting 'created' app_factory is unreliable and we need a reliable
        # order.
        app1.update(created=self.days_ago(1))
        app2.update(created=self.days_ago(2))
        app3.update(created=self.days_ago(3))
        self.refresh('webapp')

        res = self.client.get(self.url, data={'limit': '2', 'sort': 'created'})
        eq_(res.status_code, 200)
        data = json.loads(res.content)
        eq_(len(data['objects']), 2)
        eq_(int(data['objects'][0]['id']), app1.id)
        eq_(int(data['objects'][1]['id']), app2.id)

        eq_(data['meta']['total_count'], 3)
        eq_(data['meta']['limit'], 2)
        eq_(data['meta']['previous'], None)
        eq_(data['meta']['offset'], 0)

        next = urlparse(data['meta']['next'])
        eq_(next.path, self.url)
        eq_(QueryDict(next.query).dict(), {'limit': '2', 'offset': '2',
                                           'sort': 'created'})

        res = self.client.get(self.url, QueryDict(next.query).dict())
        eq_(res.status_code, 200)
        data = json.loads(res.content)
        eq_(len(data['objects']), 1)
        eq_(int(data['objects'][0]['id']), app3.id)
        eq_(data['meta']['total_count'], 3)
        eq_(data['meta']['limit'], 2)
        prev = urlparse(data['meta']['previous'])
        eq_(next.path, self.url)
        eq_(QueryDict(prev.query).dict(), {'limit': '2', 'offset': '0',
                                           'sort': 'created'})
        eq_(data['meta']['offset'], 2)
        eq_(data['meta']['next'], None)

    def test_content_ratings_reindex(self):
        self.webapp.set_content_ratings({
            mkt.ratingsbodies.GENERIC: mkt.ratingsbodies.GENERIC_18
        })
        self.refresh('webapp')
        res = self.client.get(self.url)
        obj = res.json['objects'][0]
        ok_(obj['content_ratings']['rating'])

    def test_usk_refused_exclude(self):
        geodata = self.webapp._geodata
        geodata.update(region_de_usk_exclude=True)
        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, {'region': 'de'})
        ok_(not res.json['objects'])

    def test_icon_url_never(self):
        self.webapp.update(icon_hash=None)
        self.refresh('webapp')
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['icons']['64'], self.webapp.get_icon_url(64))
        ok_(obj['icons']['64'].endswith('?modified=never'))

    def test_tag(self):
        tag1 = Tag.objects.create(tag_text='tagtagtag')
        tag2 = Tag.objects.create(tag_text='tarako')
        Tag.objects.create(tag_text='dummy')
        AddonTag.objects.create(addon=self.webapp, tag=tag1)
        AddonTag.objects.create(addon=self.webapp, tag=tag2)
        self.reindex(Webapp, 'webapp')
        res = self.client.get(self.url, {'tag': 'tarako'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        self.assertSetEqual(obj['tags'], ['tagtagtag', 'tarako'])

    def test_ratings_sort(self):
        app1 = self.webapp
        app2 = app_factory()
        user = user_factory()
        app1._reviews.create(user=user, rating=1)
        app2._reviews.create(user=user, rating=5)
        self.refresh()
        res = self.client.get(self.url, {'sort': 'rating'})
        eq_(res.status_code, 200)
        eq_(res.json['objects'][0]['id'], app2.id)
        eq_(res.json['objects'][1]['id'], app1.id)
示例#39
0
class TestApi(RestOAuth, ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.client = RestOAuthClient(None)
        self.url = reverse('search-api')
        self.webapp = Webapp.objects.get(pk=337141)
        self.category = Category.objects.create(name='test', slug='test',
                                                type=amo.ADDON_WEBAPP)
        self.webapp.save()
        self.refresh('webapp')

    def tearDown(self):
        unindex_webapps(list(Webapp.with_deleted.values_list('id', flat=True)))
        Webapp.objects.all().delete()
        super(TestApi, self).tearDown()

    def test_verbs(self):
        self._allowed_verbs(self.url, ['get'])

    def test_has_cors(self):
        self.assertCORS(self.client.get(self.url), 'get')

    def test_meta(self):
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        eq_(set(res.json.keys()), set(['objects', 'meta']))
        eq_(res.json['meta']['total_count'], 1)

    def test_wrong_category(self):
        res = self.client.get(self.url,
                              data={'cat': self.category.slug + 'xq'})
        eq_(res.status_code, 400)
        eq_(res['Content-Type'], 'application/json')

    def test_wrong_weight(self):
        self.category.update(weight=-1)
        res = self.client.get(self.url, data={'cat': self.category.slug})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 0)

    def test_wrong_sort(self):
        res = self.client.get(self.url, data={'sort': 'awesomeness'})
        eq_(res.status_code, 400)

    def test_sort(self):
        # Mocked version, to make sure we are calling ES with the parameters
        # we want.
        with patch('mkt.webapps.models.Webapp.from_search') as mocked_search:
            mocked_qs = MagicMock()
            mocked_search.return_value = mocked_qs
            for api_sort, es_sort in DEFAULT_SORTING.items():
                res = self.client.get(self.url, [('sort', api_sort)])
                eq_(res.status_code, 200, res.content)
                mocked_qs.order_by.assert_called_with(es_sort)

        # Unmocked version, to make sure elasticsearch is actually accepting
        # the params.
        for api_sort, es_sort in DEFAULT_SORTING.items():
            res = self.client.get(self.url, [('sort', api_sort)])
            eq_(res.status_code, 200)

    def test_right_category(self):
        res = self.client.get(self.url, data={'cat': self.category.pk})
        eq_(res.status_code, 200)
        eq_(res.json['objects'], [])

    def create(self):
        AddonCategory.objects.create(addon=self.webapp, category=self.category)
        self.webapp.save()
        self.refresh('webapp')

    def test_right_category_present(self):
        self.create()
        res = self.client.get(
            self.url, data={'cat': self.category.pk})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 1)

    def test_user_info_with_shared_secret(self):
        user = UserProfile.objects.all()[0]

        def fakeauth(auth, req, **kw):
            req.user = user.user
            req.amo_user = user

        with patch('mkt.api.middleware.RestSharedSecretMiddleware'
                   '.process_request', fakeauth):
            with self.settings(SITE_URL=''):
                self.create()
            res = self.client.get(
                self.url, data={'cat': self.category.pk})
            obj = res.json['objects'][0]
            assert 'user' in obj

    def test_dehydrate(self):
        with self.settings(SITE_URL='http://hy.fr'):
            self.create()
            res = self.client.get(self.url, data={'cat': self.category.pk})
            eq_(res.status_code, 200)
            obj = res.json['objects'][0]
            content_ratings = obj['content_ratings']
            eq_(obj['absolute_url'],
                absolutify(self.webapp.get_absolute_url()))
            eq_(obj['app_type'], self.webapp.app_type)
            eq_(content_ratings['descriptors'], {})
            eq_(content_ratings['interactive_elements'], [])
            eq_(content_ratings['ratings'], None)
            eq_(obj['current_version'], u'1.0')
            eq_(obj['description'],
                {'en-US': self.webapp.description.localized_string})
            eq_(obj['icons']['128'], self.webapp.get_icon_url(128))
            eq_(obj['id'], long(self.webapp.id))
            eq_(obj['manifest_url'], self.webapp.get_manifest_url())
            eq_(obj['payment_account'], None)
            self.assertApiUrlEqual(obj['privacy_policy'],
                                   '/apps/app/337141/privacy/')
            eq_(obj['public_stats'], self.webapp.public_stats)
            eq_(obj['ratings'], {'average': 0.0, 'count': 0})
            self.assertApiUrlEqual(obj['resource_uri'],
                                   '/apps/app/337141/')
            eq_(obj['slug'], self.webapp.app_slug)
            eq_(obj['supported_locales'], ['en-US', 'es', 'pt-BR'])
            ok_('1.0' in obj['versions'])
            self.assertApiUrlEqual(obj['versions']['1.0'],
                                   '/apps/versions/1268829/')

        # These only exists if requested by a reviewer.
        ok_('latest_version' not in obj)
        ok_('reviewer_flags' not in obj)

    @patch('mkt.webapps.models.Webapp.get_excluded_region_ids')
    def test_upsell(self, get_excluded_region_ids):
        get_excluded_region_ids.return_value = []
        upsell = app_factory(premium_type=amo.ADDON_PREMIUM)
        AddonUpsell.objects.create(free=self.webapp, premium=upsell)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, {'premium_types': 'free'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 1)
        obj = res.json['objects'][0]
        eq_(obj['upsell']['id'], upsell.id)
        eq_(obj['upsell']['app_slug'], upsell.app_slug)
        eq_(obj['upsell']['name'], upsell.name)
        eq_(obj['upsell']['icon_url'], upsell.get_icon_url(128))
        self.assertApiUrlEqual(obj['upsell']['resource_uri'],
                               '/apps/app/%s/' % upsell.id)
        eq_(obj['upsell']['region_exclusions'], [])

        unindex_webapps([upsell.id])
        upsell.delete()

    def test_dehydrate_regions(self):
        self.webapp.addonexcludedregion.create(region=mkt.regions.BR.id)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        regions = obj['regions']
        ok_(mkt.regions.BR.slug not in [r['slug'] for r in regions])
        eq_(len(regions), len(mkt.regions.ALL_REGION_IDS) - 1)

    def test_region_filtering(self):
        self.webapp.addonexcludedregion.create(region=mkt.regions.BR.id)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data={'region': 'br'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

    def test_languages_filtering(self):
        # This webapp's supported_locales: [u'en-US', u'es', u'pt-BR']

        res = self.client.get(self.url, data={'languages': 'fr'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

        for lang in ('fr,pt-BR', 'es, pt-BR', 'es', 'pt-BR'):
            res = self.client.get(self.url, data={'languages': lang})
            eq_(res.status_code, 200)
            obj = res.json['objects'][0]
            eq_(obj['slug'], self.webapp.app_slug)

    def test_offline_filtering(self):
        def check(offline, visible):
            res = self.client.get(self.url, data={'offline': offline})
            eq_(res.status_code, 200)
            objs = res.json['objects']
            eq_(len(objs), int(visible))

        # Should NOT show up in offline.
        # Should show up in online.
        # Should show up everywhere if not filtered.
        check(offline='True', visible=False)
        check(offline='False', visible=True)
        check(offline='None', visible=True)

        # Mark that app is capable offline.
        self.webapp.update(is_packaged=True)
        self.refresh('webapp')

        # Should show up in offline.
        # Should NOT show up in online.
        # Should show up everywhere if not filtered.
        check(offline='True', visible=True)
        check(offline='False', visible=False)
        check(offline='None', visible=True)

    def test_q(self):
        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_q_num_requests(self):
        es = WebappIndexer.get_es()
        orig_search = es.search
        es.counter = 0

        def monkey_search(*args, **kwargs):
            es.counter += 1
            return orig_search(*args, **kwargs)

        es.search = monkey_search

        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        eq_(res.json['meta']['total_count'], 1)
        eq_(len(res.json['objects']), 1)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

        # Verify only one search call was made.
        eq_(es.counter, 1)

        es.search = orig_search

    def test_q_num_requests_no_results(self):
        es = WebappIndexer.get_es()
        orig_search = es.search
        es.counter = 0

        def monkey_search(*args, **kwargs):
            es.counter += 1
            return orig_search(*args, **kwargs)

        es.search = monkey_search

        res = self.client.get(self.url, data={'q': 'noresults'})
        eq_(res.status_code, 200)
        eq_(res.json['meta']['total_count'], 0)
        eq_(len(res.json['objects']), 0)

        # Verify only one search call was made.
        eq_(es.counter, 1)

        es.search = orig_search

    def test_q_exact(self):
        app1 = app_factory(name='test app test11')
        app2 = app_factory(name='test app test21')
        app3 = app_factory(name='test app test31')
        self.refresh('webapp')

        res = self.client.get(self.url, data={'q': 'test app test21'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 3)
        # app2 should be first since it's an exact match and is boosted higher.
        obj = res.json['objects'][0]
        eq_(obj['slug'], app2.app_slug)

        unindex_webapps([app1.id, app2.id, app3.id])
        app1.delete()
        app2.delete()
        app3.delete()

    def test_q_is_tag(self):
        Tag(tag_text='whatsupp').save_tag(self.webapp)
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'whatsupp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_q_is_tag_misspelled(self):
        Tag(tag_text='whatsapp').save_tag(self.webapp)
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'whatsupp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_fuzzy_match(self):
        res = self.client.get(self.url, data={'q': 'soemthing'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_icu_folding(self):
        self.webapp.name = {'es': 'Páginas Amarillos'}
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'paginas'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_camel_case_word_splitting(self):
        self.webapp.name = 'AirCombat'
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'air combat'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_name_localized(self):
        # First test no ?lang parameter returns all localizations.
        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], {u'en-US': u'Something Something Steamcube!',
                          u'es': u'Algo Algo Steamcube!'})

        # Second test that adding ?lang returns only that localization.
        res = self.client.get(self.url,
                              data={'q': 'something', 'lang': 'es'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], u'Algo Algo Steamcube!')

    def test_other_localized(self):
        # Test fields that should be localized.
        translations = {'en-US': u'Test in English',
                        'es': u'Test in Español'}
        self.webapp.homepage = translations
        self.webapp.support_email = translations
        self.webapp.support_url = translations
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['homepage'], translations)
        eq_(obj['support_email'], translations)
        eq_(obj['support_url'], translations)

    def test_name_localized_to_default_locale(self):
        self.webapp.update(default_locale='es')
        self.refresh('webapp')

        # Make a request in another language that we know will fail.
        res = self.client.get(self.url,
                              data={'q': 'something', 'lang': 'de'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], u'Algo Algo Steamcube!')

    def test_device(self):
        AddonDeviceType.objects.create(
            addon=self.webapp, device_type=DEVICE_CHOICES_IDS['desktop'])
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'device': 'desktop'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_no_flash_on_firefoxos(self):
        AddonDeviceType.objects.create(
            addon=self.webapp, device_type=DEVICE_CHOICES_IDS['firefoxos'])
        f = self.webapp.get_latest_file()
        f.uses_flash = True
        f.save()
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'dev': 'firefoxos'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 0)

    def test_premium_types(self):
        res = self.client.get(self.url,
                              data={'premium_types': 'free'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_premium_types_empty(self):
        res = self.client.get(self.url,
                              data={'premium_types': 'premium'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

    def test_multiple_premium_types(self):
        res = self.client.get(self.url,
                              data={'premium_types': ['free', 'premium']})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_app_type_hosted(self):
        res = self.client.get(self.url,
                              data={'app_type': 'hosted'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_app_type_packaged(self):
        self.webapp.update(is_packaged=True)
        self.refresh('webapp')

        res = self.client.get(self.url,
                              data={'app_type': 'packaged'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_app_type_privileged(self):
        # Override the class-decorated patch.
        with patch('versions.models.Version.is_privileged', True):
            self.webapp.update(is_packaged=True)
            self.refresh('webapp')

            res = self.client.get(self.url,
                                  data={'app_type': 'packaged'})
            eq_(res.status_code, 200)
            eq_(len(res.json['objects']), 0)

            res = self.client.get(self.url,
                                  data={'app_type': 'privileged'})
            eq_(res.status_code, 200)
            eq_(len(res.json['objects']), 1)
            obj = res.json['objects'][0]
            eq_(obj['slug'], self.webapp.app_slug)

    def test_status_value_packaged(self):
        # When packaged and not a reviewer we exclude latest version status.
        self.webapp.update(is_packaged=True)
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['status'], amo.STATUS_PUBLIC)
        eq_('latest_version' in obj, False)

    def test_addon_type_anon(self):
        res = self.client.get(self.url, data={'type': 'app'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

        res = self.client.get(self.url, data={'type': 'vindaloo'})
        eq_(res.status_code, 400)
        error = res.json['detail']
        eq_(error.keys(), ['type'])

        res = self.client.get(self.url, data={'type': 'theme'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 0)

    def test_adolescent_popularity(self):
        """
        Adolescent regions use global popularity.

          Webapp:   Global: 0, Regional: 0
          Unknown1: Global: 1, Regional: 1 + 10 * 1 = 11
          Unknown2: Global: 2, Regional: 0

        """
        user = UserProfile.objects.all()[0]
        cd = ClientData.objects.create(region=mkt.regions.BR.id)

        unknown1 = amo.tests.app_factory()
        Installed.objects.create(addon=unknown1, user=user, client_data=cd)

        unknown2 = amo.tests.app_factory()
        Installed.objects.create(addon=unknown2, user=user)
        Installed.objects.create(addon=unknown2, user=user)

        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, data={'region': 'br'})
        eq_(res.status_code, 200)

        objects = res.json['objects']
        eq_(len(objects), 3)

        eq_(int(objects[0]['id']), unknown2.id)
        eq_(int(objects[1]['id']), unknown1.id)
        eq_(int(objects[2]['id']), self.webapp.id)

        # Cleanup to remove these from the index.
        unindex_webapps([unknown1.id, unknown2.id])
        unknown1.delete()
        unknown2.delete()

    def test_word_delimiter_preserves_original(self):
        self.webapp.description = {
            'en-US': 'This is testing word delimiting preservation in long '
                     'descriptions and here is what we want to find: WhatsApp'
        }
        self.webapp.save()
        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, data={'q': 'whatsapp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_pagination(self):
        Webapp.objects.get(pk=337141).delete()
        app1 = app_factory(name='test app test1')
        app2 = app_factory(name='test app test2')
        app3 = app_factory(name='test app test3')
        # Setting 'created' app_factory is unreliable and we need a reliable
        # order.
        app1.update(created=self.days_ago(1))
        app2.update(created=self.days_ago(2))
        app3.update(created=self.days_ago(3))
        self.refresh('webapp')

        res = self.client.get(self.url, data={'limit': '2', 'sort': 'created'})
        eq_(res.status_code, 200)
        data = json.loads(res.content)
        eq_(len(data['objects']), 2)
        eq_(int(data['objects'][0]['id']), app1.id)
        eq_(int(data['objects'][1]['id']), app2.id)

        eq_(data['meta']['total_count'], 3)
        eq_(data['meta']['limit'], 2)
        eq_(data['meta']['previous'], None)
        eq_(data['meta']['offset'], 0)

        next = urlparse(data['meta']['next'])
        eq_(next.path, self.url)
        eq_(QueryDict(next.query).dict(), {'limit': '2', 'offset': '2',
                                           'sort': 'created'})

        res = self.client.get(self.url, QueryDict(next.query).dict())
        eq_(res.status_code, 200)
        data = json.loads(res.content)
        eq_(len(data['objects']), 1)
        eq_(int(data['objects'][0]['id']), app3.id)
        eq_(data['meta']['total_count'], 3)
        eq_(data['meta']['limit'], 2)
        prev = urlparse(data['meta']['previous'])
        eq_(next.path, self.url)
        eq_(QueryDict(prev.query).dict(), {'limit': '2', 'offset': '0',
                                           'sort': 'created'})
        eq_(data['meta']['offset'], 2)
        eq_(data['meta']['next'], None)

    def test_content_ratings_reindex(self):
        self.webapp.set_content_ratings({
            mkt.ratingsbodies.ESRB: mkt.ratingsbodies.ESRB_T
        })
        self.refresh('webapp')
        res = self.client.get(self.url)
        obj = res.json['objects'][0]
        ok_(obj['content_ratings']['ratings'])

    def test_usk_refused_exclude(self):
        geodata = self.webapp._geodata
        geodata.update(region_de_usk_exclude=True)
        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, {'region': 'de'})
        ok_(not res.json['objects'])
示例#40
0
class TestApiFeatures(RestOAuth, ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.client = RestOAuthClient(None)
        self.url = reverse('search-api')
        self.webapp = Webapp.objects.get(pk=337141)
        self.category = Category.objects.create(name='test',
                                                type=amo.ADDON_WEBAPP)
        # Pick a few common device features.
        self.profile = FeatureProfile(apps=True, audio=True, fullscreen=True,
                                      geolocation=True, indexeddb=True,
                                      sms=True).to_signature()
        self.qs = {'q': 'something', 'pro': self.profile, 'dev': 'firefoxos'}

    def test_no_features(self):
        # Base test to make sure we find the app.
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_one_good_feature(self):
        # Enable an app feature that matches one in our profile.
        self.webapp.current_version.features.update(has_geolocation=True)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_one_bad_feature(self):
        # Enable an app feature that doesn't match one in our profile.
        self.webapp.current_version.features.update(has_pay=True)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        objs = json.loads(res.content)['objects']
        eq_(len(objs), 0)

    def test_all_good_features(self):
        # Enable app features so they exactly match our device profile.
        fp = FeatureProfile.from_signature(self.profile)
        self.webapp.current_version.features.update(
            **dict(('has_%s' % k, v) for k, v in fp.items()))
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_bad_profile_on_desktop(self):
        # Enable an app feature that doesn't match one in our profile.
        qs = self.qs.copy()
        del qs['dev']  # Desktop doesn't send a device.
        self.webapp.current_version.features.update(has_pay=True)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
示例#41
0
class TestRocketbarApi(ESTestCase):
    fixtures = fixture('user_2519', 'webapp_337141')

    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.profile = UserProfile.objects.get(pk=2519)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app1.save()

        self.app2 = app_factory(name=u'Something Second Something Something',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                icon_hash='fakehash',
                                created=self.days_ago(3),
                                manifest_url='http://rocket.example.com')
        self.app2.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        # Add 2 installed records so this app is boosted higher than app1.
        Installed.objects.create(user=self.profile, addon=self.app2)
        Installed.objects.create(user=self.profile, addon=self.app2)
        self.app2.save()
        self.refresh('webapp')

    def tearDown(self):
        # Cleanup to remove these from the index.
        self.app1.delete()
        self.app2.delete()
        unindex_webapps([self.app1.id, self.app2.id])
        # Required to purge the suggestions data structure. In Lucene, a
        # document is not deleted from a segment, just marked as deleted.
        WebappIndexer.get_es().optimize(WebappIndexer.get_index(),
                                        only_expunge_deletes=True)

    def test_no_results(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'whatever',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(parsed, [])

    def test_suggestions(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something Second',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})
        ok_(self.app2.get_icon_url(64).endswith('?modified=fakehash'))

    def test_suggestion_default_locale(self):
        self.app2.name.locale = 'es'
        self.app2.name.save()
        self.app2.default_locale = 'es'
        self.app2.save()
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something Second',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})

    def test_suggestions_multiple_results(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 2)
        # Show app2 first since it gets boosted higher b/c of installs.
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})
        eq_(parsed[1], {'manifest_url': self.app1.get_manifest_url(),
                        'icon': self.app1.get_icon_url(64),
                        'name': unicode(self.app1.name),
                        'slug': self.app1.app_slug})

    def test_suggestion_non_gaia_apps(self):
        AddonDeviceType.objects.all().delete()
        self.app1.save()
        self.app2.save()
        self.refresh('webapp')
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'something'})
        parsed = json.loads(response.content)
        eq_(parsed, [])

    def test_suggestions_limit(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'something',
                                                       'lang': 'en-US',
                                                       'limit': 1})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})
示例#42
0
 def setup_client(self, user):
     access = Access.objects.create(key='test_oauth_key_owner',
                                    secret=generate(),
                                    user=user)
     return RestOAuthClient(access)
示例#43
0
class TestApiFeatures(RestOAuth, ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.client = RestOAuthClient(None)
        self.url = reverse('search-api')
        self.webapp = Webapp.objects.get(pk=337141)
        self.category = Category.objects.create(name='test',
                                                type=amo.ADDON_WEBAPP)
        # Pick a few common device features.
        self.profile = FeatureProfile(apps=True, audio=True, fullscreen=True,
                                      geolocation=True, indexeddb=True,
                                      sms=True).to_signature()
        self.qs = {'q': 'something', 'pro': self.profile, 'dev': 'firefoxos'}

    def test_no_features(self):
        # Base test to make sure we find the app.
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_one_good_feature(self):
        # Enable an app feature that matches one in our profile.
        self.webapp.current_version.features.update(has_geolocation=True)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_one_bad_feature(self):
        # Enable an app feature that doesn't match one in our profile.
        self.webapp.current_version.features.update(has_pay=True)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        objs = json.loads(res.content)['objects']
        eq_(len(objs), 0)

    def test_all_good_features(self):
        # Enable app features so they exactly match our device profile.
        fp = FeatureProfile.from_signature(self.profile)
        self.webapp.current_version.features.update(
            **dict(('has_%s' % k, v) for k, v in fp.items()))
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=self.qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_bad_profile_on_desktop(self):
        # Enable an app feature that doesn't match one in our profile.
        qs = self.qs.copy()
        del qs['dev']  # Desktop doesn't send a device.
        self.webapp.current_version.features.update(has_pay=True)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data=qs)
        eq_(res.status_code, 200)
        obj = json.loads(res.content)['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
示例#44
0
class TestApi(RestOAuth, ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.client = RestOAuthClient(None)
        self.url = reverse('search-api')
        self.webapp = Webapp.objects.get(pk=337141)
        self.category = Category.objects.create(name='test', slug='test',
                                                type=amo.ADDON_WEBAPP)
        self.webapp.icon_hash = 'fakehash'
        self.webapp.save()
        self.refresh('webapp')

    def tearDown(self):
        for w in Webapp.objects.all():
            w.delete()
        unindex_webapps(list(Webapp.with_deleted.values_list('id', flat=True)))
        super(TestApi, self).tearDown()

    def test_verbs(self):
        self._allowed_verbs(self.url, ['get'])

    def test_has_cors(self):
        self.assertCORS(self.client.get(self.url), 'get')

    def test_meta(self):
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        eq_(set(res.json.keys()), set(['objects', 'meta']))
        eq_(res.json['meta']['total_count'], 1)

    def test_wrong_category(self):
        res = self.client.get(self.url,
                              data={'cat': self.category.slug + 'xq'})
        eq_(res.status_code, 400)
        eq_(res['Content-Type'], 'application/json')

    def test_wrong_weight(self):
        self.category.update(weight=-1)
        res = self.client.get(self.url, data={'cat': self.category.slug})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 0)

    def test_wrong_sort(self):
        res = self.client.get(self.url, data={'sort': 'awesomeness'})
        eq_(res.status_code, 400)

    def test_sort(self):
        # Mocked version, to make sure we are calling ES with the parameters
        # we want.
        with patch('mkt.webapps.models.Webapp.from_search') as mocked_search:
            mocked_qs = MagicMock()
            mocked_search.return_value = mocked_qs
            for api_sort, es_sort in DEFAULT_SORTING.items():
                res = self.client.get(self.url, [('sort', api_sort)])
                eq_(res.status_code, 200, res.content)
                mocked_qs.order_by.assert_called_with(es_sort)

        # Unmocked version, to make sure elasticsearch is actually accepting
        # the params.
        for api_sort, es_sort in DEFAULT_SORTING.items():
            res = self.client.get(self.url, [('sort', api_sort)])
            eq_(res.status_code, 200)

    def test_right_category(self):
        res = self.client.get(self.url, data={'cat': self.category.pk})
        eq_(res.status_code, 200)
        eq_(res.json['objects'], [])

    def create(self):
        AddonCategory.objects.create(addon=self.webapp, category=self.category)
        self.webapp.save()
        self.refresh('webapp')

    def test_right_category_present(self):
        self.create()
        res = self.client.get(
            self.url, data={'cat': self.category.pk})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 1)

    def test_user_info_with_shared_secret(self):
        user = UserProfile.objects.all()[0]

        def fakeauth(auth, req, **kw):
            req.user = user.user
            req.amo_user = user

        with patch('mkt.api.middleware.RestSharedSecretMiddleware'
                   '.process_request', fakeauth):
            with self.settings(SITE_URL=''):
                self.create()
            res = self.client.get(
                self.url, data={'cat': self.category.pk})
            obj = res.json['objects'][0]
            assert 'user' in obj

    def test_dehydrate(self):
        with self.settings(SITE_URL='http://hy.fr'):
            self.create()
            res = self.client.get(self.url, data={'cat': self.category.pk})
            eq_(res.status_code, 200)
            obj = res.json['objects'][0]
            content_ratings = obj['content_ratings']
            eq_(obj['absolute_url'],
                absolutify(self.webapp.get_absolute_url()))
            eq_(obj['app_type'], self.webapp.app_type)
            eq_(content_ratings['body'], 'generic')
            eq_(content_ratings['rating'], None)
            eq_(content_ratings['descriptors'], [])
            eq_(content_ratings['interactives'], [])
            eq_(obj['current_version'], u'1.0')
            eq_(obj['description'],
                {'en-US': self.webapp.description.localized_string})
            eq_(obj['icons']['128'], self.webapp.get_icon_url(128))
            ok_(obj['icons']['128'].endswith('?modified=fakehash'))
            eq_(obj['id'], long(self.webapp.id))
            eq_(obj['manifest_url'], self.webapp.get_manifest_url())
            eq_(obj['payment_account'], None)
            self.assertApiUrlEqual(obj['privacy_policy'],
                                   '/apps/app/337141/privacy/')
            eq_(obj['public_stats'], self.webapp.public_stats)
            eq_(obj['ratings'], {'average': 0.0, 'count': 0})
            self.assertApiUrlEqual(obj['resource_uri'],
                                   '/apps/app/337141/')
            eq_(obj['slug'], self.webapp.app_slug)
            eq_(obj['supported_locales'], ['en-US', 'es', 'pt-BR'])
            ok_('1.0' in obj['versions'])
            self.assertApiUrlEqual(obj['versions']['1.0'],
                                   '/apps/versions/1268829/')

        # These only exists if requested by a reviewer.
        ok_('latest_version' not in obj)
        ok_('reviewer_flags' not in obj)

    @patch('mkt.webapps.models.Webapp.get_excluded_region_ids')
    def test_upsell(self, get_excluded_region_ids):
        get_excluded_region_ids.return_value = []
        upsell = app_factory(premium_type=amo.ADDON_PREMIUM)
        AddonUpsell.objects.create(free=self.webapp, premium=upsell)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, {'premium_types': 'free'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 1)
        obj = res.json['objects'][0]
        eq_(obj['upsell']['id'], upsell.id)
        eq_(obj['upsell']['app_slug'], upsell.app_slug)
        eq_(obj['upsell']['name'], upsell.name)
        eq_(obj['upsell']['icon_url'], upsell.get_icon_url(128))
        self.assertApiUrlEqual(obj['upsell']['resource_uri'],
                               '/apps/app/%s/' % upsell.id)
        eq_(obj['upsell']['region_exclusions'], [])

        upsell.delete()
        unindex_webapps([upsell.id])

    def test_dehydrate_regions(self):
        self.webapp.addonexcludedregion.create(region=mkt.regions.BR.id)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        regions = obj['regions']
        ok_(mkt.regions.BR.slug not in [r['slug'] for r in regions])
        eq_(len(regions), len(mkt.regions.ALL_REGION_IDS) - 1)

    def test_region_filtering(self):
        self.webapp.addonexcludedregion.create(region=mkt.regions.BR.id)
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data={'region': 'br'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

    def test_languages_filtering(self):
        # This webapp's supported_locales: [u'en-US', u'es', u'pt-BR']

        res = self.client.get(self.url, data={'languages': 'fr'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

        for lang in ('fr,pt-BR', 'es, pt-BR', 'es', 'pt-BR'):
            res = self.client.get(self.url, data={'languages': lang})
            eq_(res.status_code, 200)
            obj = res.json['objects'][0]
            eq_(obj['slug'], self.webapp.app_slug)

    def test_offline_filtering(self):
        def check(offline, visible):
            res = self.client.get(self.url, data={'offline': offline})
            eq_(res.status_code, 200)
            objs = res.json['objects']
            eq_(len(objs), int(visible))

        # Should NOT show up in offline.
        # Should show up in online.
        # Should show up everywhere if not filtered.
        check(offline='True', visible=False)
        check(offline='False', visible=True)
        check(offline='None', visible=True)

        # Mark that app is capable offline.
        self.webapp.update(is_packaged=True)
        self.refresh('webapp')

        # Should show up in offline.
        # Should NOT show up in online.
        # Should show up everywhere if not filtered.
        check(offline='True', visible=True)
        check(offline='False', visible=False)
        check(offline='None', visible=True)

    def test_q(self):
        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_q_num_requests(self):
        es = WebappIndexer.get_es()
        orig_search = es.search
        es.counter = 0

        def monkey_search(*args, **kwargs):
            es.counter += 1
            return orig_search(*args, **kwargs)

        es.search = monkey_search

        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        eq_(res.json['meta']['total_count'], 1)
        eq_(len(res.json['objects']), 1)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

        # Verify only one search call was made.
        eq_(es.counter, 1)

        es.search = orig_search

    def test_q_num_requests_no_results(self):
        es = WebappIndexer.get_es()
        orig_search = es.search
        es.counter = 0

        def monkey_search(*args, **kwargs):
            es.counter += 1
            return orig_search(*args, **kwargs)

        es.search = monkey_search

        res = self.client.get(self.url, data={'q': 'noresults'})
        eq_(res.status_code, 200)
        eq_(res.json['meta']['total_count'], 0)
        eq_(len(res.json['objects']), 0)

        # Verify only one search call was made.
        eq_(es.counter, 1)

        es.search = orig_search

    def test_q_exact(self):
        app1 = app_factory(name='test app test11')
        app2 = app_factory(name='test app test21')
        app3 = app_factory(name='test app test31')
        self.refresh('webapp')

        res = self.client.get(self.url, data={'q': 'test app test21'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 3)
        # app2 should be first since it's an exact match and is boosted higher.
        obj = res.json['objects'][0]
        eq_(obj['slug'], app2.app_slug)

        app1.delete()
        app2.delete()
        app3.delete()
        unindex_webapps([app1.id, app2.id, app3.id])

    def test_q_is_tag(self):
        Tag(tag_text='whatsupp').save_tag(self.webapp)
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'whatsupp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_q_is_tag_misspelled(self):
        Tag(tag_text='whatsapp').save_tag(self.webapp)
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'whatsupp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_fuzzy_match(self):
        res = self.client.get(self.url, data={'q': 'soemthing'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_icu_folding(self):
        self.webapp.name = {'es': 'Páginas Amarillos'}
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'paginas'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_camel_case_word_splitting(self):
        self.webapp.name = 'AirCombat'
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'q': 'air combat'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_name_localized(self):
        # First test no ?lang parameter returns all localizations.
        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], {u'en-US': u'Something Something Steamcube!',
                          u'es': u'Algo Algo Steamcube!'})

        # Second test that adding ?lang returns only that localization.
        res = self.client.get(self.url,
                              data={'q': 'something', 'lang': 'es'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], u'Algo Algo Steamcube!')

    def test_other_localized(self):
        # Test fields that should be localized.
        translations = {'en-US': u'Test in English',
                        'es': u'Test in Español'}
        self.webapp.homepage = translations
        self.webapp.support_email = translations
        self.webapp.support_url = translations
        self.webapp.save()
        self.refresh('webapp')

        res = self.client.get(self.url, data={'q': 'something'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['homepage'], translations)
        eq_(obj['support_email'], translations)
        eq_(obj['support_url'], translations)

    def test_name_localized_to_default_locale(self):
        self.webapp.update(default_locale='es')
        self.refresh('webapp')

        # Make a request in another language that we know will fail.
        res = self.client.get(self.url,
                              data={'q': 'something', 'lang': 'de'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)
        eq_(obj['name'], u'Algo Algo Steamcube!')

    def test_device(self):
        AddonDeviceType.objects.create(
            addon=self.webapp, device_type=DEVICE_CHOICES_IDS['desktop'])
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'device': 'desktop'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_no_flash_on_firefoxos(self):
        AddonDeviceType.objects.create(
            addon=self.webapp, device_type=DEVICE_CHOICES_IDS['firefoxos'])
        f = self.webapp.get_latest_file()
        f.uses_flash = True
        f.save()
        self.webapp.save()
        self.refresh('webapp')
        res = self.client.get(self.url, data={'dev': 'firefoxos'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 0)

    def test_premium_types(self):
        res = self.client.get(self.url,
                              data={'premium_types': 'free'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_premium_types_empty(self):
        res = self.client.get(self.url,
                              data={'premium_types': 'premium'})
        eq_(res.status_code, 200)
        objs = res.json['objects']
        eq_(len(objs), 0)

    def test_multiple_premium_types(self):
        res = self.client.get(self.url,
                              data={'premium_types': ['free', 'premium']})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_app_type_hosted(self):
        res = self.client.get(self.url,
                              data={'app_type': 'hosted'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_app_type_packaged(self):
        self.webapp.update(is_packaged=True)
        self.refresh('webapp')

        res = self.client.get(self.url,
                              data={'app_type': 'packaged'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_app_type_privileged(self):
        # Override the class-decorated patch.
        with patch('versions.models.Version.is_privileged', True):
            self.webapp.update(is_packaged=True)
            self.refresh('webapp')

            res = self.client.get(self.url,
                                  data={'app_type': 'packaged'})
            eq_(res.status_code, 200)
            eq_(len(res.json['objects']), 0)

            res = self.client.get(self.url,
                                  data={'app_type': 'privileged'})
            eq_(res.status_code, 200)
            eq_(len(res.json['objects']), 1)
            obj = res.json['objects'][0]
            eq_(obj['slug'], self.webapp.app_slug)

    def test_status_value_packaged(self):
        # When packaged and not a reviewer we exclude latest version status.
        self.webapp.update(is_packaged=True)
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['status'], amo.STATUS_PUBLIC)
        eq_('latest_version' in obj, False)

    def test_addon_type_anon(self):
        res = self.client.get(self.url, data={'type': 'app'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

        res = self.client.get(self.url, data={'type': 'vindaloo'})
        eq_(res.status_code, 400)
        error = res.json['detail']
        eq_(error.keys(), ['type'])

        res = self.client.get(self.url, data={'type': 'theme'})
        eq_(res.status_code, 200)
        eq_(len(res.json['objects']), 0)

    def test_adolescent_popularity(self):
        """
        Adolescent regions use global popularity.

          Webapp:   Global: 0, Regional: 0
          Unknown1: Global: 1, Regional: 1 + 10 * 1 = 11
          Unknown2: Global: 2, Regional: 0

        """
        user = UserProfile.objects.all()[0]
        cd = ClientData.objects.create(region=mkt.regions.BR.id)

        unknown1 = amo.tests.app_factory()
        Installed.objects.create(addon=unknown1, user=user, client_data=cd)

        unknown2 = amo.tests.app_factory()
        Installed.objects.create(addon=unknown2, user=user)
        Installed.objects.create(addon=unknown2, user=user)

        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, data={'region': 'br'})
        eq_(res.status_code, 200)

        objects = res.json['objects']
        eq_(len(objects), 3)

        eq_(int(objects[0]['id']), unknown2.id)
        eq_(int(objects[1]['id']), unknown1.id)
        eq_(int(objects[2]['id']), self.webapp.id)

        # Cleanup to remove these from the index.
        unknown1.delete()
        unknown2.delete()
        unindex_webapps([unknown1.id, unknown2.id])

    def test_word_delimiter_preserves_original(self):
        self.webapp.description = {
            'en-US': 'This is testing word delimiting preservation in long '
                     'descriptions and here is what we want to find: WhatsApp'
        }
        self.webapp.save()
        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, data={'q': 'whatsapp'})
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['slug'], self.webapp.app_slug)

    def test_pagination(self):
        Webapp.objects.get(pk=337141).delete()
        app1 = app_factory(name='test app test1')
        app2 = app_factory(name='test app test2')
        app3 = app_factory(name='test app test3')
        # Setting 'created' app_factory is unreliable and we need a reliable
        # order.
        app1.update(created=self.days_ago(1))
        app2.update(created=self.days_ago(2))
        app3.update(created=self.days_ago(3))
        self.refresh('webapp')

        res = self.client.get(self.url, data={'limit': '2', 'sort': 'created'})
        eq_(res.status_code, 200)
        data = json.loads(res.content)
        eq_(len(data['objects']), 2)
        eq_(int(data['objects'][0]['id']), app1.id)
        eq_(int(data['objects'][1]['id']), app2.id)

        eq_(data['meta']['total_count'], 3)
        eq_(data['meta']['limit'], 2)
        eq_(data['meta']['previous'], None)
        eq_(data['meta']['offset'], 0)

        next = urlparse(data['meta']['next'])
        eq_(next.path, self.url)
        eq_(QueryDict(next.query).dict(), {'limit': '2', 'offset': '2',
                                           'sort': 'created'})

        res = self.client.get(self.url, QueryDict(next.query).dict())
        eq_(res.status_code, 200)
        data = json.loads(res.content)
        eq_(len(data['objects']), 1)
        eq_(int(data['objects'][0]['id']), app3.id)
        eq_(data['meta']['total_count'], 3)
        eq_(data['meta']['limit'], 2)
        prev = urlparse(data['meta']['previous'])
        eq_(next.path, self.url)
        eq_(QueryDict(prev.query).dict(), {'limit': '2', 'offset': '0',
                                           'sort': 'created'})
        eq_(data['meta']['offset'], 2)
        eq_(data['meta']['next'], None)

    def test_content_ratings_reindex(self):
        self.webapp.set_content_ratings({
            mkt.ratingsbodies.GENERIC: mkt.ratingsbodies.GENERIC_18
        })
        self.refresh('webapp')
        res = self.client.get(self.url)
        obj = res.json['objects'][0]
        ok_(obj['content_ratings']['rating'])

    def test_usk_refused_exclude(self):
        geodata = self.webapp._geodata
        geodata.update(region_de_usk_exclude=True)
        self.reindex(Webapp, 'webapp')

        res = self.client.get(self.url, {'region': 'de'})
        ok_(not res.json['objects'])

    def test_icon_url_never(self):
        self.webapp.update(icon_hash=None)
        self.refresh('webapp')
        res = self.client.get(self.url)
        eq_(res.status_code, 200)
        obj = res.json['objects'][0]
        eq_(obj['icons']['64'], self.webapp.get_icon_url(64))
        ok_(obj['icons']['64'].endswith('?modified=never'))
示例#45
0
class TestRocketbarApi(ESTestCase):
    fixtures = fixture('webapp_337141')

    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app1.save()

        self.app2 = app_factory(name=u'Something Second Something Something',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                created=self.days_ago(3),
                                manifest_url='http://rocket.example.com')
        self.app2.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app2.save()
        self.refresh('webapp')

    def tearDown(self):
        # Cleanup to remove these from the index.
        unindex_webapps([self.app1.id, self.app2.id])
        self.app1.delete()
        self.app2.delete()

    def test_no_results(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'whatever',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(parsed, [])

    def test_suggestions(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something Second',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})

    def test_suggestions_multiple_results(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 2)
        eq_(parsed[0], {'manifest_url': self.app1.get_manifest_url(),
                        'icon': self.app1.get_icon_url(64),
                        'name': unicode(self.app1.name),
                      'slug': self.app1.app_slug})
        eq_(parsed[1], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})

    def test_suggestion_non_gaia_apps(self):
        AddonDeviceType.objects.all().delete()
        self.app1.save()
        self.app2.save()
        self.refresh('webapp')
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'something'})
        parsed = json.loads(response.content)
        eq_(parsed, [])

    def test_suggestions_limit(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'something',
                                                       'lang': 'en-US',
                                                       'limit': 1})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app1.get_manifest_url(),
                        'icon': self.app1.get_icon_url(64),
                        'name': unicode(self.app1.name),
                        'slug': self.app1.app_slug})
示例#46
0
class TestRocketbarApi(ESTestCase):
    fixtures = fixture('user_2519', 'webapp_337141')

    def setUp(self):
        self.url = reverse('rocketbar-search-api')
        self.refresh('webapp')
        self.client = RestOAuthClient(None)
        self.profile = UserProfile.objects.get(pk=2519)
        self.app1 = Webapp.objects.get(pk=337141)
        self.app1.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        self.app1.save()

        self.app2 = app_factory(name=u'Something Second Something Something',
                                description=u'Second dèsc' * 25,
                                icon_type='image/png',
                                icon_hash='fakehash',
                                created=self.days_ago(3),
                                manifest_url='http://rocket.example.com')
        self.app2.addondevicetype_set.create(device_type=amo.DEVICE_GAIA.id)
        # Add 2 installed records so this app is boosted higher than app1.
        Installed.objects.create(user=self.profile, addon=self.app2)
        Installed.objects.create(user=amo.tests.user_factory(),
                                 addon=self.app2)
        self.app2.save()
        self.refresh('webapp')

    def tearDown(self):
        # Cleanup to remove these from the index.
        self.app1.delete()
        self.app2.delete()
        unindex_webapps([self.app1.id, self.app2.id])
        # Required to purge the suggestions data structure. In Lucene, a
        # document is not deleted from a segment, just marked as deleted.
        WebappIndexer.get_es().optimize(WebappIndexer.get_index(),
                                        only_expunge_deletes=True)

    def test_no_results(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'whatever',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(parsed, [])

    def test_suggestions(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something Second',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})
        ok_(self.app2.get_icon_url(64).endswith('?modified=fakehash'))

    def test_suggestion_default_locale(self):
        self.app2.name.locale = 'es'
        self.app2.name.save()
        self.app2.default_locale = 'es'
        self.app2.save()
        self.refresh()
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something Second',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})

    def test_suggestions_multiple_results(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'Something',
                                                       'lang': 'en-US'})
        parsed = json.loads(response.content)
        eq_(len(parsed), 2)
        # Show app2 first since it gets boosted higher b/c of installs.
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})
        eq_(parsed[1], {'manifest_url': self.app1.get_manifest_url(),
                        'icon': self.app1.get_icon_url(64),
                        'name': unicode(self.app1.name),
                        'slug': self.app1.app_slug})

    def test_suggestion_non_gaia_apps(self):
        AddonDeviceType.objects.all().delete()
        self.app1.save()
        self.app2.save()
        self.refresh('webapp')
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'something'})
        parsed = json.loads(response.content)
        eq_(parsed, [])

    def test_suggestions_limit(self):
        with self.assertNumQueries(0):
            response = self.client.get(self.url, data={'q': 'something',
                                                       'lang': 'en-US',
                                                       'limit': 1})
        parsed = json.loads(response.content)
        eq_(len(parsed), 1)
        eq_(parsed[0], {'manifest_url': self.app2.get_manifest_url(),
                        'icon': self.app2.get_icon_url(64),
                        'name': unicode(self.app2.name),
                        'slug': self.app2.app_slug})