Skip to content
This repository has been archived by the owner on Mar 15, 2018. It is now read-only.

Commit

Permalink
alter purchases to cope with multiple purchases, add in free and remo…
Browse files Browse the repository at this point in the history
…ve date paid sorting for now (bug 696509)
  • Loading branch information
Andy McKay committed Oct 27, 2011
1 parent ff656a8 commit 8f2403e
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 31 deletions.
17 changes: 10 additions & 7 deletions apps/users/templates/users/purchases.html
Expand Up @@ -15,8 +15,7 @@ <h1>{{ _('My Purchases') }}</h1>
{{ impala_addon_listing_header(url_base, filter.opts, sorting, filter.extras) }}
{% endif %}
<div class="items">
{% for contribution in purchases.object_list %}
{% with addon=contribution.addon %}
{% for addon in addons.object_list %}
<div class="item addon ignore-compatibility">
<div class="info">
<h3>
Expand All @@ -25,13 +24,17 @@ <h3>
</h3>
<p class="desc">{{ addon.description|truncate(250)|nl2br }}</p>
<div class="vitals c">
{% trans date=addon.created, amt=contribution.get_amount_locale(), url=url('users.support', contribution.pk) %}
<div>Purchased {{ date }} for {{ amt }} - <a href="{{ url }}">Request Support</a></div>
{% endtrans %}
</div>
{% for contribution in contributions.get(addon.pk, []) %}
<div class="purchase-byline">
{% trans date=addon.created, amt=contribution.get_amount_locale() %}
Purchased {{ date }} for {{ amt }}
{% endtrans %}
&middot; <a href="{{ url('users.support', contribution.pk) }}">{{ _('Request Support') }}</a>
</div>
{% endfor %}
</div>
</div>
</div>
{% endwith %}
{% else %}
<p>You have no purchases.</p>
{% endfor %}
Expand Down
44 changes: 32 additions & 12 deletions apps/users/tests/test_views.py
Expand Up @@ -31,6 +31,7 @@
from users.models import BlacklistedPassword, UserProfile, UserNotification
import users.notifications as email
from users.utils import EmailResetCode, UnsubscribeCode
from webapps.models import Installed


class UserViewBase(amo.tests.TestCase):
Expand Down Expand Up @@ -879,6 +880,7 @@ def setUp(self):
self.client.login(username='regular@mozilla.com', password='password')
self.user = User.objects.get(email='regular@mozilla.com')

self.addon, self.con = None, None
for x in range(1, 5):
addon = Addon.objects.create(type=amo.ADDON_EXTENSION,
name='t%s' % x)
Expand All @@ -887,9 +889,8 @@ def setUp(self):
type=amo.CONTRIB_PURCHASE)
con.created = datetime.now() - timedelta(days=10 - x)
con.save()

self.con = con
self.addon = addon
if not self.addon and not self.con:
self.addon, self.con = addon, con

def test_in_menu(self):
doc = pq(self.client.get(self.url).content)
Expand All @@ -912,31 +913,30 @@ def test_no_purchases(self):
def test_purchase_list(self):
res = self.client.get(self.url)
eq_(res.status_code, 200)
eq_(len(res.context['purchases'].object_list), 4)
eq_(len(res.context['addons'].object_list), 4)

def get_order(self, order):
res = self.client.get('%s?sort=%s' % (self.url, order))
return [str(c.addon.name) for c in
res.context['purchases'].object_list]
return [str(c.name) for c in
res.context['addons'].object_list]

def test_ordering(self):
eq_(self.get_order('name'), ['t1', 't2', 't3', 't4'])
eq_(self.get_order('price'), ['t1', 't2', 't3', 't4'])
eq_(self.get_order('date'), ['t4', 't3', 't2', 't1'])

def test_price(self):
res = self.client.get(self.url)
assert '$4.00' in pq(res.content)('div.vitals').eq(0).text()
assert '$1.00' in pq(res.content)('div.vitals').eq(0).text()

def test_price_locale(self):
res = self.client.get(self.url.replace('/en-US', '/fr'))
assert u'4,00' in pq(res.content)('div.vitals').eq(0).text()
assert u'1,00' in pq(res.content)('div.vitals').eq(0).text()

def test_receipt(self):
res = self.client.get(reverse('users.purchases.receipt',
args=[self.addon.pk]))
eq_(len(res.context['purchases'].object_list), 1)
eq_(res.context['purchases'].object_list[0].addon.pk, self.addon.pk)
eq_(len(res.context['addons'].object_list), 1)
eq_(res.context['addons'].object_list[0].pk, self.addon.pk)

def test_receipt_404(self):
url = reverse('users.purchases.receipt', args=[545])
Expand Down Expand Up @@ -1057,7 +1057,7 @@ def test_request_mails(self):
email = mail.outbox[0]
eq_(email.to, ['a@a.com'])
eq_(email.from_email, 'regular@mozilla.com')
assert '$4.00' in email.body
assert '$1.00' in email.body

def test_request_fails(self):
self.addon.support_email = 'a@a.com'
Expand All @@ -1066,3 +1066,23 @@ def test_request_fails(self):
self.client.post(self.get_url('request'), {'remove': 1})
res = self.client.post(self.get_url('reason'), {})
eq_(res.status_code, 200)

def test_free_shows_up(self):
Contribution.objects.all().delete()
res = self.client.get(self.url)
eq_(res.context['addons'][0].pk, self.addon.pk)

def test_others_free_dont(self):
Contribution.objects.all().delete()
other = UserProfile.objects.get(pk=10482)
Installed.objects.all()[0].update(user=other)
res = self.client.get(self.url)
eq_(len(res.context['addons']), 3)

def test_purchase_multiple(self):
Contribution.objects.create(user=self.user.get_profile(),
addon=self.addon, amount='1.00',
type=amo.CONTRIB_PURCHASE)
res = self.client.get(self.url)
addon_vitals = pq(res.content)('div.vitals').eq(0)
eq_(len(addon_vitals('div.purchase-byline')), 2)
39 changes: 27 additions & 12 deletions apps/users/views.py
Expand Up @@ -569,19 +569,16 @@ def unsubscribe(request, hash=None, token=None, perm_setting=None):
{'unsubscribed': unsubscribed, 'perm_settings': perm_settings})


class ContributionsFilter(BaseFilter):
opts = (('date', _lazy(u'Purchase Date')),
('price', _lazy(u'Price')),
class AddonsFilter(BaseFilter):
opts = (('price', _lazy(u'Price')),
('name', _lazy(u'Name')))

def filter(self, field):
qs = self.base_queryset
if field == 'date':
return qs.order_by('-created')
elif field == 'price':
return qs.order_by('amount')
if field == 'price':
return qs.order_by('addonpremium__price')
elif field == 'name':
return qs.order_by('addon__name')
return qs.order_by('name')


@login_required
Expand All @@ -590,21 +587,39 @@ def purchases(request, addon_id=None):
if not waffle.switch_is_active('marketplace'):
raise http.Http404

# First get all the contributions.
# TODO(ashort): this is where we'll need to get cunning about refunds.
cs = Contribution.objects.filter(user=request.amo_user,
type=amo.CONTRIB_PURCHASE)
if addon_id:
cs = cs.filter(addon=addon_id)

filter = ContributionsFilter(request, cs, key='sort', default='date')
purchases = amo.utils.paginate(request, filter.qs)
contributions = {}
for c in cs:
contributions.setdefault(c.addon_id, []).append(c)

if addon_id and not purchases.object_list:
# If you are asking for a receipt for just one item, only show that.
# Otherwise, we'll show all addons that have a contribution or are free.
if addon_id:
ids = [addon_id]
else:
free = (request.amo_user.installed_set
.exclude(addon__in=contributions.keys())
.values_list('addon_id', flat=True))
ids = contributions.keys() + list(free)

filter = AddonsFilter(request, Addon.objects.filter(id__in=ids),
key='sort', default='name')

if addon_id and not filter.qs:
# User has requested a receipt for an addon they don't have.
raise http.Http404

return jingo.render(request, 'users/purchases.html',
{'purchases': purchases, 'filter': filter,
{'addons': amo.utils.paginate(request, filter.qs),
'filter': filter,
'url_base': reverse('users.purchases'),
'contributions': contributions,
'single': bool(addon_id)})


Expand Down
3 changes: 3 additions & 0 deletions media/css/impala/listing.less
Expand Up @@ -246,6 +246,9 @@
color: @note-gray;
content: '\00B7';
}
&.purchase-byline {
display: block;
}
}
span.price {
color: @green;
Expand Down

0 comments on commit 8f2403e

Please sign in to comment.