internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: saleor/saleor

Issue:
Error when adding an attribute
Hi,

I installed a fresh version of Saleor and then tried to add a new attribute. But it failed with the following error:

Exception Type: RelatedObjectDoesNotExist at /dashboard/products/attributes/add/
Exception Value: AttributeChoiceValue has no attribute.

I can provide more detailed log if needed.

Thanks


Discussion:

Resolving patch:
diff --git a/saleor/dashboard/product/forms.py b/saleor/dashboard/product/forms.py
--- a/saleor/dashboard/product/forms.py
+++ b/saleor/dashboard/product/forms.py
@@ -274,16 +274,6 @@ class Meta:
         model = AttributeChoiceValue
         exclude = ('slug', )
 
-    def clean_display(self):
-        display = self.cleaned_data['display']
-        if (not self.instance.pk and
-                self.instance.attribute.values.filter(slug=slugify(display))):
-            raise forms.ValidationError(
-                pgettext_lazy(
-                    'Attribute choice value form error',
-                    'Name already exists'))
-        return display
-
     def save(self, commit=True):
         self.instance.slug = slugify(self.instance.display)
         return super(AttributeChoiceValueForm, self).save(commit=commit)
diff --git a/saleor/product/migrations/0032_auto_20170216_0438.py b/saleor/product/migrations/0032_auto_20170216_0438.py
new file mode 100644
--- /dev/null
+++ b/saleor/product/migrations/0032_auto_20170216_0438.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-02-16 10:38
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('product', '0031_auto_20170206_0601'),
+    ]
+
+    operations = [
+        migrations.AlterUniqueTogether(
+            name='attributechoicevalue',
+            unique_together=set([('display', 'attribute')]),
+        ),
+    ]
diff --git a/saleor/product/models/base.py b/saleor/product/models/base.py
--- a/saleor/product/models/base.py
+++ b/saleor/product/models/base.py
@@ -408,6 +408,7 @@ class AttributeChoiceValue(models.Model):
     attribute = models.ForeignKey(ProductAttribute, related_name='values')
 
     class Meta:
+        unique_together = ('display', 'attribute')
         verbose_name = pgettext_lazy(
             'Attribute choice value model',
             'attribute choices value')


Test patch:
Repository: saleor/saleor

Issue:
Missing translations list
Dashboard:
- [x] order details refund modal - amount label
- [x] order details add note modal - content label
- [ ] date format in datepicker



Discussion:

Resolving patch:
diff --git a/saleor/dashboard/order/forms.py b/saleor/dashboard/order/forms.py
--- a/saleor/dashboard/order/forms.py
+++ b/saleor/dashboard/order/forms.py
@@ -31,8 +31,10 @@ def __init__(self, *args, **kwargs):
 
 
 class ManagePaymentForm(forms.Form):
-    amount = PriceField(max_digits=12, decimal_places=2,
-                        currency=settings.DEFAULT_CURRENCY)
+    amount = PriceField(
+        label=pgettext_lazy(
+            'Payment management form (capture, refund, release)', 'Amount'),
+        max_digits=12, decimal_places=2, currency=settings.DEFAULT_CURRENCY)
 
     def __init__(self, *args, **kwargs):
         self.payment = kwargs.pop('payment')
diff --git a/saleor/order/models.py b/saleor/order/models.py
--- a/saleor/order/models.py
+++ b/saleor/order/models.py
@@ -474,7 +474,9 @@ class OrderNote(models.Model):
     user = models.ForeignKey(settings.AUTH_USER_MODEL)
     date = models.DateTimeField(auto_now_add=True)
     order = models.ForeignKey(Order, related_name='notes')
-    content = models.CharField(max_length=250)
+    content = models.CharField(
+        pgettext_lazy('Order note model', 'content'),
+        max_length=250)
 
     class Meta:
         verbose_name = pgettext_lazy('Order note model', 'Order note')


Test patch:
Repository: saleor/saleor

Issue:
Inline SVG graphics instead of pulling them from static files
We should do this both for performance reasons and for the ease of styling them with CSS (for example `fill: currentColor`).

This involves changes to both HTML and React code.


Discussion:
Also it will reduce problems with hardcoded SVG paths in React components.
React part is solved already.

Resolving patch:
diff --git a/saleor/settings.py b/saleor/settings.py
--- a/saleor/settings.py
+++ b/saleor/settings.py
@@ -74,7 +74,8 @@
 STATIC_URL = '/static/'
 STATICFILES_DIRS = [
     ('assets', os.path.join(PROJECT_ROOT, 'saleor', 'static', 'assets')),
-    ('images', os.path.join(PROJECT_ROOT, 'saleor', 'static', 'images'))
+    ('images', os.path.join(PROJECT_ROOT, 'saleor', 'static', 'images')),
+    ('dashboard', os.path.join(PROJECT_ROOT, 'saleor', 'static', 'dashboard'))
 ]
 STATICFILES_FINDERS = [
     'django.contrib.staticfiles.finders.FileSystemFinder',


Test patch:
Repository: saleor/saleor

Issue:
Upgrade frontend dependencies
`yarn outdated` shows that a lot of our frontend dependencies are outdated. We should try to upgrade them to the latest versions and make sure that everything works correctly.


Discussion:

Resolving patch:
diff --git a/saleor/graphql/api.py b/saleor/graphql/api.py
--- a/saleor/graphql/api.py
+++ b/saleor/graphql/api.py
@@ -246,7 +246,7 @@ class Query(graphene.ObjectType):
         pk=graphene.Argument(graphene.Int, required=True))
     node = relay.Node.Field()
     root = graphene.Field(lambda: Query)
-    debug = graphene.Field(DjangoDebug, name='__debug')
+    debug = graphene.Field(DjangoDebug, name='_debug')
 
     def resolve_category(self, args, context, info):
         categories = Category.tree.filter(pk=args.get('pk')).get_cached_trees()


Test patch:
Repository: saleor/saleor

Issue:
ProductAttribute's method get_formfield_name should have allow_unicode set to True by default
`ProductAttribute `method `get_formfield_name `should have `allow_unicode`set to True by default
Currently `allow_unicode` is set to False and it leads to subtle issues, where `get_formfield_name`
will return wrong name e.g. `attribute-` and completele omit unicode part
and that gives 500 on poping from form dict in 

/saleor/dashboard/product/forms.py:136


Discussion:

Resolving patch:
diff --git a/saleor/product/models.py b/saleor/product/models.py
--- a/saleor/product/models.py
+++ b/saleor/product/models.py
@@ -377,7 +377,7 @@ def __str__(self):
         return self.name
 
     def get_formfield_name(self):
-        return slugify('attribute-%s' % self.slug)
+        return slugify('attribute-%s' % self.slug, allow_unicode=True)
 
     def has_values(self):
         return self.values.exists()


Test patch:
diff --git a/tests/dashboard/test_product.py b/tests/dashboard/test_product.py
--- a/tests/dashboard/test_product.py
+++ b/tests/dashboard/test_product.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
 import pytest
@@ -130,9 +131,15 @@ def test_change_attributes_in_product_form(db, product_in_stock,
             'description': 'description',
             'attribute-author': new_author,
             'attribute-color': new_color}
-
     form = ProductForm(data, instance=product)
     assert form.is_valid()
     product = form.save()
     assert product.get_attribute(color_attribute.pk) == smart_text(new_color)
     assert product.get_attribute(text_attribute.pk) == new_author
+
+
+def test_get_formfield_name_with_unicode_characters(db):
+    text_attribute = ProductAttribute.objects.create(slug=u'ąęαβδηθλμπ',
+                                                     name=u'ąęαβδηθλμπ')
+    assert text_attribute.get_formfield_name() == 'attribute-ąęαβδηθλμπ'
+
Repository: saleor/saleor

Issue:
update_index not working with Elasticsearch 5.4
When running `python manage.py update_index` the following errors occurs:
```
elasticsearch.exceptions.RequestError: TransportError(400, 'No handler found for uri [//storefront__userprofile_user] and method [DELETE]')
```


Discussion:
I had the same issue. To fix it, I removed the '/' at the end of the ELASTICSEARCH_URL in docker-compose.yml.

Resolving patch:
diff --git a/saleor/search/backends/dashboard.py b/saleor/search/backends/dashboard.py
--- a/saleor/search/backends/dashboard.py
+++ b/saleor/search/backends/dashboard.py
@@ -94,7 +94,7 @@ def _do_search(self):
         scores = {}
         for hit in hits['hits']['hits']:
             hit_type = hit['_type']
-            hit_pk = hit['fields']['pk'][0]
+            hit_pk = hit['_source']['pk']
             search_hits[hit_type].append(hit_pk)
             scores[hit['_id']] = hit['_score']
 


Test patch:
Repository: saleor/saleor

Issue:
Integrate Celery
Almost every project needs a task queue and Saleor should come with one by default. Celery is one of the most popular task queues for Python and it's also easy to integrate and use. Things that should be run in task queue by default include:
- sending emails
- generating feed files (Google Merchant feed)


Discussion:
Thumbnails generation should be delegated as well. What tool for that we are using right now @elwoodxblues ?
`versatileimagefield` generates thumbnails when they are first accessed, there is no pre-generation right now if I'm correct.

Resolving patch:
diff --git a/saleor/__init__.py b/saleor/__init__.py
--- a/saleor/__init__.py
+++ b/saleor/__init__.py
@@ -1 +1,5 @@
+from __future__ import absolute_import, unicode_literals
+from .celeryconf import app as celery_app
+
+__all__ = ['celery_app']
 __version__ = 'dev'
diff --git a/saleor/celeryconf.py b/saleor/celeryconf.py
new file mode 100644
--- /dev/null
+++ b/saleor/celeryconf.py
@@ -0,0 +1,14 @@
+from __future__ import unicode_literals
+
+import os
+from celery import Celery
+from django.conf import settings
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'saleor.settings')
+
+app = Celery('saleor')
+
+CELERY_TIMEZONE = 'UTC'
+
+app.config_from_object('django.conf:settings', namespace='CELERY')
+app.autodiscover_tasks()
diff --git a/saleor/settings.py b/saleor/settings.py
--- a/saleor/settings.py
+++ b/saleor/settings.py
@@ -180,6 +180,7 @@
     'social_django',
     'django_countries',
     'django_filters',
+    'django_celery_results',
 ]
 
 LOGGING = {
@@ -402,3 +403,11 @@ def get_host():
 SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
 SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
     'fields': 'id, email'}
+
+# CELERY SETTINGS
+CELERY_BROKER_URL = os.environ.get('REDIS_BROKER_URL') or ''
+CELERY_TASK_ALWAYS_EAGER = False if CELERY_BROKER_URL else True
+CELERY_ACCEPT_CONTENT = ['json']
+CELERY_TASK_SERIALIZER = 'json'
+CELERY_RESULT_SERIALIZER = 'json'
+CELERY_RESULT_BACKEND = 'django-db'


Test patch:
diff --git a/tests/test_asynchronous_tasks.py b/tests/test_asynchronous_tasks.py
new file mode 100644
--- /dev/null
+++ b/tests/test_asynchronous_tasks.py
@@ -0,0 +1,14 @@
+from __future__ import unicode_literals
+
+import celery
+import pytest
+
+
+@celery.shared_task
+def dummy_task(x):
+    return x+1
+
+
+@pytest.mark.integration
+def test_task_running_asynchronously_on_worker(celery_worker):
+    assert dummy_task.delay(42).get(timeout=10) == 43
Repository: saleor/saleor

Issue:
FieldError while using ElasticSearch search
On fresh installation, when trying to use search from the main page:
```
Request Method: | GET
-- | --
http://localhost:8000/search/?q=das
1.11.5
FieldError
Cannot filter search results with field "is_published". Please add index.FilterField('is_published') to Product.search_fields.
/app/saleor/search/backends/base.py in _process_filter, line 53
/usr/local/bin/python
3.5.4
['/app',  '/usr/local/lib/python35.zip',  '/usr/local/lib/python3.5',  '/usr/local/lib/python3.5/plat-linux',  '/usr/local/lib/python3.5/lib-dynload',  '/usr/local/lib/python3.5/site-packages']
Fri, 6 Oct 2017 05:02:58 -0500
```
Confirmed on 3 separate machines, running from the docker


Discussion:

Resolving patch:
diff --git a/saleor/product/models.py b/saleor/product/models.py
--- a/saleor/product/models.py
+++ b/saleor/product/models.py
@@ -146,7 +146,8 @@ class Product(models.Model, ItemRange, index.Indexed):
     search_fields = [
         index.SearchField('name', partial_match=True),
         index.SearchField('description'),
-        index.FilterField('available_on')]
+        index.FilterField('available_on'),
+        index.FilterField('is_published')]
 
     class Meta:
         app_label = 'product'
diff --git a/saleor/search/backends/elasticsearch.py b/saleor/search/backends/elasticsearch.py
--- a/saleor/search/backends/elasticsearch.py
+++ b/saleor/search/backends/elasticsearch.py
@@ -220,10 +220,14 @@ def _process_lookup(self, field, lookup, value):
         if lookup == 'exact':
             if value is None:
                 return {
-                    'missing': {
-                        'field': column_name,
+                    'bool': {
+                        'must_not': {
+                            'term': {
+                                'field': column_name
+                                }
+                            }
+                        }
                     }
-                }
             else:
                 return {
                     'term': {
@@ -234,10 +238,14 @@ def _process_lookup(self, field, lookup, value):
         if lookup == 'isnull':
             if value:
                 return {
-                    'missing': {
-                        'field': column_name,
+                    'bool': {
+                        'must_not': {
+                            'term': {
+                                'field': column_name
+                                }
+                            }
+                        }
                     }
-                }
             else:
                 return {
                     'exists': {


Test patch:
Repository: saleor/saleor

Issue:
Superuser can change his status
In `StaffForm`:
https://github.com/mirumee/saleor/blob/master/saleor/dashboard/staff/forms.py#L12-L13
Widget is disabled `self.fields['is_staff'].widget.attrs['disabled'] = True` 
But it won't prevent you from changing values on POST.
We should disable field instead, like `self.fields['is_active'].disabled = True` 
Test covering this would be nice as well.



Discussion:

Resolving patch:
diff --git a/saleor/dashboard/staff/forms.py b/saleor/dashboard/staff/forms.py
--- a/saleor/dashboard/staff/forms.py
+++ b/saleor/dashboard/staff/forms.py
@@ -9,8 +9,8 @@ def __init__(self, *args, **kwargs):
         kwargs.update(initial={'is_staff': True})
         super(StaffForm, self).__init__(*args, **kwargs)
         if self.user == self.instance:
-            self.fields['is_staff'].widget.attrs['disabled'] = True
-            self.fields['is_active'].widget.attrs['disabled'] = True
+            self.fields['is_staff'].disabled = True
+            self.fields['is_active'].disabled = True
 
     class Meta:
         model = User


Test patch:
diff --git a/tests/dashboard/test_staff.py b/tests/dashboard/test_staff.py
--- a/tests/dashboard/test_staff.py
+++ b/tests/dashboard/test_staff.py
@@ -37,6 +37,20 @@ def test_staff_form_create_not_valid(admin_client, staff_user):
     assert staff_user.groups.count() == 0
 
 
+def test_admin_cant_change_his_permissions(admin_client, admin_user):
+    assert admin_user.is_active
+    assert admin_user.is_staff
+
+    url = reverse('dashboard:staff-details', kwargs={'pk': admin_user.pk})
+    data = {'is_active': False, 'is_staff': False}
+    response = admin_client.post(url, data)
+    admin_user = User.objects.get(pk=admin_user.pk)
+
+    assert response.status_code == 200
+    assert admin_user.is_active
+    assert admin_user.is_staff
+
+
 def test_delete_staff(admin_client, staff_user):
     assert User.objects.all().count() == 2
     url = reverse('dashboard:staff-delete', kwargs={'pk': staff_user.pk})
Repository: saleor/saleor

Issue:
BabelDjango upgrade
can BabelDjango be upgraded with [django-babel](https://github.com/python-babel/django-babel)?

I see it's set to >=0.2 in `requirements.in` but the most recent version I see is [0.2.2](https://pypi.python.org/pypi/BabelDjango) from 2008?

Seems like the only things that use BabelDjango are the `LocaleMiddleware`(using the pre-1.10 middleware syntax) and `currencyfmt` in `/cart/views`. Is that right?


Discussion:
Yes, we should very much upgrade both in Saleor and in django-prices.

Resolving patch:
diff --git a/saleor/cart/views.py b/saleor/cart/views.py
--- a/saleor/cart/views.py
+++ b/saleor/cart/views.py
@@ -1,7 +1,7 @@
 """Cart-related views."""
 from __future__ import unicode_literals
 
-from babeldjango.templatetags.babel import currencyfmt
+from django_babel.templatetags.babel import currencyfmt
 from django.core.urlresolvers import reverse
 from django.http import JsonResponse
 from django.shortcuts import get_object_or_404, redirect, render
diff --git a/saleor/settings.py b/saleor/settings.py
--- a/saleor/settings.py
+++ b/saleor/settings.py
@@ -134,7 +134,7 @@ def get_list(text):
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.locale.LocaleMiddleware',
-    'babeldjango.middleware.LocaleMiddleware',
+    'django_babel.middleware.LocaleMiddleware',
     'saleor.core.middleware.DiscountMiddleware',
     'saleor.core.middleware.GoogleAnalytics',
     'saleor.core.middleware.CountryMiddleware',
@@ -175,7 +175,7 @@ def get_list(text):
 
     # External apps
     'versatileimagefield',
-    'babeldjango',
+    'django_babel',
     'bootstrap3',
     'django_prices',
     'django_prices_openexchangerates',


Test patch:
diff --git a/tests/test_cart.py b/tests/test_cart.py
--- a/tests/test_cart.py
+++ b/tests/test_cart.py
@@ -4,12 +4,12 @@
 from uuid import uuid4
 
 import pytest
-from babeldjango.templatetags.babel import currencyfmt
 from django.contrib.auth.models import AnonymousUser
 from django.core import signing
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.urlresolvers import reverse
 from django.http import HttpResponse
+from django_babel.templatetags.babel import currencyfmt
 from mock import MagicMock, Mock
 from prices import Price
 from satchless.item import InsufficientStock
Repository: saleor/saleor

Issue:
Switch to publish/unpublish products uses GET instead of POST
The switch that lives in the product details dashboard does GET requests to change the product state (`product_toggle_is_published` view). We should always use POST for requests that modify the state or trigger actions. 


Discussion:

Resolving patch:
diff --git a/saleor/dashboard/product/views.py b/saleor/dashboard/product/views.py
--- a/saleor/dashboard/product/views.py
+++ b/saleor/dashboard/product/views.py
@@ -178,6 +178,7 @@ def product_detail(request, pk):
     return TemplateResponse(request, 'dashboard/product/detail.html', ctx)
 
 
+@require_POST
 @staff_member_required
 @permission_required('product.edit_product')
 def product_toggle_is_published(request, pk):


Test patch:
Repository: saleor/saleor

Issue:
Set focus on input field when opening "Add note" modal



Discussion:

Resolving patch:
diff --git a/saleor/dashboard/order/forms.py b/saleor/dashboard/order/forms.py
--- a/saleor/dashboard/order/forms.py
+++ b/saleor/dashboard/order/forms.py
@@ -22,10 +22,9 @@ class OrderNoteForm(forms.ModelForm):
     class Meta:
         model = OrderNote
         fields = ['content']
-        widgets = {'content': forms.Textarea({
-            'rows': 5,
-            'placeholder': pgettext_lazy(
-                'Order note form placeholder', 'Note')})}
+        widgets = {
+            'content': forms.Textarea()
+        }
 
     def __init__(self, *args, **kwargs):
         super(OrderNoteForm, self).__init__(*args, **kwargs)


Test patch:
Repository: saleor/saleor

Issue:
Add robots meta tag and "nofollow" link attribute
1. Fragile pages should be not indexed by search engines.
```
<meta name=”robots” content=”nofollow, noindex”>
```
- [x] Add above meta tag to order's confirmation page

2. Pages that brings no to little content value should not be crawled
```
<meta name=”robots” content=”nofollow”>
```
- [x] Add above meta tag to sign in/sign up/cart pages 
3.  Add link attribute
- [x] Links pointing to above pages should have set attribute `rel="nofollow"` 


Discussion:

Resolving patch:
diff --git a/saleor/core/views.py b/saleor/core/views.py
--- a/saleor/core/views.py
+++ b/saleor/core/views.py
@@ -2,7 +2,6 @@
 
 from django.template.response import TemplateResponse
 from django.contrib import messages
-from django.conf import settings
 from django.utils.translation import pgettext_lazy
 from impersonate.views import impersonate as orig_impersonate
 


Test patch:
Repository: saleor/saleor

Issue:
Logging does not redirect to ?next= link
### What I'm trying to achieve

Currently Saleor has an option to redirect user to particular URL after being asked to log in - which isn't working ATM, beacuse user gets redirected to storefront main page.

### Steps to reproduce the problem

1. Go to auth-protected URL (such as `/dashboard`)
2. Log in

### What I expected to happen

To redirect user to requested page.

### What happened instead/how it failed

User gets redirected to `/`


Discussion:

Resolving patch:
diff --git a/saleor/registration/views.py b/saleor/registration/views.py
--- a/saleor/registration/views.py
+++ b/saleor/registration/views.py
@@ -34,16 +34,13 @@ def signup(request):
         form.save()
         password = form.cleaned_data.get('password')
         email = form.cleaned_data.get('email')
-        user = auth.authenticate(request=request, email=email,
-                                 password=password)
+        user = auth.authenticate(
+            request=request, email=email, password=password)
         if user:
             auth.login(request, user)
         messages.success(request, _('User has been created'))
-        redirect_url = request.POST.get('next', '')
-        if redirect_url:
-            return redirect(redirect_url)
-        else:
-            return redirect(settings.LOGIN_REDIRECT_URL)
+        redirect_url = request.POST.get('next', settings.LOGIN_REDIRECT_URL)
+        return redirect(redirect_url)
     ctx = {'form': form}
     return TemplateResponse(request, 'account/signup.html', ctx)
 


Test patch:
diff --git a/tests/test_registration.py b/tests/test_registration.py
--- a/tests/test_registration.py
+++ b/tests/test_registration.py
@@ -58,6 +58,16 @@ def test_login_view_next(client, customer_user):
     assert redirect_location == '/cart/'
 
 
+def test_login_view_redirect(client, customer_user):
+    url = reverse('account_login')
+    data = {
+        'username': 'test@example.com', 'password': 'password',
+        'next': '/cart/'}
+    response = client.post(url, data)
+    redirect_location = get_redirect_location(response)
+    assert redirect_location == '/cart/'
+
+
 def test_logout_view_no_user(client):
     url = reverse('account_logout')
     response = client.get(url)
@@ -102,6 +112,16 @@ def test_signup_view_create_user(client, db):
     assert redirect_location == '/'
 
 
+def test_signup_view_redirect(client, customer_user):
+    url = reverse('account_signup')
+    data = {
+        'email': 'client@example.com', 'password': 'password',
+        'next': '/cart/'}
+    response = client.post(url, data)
+    redirect_location = get_redirect_location(response)
+    assert redirect_location == '/cart/'
+
+
 def test_signup_view_fail(client, db, customer_user):
     url = reverse('account_signup')
     data = {'email': customer_user.email, 'password': 'password'}