Skip to content

Commit

Permalink
Merge branch 'prs/181'
Browse files Browse the repository at this point in the history
  • Loading branch information
codeinthehole committed May 15, 2012
2 parents 48a2da1 + 27a676d commit b28aa3f
Show file tree
Hide file tree
Showing 15 changed files with 629 additions and 11 deletions.
12 changes: 6 additions & 6 deletions oscar/apps/catalogue/reviews/forms.py
Expand Up @@ -5,12 +5,12 @@ class SignedInUserProductReviewForm(forms.ModelForm):
class Meta:
model = get_model('reviews', 'productreview')
fields = ('title', 'score', 'body')


class AnonymousUserProductReviewForm(forms.ModelForm):
name = forms.CharField(required=True)
email = forms.EmailField(required=True)

class Meta:
model = get_model('reviews', 'productreview')
fields = ('title', 'score', 'body', 'name', 'email', 'homepage')
Expand All @@ -19,11 +19,11 @@ class Meta:
class VoteForm(forms.ModelForm):
def clean(self):
user = self.instance.user
review = self.instance.review
review = self.instance.review
if review.user == user:
raise forms.ValidationError("You cannot vote on your own reviews!")
return self.cleaned_data

class Meta:
model = get_model('reviews', 'vote')
exclude = ('review', 'user',)
exclude = ('review', 'user',)
3 changes: 3 additions & 0 deletions oscar/apps/dashboard/app.py
Expand Up @@ -10,6 +10,7 @@
from oscar.apps.dashboard.pages.app import application as pages_app
from oscar.apps.dashboard.offers.app import application as offers_app
from oscar.apps.dashboard.ranges.app import application as ranges_app
from oscar.apps.dashboard.reviews.app import application as reviews_app
from oscar.apps.dashboard import views


Expand All @@ -25,6 +26,7 @@ class DashboardApplication(Application):
pages_app = pages_app
offers_app = offers_app
ranges_app = ranges_app
reviews_app = reviews_app

def get_urls(self):
urlpatterns = patterns('',
Expand All @@ -37,6 +39,7 @@ def get_urls(self):
url(r'^pages/', include(self.pages_app.urls)),
url(r'^offers/', include(self.offers_app.urls)),
url(r'^ranges/', include(self.ranges_app.urls)),
url(r'^reviews/', include(self.reviews_app.urls)),
)
return self.post_process_urls(urlpatterns)

Expand Down
Empty file.
34 changes: 34 additions & 0 deletions oscar/apps/dashboard/reviews/app.py
@@ -0,0 +1,34 @@
from django.conf.urls.defaults import patterns, url
from django.contrib.admin.views.decorators import staff_member_required

from oscar.core.application import Application
from oscar.apps.dashboard.nav import register, Node
from oscar.apps.dashboard.reviews import views

node = Node('Reviews', 'dashboard:reviews-list')
register(node, 80)


class ReviewsApplication(Application):
name = None
list_view = views.ReviewListView
update_view = views.ReviewUpdateView
delete_view = views.ReviewDeleteView

def get_urls(self):
urlpatterns = patterns('',
url(r'^$', self.list_view.as_view(), name='reviews-list'),
url(r'^(?P<pk>\d+)/$', self.update_view.as_view(),
name='reviews-update'
),
url(r'^(?P<pk>\d+)/delete/$', self.delete_view.as_view(),
name='reviews-delete'
),
)
return self.post_process_urls(urlpatterns)

def get_url_decorator(self, url_name):
return staff_member_required


application = ReviewsApplication()
22 changes: 22 additions & 0 deletions oscar/apps/dashboard/reviews/forms.py
@@ -0,0 +1,22 @@
from django import forms
from django.db.models import get_model

ProductReview = get_model('reviews', 'productreview')


class DashboardProductReviewForm(forms.ModelForm):
class Meta:
model = ProductReview
fields = ('title', 'body', 'score', 'status')


class ProductReviewSearchForm(forms.Form):
NO_SELECTION = 4
STATUS_CHOICES = (
(NO_SELECTION, '------------'),
) + ProductReview.STATUS_CHOICES
keyword = forms.CharField(required=False)
status = forms.ChoiceField(required=False, choices=STATUS_CHOICES)
date_from = forms.DateTimeField(required=False)
date_to = forms.DateTimeField(required=False, label='to')
name = forms.CharField(required=False)
Empty file.
141 changes: 141 additions & 0 deletions oscar/apps/dashboard/reviews/tests.py
@@ -0,0 +1,141 @@
from datetime import datetime, timedelta

from django.db.models import get_model
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User

from django_dynamic_fixture import get

from oscar.test import ClientTestCase

ProductReview = get_model('reviews', 'productreview')


class ReviewsDashboardTests(ClientTestCase):
is_staff = True

def test_reviews_dashboard_is_accessible_to_staff(self):
url = reverse('dashboard:reviews-list')
response = self.client.get(url)
self.assertIsOk(response)

def test_bulk_editing_review_status(self):
url = reverse('dashboard:reviews-list')

user1 = get(User)
user2 = get(User)

get(ProductReview, user=user1, status=0)
get(ProductReview, user=user2, status=0)
get(ProductReview, user=user2, status=0)

assert(ProductReview.objects.count() == 3)

post_params = {
'status': 1,
'selected_review': [3, 2],
'action': ['update_selected_review_status'],
}
self.client.post(url, post_params)

self.assertEquals(ProductReview.objects.get(pk=1).status, 0)
self.assertEquals(ProductReview.objects.get(pk=2).status, 1)
self.assertEquals(ProductReview.objects.get(pk=3).status, 1)

def test_filter_reviews_by_name(self):
url = reverse('dashboard:reviews-list')

user1 = get(User, first_name='Peter', last_name='Griffin')
user2 = get(User, first_name='Lois', last_name='Griffin')

get(ProductReview, user=user1, status=0)
get(ProductReview, user=user2, status=0)
get(ProductReview, user=user2, status=0)

response = self.client.get(url, {'name': 'peter'})

self.assertEquals(len(response.context['review_list']), 1)
self.assertEquals(response.context['review_list'][0].user, user1)

response = self.client.get(url, {'name': 'lois griffin'})

self.assertEquals(len(response.context['review_list']), 2)
for review in response.context['review_list']:
self.assertEquals(review.user, user2)

def test_filter_reviews_by_keyword(self):
url = reverse('dashboard:reviews-list')

user1 = get(User)
user2 = get(User)

review1 = get(ProductReview, user=user1, title='Sexy Review')
review2 = get(ProductReview, user=user2, title='Anry Review',
body='argh')
get(ProductReview, user=user2, title='Lovely Thing')

response = self.client.get(url, {'keyword': 'argh'})
self.assertItemsEqual(response.context['review_list'], [review2])

response = self.client.get(url, {'keyword': 'review'})
self.assertItemsEqual(
response.context['review_list'],
[review1, review2]
)

def test_filter_reviews_by_date(self):
url = reverse('dashboard:reviews-list')

user1 = get(User)
user2 = get(User)

now = datetime.now()
review1 = get(ProductReview, user=user1)
review1.date_created = now
review1.save()
review2 = get(ProductReview, user=user2)
review2.date_created = now - timedelta(days=2)
review2.save()
review3 = get(ProductReview, user=user2)
review3.date_created = now - timedelta(days=10)
review3.save()

response = self.client.get(url, {'date_from': now - timedelta(days=5)})
self.assertItemsEqual(
response.context['review_list'],
[review1, review2]
)

response = self.client.get(url, {'date_to': now - timedelta(days=5)})
self.assertItemsEqual(response.context['review_list'], [review3])

response = self.client.get(url, {
'date_from': now - timedelta(days=12),
'date_to': now - timedelta(days=9)
})
self.assertItemsEqual(response.context['review_list'], [review3])

def test_filter_reviews_by_status(self):
url = reverse('dashboard:reviews-list')

user1 = get(User)
user2 = get(User)

review1 = get(ProductReview, user=user1, status=1)
review2 = get(ProductReview, user=user2, status=0)
review3 = get(ProductReview, user=user2, status=2)

response = self.client.get(url, {'status': 0})
self.assertItemsEqual(response.context['review_list'], [review2])

response = self.client.get(url, {'status': 1})
self.assertItemsEqual(response.context['review_list'], [review1])

response = self.client.get(url, {'status': 2})
self.assertItemsEqual(response.context['review_list'], [review3])

response = self.client.get(url, {'status': 3})
self.assertItemsEqual(
response.context['review_list'],
[review1, review2, review3]
)
29 changes: 29 additions & 0 deletions oscar/apps/dashboard/reviews/utils.py
@@ -0,0 +1,29 @@
from oscar.core.loading import get_class, get_classes
OrderReportGenerator = get_class('order.reports', 'OrderReportGenerator')
ProductReportGenerator, UserReportGenerator = get_classes('analytics.reports', ['ProductReportGenerator', 'UserReportGenerator'])
OpenBasketReportGenerator, SubmittedBasketReportGenerator = get_classes(
'basket.reports', ['OpenBasketReportGenerator', 'SubmittedBasketReportGenerator'])
OfferReportGenerator = get_class('offer.reports', 'OfferReportGenerator')
VoucherReportGenerator = get_class('voucher.reports', 'VoucherReportGenerator')


class GeneratorRepository(object):

generators = [OrderReportGenerator,
ProductReportGenerator,
UserReportGenerator,
OpenBasketReportGenerator,
SubmittedBasketReportGenerator,
VoucherReportGenerator,
OfferReportGenerator]

def get_report_generators(self):
return self.generators

def get_generator(self, code):
for generator in self.generators:
if generator.code == code:
return generator
return None


0 comments on commit b28aa3f

Please sign in to comment.