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

Issue:
Добавь тег в yml
Во все фиды добавь тег vendor. В тег засунь производителя. Он у нас идет свойством. Если у товара нет производителя - тег не ставь. 
https://yandex.ru/support/partnermarket/elements/vendor-name-model.html



Discussion:

Resolving patch:
diff --git a/shopelectro/management/commands/price.py b/shopelectro/management/commands/price.py
--- a/shopelectro/management/commands/price.py
+++ b/shopelectro/management/commands/price.py
@@ -7,7 +7,7 @@
 from django.template.loader import render_to_string
 from django.urls import reverse
 
-from shopelectro.models import Product, Category
+from shopelectro.models import Product, Category, Tag
 
 
 class PriceFilter:
@@ -75,12 +75,13 @@ def put_utm(product):
             utm_mark_query = '&'.join('{}={}'.format(k, v) for k, v in utm_marks)
             product.utm_url = '{}{}?{}'.format(settings.BASE_URL, url, utm_mark_query)
 
-            product.prepared_params = list(
-                filter(
+            product.prepared_params = [
+                (group, tags[0].name)
+                for (group, tags) in filter(
                     lambda x: x[0].name != 'Производитель',
                     product.get_params()
-                )
-            )
+                ) if tags
+            ]
 
             return product
 
@@ -91,6 +92,10 @@ def put_crumbs(product):  # Ignore PyDocStyleBear
             )
             return product
 
+        def put_brand(product, brands):
+            product.brand = brands.get(product)
+            return product
+
         def filter_categories(utm):
             categories_to_exclude = (
                 Category.objects
@@ -115,11 +120,13 @@ def filter_categories(utm):
 
         def prepare_products(categories_, utm):
             """Filter product list and patch it for rendering."""
+            products = PriceFilter(utm).run(
+                Product.actives.filter_by_categories(categories_)
+            )
+            brands = Tag.objects.get_brands(products)
             return [
-                put_crumbs(put_utm(product))
-                for product in PriceFilter(utm).run(
-                    Product.actives.filter_by_categories(categories_)
-                )
+                put_brand(put_crumbs(put_utm(product)), brands)
+                for product in products
             ]
 
         categories = (


Test patch:
diff --git a/shopelectro/tests/tests_commands.py b/shopelectro/tests/tests_commands.py
--- a/shopelectro/tests/tests_commands.py
+++ b/shopelectro/tests/tests_commands.py
@@ -252,3 +252,13 @@ def test_products_in_yandex_price(self):
             len(products_in_yandex_price),
             Product.objects.filter(page__images__isnull=False).distinct().count()
         )
+
+    def test_brands(self):
+        """Price contains brand data."""
+        for price in settings.UTM_PRICE_MAP.values():
+            offer = self.get_price_offers_node(price).find('offer')
+            product = Product.objects.filter(id=offer.get('id')).first()
+            self.assertEqual(
+                product.get_brand_name(),
+                offer.find(f'vendor').text,
+            )
Repository: fidals/shopelectro

Issue:
Правь шаблон писем
В шаблоне письма, который приходит если оплачивать онлайн, нет строки комментариями. Как в обычном шаблоне. Добавь.


Discussion:

Resolving patch:
diff --git a/shopelectro/views/ecommerce.py b/shopelectro/views/ecommerce.py
--- a/shopelectro/views/ecommerce.py
+++ b/shopelectro/views/ecommerce.py
@@ -1,3 +1,5 @@
+import json
+
 from django.conf import settings
 from django.core import serializers
 from django.http import HttpResponse, JsonResponse
@@ -18,9 +20,13 @@ class OrderPage(ec_views.OrderPage):
     cart = SECart
 
     def get_context_data(self, request, **kwargs):
+        data = super().get_context_data(request, **kwargs)
         return {
-            **super(OrderPage, self).get_context_data(request, **kwargs),
+            **data,
             'page': CustomPage.objects.get(slug='order'),
+            'raw_order_fields': json.dumps({
+                field.html_name: f'#{field.id_for_label}' for field in data['form']
+            }),
         }
 
 
@@ -108,8 +114,7 @@ class YandexOrder(OrderPage):
 
     def post(self, request):
         cart = self.cart(request.session)
-        form = self.order_form(request.POST.dict())
-
+        form = self.order_form(request.POST)
         if not form.is_valid():
             return render(request, self.template, {'cart': cart, 'form': form})
 


Test patch:
Repository: fidals/shopelectro

Issue:
Меняй вместимость H1
Делай допустимый объем символов в H1 страниц категорий 1000 символов. 
Имеется в виду в админке. 


Discussion:

Resolving patch:
diff --git a/shopelectro/admin.py b/shopelectro/admin.py
--- a/shopelectro/admin.py
+++ b/shopelectro/admin.py
@@ -238,10 +238,13 @@ class OrderAdmin(mixins.PermissionsControl):
 
     add = False
     inlines = [PositionInline]
-    list_display = ['id', 'name', 'email', 'phone', 'total_price', 'payment_type', 'paid']
+    list_display = ['id_', 'name', 'email', 'phone', 'total_price', 'payment_type', 'paid']
     search_fields = ['name', 'email', 'phone']
     list_display_links = ['name']
 
+    def id_(self, obj):
+        return obj.fake_order_number
+
 
 se_admin = SEAdminSite(name='se_admin')
 se_admin.register(CustomPage, models.CustomPageAdmin)
diff --git a/shopelectro/migrations/0027_increase_h1_name_size.py b/shopelectro/migrations/0027_increase_h1_name_size.py
new file mode 100644
--- /dev/null
+++ b/shopelectro/migrations/0027_increase_h1_name_size.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2018-09-21 09:16
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('shopelectro', '0026_remove_product_duplications'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='category',
+            name='name',
+            field=models.CharField(db_index=True, max_length=1000, verbose_name='name'),
+        ),
+    ]


Test patch:
Repository: fidals/shopelectro

Issue:
Fix env substitution in docker-compose.yml for docker-rm
https://ci.fidals.com/fidals/shopelectro/938/12


Discussion:

Resolving patch:
diff --git a/shopelectro/management/commands/excel.py b/shopelectro/management/commands/excel.py
--- a/shopelectro/management/commands/excel.py
+++ b/shopelectro/management/commands/excel.py
@@ -1,7 +1,7 @@
 """
 Generate Excel price-list.
 
-Use this excel editor lib: https://openpyxl.readthedocs.io/en/default/
+Use this excel editor lib: https://openpyxl.readthedocs.io/en/stable/
 """
 import datetime
 import os


Test patch:
Repository: fidals/shopelectro

Issue:
Disabled caching mech
created from #603

Seems it's problems with cache. Checked with debug toolbar on prod: we have 0 cache hits now.
So, i'll see on our caching mech


Discussion:
suffered from local django-debug-toolbar.
`http://127.0.0.1:8010/static/debug_toolbar/js/toolbar.js` responded with old file, not new one.
It was about nginx cache
django says, that we should enable cache middleware.
I'll try to do it
https://docs.djangoproject.com/en/1.11/topics/cache/#the-per-site-cache

Resolving patch:
diff --git a/shopelectro/settings/base.py b/shopelectro/settings/base.py
--- a/shopelectro/settings/base.py
+++ b/shopelectro/settings/base.py
@@ -73,7 +73,9 @@
 MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.cache.UpdateCacheMiddleware',
     'django.middleware.common.CommonMiddleware',
+    'django.middleware.cache.FetchFromCacheMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',


Test patch:
Repository: fidals/shopelectro

Issue:
Long serv response
Every page responses with timeout of ~3s.
Sometimes category and product pages return 502 error.

Checked this pages: Main, Category, Product




Discussion:
on local machine with fixtures category page eat responses with ~1.6 sec.
DB queries part takes only 100 ms.

So, we have ~1.5 sec inside app
seems it's about templates. View logic with disabled templates stuff responses in 300-400 ms.

And version `1.5.0` renders category page with 1.5 sec too.

Maybe we had caching enabled, but it disabled now
seems it's problems with cache. Checked with debug toolbar on prod: we have 0 cache hits now.
So, i'll see on our caching mech
blocked by #606 
now release cache mech enabling and test if this issue is resolved
released it. Problem is still there
i'll fully reproduce prods SE structure on local and start debugging
reproduced it on local. Gunicorn worker fails with timeout. I'm debugging it
found thin place in code. It's here:
https://github.com/fidals/refarm-site/blob/master/images/models.py#L36

This two nested cycle eat ~6 sec of cpu time for every request on my local machine (core i7)
appended lru_cache for this problem place. Now releasing it

Resolving patch:
diff --git a/etc/gunicorn.py b/etc/gunicorn.py
--- a/etc/gunicorn.py
+++ b/etc/gunicorn.py
@@ -6,4 +6,5 @@
 worker_class = 'sync'
 max_requests = 300
 max_requests_jitter = 300
+timeout = 120
 errorlog = '-'
diff --git a/shopelectro/models.py b/shopelectro/models.py
--- a/shopelectro/models.py
+++ b/shopelectro/models.py
@@ -223,6 +223,7 @@ class ExcludedModelTPageQuerySet(pages_models.PageQuerySet):
     def exclude_type(self):
         return self.exclude(type=pages_models.Page.MODEL_TYPE)
 
+
 # @todo #rf169:30m Fix model.Manager bad inheritance
 #  Now we have this problem:
 #  ```


Test patch:
Repository: fidals/shopelectro

Issue:
Cache hat catalog menu
It's hard operation to calc this menu. But it's sided on every page

We can do templates caching with this mech:
https://docs.djangoproject.com/en/1.11/topics/cache/#template-fragment-caching


Discussion:

Resolving patch:
diff --git a/shopelectro/views/catalog.py b/shopelectro/views/catalog.py
--- a/shopelectro/views/catalog.py
+++ b/shopelectro/views/catalog.py
@@ -83,8 +83,10 @@ def get_images_context(self):
                 url_kwargs={},
                 request=self.request,
                 page=self.product.page,
-                products=models.Product.objects.all(),
-                product_pages=models.ProductPage.objects.all(),
+                products=models.Product.objects.filter(id=self.product.id),
+                product_pages=models.ProductPage.objects.filter(
+                    shopelectro_product=self.product
+                ),
             )
         )
 


Test patch:
Repository: fidals/shopelectro

Issue:
Правь телефоны на success page
Сейчас при совершении заказа выдает контактный телефон 222222222. 
Вставляй телефон магазина 
![2018-11-06 11 56 59](https://user-images.githubusercontent.com/4608937/48053209-258e0b00-e1bb-11e8-94e3-6b80ff623915.jpg)



Discussion:

Resolving patch:
diff --git a/shopelectro/context_processors.py b/shopelectro/context_processors.py
--- a/shopelectro/context_processors.py
+++ b/shopelectro/context_processors.py
@@ -11,5 +11,5 @@ def shop(request):
     return {
         'shop': settings.SHOP,
         'DEBUG': settings.DEBUG,
-        'BASE_URL': settings.BASE_URL
+        'BASE_URL': settings.BASE_URL,
     }
diff --git a/shopelectro/settings/base.py b/shopelectro/settings/base.py
--- a/shopelectro/settings/base.py
+++ b/shopelectro/settings/base.py
@@ -313,6 +313,7 @@
     'success_url': BASE_URL + '/shop/order-success/',
     'fail_url': BASE_URL + '/',
     'cps_phone': '+78124163200',
+    'cps_formatted_phone': '416-32-00',
     'cps_email': 'info@shopelectro.ru',
     'local_delivery_cost': 300,
     'local_delivery_cost_threshold': 5000,


Test patch:
Repository: fidals/shopelectro

Issue:
Чини шаблон письма
http://prntscr.com/lvr5u4 куда-то делся телефон магазина  8 (812) 416-32-00


Discussion:

Resolving patch:
diff --git a/shopelectro/views/ecommerce.py b/shopelectro/views/ecommerce.py
--- a/shopelectro/views/ecommerce.py
+++ b/shopelectro/views/ecommerce.py
@@ -18,6 +18,10 @@
 class OrderPage(ec_views.OrderPage):
     order_form = OrderForm
     cart = SECart
+    # Django does not provide context_processors for render_to_string function,
+    # which is used to render an order mail. So we have to explicitly pass
+    # a context to it.
+    email_extra_context = {'shop': settings.SHOP}
 
     def get_context_data(self, request, **kwargs):
         data = super().get_context_data(request, **kwargs)
@@ -79,9 +83,9 @@ def one_click_buy(request):
     Accept XHR, save Order to DB, send mail about it
     and return 200 OK.
     """
-    SECart(request.session).clear()
-
     cart = SECart(request.session)
+    cart.clear()
+
     product = get_object_or_404(Product, id=request.POST['product'])
     cart.add(product, int(request.POST['quantity']))
     order = Order(phone=request.POST['phone'])
@@ -91,6 +95,8 @@ def one_click_buy(request):
         subject=settings.EMAIL_SUBJECTS['one_click'],
         order=order,
         to_customer=False,
+        # see se.OrderPage class for a detail about `shop` context.
+        extra_context={'shop': settings.SHOP},
     )
     return HttpResponse('ok')
 
diff --git a/shopelectro/views/service.py b/shopelectro/views/service.py
--- a/shopelectro/views/service.py
+++ b/shopelectro/views/service.py
@@ -77,6 +77,8 @@ def send_mail_to_shop(order):
                 'paid': paid,
                 'profit': profit,
                 'commission': commission,
+                # see se.OrderPage class for a detail about `shop` context.
+                'shop': settings.SHOP,
             })
 
     def send_mail_to_customer(order):
@@ -84,6 +86,8 @@ def send_mail_to_customer(order):
             subject=settings.EMAIL_SUBJECTS['yandex_order'],
             order=order,
             to_shop=False,
+            # see se.OrderPage class for a detail about `shop` context.
+            extra_context={'shop': settings.SHOP},
         )
 
     if not has_correct_md5(request.POST):


Test patch:
diff --git a/shopelectro/tests/tests_selenium.py b/shopelectro/tests/tests_selenium.py
--- a/shopelectro/tests/tests_selenium.py
+++ b/shopelectro/tests/tests_selenium.py
@@ -784,6 +784,9 @@ def test_order_email(self):
         self.assertIn('Наличные', sent_mail_body)
         self.assertIn('+7 (222) 222 22 22', sent_mail_body)
         self.assertIn('test@test.test', sent_mail_body)
+        self.assertIn(f'tel:{settings.SHOP["cps_phone"]}', sent_mail_body)
+        self.assertIn(settings.SHOP['cps_formatted_phone'], sent_mail_body)
+
         for code in clean_codes:
             self.assertInHTML(
                 '<td align="left"'
Repository: fidals/shopelectro

Issue:
Grade to Django 1.11. stb2
Current 1.10 contains minor security issues


Discussion:
Let's bump it to `1.11.17`. This version [should be used](https://docs.djangoproject.com/en/2.1/faq/install/#what-python-version-can-i-use-with-django) for python 3.7

Resolving patch:
diff --git a/shopelectro/settings/base.py b/shopelectro/settings/base.py
--- a/shopelectro/settings/base.py
+++ b/shopelectro/settings/base.py
@@ -11,6 +11,7 @@
 """
 
 import os
+import socket
 from datetime import datetime
 
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
@@ -221,6 +222,9 @@
 }
 
 TEST_RUNNER = 'refarm_test_utils.runners.RefarmTestRunner'
+# address for selenium-based tests
+# host name doesn't resolve at CI, so we have to use host address
+LIVESERVER_HOST = socket.gethostbyname(socket.gethostname())
 
 SITE_CREATED = datetime(2013, 1, 1)
 


Test patch:
diff --git a/shopelectro/tests/helpers.py b/shopelectro/tests/helpers.py
--- a/shopelectro/tests/helpers.py
+++ b/shopelectro/tests/helpers.py
@@ -60,6 +60,7 @@ class SeleniumTestCase(LiveServerTestCase):
     """Common superclass for running selenium-based tests."""
 
     fixtures = ['dump.json']
+    host = settings.LIVESERVER_HOST
 
     @classmethod
     def setUpClass(cls):
@@ -89,7 +90,7 @@ def setUpClass(cls):
     def tearDownClass(cls):
         """Close selenium session."""
         cls.browser.quit()
-        super(SeleniumTestCase, cls).tearDownClass()
+        super().tearDownClass()
 
     @contextmanager
     def screen_fail(self, filename=''):
diff --git a/shopelectro/tests/tests_selenium_mobile.py b/shopelectro/tests/tests_selenium_mobile.py
--- a/shopelectro/tests/tests_selenium_mobile.py
+++ b/shopelectro/tests/tests_selenium_mobile.py
@@ -19,6 +19,7 @@ class MobileSeleniumTestCase(LiveServerTestCase):
     """Common superclass for running selenium-based tests."""
 
     fixtures = ['dump.json']
+    host = settings.LIVESERVER_HOST
 
     @classmethod
     def setUpClass(cls):
Repository: fidals/shopelectro

Issue:
tests_selenium.py:976: Resurrect test `test_cart_page_open`
The puzzle `473-5159ab9c` from #473 has to be resolved:

https://github.com/fidals/shopelectro/blob/f7dc2793dc5c7eddb2e68a68368337d77ba3139e/shopelectro/tests/tests_selenium.py#L976-L976

The puzzle was created by duker33 on 08-Aug-18. 

Estimate: 15 minutes,     

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is _removed_ from the source code. Here is more about [PDD](http://www.yegor256.com/2009/03/04/pdd.html) and [about me](http://www.yegor256.com/2017/04/05/pdd-in-action.html).


Discussion:
@artemiyds2 @duker33 please pay attention to this new issue.
it's not a profitable task for me. But we have to resurrect this important test.
I take it with x2 rate

Resolving patch:
diff --git a/shopelectro/models.py b/shopelectro/models.py
--- a/shopelectro/models.py
+++ b/shopelectro/models.py
@@ -7,7 +7,6 @@
 from django.db import models
 from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
-import mptt
 
 from catalog import models as catalog_models
 from ecommerce import models as ecommerce_models


Test patch:
diff --git a/shopelectro/tests/tests_selenium.py b/shopelectro/tests/tests_selenium.py
--- a/shopelectro/tests/tests_selenium.py
+++ b/shopelectro/tests/tests_selenium.py
@@ -16,7 +16,6 @@
 from selenium.webdriver.support import expected_conditions as EC, ui
 
 from pages.models import FlatPage, CustomPage
-
 from shopelectro.models import Category, Product
 from shopelectro.tests import helpers
 
@@ -57,6 +56,8 @@ def is_cart_empty(browser):
     return browser.find_element_by_class_name('js-cart-is-empty').is_displayed()
 
 
+# @todo #494:15m Rm `wait_page_loading` function in favor of analogous method.
+#  In favor of `helpers.SeleniumTestCase.wait_page_loaded`
 def wait_page_loading(browser):
     ui.WebDriverWait(browser, 60).until(
         EC.visibility_of_element_located(
@@ -1026,8 +1027,6 @@ def test_full_buy_goal(self):
         self.assertTrue('FULL_BUY_SEND' in self.reached_goals)
         self.assertTrue('CMN_BUY_SEND' in self.reached_goals)
 
-    # @todo #473:15m Resurrect test `test_cart_page_open`
-    @unittest.skip
     def test_cart_page_open(self):
         self.buy_product()
         self.prevent_default('click', '.js-go-to-cart')
Repository: fidals/shopelectro

Issue:
Make SiteDriver a context manager
It will provide convenient api to manage selenium resources and properly shout down selenium driver.   


Discussion:

Resolving patch:
diff --git a/shopelectro/celery.py b/shopelectro/celery.py
--- a/shopelectro/celery.py
+++ b/shopelectro/celery.py
@@ -37,7 +37,11 @@
 beat_schedule = {
     'update-catalog': {
         'task': 'shopelectro.tasks.update_catalog',
-        'schedule': timedelta(hours=2),
+        'schedule': timedelta(hours=2).total_seconds(),
+    },
+    'check-purchase': {
+        'task': 'shopelectro.tasks.check_purchase',
+        'schedule': timedelta(days=1).total_seconds(),
     },
 }
 
@@ -48,6 +52,11 @@
         'routing_key': 'utils.command',
         'priority': 30,
     },
+    'shopelectro.tasks.check_purchase': {
+        'queue': 'command',
+        'routing_key': 'utils.command',
+        'priority': 20,
+    },
     'ecommerce.tasks.send_mail': {
         'queue': 'mail',
         'routing_key': 'utils.mail',
diff --git a/shopelectro/selenium/driver.py b/shopelectro/selenium/driver.py
--- a/shopelectro/selenium/driver.py
+++ b/shopelectro/selenium/driver.py
@@ -17,5 +17,11 @@ def __init__(self, *, site_url, **kwargs):
         self.site_url = site_url
         self.wait = WebDriverWait(self, settings.SELENIUM_WAIT_SECONDS)
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, *args, **kwargs):
+        self.quit()
+
     def get(self, url):
         super().get(urljoin(self.site_url, url))
diff --git a/shopelectro/tasks.py b/shopelectro/tasks.py
--- a/shopelectro/tasks.py
+++ b/shopelectro/tasks.py
@@ -63,8 +63,6 @@ def update_catalog():
         collect_static()
     ]
 
-# @todo #690:30m Schedule check_purchase in the celery beat.
-
 
 @app.task(
     bind=True,
@@ -73,18 +71,18 @@ def update_catalog():
 )
 def check_purchase(self):
     try:
-        driver = selenium.SiteDriver(site_url=settings.BASE_URL)
-        category_page = selenium.CategoryPage(driver, CategoryPage.objects.first().slug)
-        category_page.load()
-        category_page.add_to_cart()
-
-        order_page = selenium.OrderPage(driver)
-        order_page.load()
-        order_page.fill_contacts()
-        order_page.make_order()
-
-        success_page = selenium.SuccessPage(driver)
-        assert success_page.is_success()
+        with selenium.SiteDriver(site_url=settings.BASE_URL) as driver:
+            category_page = selenium.CategoryPage(driver, CategoryPage.objects.first().slug)
+            category_page.load()
+            category_page.add_to_cart()
+
+            order_page = selenium.OrderPage(driver)
+            order_page.load()
+            order_page.fill_contacts()
+            order_page.make_order()
+
+            success_page = selenium.SuccessPage(driver)
+            assert success_page.is_success()
     except (WebDriverException, AssertionError) as err:
         if self.request.retries + 1 > self.max_retries:
             # report on the last attempt


Test patch: