From 49af8ca391bb3d1aa630ab7ee6548c137ce4a884 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Mon, 11 Nov 2019 20:34:10 +0100
Subject: [PATCH] matomo: manage secondary instances (#37576)

---
 hobo/matomo/utils.py       |  24 ++++--
 tests/test_matomo_utils.py | 148 ++++++++++++++++++++++++++++++++++---
 tests/test_matomo_views.py |  10 ++-
 3 files changed, 164 insertions(+), 18 deletions(-)

diff --git a/hobo/matomo/utils.py b/hobo/matomo/utils.py
index b5f208f..332bd5a 100644
--- a/hobo/matomo/utils.py
+++ b/hobo/matomo/utils.py
@@ -89,11 +89,12 @@ def put_tracking_js(tracking_js):
 def get_tenant_name_and_public_urls():
     """get an alias for our matomo's id and urls to monitor"""
     tenant_name = None
-    services = [x for x in Combo.objects.all() if 'portal-user' in x.template_name]
+    services = [x for x in Combo.objects.all()
+                if 'portal-user' in x.template_name and not x.secondary]
     if services != [] and services[0] != '':
         tenant_name = urlparse.urlparse(services[0].base_url).netloc
-    services += [x for x in Wcs.objects.all()]
-    services += [x for x in Fargo.objects.all()]
+    services += [x for x in Wcs.objects.all() if not x.secondary]
+    services += [x for x in Fargo.objects.all() if not x.secondary]
     site_urls = [x.base_url for x in services if x.base_url != '']
     return tenant_name, site_urls
 
@@ -177,9 +178,19 @@ class MatomoWS(object):
             raise MatomoException('get_site_id_from_site_url fails')
         return tag.text
 
-    def add_site(self, site_name, site_urls):
+    def add_site(self, site_name):
         data = {'method': 'SitesManager.addSite',
                 'siteName': site_name}
+        tree = self.call(data)
+        try:
+            tag = tree.xpath('/result')[0]
+        except IndexError:
+            raise MatomoException('add_site fails')
+        return tag.text
+
+    def add_site_alias_urls(self, id_site, site_urls):
+        data = {'method': 'SitesManager.addSiteAliasUrls',
+                'idSite': id_site}
         cpt = 0
         for url in site_urls:
             key = 'urls[%i]' % cpt
@@ -189,7 +200,7 @@ class MatomoWS(object):
         try:
             tag = tree.xpath('/result')[0]
         except IndexError:
-            raise MatomoException('add_site fails')
+            raise MatomoException('add_site_alias_urls fails')
         return tag.text
 
     def add_user(self, user_login, password, initial_id_site):
@@ -246,9 +257,10 @@ def upgrade_site(matomo, tenant_name, site_urls):
         id_site = matomo.get_site_id_from_site_url(tenant_name)
     except MatomoError as exc:
         if str(exc) == 'url not found':
-            id_site = matomo.add_site(tenant_name, site_urls)
+            id_site = matomo.add_site(tenant_name)
         else:
             raise exc
+    matomo.add_site_alias_urls(id_site, site_urls)
     return id_site
 
 def upgrade_user(matomo, user_login, id_site):
diff --git a/tests/test_matomo_utils.py b/tests/test_matomo_utils.py
index b02c002..8411001 100644
--- a/tests/test_matomo_utils.py
+++ b/tests/test_matomo_utils.py
@@ -87,6 +87,16 @@ ADD_SITE_BAD_RESPONSE = """<?xml version="1.0" encoding="utf-8" ?>
 <not_result>no result tag</not_result>
 """
 
+ADD_SITE_ALIAS_URLS_SUCCESS = """<?xml version="1.0" encoding="utf-8" ?>
+<result>1</result>
+"""
+
+ADD_SITE_ALIAS_URLS_ERROR = """<?xml version="1.0" encoding="utf-8" ?>
+<result>
+        <error message="Merci de specifier une valeur pour idSite" />
+</result>
+"""
+
 USER_ALREADY_THERE = """<?xml version="1.0" encoding="utf-8" ?>
 <result>
     <error message="Username 'hobo.dev.publik.love' already exists." />
@@ -220,6 +230,94 @@ def test_get_tenant_name_and_public_urls():
                          'https://wcs.dev.publik.love/',
                          'https://fargo.dev.publik.love/']
 
+def test_get_tenant_name_and_public_urls_on_primary():
+    Hobo.objects.create(base_url='https://hobo.ville1.love',
+                        slug='hobo-ville1')
+    Hobo.objects.create(base_url='https://hobo.ville2.love',
+                        slug='hobo-ville2')
+    Combo.objects.create(base_url='https://combo.agglo.love',
+                         template_name='...portal-user...',
+                         slug='portal')
+    Combo.objects.create(base_url='https://combo.ville1.love',
+                         template_name='...portal-user...',
+                         slug='_hobo-ville1_portal',
+                         secondary=True)
+    Combo.objects.create(base_url='https://combo.ville2.love',
+                         template_name='...portal-user...',
+                         slug='_hobo-ville2_portal',
+                         secondary=True)
+    Combo.objects.create(base_url='https://agent-combo.agglo.love',
+                         template_name='...portal-agent...',
+                         slug='portal-agent')
+    Combo.objects.create(base_url='https://agent-combo.ville1.love',
+                         template_name='...portal-agent...',
+                         slug='_hobo-ville1_portal-agent',
+                         secondary=True)
+    Combo.objects.create(base_url='https://agent-combo.ville2.love',
+                         template_name='...portal-agent...',
+                         slug='_hobo-ville2_portal-agent',
+                         secondary=True)
+    Wcs.objects.create(base_url='https://wcs.agglo.love',
+                       slug='eservices')
+    Wcs.objects.create(base_url='https://wcs.ville1.love',
+                       slug='_hobo-ville1_eservices',
+                       secondary=True)
+    Wcs.objects.create(base_url='https://wcs.ville2.love',
+                       slug='_hobo-ville2_eservices',
+                       secondary=True)
+    Fargo.objects.create(base_url='https://fargo.agglo.love',
+                         slug='porte-doc')
+    Fargo.objects.create(base_url='https://fargo.ville1.love',
+                         slug='_hobo-ville1_porte-doc',
+                         secondary=True)
+    Fargo.objects.create(base_url='https://fargo.ville2.love',
+                         slug='_hobo-ville2_porte-doc',
+                         secondary=True)
+
+    tenant_name, site_urls = get_tenant_name_and_public_urls()
+    assert tenant_name == 'combo.agglo.love'
+    assert site_urls == ['https://combo.agglo.love/',
+                         'https://wcs.agglo.love/',
+                         'https://fargo.agglo.love/']
+
+def test_get_tenant_name_and_public_urls_on_secondary():
+    Hobo.objects.create(base_url='https://hobo.agglo.love',
+                        slug='_interco_hobo')
+    Hobo.objects.create(base_url='https://hobo.ville1.love',
+                        slug='_interco_hobo-ville1')
+    Hobo.objects.create(base_url='https://hobo.ville2.love',
+                        slug='_interco_hobo-ville2')
+    Combo.objects.create(base_url='https://combo.agglo.love',
+                         template_name='...portal-user...',
+                         slug='_interco_portal',
+                         secondary=True)
+    Combo.objects.create(base_url='https://combo.ville2.love',
+                         template_name='...portal-user...',
+                         slug='portal')
+    Combo.objects.create(base_url='https://agent-combo.agglo.love',
+                         template_name='...portal-agent...',
+                         slug='_interco_portal-agent',
+                         secondary=True)
+    Combo.objects.create(base_url='https://agent-combo.ville2.love',
+                         template_name='...portal-agent...',
+                         slug='portal-agent')
+    Wcs.objects.create(base_url='https://wcs.agglo.love',
+                       slug='_interco_eservices',
+                       secondary=True)
+    Wcs.objects.create(base_url='https://wcs.ville2.love',
+                       slug='eservices')
+    Fargo.objects.create(base_url='https://fargo.agglo.love',
+                         slug='_interco_porte-doc',
+                         secondary=True)
+    Fargo.objects.create(base_url='https://fargo.ville2.love',
+                         slug='porte-doc')
+
+    tenant_name, site_urls = get_tenant_name_and_public_urls()
+    assert tenant_name == 'combo.ville2.love'
+    assert site_urls == ['https://combo.ville2.love/',
+                         'https://wcs.ville2.love/',
+                         'https://fargo.ville2.love/']
+
 def test_matomo_constructor():
     """build the matomo webservice object"""
     with override_settings(MATOMO_SERVER=CONFIG):
@@ -352,15 +450,13 @@ def test_get_site_from_site_url(mocked_post):
 def test_add_site(mocked_post):
     """webservice to add a new site"""
     mocked_post.return_value.status_code = 200
-    urls = ['https://combo.dev.publik.love',
-            'https://wcs.dev.publik.love']
     with override_settings(MATOMO_SERVER=CONFIG):
         matomo = MatomoWS()
 
         # success
         content = ADD_SITE_SUCCESS
         mocked_post.return_value.content = content
-        site_id = matomo.add_site("hobo.dev.publik.love", urls)
+        site_id = matomo.add_site("hobo.dev.publik.love")
         assert site_id == '42'
 
         # error
@@ -368,13 +464,41 @@ def test_add_site(mocked_post):
         mocked_post.return_value.content = content
         with pytest.raises(MatomoError,
                            match="Please specify a value for 'siteName'."):
-            site_id = matomo.add_site("hobo.dev.publik.love", urls)
+            site_id = matomo.add_site("hobo.dev.publik.love")
 
         # strange message
         content = ADD_SITE_BAD_RESPONSE
         mocked_post.return_value.content = content
         with pytest.raises(MatomoException, match='add_site fails'):
-            site_id = matomo.add_site("hobo.dev.publik.love", urls)
+            site_id = matomo.add_site("hobo.dev.publik.love")
+
+@mock.patch('requests.post')
+def test_add_site_alias_url(mocked_post):
+    """webservice to add a new site"""
+    mocked_post.return_value.status_code = 200
+    urls = ['https://combo.dev.publik.love',
+            'https://wcs.dev.publik.love']
+    with override_settings(MATOMO_SERVER=CONFIG):
+        matomo = MatomoWS()
+
+        # success
+        content = ADD_SITE_ALIAS_URLS_SUCCESS
+        mocked_post.return_value.content = content
+        site_id = matomo.add_site_alias_urls('42', urls)
+        assert site_id == '1'
+
+        # error
+        content = ADD_SITE_ALIAS_URLS_ERROR
+        mocked_post.return_value.content = content
+        with pytest.raises(MatomoError,
+                           match="Merci de specifier une valeur pour idSite"):
+            site_id = matomo.add_site_alias_urls(None, urls)
+
+        # strange message
+        content = ADD_SITE_BAD_RESPONSE
+        mocked_post.return_value.content = content
+        with pytest.raises(MatomoException, match='add_site_alias_urls fails'):
+            site_id = matomo.add_site_alias_urls('42', urls)
 
 @mock.patch('requests.post')
 def test_add_user(mocked_post):
@@ -525,17 +649,23 @@ def test_upgrade_site(mocked_post):
         matomo = MatomoWS()
 
         # site not already here
-        contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS]
+        contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, ADD_SITE_ALIAS_URLS_SUCCESS]
         mocked_post.side_effect = requests_post_mocked_replies(contents)
         site_id = upgrade_site(matomo, "hobo.dev.publik.love", urls)
         assert site_id == '42'
 
         # site already here
-        contents = [GET_SITE_42_FROM_URL]
+        contents = [GET_SITE_42_FROM_URL, ADD_SITE_ALIAS_URLS_SUCCESS]
         mocked_post.side_effect = requests_post_mocked_replies(contents)
         site_id = upgrade_site(matomo, "hobo.dev.publik.love", urls)
         assert site_id == '42'
 
+        # error while updating urls
+        contents = [GET_SITE_42_FROM_URL, ADD_SITE_ALIAS_URLS_ERROR]
+        mocked_post.side_effect = requests_post_mocked_replies(contents)
+        with pytest.raises(MatomoException):
+            upgrade_site(matomo, "hobo.dev.publik.love", urls)
+
         # error while adding new site
         contents = [GET_NO_SITE_FROM_URL, MATOMO_ERROR]
         mocked_post.side_effect = requests_post_mocked_replies(contents)
@@ -663,7 +793,7 @@ def test_auto_configure_matomo(mocked_post):
     Fargo.objects.create(base_url='https://fargo.dev.publik.love')
 
     with override_settings(MATOMO_SERVER=CONFIG):
-        contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
+        contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, ADD_SITE_ALIAS_URLS_SUCCESS,
                     DEL_UNKNOWN_USER, MATOMO_SUCCESS,
                     JAVASCRIPT_TAG, PING_SUCCESS]
         mocked_post.side_effect = requests_post_mocked_replies(contents)
@@ -696,7 +826,7 @@ def test_auto_configure_matomo_error(mocked_post):
     Fargo.objects.create(base_url='https://fargo.dev.publik.love')
 
     with override_settings(MATOMO_SERVER=CONFIG):
-        contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
+        contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, ADD_SITE_ALIAS_URLS_SUCCESS,
                     DEL_UNKNOWN_USER, MATOMO_SUCCESS,
                     JAVASCRIPT_TAG_BAD_RESPONSE]
         mocked_post.side_effect = requests_post_mocked_replies(contents)
diff --git a/tests/test_matomo_views.py b/tests/test_matomo_views.py
index 04fd6f2..12b5686 100644
--- a/tests/test_matomo_views.py
+++ b/tests/test_matomo_views.py
@@ -28,6 +28,10 @@ ADD_SITE_SUCCESS = """<?xml version="1.0" encoding="utf-8" ?>
 <result>42</result>
 """
 
+ADD_SITE_ALIAS_URLS_SUCCESS = """<?xml version="1.0" encoding="utf-8" ?>
+<result>1</result>
+"""
+
 DEL_UNKNOWN_USER = """<?xml version="1.0" encoding="utf-8" ?>
 <result>
         <error message="User 'hobo.dev.publik.love' doesn't exist." />
@@ -161,7 +165,7 @@ def test_enable_auto(mocked_post, admin_user):
     Wcs.objects.create(base_url='https://wcs.dev.publik.love')
     Fargo.objects.create(base_url='https://fargo.dev.publik.love')
 
-    contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
+    contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, ADD_SITE_ALIAS_URLS_SUCCESS,
                 DEL_UNKNOWN_USER, MATOMO_SUCCESS,
                 JAVASCRIPT_TAG, PING_SUCCESS]
 
@@ -185,7 +189,7 @@ def test_enable_auto_warning(mocked_post, admin_user):
     Wcs.objects.create(base_url='https://wcs.dev.publik.love')
     Fargo.objects.create(base_url='https://fargo.dev.publik.love')
 
-    contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
+    contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, ADD_SITE_ALIAS_URLS_SUCCESS,
                 DEL_UNKNOWN_USER, MATOMO_SUCCESS,
                 JAVASCRIPT_TAG, PING_ERROR]
 
@@ -212,7 +216,7 @@ def test_enable_auto_error(mocked_post, admin_user):
     Wcs.objects.create(base_url='https://wcs.dev.publik.love')
     Fargo.objects.create(base_url='https://fargo.dev.publik.love')
 
-    contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
+    contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, ADD_SITE_ALIAS_URLS_SUCCESS,
                 DEL_UNKNOWN_USER, MATOMO_SUCCESS,
                 JAVASCRIPT_TAG_BAD_RESPONSE]
 
-- 
2.24.0

