Repository: fidals/shopelectro

Issue:
Добавляй блок на главную 
Дублируем блок "Большой выбор аккумуляторов, батареек и блоков питания" и выводим перед ним:

Заголовок “Новогодние товары: гирлянды, украшения и фейерверки”

1 ссылка:
Название: Новогодние гирлянды <b>от NNN* руб.</b>
https://www.shopelectro.ru/catalog/categories/novogodnie-girliandy-207/
https://www.shopelectro.ru/media/cache/c3/95/c3959207881bad593025f0c816f684ad.png

2 ссылка:
Название: Лазерные проекторы <b>от NNN* руб.</b>
https://www.shopelectro.ru/catalog/categories/novogodnie-lazernye-proektory-209/
https://www.shopelectro.ru/media/cache/94/a1/94a112b12d4f69d1a23d773f7531422a.png

3 ссылка:
Название: Новогодние фейерверки и салюты <b>от NNN* руб.</b>
https://www.shopelectro.ru/catalog/categories/pirotekhnika/
https://www.shopelectro.ru/media/cache/09/8e/098e803979561596242e97a22eb7f8de.png



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
@@ -67,23 +67,31 @@ def get_context_data(self, **kwargs):
             # with it's own logic
             return context_
 
+        tile_products = self.product.get_siblings(
+            offset=settings.PRODUCT_SIBLINGS_COUNT
+        )
+        product_images = self.get_images_context_data(tile_products)['product_images']
+
         return {
             **context_,
             'price_bounds': settings.PRICE_BOUNDS,
             'group_tags_pairs': self.product.get_params(),
-            'product_images': self.get_images_context_data()['product_images'],
-            'tile_products': self.product.get_siblings(offset=settings.PRODUCT_SIBLINGS_COUNT),
+            'product_images': product_images,
+            'tile_products': tile_products,
         }
 
-    def get_images_context_data(self) -> dict:
+    def get_images_context_data(self, products) -> dict:
+        """Return images for given products."""
+        products_to_filter = [self.product, *products]
+        product_ids_to_filter = [p.id for p in products_to_filter]
         return (
             se_context.ProductImages(
                 url_kwargs={},
                 request=self.request,
                 page=self.product.page,
-                products=models.Product.objects.filter(id=self.product.id),
+                products=models.Product.objects.filter(id__in=product_ids_to_filter),
                 product_pages=models.ProductPage.objects.filter(
-                    shopelectro_product=self.product
+                    shopelectro_product__in=products_to_filter
                 ),
             ).get_context_data()
         )
@@ -98,18 +106,19 @@ def render_siblings_on_404(
             page__is_active=False
         ).first()
         if inactive_product:
+            siblings = inactive_product.get_siblings(
+                offset=settings.PRODUCT_SIBLINGS_COUNT
+            )
             self.object = inactive_product
             context_ = self.get_context_data(
                 object=inactive_product,
-                tile_products=inactive_product.get_siblings(
-                    offset=settings.PRODUCT_SIBLINGS_COUNT
-                ),
+                tile_products=siblings,
                 tile_title='Возможно вас заинтересуют похожие товары:',
                 **url_kwargs,
             )
 
             context_['product_images'] = (
-                self.get_images_context_data()['product_images']
+                self.get_images_context_data(siblings)['product_images']
             )
             return render(request, 'catalog/product_404.html', context_, status=404)
 


Test patch:
diff --git a/shopelectro/tests/tests_views.py b/shopelectro/tests/tests_views.py
--- a/shopelectro/tests/tests_views.py
+++ b/shopelectro/tests/tests_views.py
@@ -474,6 +474,17 @@ class ProductPage(TestCase):
     def setUp(self):
         self.product = models.Product.objects.first()
 
+    def get_product_page(self, product: models.Product=None):
+        product = product or self.product
+        return self.client.get(product.url)
+
+    def get_product_soup(self, product: models.Product=None) -> BeautifulSoup:
+        product_page = self.get_product_page(product)
+        return BeautifulSoup(
+            product_page.content.decode('utf-8'),
+            'html.parser'
+        )
+
     def test_orphan_product(self):
         self.product.category = None
         self.product.save()
@@ -483,7 +494,7 @@ def test_orphan_product(self):
 
     def test_related_products(self):
         """404 page of sometimes removed product should contain product's siblings."""
-        response = self.client.get(self.product.url)
+        response = self.get_product_page()
         # 404 page should show 10 siblings. We'll check the last one
         sibling_product = self.product.category.products.all()[9]
         self.assertTrue(
@@ -495,7 +506,7 @@ def test_related_products_on_404(self):
         self.product.page.is_active = False
         self.product.save()  # saves product.page too
 
-        response = self.client.get(self.product.url)
+        response = self.get_product_page()
         # 404 page should show 10 siblings. We'll check the last one
         sibling_product = self.product.category.products.all()[9]
         self.assertEqual(response.status_code, 404)
@@ -503,6 +514,17 @@ def test_related_products_on_404(self):
             sibling_product.name in str(response.content)
         )
 
+    def test_related_product_images(self):
+        """Check previews for product's siblings on product page."""
+        product_soup = self.get_product_soup(product=models.Product.objects.get(id=19))
+        img_path = (
+            product_soup
+            .find_all(class_='stuff-top-item')[-1]
+            .find('img')['src']
+        )
+        # app shows logo image if preview can't generated
+        self.assertNotIn('logo', img_path)
+
 
 class ProductPageSchema(TestCase):