Repository: fidals/shopelectro

Issue:
tests_js_analytics.py:101-102: Create Goals class for...
The puzzle `808-f72e84e8` from #808 has to be resolved: 

https://github.com/fidals/shopelectro/blob/de1fc9c6b2459293fed2a39bf34c486042146f8e/shopelectro/tests/tests_js_analytics.py#L101-L102

The puzzle was created by Artemiy on 02-Jul-19. 

Estimate: 30 minutes,  role: DEV. 

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.

Resolving patch:
diff --git a/shopelectro/selenium/__init__.py b/shopelectro/selenium/__init__.py
--- a/shopelectro/selenium/__init__.py
+++ b/shopelectro/selenium/__init__.py
@@ -14,3 +14,4 @@
 
 from .driver import SiteDriver
 from .pages import *
+from .analytics_goals import Goals, YandexEcommerceGoals
diff --git a/shopelectro/selenium/analytics_goals.py b/shopelectro/selenium/analytics_goals.py
new file mode 100644
--- /dev/null
+++ b/shopelectro/selenium/analytics_goals.py
@@ -0,0 +1,46 @@
+import abc
+
+from shopelectro.selenium import SiteDriver
+
+# @todo #929:30m Implement GoogleEcommerceGoals and YandexMetrikaGoals and use them in tests.
+
+
+class Goals(abc.ABC):
+    """Front-end reached goals."""
+
+    def __init__(self, driver: SiteDriver):
+        self.driver = driver
+
+    @abc.abstractmethod
+    def fetch(self):
+        raise NotImplementedError
+
+    @abc.abstractmethod
+    def __iter__(self):
+        raise NotImplementedError
+
+    @abc.abstractmethod
+    def __getitem__(self, index: int):
+        raise NotImplementedError
+
+
+class YandexEcommerceGoals(Goals):  # Ignore PyDocStyleBear
+    """
+    Unwrap an excess nesting level common for every goal:
+    [{"ecommerce": ...}] -> ...
+    Structure docs: https://yandex.com/support/metrica/data/e-commerce.html
+    """
+
+    def __init__(self, driver: SiteDriver):
+        super().__init__(driver)
+        self.goals = []
+
+    def fetch(self):
+        self.goals = self.driver.execute_script('return window.dataLayer.results;')
+
+    def __getitem__(self, index: int):
+        return self.goals[index][0]['ecommerce']
+
+    def __iter__(self):
+        for g in self.goals:
+            yield g[0]['ecommerce']
diff --git a/shopelectro/selenium/driver.py b/shopelectro/selenium/driver.py
--- a/shopelectro/selenium/driver.py
+++ b/shopelectro/selenium/driver.py
@@ -26,3 +26,7 @@ def __exit__(self, *args, **kwargs):
 
     def get(self, url):
         super().get(urljoin(self.site_url, url))
+
+    def delete_session(self):
+        self.delete_cookie('sessionid')
+        self.execute_script('localStorage.clear();')


Test patch:
diff --git a/shopelectro/tests/tests_js_analytics.py b/shopelectro/tests/tests_js_analytics.py
--- a/shopelectro/tests/tests_js_analytics.py
+++ b/shopelectro/tests/tests_js_analytics.py
@@ -92,18 +92,13 @@ class YandexEcommerce(Ecommerce):
 
     def tearDown(self):
         # delete the session to clear the cart
-        self.browser.delete_cookie('sessionid')
-        self.browser.execute_script('localStorage.clear();')
+        self.browser.delete_session()
         super().tearDown()
 
-    # @todo #808:30m Create Goals class for tests.
-    #  Remove these utility functions in favor of the class.
-    def get_goals(self):
-        return self.browser.execute_script('return window.dataLayer.results;')
-
-    def get_goal(self, reached, index=0):
-        """Get a goal with the given index and unfold it."""
-        return reached[index][0]['ecommerce']
+    def get_goals(self) -> selenium.Goals:
+        goals = selenium.YandexEcommerceGoals(self.browser)
+        goals.fetch()
+        return goals
 
     def test_purchase(self):
         self.buy()
@@ -113,7 +108,7 @@ def test_purchase(self):
         reached_goals = self.get_goals()
         self.assertTrue(reached_goals)
 
-        reached = self.get_goal(reached_goals)
+        reached = reached_goals[0]
         self.assertIn('purchase', reached)
         self.assertEqual(reached['currencyCode'], 'RUB')
 
@@ -140,7 +135,7 @@ def test_product_detail(self):
         reached_goals = self.get_goals()
         self.assertTrue(reached_goals)
 
-        reached = self.get_goal(reached_goals)
+        reached = reached_goals[0]
         self.assertIn('detail', reached)
         self.assertEqual(reached['currencyCode'], 'RUB')
 
@@ -171,7 +166,7 @@ def test_clear_cart(self):  # Ignore CPDBear
         reached_goals = self.get_goals()
         self.assertTrue(reached_goals)
 
-        reached = self.get_goal(reached_goals, 2)
+        reached = reached_goals[2]
         self.assertIn('remove', reached)
         self.assertEqual(reached['currencyCode'], 'RUB')
 
@@ -200,7 +195,7 @@ def test_remove_from_cart(self):
         reached_goals = self.get_goals()
         self.assertTrue(reached_goals)
 
-        reached = self.get_goal(reached_goals, 2)
+        reached = reached_goals[2]
         self.assertIn('remove', reached)
         self.assertEqual(reached['currencyCode'], 'RUB')
 
@@ -227,7 +222,7 @@ def test_add_from_product_page(self):
         reached_goals = self.get_goals()
         self.assertTrue(reached_goals)
 
-        reached = self.get_goal(reached_goals, 1)  # Ignore CPDBear
+        reached = reached_goals[1]  # Ignore CPDBear
         self.assertIn('add', reached)
         self.assertEqual(reached['currencyCode'], 'RUB')
 
@@ -258,7 +253,7 @@ def test_add_from_category_page(self):
         reached_goals = self.get_goals()
         self.assertTrue(reached_goals)
 
-        reached = self.get_goal(reached_goals)
+        reached = reached_goals[0]
         self.assertIn('add', reached)
         self.assertEqual(reached['currencyCode'], 'RUB')
 
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
@@ -636,10 +636,8 @@ def setUp(self):
         self.wait_page_loading()
 
     def tearDown(self):
-        # Delete only a session cookie to flush a cart.
         # If we will flush all cookies it will probably rise csrf-protection errors.
-        self.browser.delete_cookie('sessionid')
-        self.browser.execute_script('localStorage.clear();')
+        self.browser.delete_session()
 
     def buy_products(self):
         self.browser.get(self.category)