From 6c3b7bd81214788e1c018861c89d072f2142397a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Mon, 27 Sep 2021 14:21:34 +0200
Subject: [PATCH] family: clean app, remove unused models (#56015)

---
 combo/apps/family/README                      |   8 --
 combo/apps/family/__init__.py                 |  31 ----
 combo/apps/family/forms.py                    |  27 ----
 combo/apps/family/migrations/0008_clean.py    |  14 ++
 combo/apps/family/models.py                   |  34 +----
 combo/apps/family/templates/family/infos.html |  66 ---------
 .../family/templates/family/link_form.html    |  27 ----
 .../apps/family/templates/family/person.html  |  36 -----
 .../templates/family/unlink_confirm.html      |  11 --
 combo/apps/family/urls.py                     |  24 ----
 combo/apps/family/utils.py                    |  61 --------
 combo/apps/family/views.py                    |  72 ----------
 tests/settings.py                             |   2 -
 tests/test_manager.py                         |  25 +---
 tests/test_public.py                          | 135 ------------------
 tests/test_search.py                          |   2 +-
 16 files changed, 20 insertions(+), 555 deletions(-)
 delete mode 100644 combo/apps/family/README
 delete mode 100644 combo/apps/family/forms.py
 create mode 100644 combo/apps/family/migrations/0008_clean.py
 delete mode 100644 combo/apps/family/templates/family/infos.html
 delete mode 100644 combo/apps/family/templates/family/link_form.html
 delete mode 100644 combo/apps/family/templates/family/person.html
 delete mode 100644 combo/apps/family/templates/family/unlink_confirm.html
 delete mode 100644 combo/apps/family/urls.py
 delete mode 100644 combo/apps/family/utils.py
 delete mode 100644 combo/apps/family/views.py

diff --git a/combo/apps/family/README b/combo/apps/family/README
deleted file mode 100644
index f21cac1c..00000000
--- a/combo/apps/family/README
+++ /dev/null
@@ -1,8 +0,0 @@
-Combo family cell
-=================
-
-To be visible, this cell needs a 'passerelle' entry in settings.KNOWN_SERVICES
-(see ../wcs/README) and a FAMILY_SERVICE attribute in settings:
-
-  FAMILY_SERVICE = {'root': '/connector/instance/'}
-
diff --git a/combo/apps/family/__init__.py b/combo/apps/family/__init__.py
index ddc7bc3e..e69de29b 100644
--- a/combo/apps/family/__init__.py
+++ b/combo/apps/family/__init__.py
@@ -1,31 +0,0 @@
-# combo - content management system
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-import django.apps
-from django.utils.translation import ugettext_lazy as _
-
-
-class AppConfig(django.apps.AppConfig):
-    name = 'combo.apps.family'
-    verbose_name = _('Family')
-
-    def get_before_urls(self):
-        from . import urls
-
-        return urls.urlpatterns
-
-
-default_app_config = 'combo.apps.family.AppConfig'
diff --git a/combo/apps/family/forms.py b/combo/apps/family/forms.py
deleted file mode 100644
index bc86f197..00000000
--- a/combo/apps/family/forms.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# combo - content management system
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from django import forms
-from django.utils.translation import ugettext_lazy as _
-
-
-class FamilyLinkForm(forms.Form):
-    family_id = forms.CharField(
-        label=_('Family identifier'), widget=forms.TextInput(attrs={'required': 'required'})
-    )
-    family_code = forms.CharField(
-        label=_('Secret code'), widget=forms.PasswordInput(attrs={'required': 'required'})
-    )
diff --git a/combo/apps/family/migrations/0008_clean.py b/combo/apps/family/migrations/0008_clean.py
new file mode 100644
index 00000000..08efa0be
--- /dev/null
+++ b/combo/apps/family/migrations/0008_clean.py
@@ -0,0 +1,14 @@
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('family', '0007_weekly_agenda_user_template'),
+    ]
+
+    operations = [
+        migrations.DeleteModel(
+            name='FamilyInfosCell',
+        ),
+    ]
diff --git a/combo/apps/family/models.py b/combo/apps/family/models.py
index 1abb6ec1..798fcd59 100644
--- a/combo/apps/family/models.py
+++ b/combo/apps/family/models.py
@@ -19,39 +19,7 @@ from django.db import models
 from django.utils.translation import ugettext_lazy as _
 
 from combo.data.library import register_cell_class
-from combo.data.models import CellBase, JsonCellBase
-
-from .utils import get_family, is_family_enabled
-
-
-@register_cell_class
-class FamilyInfosCell(CellBase):
-    default_template_name = 'family/infos.html'
-    user_dependant = True
-
-    class Meta:
-        verbose_name = _('Family Information Cell')
-
-    class Media:
-        js = (
-            'xstatic/jquery-ui.min.js',
-            'js/gadjo.js',
-        )
-
-    @classmethod
-    def is_enabled(cls):
-        return is_family_enabled()
-
-    def get_cell_extra_context(self, context):
-        if context.get('placeholder_search_mode'):
-            return {}
-        user = self.get_concerned_user(context)
-        if not user or user.is_anonymous:
-            return {}
-        response = get_family(user=user, raise_if_not_cached=not (context.get('synchronous')))
-        if response.status_code == 200:
-            return {'family': response.json()}
-        return {'error': _('An error occured while retrieving family details.')}
+from combo.data.models import JsonCellBase
 
 
 @register_cell_class
diff --git a/combo/apps/family/templates/family/infos.html b/combo/apps/family/templates/family/infos.html
deleted file mode 100644
index 596f04c1..00000000
--- a/combo/apps/family/templates/family/infos.html
+++ /dev/null
@@ -1,66 +0,0 @@
-{% load i18n %}
-{% block cell-content %}
-<h2>{% trans "Informations related to your family" %}</h2>
-
-{% trans "Top content for unlinked users" as top_content %}
-{% placeholder "family_unlinked_user" name=top_content render=False %}
-
-<div>
-  {% if not user.is_authenticated %}
-  {% placeholder "family_unlinked_user" %}
-  {% elif error %}
-  <p>{{error}}</p>
-  {% elif not family.data %}
-  {% url 'family-link' as link_url %}
-  {% placeholder "family_unlinked_user" %}
-  <div class="family-link">
-    <a href="{{ link_url }}" rel="popup">{% trans "Link to your family" %}</a>
-  </div>
-  {% else %}
-  <div class="family_unlink">
-    <a href="{% url 'family-unlink' %}" rel="popup">{% trans "Unlink" %}</a>
-  </div>
-  {% with data=family.data %}
-  {% if data.address or data.quotient %}
-  <div class="family-data">
-    {% if data.address %}
-    <div class="address">
-      <h4>{% trans "Address" %}</h4>
-      <p>{{ data.address }}</p>
-    </div>
-    {% endif %}
-    {% if data.quotient %}
-    <p class="family-quotient">
-      <span class="label">{% trans "Family quotient:" %}</span>
-      <span class="value">{{ data.quotient }}</span>
-    </p>
-    {% endif %}
-  </div>
-  {% endif %}
-  <div class="family_members">
-  {% if data.adults %}
-  <div class="family_adults">
-    <h3>{% trans "Adults" %}</h3>
-    {% for adult in data.adults %}
-    <div>
-      {% include 'family/person.html' with person=adult %}
-    </div>
-    {% endfor %}
-  </div>
-  {% endif %}
-
-  {% if data.children %}
-  <div class="family_children">
-    <h3>{% trans "Children" %}</h3>
-    {% for child in data.children %}
-    <div>
-      {% include 'family/person.html' with person=child %}
-    </div>
-    {% endfor %}
-  </div>
-  {% endif %}
-  </div>
-  {% endwith %}
-  {% endif %}
-</div>
-{% endblock %}
diff --git a/combo/apps/family/templates/family/link_form.html b/combo/apps/family/templates/family/link_form.html
deleted file mode 100644
index 0a58eae6..00000000
--- a/combo/apps/family/templates/family/link_form.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% load i18n %}
-<div id="content">
-  <div id="appbar">
-    <h2>{% trans "Link to a family" %}</h2>
-  </div>
-  <form method="post" class="quixote" action='{% url "family-link" %}'>
-    {% csrf_token %}
-    {% if family_link_intro_text %}
-      {{family_link_intro_text|linebreaks}}
-    {% else %}
-      <p>
-      {% blocktrans %}
-      Enter your family credentials below.
-      {% endblocktrans %}
-      </p>
-    {% endif %}
-    {% for field in form %}
-    <div class="widget grid-1-2">
-      <div class="title"><label>{{field.label_tag}}</label></div>
-      <div class="content">{{field}}</div>
-    </div>
-    {% endfor %}
-    <div class="buttons">
-      <button class="submit-button">{% trans "Submit" %}</button>
-    </div>
-  </form>
-</div>
diff --git a/combo/apps/family/templates/family/person.html b/combo/apps/family/templates/family/person.html
deleted file mode 100644
index 82c35605..00000000
--- a/combo/apps/family/templates/family/person.html
+++ /dev/null
@@ -1,36 +0,0 @@
-{% load i18n %}
-<p class="name"><span>{{ person.first_name }} {{ person.last_name }}</span></p>
-{% if person.birthdate %}
-<p class="birthdate">
-  <span class="label">{% trans "Born on" %}</span>
-  <span class="value">{{ person.birthdate }}</span>
-</p>
-{% endif %}
-
-<div class="address">
-  <h4>{% trans "Address" %}</h4>
-  <p>{{ person.address }}</p>
-</div>
-
-{% if person.phone or person.cellphone or person.email %}
-<div class="contact">
-{% if person.phone %}
-  <p class="phone">
-    <span class="label">{% trans "Phone:" %}</span>
-    <span class="value">{{ person.phone }}</span>
-  </p>
-{% endif %}
-{% if person.cellphone %}
-  <p class="cellphone">
-    <span class="label">{% trans "Cellphone:" %}</span>
-    <span class="value">{{ person.cellphone }}</span>
-  </p>
-{% endif %}
-{% if person.email %}
-  <p class="email">
-    <span class="label">{% trans "Email:" %}</span>
-    <span class="value"{{ person.email }}</span>
-  </p>
-{% endif %}
-</div>
-{% endif %}
diff --git a/combo/apps/family/templates/family/unlink_confirm.html b/combo/apps/family/templates/family/unlink_confirm.html
deleted file mode 100644
index 64f0da8f..00000000
--- a/combo/apps/family/templates/family/unlink_confirm.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% load i18n %}
-
-<div id="content">
-<form method="post">
-  {% csrf_token %}
-  {% trans "Unlink your personal account from this family account?" %}
-  <div class="buttons">
-    <button class="delete-button">{% trans 'Unlink' %}</button>
-  </div>
-</form>
-</div>
diff --git a/combo/apps/family/urls.py b/combo/apps/family/urls.py
deleted file mode 100644
index bae6f2d8..00000000
--- a/combo/apps/family/urls.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# combo - content management system
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from django.conf.urls import url
-
-from .views import FamilyLinkView, FamilyUnlinkView
-
-urlpatterns = [
-    url(r'^family/link/?$', FamilyLinkView.as_view(), name='family-link'),
-    url(r'^family/unlink/?$', FamilyUnlinkView.as_view(), name='family-unlink'),
-]
diff --git a/combo/apps/family/utils.py b/combo/apps/family/utils.py
deleted file mode 100644
index 7771bb99..00000000
--- a/combo/apps/family/utils.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# combo - content management system
-# Copyright (C) 2015-2016  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from django.conf import settings
-
-from combo.utils import requests
-
-
-def get_passerelle_service():
-    try:
-        return [x for x in settings.KNOWN_SERVICES['passerelle'].values() if not x.get('secondary')][0]
-    except (AttributeError, IndexError, KeyError):
-        return None
-
-
-def is_family_enabled():
-    return get_passerelle_service() and hasattr(settings, 'FAMILY_SERVICE')
-
-
-def remote_service(endpoint, **kwargs):
-    path = settings.FAMILY_SERVICE.get('root') + endpoint
-    return requests.get(
-        path, remote_service=get_passerelle_service(), headers={'accept': 'application/json'}, **kwargs
-    )
-
-
-def get_family(**kwargs):
-    endpoint = 'family/'
-    return remote_service(endpoint, **kwargs)
-
-
-def link_family(user, family_id, family_code):
-    endpoint = 'family/link/'
-    kwargs = {
-        'user': user,
-        'invalidate_cache': True,
-        'params': {
-            'login': family_id,
-            'password': family_code,
-        },
-    }
-    return remote_service(endpoint, **kwargs)
-
-
-def unlink_family(user):
-    endpoint = 'family/unlink/'
-    kwargs = {'user': user, 'invalidate_cache': True}
-    return remote_service(endpoint, **kwargs)
diff --git a/combo/apps/family/views.py b/combo/apps/family/views.py
deleted file mode 100644
index ad4a69ef..00000000
--- a/combo/apps/family/views.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# combo - content management system
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from django.contrib import messages
-from django.http import HttpResponseRedirect
-from django.utils.translation import ugettext_lazy as _
-from django.views.generic import FormView, TemplateView
-
-from .forms import FamilyLinkForm
-from .utils import link_family, unlink_family
-
-ERROR_MESSAGES = {
-    100: _('Wrong credentials: make sure you typed them correctly.'),
-    101: _('This family account is blocked.'),
-}
-
-
-class FamilyLinkView(FormView):
-    form_class = FamilyLinkForm
-    template_name = 'family/link_form.html'
-
-    def get_success_url(self):
-        if self.request.META.get('HTTP_REFERER'):
-            return self.request.META['HTTP_REFERER']
-        # return to current location if no referer
-        return '.'
-
-    def form_valid(self, form):
-        response = link_family(
-            self.request.user, form.cleaned_data['family_id'], form.cleaned_data['family_code']
-        )
-
-        if not response.ok or response.json().get('err'):
-            error_code = response.json().get('err')
-            error_message = ERROR_MESSAGES.get(
-                error_code, _('Failed to link to family. Please check your credentials and retry later.')
-            )
-            messages.error(self.request, error_message)
-        else:
-            messages.info(self.request, _('Your account was successfully linked.'))
-        return super().form_valid(form)
-
-
-class FamilyUnlinkView(TemplateView):
-    template_name = 'family/unlink_confirm.html'
-
-    def post(self, request, *args, **kwargs):
-        response = unlink_family(request.user)
-
-        if not response.ok or response.json().get('err'):
-            messages.error(request, _('An error occured when unlinking.'))
-        else:
-            messages.info(request, _('Your account was successfully unlinked.'))
-
-        if self.request.META.get('HTTP_REFERER'):
-            return HttpResponseRedirect(self.request.META['HTTP_REFERER'])
-        # fallback to homepage if no referer
-        return HttpResponseRedirect('/')
diff --git a/tests/settings.py b/tests/settings.py
index 4783cabb..5958216b 100644
--- a/tests/settings.py
+++ b/tests/settings.py
@@ -79,8 +79,6 @@ if 'DISABLE_MIGRATIONS' in os.environ:
     MIGRATION_MODULES = DisableMigrations()
 
 
-FAMILY_SERVICE = {'root': '/'}
-
 BOOKING_CALENDAR_CELL_ENABLED = True
 LEGACY_CHART_CELL_ENABLED = True
 
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 6d70e976..51de0581 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -27,7 +27,6 @@ from pyquery import PyQuery
 from webtest import Upload
 
 from combo.apps.assets.models import Asset
-from combo.apps.family.models import FamilyInfosCell
 from combo.apps.maps.models import MapLayer
 from combo.apps.search.models import SearchCell
 from combo.data.forms import LinkCellForm
@@ -878,7 +877,7 @@ def test_site_export_import_json(app, admin_user):
     resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json')
     with CaptureQueriesContext(connection) as ctx:
         resp = resp.form.submit()
-        assert len(ctx.captured_queries) in [307, 308]
+        assert len(ctx.captured_queries) in [302, 303]
     assert Page.objects.count() == 4
     assert PageSnapshot.objects.all().count() == 4
 
@@ -889,7 +888,7 @@ def test_site_export_import_json(app, admin_user):
     resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json')
     with CaptureQueriesContext(connection) as ctx:
         resp = resp.form.submit()
-        assert len(ctx.captured_queries) == 276
+        assert len(ctx.captured_queries) == 272
     assert set(Page.objects.get(slug='one').related_cells['cell_types']) == {'data_textcell', 'data_linkcell'}
     assert Page.objects.count() == 4
     assert LinkCell.objects.count() == 2
@@ -2139,22 +2138,6 @@ def test_page_cell_placeholder(app, admin_user):
     assert re.findall('<h2>(.*)</h2>', resp.text) == ['Page - One', 'Content', 'JSON Prototype / Foobar']
 
 
-def test_page_familycell_placeholder(app, admin_user):
-    page = Page(title='My family', slug='my-family', template_name='standard')
-    page.save()
-    cell = FamilyInfosCell(page=page, placeholder='content', order=0)
-    cell.save()
-
-    app = login(app)
-    resp = app.get('/manage/pages/%s/' % page.id)
-    assert re.findall('data-placeholder-key="(.*)">', resp.text) == ['content', "family_unlinked_user"]
-    assert re.findall('<h2>(.*)</h2>', resp.text) == [
-        'Page - My family',
-        'Content',
-        'Family Information Cell / Top content for unlinked users',
-    ]
-
-
 def test_page_discover_placeholder_with_error_cells(app, admin_user):
     page = Page(title='One', slug='one', template_name='standard')
     page.save()
@@ -2220,7 +2203,7 @@ def test_page_versionning(app, admin_user):
 
     with CaptureQueriesContext(connection) as ctx:
         resp2 = resp.click('view', index=1)
-        assert len(ctx.captured_queries) == 71
+        assert len(ctx.captured_queries) == 70
     assert Page.snapshots.latest('pk').related_cells == {'cell_types': ['data_textcell']}
     assert resp2.text.index('Hello world') < resp2.text.index('Foobar3')
 
@@ -2281,7 +2264,7 @@ def test_page_versionning(app, admin_user):
     resp = resp.click('restore', index=6)
     with CaptureQueriesContext(connection) as ctx:
         resp = resp.form.submit().follow()
-        assert len(ctx.captured_queries) == 146
+        assert len(ctx.captured_queries) == 144
 
     resp2 = resp.click('See online')
     assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3')
diff --git a/tests/test_public.py b/tests/test_public.py
index 72e1ff29..77e9508a 100644
--- a/tests/test_public.py
+++ b/tests/test_public.py
@@ -23,7 +23,6 @@ except ImportError:
 import requests
 
 from combo.apps.assets.models import Asset
-from combo.apps.family.models import FamilyInfosCell
 from combo.data.models import (
     ConfigJsonCell,
     FeedCell,
@@ -833,140 +832,6 @@ def test_post_cell(app):
                 assert resp2.content == b'a,b\n1,2'
 
 
-def test_familyinfos_cell_with_placeholders(app, admin_user):
-    Page.objects.all().delete()
-    page = Page(title='Family', slug='index', template_name='standard')
-    page.save()
-    family_cell = FamilyInfosCell(page=page, placeholder='content', order=0)
-    family_cell.save()
-    TextCell(
-        page=page,
-        placeholder='family_unlinked_user',
-        text='<p>Hello anonymous user</p>',
-        order=0,
-        restricted_to_unlogged=True,
-        public=True,
-    ).save()
-    TextCell(
-        page=page,
-        placeholder='family_unlinked_user',
-        text='<p>You are not linked</p>',
-        order=1,
-        public=False,
-        restricted_to_unlogged=False,
-    ).save()
-
-    with override_settings(FAMILY_SERVICE={'root': '/family/'}):
-        with mock.patch('combo.utils.requests.send') as requests_send:
-            resp = app.get('/')
-            assert "<p>Hello anonymous user</p>" in resp.text
-            assert "<p>You are not linked</p>" not in resp.text
-
-            app = login(app)
-            data = {'err': 0, 'data': None}
-            requests_send.return_value = mock.Mock(
-                json=lambda: data, content=json.dumps(data), status_code=200
-            )
-            # make sure no data are loaded
-            resp = app.get('/')
-            assert resp.html.body.find('div', {'class': 'familyinfoscell'}).text.strip() == 'Loading...'
-            # put data in cache
-            resp = app.get(
-                reverse(
-                    'combo-public-ajax-page-cell',
-                    kwargs={'page_pk': page.pk, 'cell_reference': family_cell.get_reference()},
-                )
-            )
-            resp = app.get('/')
-            assert "<p>Hello anonymous user</p>" not in resp.text
-            assert "<p>You are not linked</p>" in resp.text
-
-
-@mock.patch('combo.utils.requests.get')
-def test_familycell_link(requests_get, app, settings, admin_user):
-    settings.FAMILY_SERVICE = {'root': '/family/'}
-    Page.objects.all().delete()
-    page = Page(title='Family', slug='index', template_name='standard')
-    page.save()
-    family_cell = FamilyInfosCell(page=page, placeholder='content', order=0)
-    family_cell.save()
-    TextCell(
-        page=page,
-        placeholder='family_unlinked_user',
-        text='<p>Hello anonymous user</p>',
-        order=0,
-        restricted_to_unlogged=True,
-        public=True,
-    ).save()
-    TextCell(
-        page=page,
-        placeholder='family_unlinked_user',
-        text='<p>You are not linked</p>',
-        order=1,
-        public=False,
-        restricted_to_unlogged=False,
-    ).save()
-    app = login(app)
-    # when linking fails
-    requests_get.return_value = mock.Mock(ok=False, json=lambda: {'err': 102})
-    resp = app.get('/family/link/')
-    resp.form['family_id'] = '123'
-    resp.form['family_code'] = 'l33t'
-    resp = resp.form.submit().follow()
-    messages = resp.context['messages']
-    assert len(messages._loaded_messages) == 1
-    assert (
-        messages._loaded_messages[0].message
-        == 'Failed to link to family. Please check your credentials and retry later.'
-    )
-    requests_get.return_value = mock.Mock(ok=True, json=lambda: {})
-    resp.form['family_id'] = '123'
-    resp.form['family_code'] = 'l33t'
-    resp = resp.form.submit().follow()
-    messages = resp.context['messages']
-    assert len(messages._loaded_messages) == 2
-    assert messages._loaded_messages[1].message == 'Your account was successfully linked.'
-
-
-@mock.patch('combo.utils.requests.get')
-def test_familycell_unlink(requests_get, app, settings, admin_user):
-    settings.FAMILY_SERVICE = {'root': '/family/'}
-    Page.objects.all().delete()
-    page = Page(title='Family', slug='index', template_name='standard')
-    page.save()
-    family_cell = FamilyInfosCell(page=page, placeholder='content', order=0)
-    family_cell.save()
-    TextCell(
-        page=page,
-        placeholder='family_unlinked_user',
-        text='<p>Hello anonymous user</p>',
-        order=0,
-        restricted_to_unlogged=True,
-        public=True,
-    ).save()
-    TextCell(
-        page=page,
-        placeholder='family_unlinked_user',
-        text='<p>You are not linked</p>',
-        order=1,
-        public=False,
-        restricted_to_unlogged=False,
-    ).save()
-    app = login(app)
-    requests_get.return_value = mock.Mock(ok=False, json=lambda: {'err': 102})
-    resp = app.get('/family/unlink/')
-    resp = resp.form.submit().follow()
-    messages = resp.context['messages']
-    assert len(messages._loaded_messages) == 1
-    assert messages._loaded_messages[0].message == 'An error occured when unlinking.'
-    requests_get.return_value = mock.Mock(ok=True, json=lambda: {})
-    resp = app.get('/family/unlink/')
-    resp = resp.form.submit().follow()
-    messages = resp.context['messages']
-    assert len(messages._loaded_messages) == 2
-    assert messages._loaded_messages[1].message == 'Your account was successfully unlinked.'
-
-
 def test_synchronous_placeholder(app):
     page = Page(title='foo', slug='foo', template_name='standard', order=0)
     page.save()
diff --git a/tests/test_search.py b/tests/test_search.py
index 83ce2685..b8536542 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -1371,7 +1371,7 @@ def test_index_site_num_queries(settings, app):
     assert IndexedCell.objects.count() == 50
     with CaptureQueriesContext(connection) as ctx:
         index_site()
-        assert len(ctx.captured_queries) == 223
+        assert len(ctx.captured_queries) == 222
 
     SearchCell.objects.create(
         page=page, placeholder='content', order=0, _search_services={'data': ['search1']}
-- 
2.33.0

