Repository: fidals/shopelectro

Issue:
Products rss for Google Merchant
Google Merchant has some semihidden and strange subservice looking like google adwords for the search. It couldn't integrate with an existing gm.yml file, but requires rss. It has no open documentation and/or validator and we have just one from seo guys

[Trello task](https://trello.com/c/39zr3xox/21-9-14k-%D0%B4%D0%B5%D0%BB%D0%B0%D0%B9-%D1%84%D0%B8%D0%B4-%D0%BF%D0%BE-%D0%BC%D0%B5%D1%80%D1%87%D0%B0%D0%BD%D1%82-%D1%86%D0%B5%D0%BD%D1%82%D1%80) contains details


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
@@ -23,13 +23,14 @@
 
 # --- files processing ---
 class File:
-    def __init__(self, path: str, context: dict):
+    def __init__(self, path: str, context: dict, template_path: str):
         self.path = path
         self.context = context
+        self.template_path = template_path
 
     def create(self):
         with open(self.path, 'w', encoding='utf-8') as file:
-            file.write(render_to_string('prices/price.yml', self.context).strip())
+            file.write(render_to_string(self.template_path, self.context).strip())
         logger.info(f'{self.path} generated.')
 
 
@@ -208,9 +209,15 @@ class Command(BaseCommand):
     BASE_DIR = settings.ASSETS_DIR
 
     def handle(self, *args, **options):
-        Files(
-            [File(
+        Files([
+            *[File(
                 path=os.path.join(self.BASE_DIR, filename),
-                context=Context(target).context()
-            ) for target, filename in settings.UTM_PRICE_MAP.items()]
-        ).create()
+                context=Context(target).context(),
+                template_path='prices/price.yml',
+            ) for target, filename in settings.UTM_PRICE_MAP.items()],
+            File(
+                path=os.path.join(self.BASE_DIR, 'gm.rss'),
+                context=Context('GM').context(),
+                template_path='prices/price.rss',
+            )
+        ]).create()


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
@@ -18,6 +18,7 @@
 from django.test import TestCase, override_settings, tag
 
 from shopelectro.exception import UpdateCatalogException
+from shopelectro.management.commands import price
 from shopelectro.management.commands._update_catalog import (
     update_products, update_tags, update_pack,
 )
@@ -269,7 +270,7 @@ def remove(self):
 
 
 @tag('fast')
-class GeneratePrices(TestCase):
+class PricesTest(TestCase):
 
     fixtures = ['dump.json']
     CATEGORY_TO_EXCLUDE = 'Category #1 of #Category #0 of #Category #1'
@@ -288,13 +289,13 @@ class GeneratePrices(TestCase):
     def setUpTestData(cls):
         with cls.ignore_categories, cls.ignore_products:
             call_command('price')
-        super(GeneratePrices, cls).setUpTestData()
+        super().setUpTestData()
         cls.prices = Prices(settings.UTM_PRICE_MAP.keys())
 
     @classmethod
     def tearDownClass(cls):
         cls.prices.remove()
-        super(GeneratePrices, cls).tearDownClass()
+        super().tearDownClass()
 
     def test_prices_exists(self):
         """Price command should generate various price-list files."""
@@ -309,6 +310,20 @@ def test_categories_in_price(self):
         categories_in_price = self.prices['priceru'].categories_node
         self.assertEqual(len(categories_in_price), Category.objects.count())
 
+    # @todo #1004:30m  Organize yml and rss prices testing in the right way.
+    #  Now rss price has no clear class separation, like yml prices have.
+    #  Prices filename is hardcoded.
+    #  Depends from #714.
+    @ignore_categories
+    @ignore_products
+    def test_items_in_price_rss(self):
+        filename = 'gm.rss'
+        file_path = os.path.join(settings.ASSETS_DIR, filename)
+        root_node = ElementTree.parse(file_path)
+        items: list = root_node.getroot().find('channel').findall('item')
+        db_count = len(price.Context('GM').context()['products'])
+        self.assertEqual(len(items), db_count)
+
     def test_categories_in_yandex_price(self):
         categories = self.prices['YM'].categories_node
         self.assertEqual(