Example #1
0
    def test_compatible_app_redirect(self):
        """
        For add-ons incompatible with the current app, redirect to one
        that's supported.
        """
        addon = Addon.objects.get(id=3615)
        comp_app = addon.compatible_apps.keys()[0]
        not_comp_app = [a for a in amo.APP_USAGE
                        if a not in addon.compatible_apps.keys()][0]

        # no SeaMonkey version => redirect
        prefixer = amo.urlresolvers.get_url_prefix()
        prefixer.app = not_comp_app.short
        response = self.client.get(reverse('addons.detail', args=[addon.id]),
                                   follow=False)
        eq_(response.status_code, 301)
        eq_(response['Location'].find(not_comp_app.short), -1)
        assert (response['Location'].find(comp_app.short) >= 0)

        # compatible app => 200
        prefixer = amo.urlresolvers.get_url_prefix()
        prefixer.app = comp_app.short
        response = self.client.get(reverse('addons.detail', args=[addon.id]),
                                   follow=False)
        eq_(response.status_code, 200)
Example #2
0
def in_app_config(request, addon_id, addon, webapp=True):
    inapp = addon.premium_type in amo.ADDON_INAPPS
    if not inapp:
        messages.error(request,
                       _('Your app is not configured for in-app payments.'))
        return redirect(reverse('mkt.developers.apps.payments',
                                args=[addon.app_slug]))
    try:
        account = addon.app_payment_account
    except ObjectDoesNotExist:
        messages.error(request, _('No payment account for this app.'))
        return redirect(reverse('mkt.developers.apps.payments',
                                args=[addon.app_slug]))

    seller_config = get_seller_product(account)

    owner = acl.check_addon_ownership(request, addon)
    if request.method == 'POST':
        # Reset the in-app secret for the app.
        (client.api.generic
               .product(seller_config['resource_pk'])
               .patch(data={'secret': generate_key(48)}))
        messages.success(request, _('Changes successfully saved.'))
        return redirect(reverse('mkt.developers.apps.in_app_config',
                                args=[addon.app_slug]))

    return jingo.render(request, 'developers/payments/in-app-config.html',
                        {'addon': addon, 'owner': owner,
                         'seller_config': seller_config})
Example #3
0
def setup_viewer(request, file_obj):
    data = {
        "file": file_obj,
        "version": file_obj.version,
        "addon": file_obj.version.addon,
        "status": False,
        "selected": {},
        "validate_url": "",
    }

    if acl.check_reviewer(request) or acl.check_addon_ownership(
        request, file_obj.version.addon, viewer=True, ignore_disabled=True
    ):
        data["validate_url"] = reverse(
            "mkt.developers.apps.json_file_validation", args=[file_obj.version.addon.app_slug, file_obj.id]
        )

    if acl.check_reviewer(request):
        data["file_link"] = {
            "text": _("Back to review"),
            "url": reverse("reviewers.apps.review", args=[data["addon"].app_slug]),
        }
    else:
        data["file_link"] = {"text": _("Back to app"), "url": reverse("detail", args=[data["addon"].pk])}
    return data
Example #4
0
    def test_other_author_addons(self):
        """
        Make sure the list of other author addons doesn't include this one.
        """
        r = self.client.get(reverse('addons.detail', args=[8680]))
        doc = pq(r.content)
        eq_(len([a.attrib['value'] for a
                 in doc('#addons-author-addons-select option')
                 if a.attrib['value'] == '8680']), 0)

        # Test "other addons" redirect functionality with valid and
        # invalid input.
        forward_to = lambda input: self.client.get(reverse(
            'addons.detail', args=[8680]), {
                'addons-author-addons-select': input})
        # Valid input.
        response = forward_to('3615')
        eq_(response.status_code, 301)
        assert response['Location'].find('3615') > 0
        # Textual input.
        response = forward_to('abc')
        eq_(response.status_code, 400)
        # Unicode input.
        response = forward_to(u'\u271D')
        eq_(response.status_code, 400)
Example #5
0
 def setUp(self):
     self.client.login(username='******', password='******')
     args = ['fligtar', 'slug']
     Collection.objects.create(slug='slug', author_id=9945)
     self.c_url = reverse('collections.detail', args=args)
     self.up = reverse('collections.vote', args=args + ['up'])
     self.down = reverse('collections.vote', args=args + ['down'])
Example #6
0
def upload_validation_context(request, upload, addon_slug=None, addon=None,
                              url=None):
    if addon_slug and not addon:
        addon = get_object_or_404(Addon, slug=addon_slug)
    if not settings.VALIDATE_ADDONS:
        upload.task_error = ''
        upload.is_webapp = True
        upload.validation = json.dumps({'errors': 0, 'messages': [],
                                        'metadata': {}, 'notices': 0,
                                        'warnings': 0})
        upload.save()

    validation = json.loads(upload.validation) if upload.validation else ''
    if not url:
        if addon:
            url = reverse('mkt.developers.upload_detail_for_addon',
                          args=[addon.slug, upload.uuid])
        else:
            url = reverse('mkt.developers.upload_detail',
                          args=[upload.uuid, 'json'])
    report_url = reverse('mkt.developers.upload_detail', args=[upload.uuid])

    return make_validation_result(dict(upload=upload.uuid,
                                       validation=validation,
                                       error=upload.task_error, url=url,
                                       full_report_url=report_url))
Example #7
0
 def setUp(self):
     super(BlocklistTest, self).setUp()
     self.fx4_url = reverse('blocklist', args=[3, amo.FIREFOX.guid, '4.0'])
     self.fx2_url = reverse('blocklist', args=[2, amo.FIREFOX.guid, '2.0'])
     self.mobile_url = reverse('blocklist', args=[2, amo.MOBILE.guid, '.9'])
     cache.clear()
     self.details = BlocklistDetail.objects.create()
Example #8
0
    def test_edit_buttons(self):
        """Ensure admin/user edit buttons are shown."""

        def get_links(id):
            """Grab profile, return edit links."""
            url = reverse("users.profile", args=[id])
            r = self.client.get(url)
            return pq(r.content)("#profile-actions a")

        # Anonymous user.
        links = get_links(self.user.id)
        eq_(links.length, 1)
        eq_(links.eq(0).attr("href"), reverse("users.abuse", args=[self.user.id]))

        # Non-admin, someone else's profile.
        self.client.login(username="******", password="******")
        links = get_links(9945)
        eq_(links.length, 1)
        eq_(links.eq(0).attr("href"), reverse("users.abuse", args=[9945]))

        # Non-admin, own profile.
        links = get_links(self.user.id)
        eq_(links.length, 1)
        eq_(links.eq(0).attr("href"), reverse("users.edit"))

        # Admin, someone else's profile.
        admingroup = Group(rules="Users:Edit")
        admingroup.save()
        GroupUser.objects.create(group=admingroup, user=self.user)
        cache.clear()

        # Admin, own profile.
        links = get_links(self.user.id)
        eq_(links.length, 2)
        eq_(links.eq(0).attr("href"), reverse("users.edit"))
Example #9
0
def validate_addon(request):
    return jingo.render(request, 'developers/validate_addon.html', {
        'upload_hosted_url':
            reverse('mkt.developers.standalone_hosted_upload'),
        'upload_packaged_url':
            reverse('mkt.developers.standalone_packaged_upload'),
    })
Example #10
0
    def test_acl_collections_edit(self):
        # Test users in group with 'Collections:Edit' are allowed.
        user = UserProfile.objects.get(email='*****@*****.**')
        group = Group.objects.create(name='Staff', rules='Collections:Edit')
        GroupUser.objects.create(user=user, group=group)
        r = self.client.post(self.add_url, self.data, follow=True)
        self.login_regular()
        url_args = ['admin', self.slug]

        url = reverse('collections.edit', args=url_args)
        r = self.client.get(url)
        eq_(r.status_code, 200)

        url = reverse('collections.edit_addons', args=url_args)
        r = self.client.get(url)
        eq_(r.status_code, 405)
        # Passed acl check, but this view needs a POST.

        url = reverse('collections.edit_contributors', args=url_args)
        r = self.client.get(url)
        eq_(r.status_code, 405)
        # Passed acl check, but this view needs a POST.

        url = reverse('collections.edit_privacy', args=url_args)
        r = self.client.get(url)
        eq_(r.status_code, 405)
        # Passed acl check, but this view needs a POST.

        url = reverse('collections.delete', args=url_args)
        r = self.client.get(url)
        eq_(r.status_code, 200)
Example #11
0
 def account(acc):
     app_names = (', '.join(unicode(apa.addon.name)
                  for apa in acc.addonpaymentaccount_set.all()
                     if hasattr(apa, 'addon')))
     provider = acc.get_provider()
     data = {
         'account-url':
             reverse('mkt.developers.provider.payment_account',
                     args=[acc.pk]),
         'agreement-url': acc.get_agreement_url(),
         'agreement': 'accepted' if acc.agreed_tos else 'rejected',
         'app-names': jinja2.escape(app_names),
         'delete-url':
             reverse('mkt.developers.provider.delete_payment_account',
                     args=[acc.pk]),
         'id': acc.pk,
         'name': jinja2.escape(unicode(acc)),
         'provider': provider.name,
         'provider-full': unicode(provider.full),
         'shared': acc.shared,
     }
     if waffle.switch_is_active('bango-portal') and app_slug:
         data['portal-url'] = reverse(
             'mkt.developers.apps.payments.bango_portal_from_addon',
             args=[app_slug])
     return data
Example #12
0
    def test_prepare_pay(self):
        from mkt.purchase.webpay import make_ext_id

        data = self.post(self.prepare_pay)
        cn = Contribution.objects.get()
        eq_(cn.type, amo.CONTRIB_PENDING)
        eq_(cn.user, self.user)
        eq_(cn.price_tier, self.price)

        data = jwt.decode(data["webpayJWT"].encode("ascii"), verify=False)
        eq_(data["typ"], settings.APP_PURCHASE_TYP)
        eq_(data["aud"], settings.APP_PURCHASE_AUD)
        req = data["request"]
        eq_(req["pricePoint"], self.price.name)
        eq_(req["id"], make_ext_id(self.addon.pk))
        eq_(req["name"], unicode(self.addon.name))
        eq_(req["description"], unicode(self.addon.description))
        eq_(req["postbackURL"], absolutify(reverse("webpay.postback")))
        eq_(req["chargebackURL"], absolutify(reverse("webpay.chargeback")))
        eq_(req["icons"]["512"], absolutify(self.addon.get_icon_url(512)))
        pd = urlparse.parse_qs(req["productData"])
        eq_(pd["contrib_uuid"][0], cn.uuid)
        eq_(pd["seller_uuid"][0], self.seller.uuid)
        eq_(pd["addon_id"][0], str(self.addon.pk))
        eq_(pd["application_size"][0], "388096")
Example #13
0
def app_search(request):
    results = []
    q = request.GET.get("q", u"").lower().strip()
    addon_type = int(request.GET.get("type", amo.ADDON_WEBAPP))
    fields = ("name", "app_slug")
    non_es_fields = ["id", "name__localized_string"] + list(fields)
    if q.isnumeric():
        qs = Addon.objects.filter(type=addon_type, pk=q).values(*non_es_fields)
    else:
        # Try to load by GUID:
        qs = Addon.objects.filter(type=addon_type, guid=q).values(*non_es_fields)
        if not qs.count():
            if addon_type == amo.ADDON_WEBAPP:
                qs = S(WebappIndexer)
            else:
                qs = S(Addon)
            qs = qs.filter(type=addon_type).query(should=True, **_expand_query(q, fields)).values_dict(*fields)
        qs = _slice_results(request, qs)
    for app in qs:
        if "name__localized_string" in app:
            # This is a result from the database.
            app["url"] = reverse("lookup.app_summary", args=[app["id"]])
            app["name"] = app["name__localized_string"]
            results.append(app)
        else:
            # This is a result from elasticsearch which returns lists.
            app["url"] = reverse("lookup.app_summary", args=[app["id"][0]])
            for field in ("id", "app_slug"):
                app[field] = app.get(field, [None])[0]
            for name in app["name"]:
                dd = app.copy()
                dd["name"] = name
                results.append(dd)
    return {"results": results}
Example #14
0
    def test_non_indexed_cat(self):
        new_cat = Category.objects.create(name='Slap Tickling', slug='booping',
                                          type=amo.ADDON_WEBAPP)
        r = self.client.get(reverse('browse.apps', args=[new_cat.slug]))

        # If the category has no indexed apps, we redirect to main search page.
        self.assertRedirects(r, reverse('search.search'))
Example #15
0
def get_preapproval_key(data):
    """
    Get a preapproval key from PayPal. If this passes, you get a key that
    you can use in a redirect to PayPal.
    """
    paypal_data = {
        'currencyCode': 'USD',
        'startingDate': data['startDate'].strftime('%Y-%m-%d'),
        'endingDate': data['endDate'].strftime('%Y-%m-%d'),
        'maxTotalAmountOfAllPayments': str(data.get('maxAmount', '2000')),
        'returnUrl': absolutify(reverse(data['pattern'], args=['complete'])),
        'cancelUrl': absolutify(reverse(data['pattern'], args=['cancel'])),
    }
    if settings.PAYPAL_LIMIT_PREAPPROVAL:
        paypal_data.update({
            'maxAmountPerPayment': 15,
            'maxNumberOfPaymentsPerPeriod': 15,
            'paymentPeriod': 'DAILY',
        })

    with statsd.timer('paypal.preapproval.token'):
        response = _call(settings.PAYPAL_PAY_URL + 'Preapproval', paypal_data,
                         ip=data.get('ip'))

    return response
Example #16
0
def sidebar(app):
    """Populates the sidebar with (categories, types)."""
    from addons.models import Category
    if app is None:
        return [], []

    # We muck with query to make order_by and extra_order_by play nice.
    q = Category.objects.filter(application=app.id, weight__gte=0,
                                type=amo.ADDON_EXTENSION)
    categories = order_by_translation(q, 'name')
    categories.query.extra_order_by.insert(0, 'weight')

    Type = collections.namedtuple('Type', 'id name url')
    base = urlresolvers.reverse('home')
    types = [Type(99, _('Collections'), base + 'collections/')]

    shown_types = {
        amo.ADDON_PERSONA: urlresolvers.reverse('browse.personas'),
        amo.ADDON_DICT: urlresolvers.reverse('browse.language-tools'),
        amo.ADDON_SEARCH: urlresolvers.reverse('browse.search-tools'),
        amo.ADDON_THEME: urlresolvers.reverse('browse.themes'),
    }
    titles = dict(amo.ADDON_TYPES,
                  **{amo.ADDON_DICT: _('Dictionaries & Language Packs')})
    for type_, url in shown_types.items():
        if type_ in app.types:
            types.append(Type(type_, titles[type_], url))

    return categories, sorted(types, key=lambda x: x.name)
Example #17
0
def get_absolute_url(url):
    if isinstance(url, tuple):
        url = reverse(url[0], args=url[1:])
    else:
        url = reverse(url)

    return 'http://%s%s' % ('api', url)
Example #18
0
 def test_create_no_license_url(self):
     self.create_no_license()
     self.client.login(username='******', password='******')
     res = self.client.get(reverse('devhub.submit.resume',
                                   args=['xpi-name']))
     self.assertRedirects(res, reverse('devhub.submit.5',
                                       args=['xpi-name']))
Example #19
0
    def test_lang_initial(self):
        """If no lang is set on the user, initial value is current locale."""
        # Lang is already set: don't change it.
        res = self.client.get(self.url)
        form = res.context['form']
        eq_(form.initial['lang'], 'en-US')

        with self.activate('fr'):
            res = self.client.get(reverse('users.edit'))
            form = res.context['form']
            eq_(form.initial['lang'], 'en-US')

        # Lang isn't set yet: initial value is set to the current locale.
        user = UserProfile.objects.get(email='*****@*****.**')
        user.lang = None
        user.save()

        res = self.client.get(self.url)
        form = res.context['form']
        eq_(form.initial['lang'], 'en-US')

        with self.activate('fr'):
            res = self.client.get(reverse('users.edit'))
            form = res.context['form']
            eq_(form.initial['lang'], 'fr')
Example #20
0
 def setUp(self):
     super(TestEditMedia, self).setUp()
     self.media_edit_url = self.get_url('media', True)
     self.icon_upload = reverse('devhub.addons.upload_icon',
                                args=[self.addon.slug])
     self.preview_upload = reverse('devhub.addons.upload_preview',
                                   args=[self.addon.slug])
Example #21
0
def create_test_receipt(root, status):
    time_ = calendar.timegm(time.gmtime())
    detail = absolutify(reverse('receipt.test.details'))
    receipt = {
        'detail': absolutify(detail),
        'exp': time_ + (60 * 60 * 24),
        'iat': time_,
        'iss': settings.SITE_URL,
        'nbf': time_,
        'product': {
            'storedata': urlencode({'id': 0}),
            'url': root,
        },
        'reissue': detail,
        'typ': 'test-receipt',
        'user': {
            'type': 'directed-identifier',
            'value': 'none'
        },
        'verify': absolutify(reverse('receipt.test.verify',
                                     kwargs={'status': status}))

    }
    if settings.SIGNING_SERVER_ACTIVE:
        return sign(receipt)
    else:
        return jwt.encode(receipt, get_key(), u'RS512')
Example #22
0
def legacy_theme_redirects(request, category=None, category_name=None):
    url = None

    if category_name is not None:
        # This format is for the Complete Themes RSS feed.
        url = reverse('browse.themes.rss', args=[category_name])
    else:
        if not category or category == 'all':
            url = reverse('browse.personas')
        else:
            try:
                # Theme?
                cat = Category.objects.filter(slug=category,
                                              type=amo.ADDON_PERSONA)[0]
            except IndexError:
                pass
            else:
                # Hey, it was a Theme.
                url = reverse('browse.personas', args=[cat.slug])

    if url:
        if 'sort' in request.GET:
            url = amo.utils.urlparams(url, sort=request.GET['sort'])
        return redirect(url, permanent=not settings.DEBUG)
    else:
        raise Http404
Example #23
0
    def test_submit_theme(self):
        res = self.client.post(reverse('submit.theme'), data=self.data)

        eq_(Addon.objects.count(), 1)
        eq_(Persona.objects.count(), 1)

        addon = Addon.objects.all()[0]
        persona = Persona.objects.all()[0]

        self.assert3xx(res, reverse('submit.theme.done', args=[addon.slug]))

        eq_(addon.name, self.data['name'])
        eq_(addon.slug, self.data['slug'])
        eq_(addon.categories.all()[0].id, 1)
        eq_(addon.authors.all()[0].username, 'admin')
        eq_(addon.description, self.data['summary'])
        eq_(addon.status, amo.STATUS_PENDING)
        eq_(addon.type, amo.ADDON_PERSONA)
        eq_(persona.addon, addon)
        eq_(persona.license_id, int(self.data['license']))
        eq_(persona.display_username, 'admin')
        eq_(persona.accentcolor, self.data['accentcolor'][1:])
        eq_(persona.textcolor, self.data['textcolor'][1:])

        res = self.client.get(reverse('submit.theme.done', args=[addon.slug]))
        eq_(res.status_code, 200)
Example #24
0
def json_upload_detail(upload):
    if not settings.VALIDATE_ADDONS:
        upload.task_error = ''
        upload.validation = json.dumps({'errors': 0, 'messages': [],
                                        'notices': 0, 'warnings': 0})
        upload.save()

    validation = json.loads(upload.validation) if upload.validation else ""
    url = reverse('devhub.upload_detail', args=[upload.uuid, 'json'])
    full_report_url = reverse('devhub.upload_detail', args=[upload.uuid])
    plat_exclude = []

    if validation:
        if validation['errors'] == 0:
            try:
                apps = parse_addon(upload.path).get('apps', [])
                app_ids = set([a.id for a in apps])
                supported_platforms = []
                if amo.MOBILE.id in app_ids:
                    supported_platforms.extend(amo.MOBILE_PLATFORMS.keys())
                    app_ids.remove(amo.MOBILE.id)
                if len(app_ids):
                    # Targets any other non-mobile app:
                    supported_platforms.extend(amo.DESKTOP_PLATFORMS.keys())
                s = amo.SUPPORTED_PLATFORMS.keys()
                plat_exclude = set(s) - set(supported_platforms)
                plat_exclude = [str(p) for p in plat_exclude]
            except django_forms.ValidationError, exc:
                # XPI parsing errors will be reported in the form submission
                # (next request).
                # TODO(Kumar) It would be nicer to present errors to the user
                # right here to avoid confusion about platform selection.
                log.error("XPI parsing error, ignored: %s" % exc)
Example #25
0
    def setUp(self):
        self.client.login(username='******', password='******')
        waffle.models.Switch.objects.get_or_create(name='mkt-themes',
                                                   active=True)

        License.objects.create(id=amo.LICENSE_COPYRIGHT.id)
        header_img = get_image_path('persona-header.jpg')
        res = self.client.post(reverse('submit.theme.upload',
                                       args=['persona_header']),
                               {'upload_image': open(header_img, 'rb')})
        header_hash = json.loads(res.content)['upload_hash']
        footer_img = get_image_path('persona-footer.jpg')
        res = self.client.post(reverse('submit.theme.upload',
                                       args=['persona_footer']),
                               {'upload_image': open(footer_img, 'rb')})
        footer_hash = json.loads(res.content)['upload_hash']
        self.data = {
            'category': '1',
            'name': 'testpersona',
            'slug': 'testslug',
            'summary': 'testsummary',
            'tags': 'tag1, tag2',
            'license': amo.LICENSE_COPYRIGHT.id,
            'accentcolor': '#000000',
            'textcolor': '#ffffff',
            'header_hash': header_hash,
            'footer_hash': footer_hash,
        }
Example #26
0
def reviewers_breadcrumbs(context, queue=None, addon_queue=None, items=None):
    """
    Wrapper function for ``breadcrumbs``. Prepends 'Editor Tools'
    breadcrumbs.

    **items**
        list of [(url, label)] to be inserted after Add-on.
    **addon_queue**
        Addon object. This sets the queue by addon type or addon status.
    **queue**
        Explicit queue type to set.
    """
    crumbs = [(reverse('reviewers.home'), _('Reviewer Tools'))]

    if addon_queue and addon_queue.type == amo.ADDON_WEBAPP:
        queue = 'pending'

    if queue:
        queues = {'pending': _('Apps')}

        if items and not queue == 'queue':
            url = reverse('reviewers.apps.queue_%s' % queue)
        else:
            # The Addon is the end of the trail.
            url = None
        crumbs.append((url, queues[queue]))

    if items:
        crumbs.extend(items)
    return impala_breadcrumbs(context, crumbs, add_default=True)
Example #27
0
 def test_resume_step(self):
     self._step()
     payments_url = reverse('submit.app.payments',
                            args=[self.webapp.app_slug])
     r = self.client.get(payments_url, follow=True)
     self.assertRedirects(r, reverse('submit.app.details',
                                     args=[self.webapp.app_slug]))
Example #28
0
    def test_user_review_history(self):
        addon_factory(type=amo.ADDON_PERSONA, status=self.status)

        reviewer = self.create_and_become_reviewer()

        res = self.client.get(reverse('reviewers.themes.history'))
        eq_(res.status_code, 200)
        doc = pq(res.content)
        eq_(doc('tbody tr').length, 0)

        theme = Persona.objects.all()[0]
        for x in range(3):
            amo.log(amo.LOG.THEME_REVIEW, theme.addon, user=reviewer,
                    details={'action': rvw.ACTION_APPROVE,
                             'comment': '', 'reject_reason': ''})

        res = self.client.get(reverse('reviewers.themes.history'))
        eq_(res.status_code, 200)
        doc = pq(res.content)
        eq_(doc('tbody tr').length, 3)

        res = self.client.get(reverse('reviewers.themes.logs'))
        eq_(res.status_code, 200)
        doc = pq(res.content)
        eq_(doc('tbody tr').length, 3 * 2)  # Double for comment rows.
Example #29
0
def mine(request, slug=None):
    username = request.amo_user.username
    if slug is None:
        loc = reverse('collections.user', args=[username])
    else:
        loc = reverse('collections.detail', args=[username, slug])
    return redirect(loc)
Example #30
0
def reviewers_breadcrumbs(context, queue=None, items=None):
    """
    Wrapper function for ``breadcrumbs``. Prepends 'Editor Tools'
    breadcrumbs.

    **queue**
        Explicit queue type to set.
    **items**
        list of [(url, label)] to be inserted after Add-on.
    """
    crumbs = [(reverse('reviewers.home'), _('Reviewer Tools'))]

    if queue:
        queues = {'pending': _('Apps'),
                  'rereview': _('Re-reviews'),
                  'escalated': _('Escalations')}

        if items:
            url = reverse('reviewers.apps.queue_%s' % queue)
        else:
            # The Addon is the end of the trail.
            url = None
        crumbs.append((url, queues[queue]))

    if items:
        crumbs.extend(items)
    return impala_breadcrumbs(context, crumbs, add_default=True)
Example #31
0
 def test_list_collections(self):
     r = self.client.get(
         reverse('collections.ajax_list') + '?addon_id=3615', )
     doc = pq(r.content)
     eq_(doc('li').attr('data-id'), '80')
Example #32
0
def _prepare_pay(request, addon):
    """Prepare a JWT to pass into navigator.pay()"""
    if addon.is_premium() and addon.has_purchased(request.amo_user):
        log.info('Already purchased: %d' % addon.pk)
        raise AlreadyPurchased

    amount, currency, uuid_, contrib_for = start_purchase(request, addon)
    log.debug('Storing contrib for uuid: %s' % uuid_)
    Contribution.objects.create(addon_id=addon.id,
                                amount=amount,
                                source=request.REQUEST.get('src', ''),
                                source_locale=request.LANG,
                                uuid=str(uuid_),
                                type=amo.CONTRIB_PENDING,
                                paykey=None,
                                user=request.amo_user,
                                price_tier=addon.premium.price,
                                client_data=ClientData.get_or_create(request))

    # Until atob() supports encoded HTML we are stripping all tags.
    # See bug 831524
    app_description = bleach.clean(unicode(addon.description),
                                   strip=True,
                                   tags=[])

    acct = addon.app_payment_account.payment_account
    seller_uuid = acct.solitude_seller.uuid
    application_size = addon.current_version.all_files[0].size
    issued_at = calendar.timegm(time.gmtime())
    icons = {}
    for size in amo.ADDON_ICON_SIZES:
        icons[str(size)] = absolutify(addon.get_icon_url(size))
    req = {
        'iss': settings.APP_PURCHASE_KEY,
        'typ': settings.APP_PURCHASE_TYP,
        'aud': settings.APP_PURCHASE_AUD,
        'iat': issued_at,
        'exp': issued_at + 3600,  # expires in 1 hour
        'request': {
            'name':
            unicode(addon.name),
            'description':
            app_description,
            'pricePoint':
            addon.premium.price.name,
            'id':
            make_ext_id(addon.pk),
            'postbackURL':
            absolutify(reverse('webpay.postback')),
            'chargebackURL':
            absolutify(reverse('webpay.chargeback')),
            'productData':
            urlencode({
                'contrib_uuid': uuid_,
                'seller_uuid': seller_uuid,
                'addon_id': addon.pk,
                'application_size': application_size
            }),
            'icons':
            icons,
        }
    }

    jwt_ = sign_webpay_jwt(req)
    log.debug('Preparing webpay JWT for addon %s: %s' % (addon, jwt_))
    app_pay_cef.log(request,
                    'Preparing JWT',
                    'preparing_jwt',
                    'Preparing JWT for: %s' % (addon.pk),
                    severity=3)

    if request.API:
        url = reverse('api_dispatch_detail',
                      kwargs={
                          'resource_name': 'status',
                          'api_name': 'webpay',
                          'uuid': uuid_
                      })
    else:
        url = reverse('webpay.pay_status', args=[addon.app_slug, uuid_])
    return {'webpayJWT': jwt_, 'contribStatusURL': url}
Example #33
0
 def test_super_review_email(self):
     self.setup_data(amo.STATUS_NULL)
     self.helper.handler.process_super_review()
     url = reverse('editors.review', args=[self.addon.pk], add_prefix=False)
     assert url in mail.outbox[1].body
Example #34
0
 def test_activate_app_locale(self):
     with self.activate(locale='de', app='thunderbird'):
         eq_(urlresolvers.reverse('home'), '/de/thunderbird/')
     eq_(urlresolvers.reverse('home'), '/en-US/firefox/')
Example #35
0
 def test_activate_app(self):
     with self.activate(app='mobile'):
         eq_(urlresolvers.reverse('home'), '/en-US/mobile/')
     eq_(urlresolvers.reverse('home'), '/en-US/firefox/')
Example #36
0
 def test_activate_locale(self):
     with self.activate(locale='fr'):
         eq_(urlresolvers.reverse('home'), '/fr/firefox/')
     eq_(urlresolvers.reverse('home'), '/en-US/firefox/')
Example #37
0
 def test_bad_collection(self):
     r = self.client.post(reverse('collections.ajax_add'), {'id': 'adfa'})
     eq_(r.status_code, 400)
Example #38
0
 def test_login_required(self):
     self.client.logout()
     r = self.client.post(self.add)
     eq_(r.status_code, 302)
     self.assert_(reverse('users.login') in r['Location'], r['Location'])
Example #39
0
 def test_edit_addons_get(self):
     self.create_collection()
     url = reverse('collections.edit_addons', args=['admin', self.slug])
     r = self.client.get(url, follow=True)
     eq_(r.status_code, 405)
Example #40
0
 def test_no_ajax_response(self):
     r = self.client.post(self.add, {'addon_id': self.addon.id},
                          follow=True)
     self.assertRedirects(
         r, reverse('collections.detail', args=['jbalogh', 'mobile']))
Example #41
0
 def test_login_required(self):
     self.client.logout()
     r = self.client.post(self.up, follow=True)
     url, _ = r.redirect_chain[-1]
     eq_(r.status_code, 200)
     self.assert_(reverse('users.login') in url)
Example #42
0
 def check_redirect(self, request):
     url = '%s?addon_id=%s' % (reverse('collections.ajax_list'),
                               self.addon.id)
     self.assert3xx(request, url)
Example #43
0
    def test_collection_directory_redirects_with_login(self):
        self.client.login(username='******', password='******')

        self.check_response('/collections/favorites/', 301,
                            reverse('collections.following'))
Example #44
0
 def test_breadcrumbs(self):
     r = self.client.get(self.add_url)
     expected = [('Add-ons for Firefox', reverse('home')),
                 ('Collections', reverse('collections.list')),
                 ('Create', None)]
     amo.tests.check_links(expected, pq(r.content)('#breadcrumbs li'))
Example #45
0
 def setUp(self):
     super(TestCollectionDetailFeed, self).setUp()
     self.collection = c = Collection.objects.get(id=57181)
     self.feed_url = reverse('collections.detail.rss',
                             args=[c.author.username, c.slug])
Example #46
0
 def test_not_mine(self):
     self.client.logout()
     r = self.client.get(reverse('collections.user', args=['jbalogh']))
     eq_(r.context['page'], 'user')
     assert '#p-mine' not in pq(r.content)('style').text(), (
         "'Collections I've Made' sidebar link shouldn't be highlighted.")
Example #47
0
 def setUp(self):
     super(TestCollectionFeed, self).setUp()
     self.url = reverse('collections.list')
     self.rss_url = reverse('collections.rss')
     self.filter = CollectionFilter
Example #48
0
 def test_collections(self):
     r = self.client.get(reverse('collections.list'))
     eq_(r.status_code, 200)
     self.assertTemplateUsed(r, 'bandwagon/impala/collection_listing.html')
Example #49
0
 def test_ajax_list_no_addon_id(self):
     eq_(self.client.get(reverse('collections.ajax_list')).status_code, 400)
Example #50
0
 def setUp(self):
     super(TestCollectionListing, self).setUp()
     cache.clear()
     self.url = reverse('collections.list')
Example #51
0
def transaction_refund(request, tx_uuid):
    contrib = get_object_or_404(Contribution,
                                uuid=tx_uuid,
                                type=amo.CONTRIB_PURCHASE)
    refund_contribs = contrib.get_refund_contribs()
    refund_contrib = refund_contribs[0] if refund_contribs.exists() else None

    if refund_contrib:
        messages.error(request, _('A refund has already been processed.'))
        return redirect(reverse('lookup.transaction_summary', args=[tx_uuid]))

    form = TransactionRefundForm(request.POST)
    if not form.is_valid():
        return render(
            request, 'lookup/transaction_summary.html',
            dict({
                'uuid': tx_uuid,
                'tx_refund_form': form,
                'tx_form': TransactionSearchForm()
            }.items() + _transaction_summary(tx_uuid).items()))

    data = {
        'uuid': contrib.transaction_id,
        'manual': form.cleaned_data['manual']
    }
    if settings.BANGO_FAKE_REFUNDS:
        data['fake_response_status'] = {
            'responseCode': form.cleaned_data['fake']
        }

    try:
        res = client.api.bango.refund.post(data)
    except (HttpClientError, HttpServerError):
        # Either doing something not supposed to or Solitude had an issue.
        log.exception('Refund error: %s' % tx_uuid)
        messages.error(
            request,
            _('You cannot make a refund request for this transaction.'))
        return redirect(reverse('lookup.transaction_summary', args=[tx_uuid]))

    if res['status'] in [PENDING, COMPLETED]:
        # Create refund Contribution by cloning the payment Contribution.
        refund_contrib = Contribution.objects.get(id=contrib.id)
        refund_contrib.id = None
        refund_contrib.save()
        refund_contrib.update(
            type=amo.CONTRIB_REFUND,
            related=contrib,
            uuid=hashlib.md5(str(uuid.uuid4())).hexdigest(),
            amount=-refund_contrib.amount if refund_contrib.amount else None,
            transaction_id=res['uuid'])

    if res['status'] == PENDING:
        # Create pending Refund.
        refund_contrib.enqueue_refund(
            amo.REFUND_PENDING,
            request.amo_user,
            refund_reason=form.cleaned_data['refund_reason'])
        log.info('Refund pending: %s' % tx_uuid)
        email_buyer_refund_pending(contrib)
        messages.success(request,
                         _('Refund for this transaction now pending.'))
    elif res['status'] == COMPLETED:
        # Create approved Refund.
        refund_contrib.enqueue_refund(
            amo.REFUND_APPROVED,
            request.amo_user,
            refund_reason=form.cleaned_data['refund_reason'])
        log.info('Refund approved: %s' % tx_uuid)
        email_buyer_refund_approved(contrib)
        messages.success(
            request, _('Refund for this transaction successfully approved.'))
    elif res['status'] == FAILED:
        # Bango no like.
        log.error('Refund failed: %s' % tx_uuid)
        messages.error(request,
                       _('Refund request for this transaction failed.'))

    return redirect(reverse('lookup.transaction_summary', args=[tx_uuid]))
Example #52
0
 def test_ajax_list_bad_addon_id(self):
     url = reverse('collections.ajax_list') + '?addon_id=fff'
     eq_(self.client.get(url).status_code, 400)
Example #53
0
 def files_redirect(self, file):
     return reverse('files.redirect', args=[self.file.pk, file])
Example #54
0
def standalone_upload_detail(request, type_, uuid):
    upload = get_object_or_404(FileUpload, uuid=uuid)
    url = reverse('mkt.developers.standalone_upload_detail',
                  args=[type_, uuid])
    return upload_validation_context(request, upload, url=url)
Example #55
0
 def poll_url(self):
     return reverse('files.compare.poll',
                    args=[self.files[0].pk, self.files[1].pk])
Example #56
0
 def files_serve(self, file):
     return reverse('files.serve', args=[self.file.pk, file])
Example #57
0
 def poll_url(self):
     return reverse('files.poll', args=[self.file.pk])
Example #58
0
 def file_url(self, file=None):
     args = [self.files[0].pk, self.files[1].pk]
     if file:
         args.extend(['file', file])
     return reverse('files.compare', args=args)
Example #59
0
    def test_browse_redirect(self):
        ids = self.files[0].id,

        res = self.client.post(self.file_url(), {'left': ids[0]})
        self.assert3xx(res, reverse('files.list', args=ids))
Example #60
0
 def file_url(self, file=None):
     args = [self.file.pk]
     if file:
         args.extend(['file', file])
     return reverse('files.list', args=args)