From 07add811cbc10223f3f7b68122bf6ef72a3d79d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 7 May 2020 08:47:50 +0200
Subject: [PATCH] tests: remove w.c.s. from test dependencies (#42706)

---
 README            |   6 -
 get_wcs.sh        |   6 -
 tests/test_wcs.py | 675 ++++++++++++++++++++--------------------------
 tox.ini           |   2 -
 4 files changed, 287 insertions(+), 402 deletions(-)
 delete mode 100755 get_wcs.sh

diff --git a/README b/README
index 06ba0ff..86b6978 100644
--- a/README
+++ b/README
@@ -88,12 +88,6 @@ Unit tests are written using py.test, and its pytest-django support library.
 
   DJANGO_SETTINGS_MODULE=combo.settings COMBO_SETTINGS_FILE=tests/settings.py py.test
 
-Tests for w.c.s. cells do require access to the wcsctl script, its location has
-to be given in a WCSCTL environment variable, this give a full command line:
-
-  WCSCTL=$(pwd)/wcs/wcsctl.py \
-  DJANGO_SETTINGS_MODULE=combo.settings COMBO_SETTINGS_FILE=tests/settings.py py.test
-
 
 License
 -------
diff --git a/get_wcs.sh b/get_wcs.sh
deleted file mode 100755
index 47c234b..0000000
--- a/get_wcs.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh -xue
-
-cd $TOX_WORK_DIR
-test -d wcs || git clone http://git.entrouvert.org/wcs.git
-(cd wcs && git pull)
-rm -rf wcs/tests
diff --git a/tests/test_wcs.py b/tests/test_wcs.py
index 9b894f6..a321653 100644
--- a/tests/test_wcs.py
+++ b/tests/test_wcs.py
@@ -2,22 +2,15 @@
 
 import pytest
 
+import copy
 import json
 import re
-import requests
-import subprocess
-import shutil
-import sys
-import tempfile
-import time
-import os
 
 from django.apps import apps
 from django.conf import settings
 from django.core.cache import cache
 from django.urls import reverse
 from django.db import connection
-from django.test import override_settings
 from django.test.client import RequestFactory
 from django.test.utils import CaptureQueriesContext
 from django.utils.six.moves.urllib import parse as urlparse
@@ -27,14 +20,14 @@ import mock
 from combo.data.library import get_cell_classes
 from combo.data.models import CellBase, LinkListCell, Page, ValidityInfo
 from combo.apps.search.engines import engines
-from combo.apps.wcs.models import (WcsFormCell, WcsCurrentFormsCell,
-        WcsFormsOfCategoryCell, WcsCurrentDraftsCell, WcsCategoryCell,
-        TrackingCodeInputCell, BackofficeSubmissionCell, WcsCareFormsCell)
+from combo.apps.wcs.models import (
+    WcsFormCell, WcsCurrentFormsCell,
+    WcsFormsOfCategoryCell, WcsCurrentDraftsCell, WcsCategoryCell,
+    TrackingCodeInputCell, BackofficeSubmissionCell, WcsCareFormsCell)
 
-from combo.apps.search.models import SearchCell, IndexedCell
+from combo.apps.search.models import SearchCell
 from combo.apps.search.utils import index_site, search_site
 from django.contrib.auth.models import AnonymousUser
-from django.test.client import RequestFactory
 
 from combo.utils import NothingInCacheException
 
@@ -42,137 +35,51 @@ from .test_manager import login
 
 pytestmark = pytest.mark.django_db
 
-wcs_present = pytest.mark.skipif('WCS_MANAGE' not in os.environ or not os.path.exists(os.environ['WCS_MANAGE']),
-        reason='WCS_MANAGE not defined in environment')
-
-WCS_MANAGE = os.environ.get('WCS_MANAGE')
-
-WCS_SCRIPTS = {
-        'setup-auth': """
-from quixote import get_publisher
-
-get_publisher().cfg['identification'] = {'methods': ['password']}
-get_publisher().cfg['debug'] = {'display_exceptions': 'text'}
-get_publisher().write_cfg()
-""",
-        'create-user': """
-from quixote import get_publisher
-from qommon.ident.password_accounts import PasswordAccount
-
-user = get_publisher().user_class()
-user.name = 'foo bar'
-user.email = 'foo@example.net'
-user.store()
-account = PasswordAccount(id='user')
-account.set_password('user')
-account.user_id = user.id
-account.store()
-""",
-        'create-data': """
-import datetime
-from quixote import get_publisher
-
-from wcs.categories import Category
-from wcs.formdef import FormDef
-from wcs.roles import Role
-from wcs import fields
-
-cats = []
-for i in range(1, 10):
-   cat = Category()
-   cat.name = 'Test %d' % i
-   cat.description = 'Hello world'
-   cat.store()
-   cats.append(cat)
-
-formdef = FormDef()
-formdef.name = 'form title'
-formdef.category_id = cat.id
-formdef.keywords = 'foo, bar'
-formdef.fields = [
-    fields.StringField(id='1', label='1st field', type='string'),
-    fields.ItemField(id='2', label='2nd field', type='item',
-                     items=['foo', 'bar', 'baz']),
+
+WCS_FORMDEFS_DATA = [
+    {'slug': 'form-title', 'title': 'form title', 'url': '/form-title/', 'keywords': ['foo', 'bar']},
+    {'slug': 'a-second-form-title', 'title': 'a second form title', 'url': '/a-second-form-title/'},
+    {'slug': 'a-private-form', 'title': 'a private form', 'url': '/a-private-form/'},
+    {'slug': 'third-form-title', 'title': 'third form title', 'url': '/third-form-title/'},
+]
+
+WCS_CATEGORIES_DATA = [
+    {'slug': 'test-%s' % i, 'title': 'Test %s' % i, 'url': '/test-%s/' % i}
+    for i in [3, 9]
+]
+
+WCS_CATEGORIES_FORMDEFS_DATA = [
+    {'slug': 'form-title', 'title': 'form title', 'url': '/form-title/', 'keywords': ['foo', 'bar'], 'count': 42},
+    {'slug': 'a-second-form-title', 'title': 'a second form title', 'url': '/a-second-form-title/', 'count': 35},
+]
+
+WCS_USER_FORMS_DATA = [
+    {'name': 'name', 'title': 'Title', 'url': '/form/1/', 'form_receipt_datetime': '2015-01-01T00:00:00', 'readable': True,
+     'category_slug': 'test-9'},
+    {'name': 'name', 'url': '/form/2/', 'form_receipt_datetime': '2015-01-01T00:00:00', 'readable': True},
+    {'name': 'name', 'title': 'Title', 'url': '/form/3/', 'form_receipt_datetime': '2015-01-01T00:00:00'},
+    {'name': 'name', 'title': 'Title', 'url': '/form/4/', 'form_receipt_datetime': '2015-01-01T00:00:00', 'readable': True,
+     'form_status_is_endpoint': True, 'category_slug': 'test-9'},
+]
+
+WCS_FORMS_DATA = [
+    {
+        'form_receipt_datetime': '2019-10-17T16:46:03',
+        'form_url_backoffice': '/backoffice/management/foobar/1/',
+    },
+    {
+        'form_receipt_datetime': '2019-10-17T16:46:04',
+        'form_url_backoffice': '/backoffice/management/foobar/2/',
+    },
+]
+
+WCS_USER_DRAFTS_DATA = [
+    {'name': 'name', 'title': 'Title', 'url': '/form/1/', 'form_receipt_datetime': '2015-01-01T00:00:00', 'category_slug': 'test-9'},
+    {'name': 'name', 'url': '/form/2/', 'form_receipt_datetime': '2015-01-01T00:00:00'},
+    {'name': 'name', 'title': 'Title', 'url': '/form/3/', 'form_receipt_datetime': '2015-01-01T00:00:00'},
+    {'name': 'name', 'title': 'Title', 'url': '/form/4/', 'form_receipt_datetime': '2015-01-01T00:00:00',
+     'form_status_is_endpoint': True, 'category_slug': 'test-9'},
 ]
-formdef.store()
-
-user = get_publisher().user_class.select()[0]
-
-for i in range(50):
-    formdata = formdef.data_class()()
-    formdata.just_created()
-    formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
-    formdata.data = {'1': 'FOO BAR %d' % i}
-    if i%4 == 0:
-        formdata.data['2'] = 'foo'
-        formdata.data['2_display'] = 'foo'
-    elif i%4 == 1:
-        formdata.data['2'] = 'bar'
-        formdata.data['2_display'] = 'bar'
-    else:
-        formdata.data['2'] = 'baz'
-        formdata.data['2_display'] = 'baz'
-    if i%3 == 0:
-        formdata.jump_status('new')
-    else:
-        formdata.jump_status('finished')
-    if i%7 == 0:
-        formdata.user_id = user.id
-    formdata.store()
-
-# another formdef in same category
-formdef = FormDef()
-formdef.name = 'a second form title'
-formdef.category_id = cat.id
-formdef.fields = []
-formdef.store()
-
-# a formdef in another category
-formdef = FormDef()
-formdef.name = 'third form title'
-formdef.category_id = cats[2].id
-formdef.fields = []
-formdef.enable_tracking_codes = True
-formdef.store()
-
-# a draft of that formdef
-formdata = formdef.data_class()()
-formdata.data = {}
-formdata.page_no = 1
-formdata.status = 'draft'
-formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
-formdata.user_id = user.id
-formdata.store()
-
-if '127.0.0.2' in get_publisher().get_frontoffice_url():
-    # create a tracking code on second website only
-    code = get_publisher().tracking_code_class()
-    code.id = 'CNPHNTFB'
-    code.formdata = formdata
-
-# a private formdef
-role = Role(name='Blah')
-role.store()
-
-formdef = FormDef()
-formdef.name = 'a private form'
-formdef.category_id = cats[2].id
-formdef.roles = [role.id]
-formdef.backoffice_submission_roles = [role.id]
-formdef.fields = []
-formdef.store()
-
-user2 = get_publisher().user_class()  # agent
-user2.name = 'foo2 bar2'
-user2.email = 'foo2@example.net'
-user2.roles = [role.id]
-user2.store()
-""",
-
-}
-
-WCS_DIR = tempfile.mkdtemp()
-WCS_PID = None
 
 
 class MockUser(object):
@@ -191,70 +98,40 @@ class MockUserWithNameId(object):
         return 'xyz'
 
 
-def run_wcs_script(script, hostname):
-    script_path = os.path.join(WCS_DIR, script + '.py')
-    fd = open(script_path, 'w')
-    fd.write(WCS_SCRIPTS[script])
-    fd.close()
-    subprocess.check_call([sys.executable, WCS_MANAGE, 'runscript', '--app-dir', WCS_DIR,
-        '--vhost', hostname, script_path],
-        env={'DJANGO_SETTINGS_MODULE': 'wcs.settings'})
-
-
-def setup_module(module):
-    global WCS_PID
-
-    if not WCS_MANAGE:
-        return
-
-    for hostname in ['127.0.0.1', '127.0.0.2']:
-        os.mkdir(os.path.join(WCS_DIR, hostname))
-
-        run_wcs_script('setup-auth', hostname)
-        run_wcs_script('create-user', hostname)
-        run_wcs_script('create-data', hostname)
-
-        fd = open(os.path.join(WCS_DIR, hostname, 'site-options.cfg'), 'w')
-        fd.write('''[api-secrets]
-combo = combo
-''')
-        fd.close()
+class MockedRequestResponse(mock.Mock):
+    status_code = 200
 
-    with open(os.path.join(WCS_DIR, 'wcs.cfg'), 'w') as fd:
-        fd.write('''[main]
-app_dir = %s\n''' % WCS_DIR)
+    def json(self):
+        return json.loads(self.content)
 
-    with open(os.path.join(WCS_DIR, 'local_settings.py'), 'w') as fd:
-        fd.write('''
-WCS_LEGACY_CONFIG_FILE = '%s/wcs.cfg'
-THEMES_DIRECTORY = '/'
-ALLOWED_HOSTS = ['127.0.0.1', '127.0.0.2']
-''' % WCS_DIR)
 
-    WCS_PID = os.fork()
-    if not WCS_PID:
-        os.chdir(os.path.dirname(WCS_MANAGE))
-        os.environ['DJANGO_SETTINGS_MODULE'] = 'wcs.settings'
-        os.environ['WCS_SETTINGS_FILE'] = os.path.join(WCS_DIR, 'local_settings.py')
-        os.execvp('python', [sys.executable, 'manage.py', 'runserver', '--noreload', '0.0.0.0:8999'])
-        sys.exit(0)
+def get_data_from_url(url):
+    if '/api/formdefs/' in url:
+        return WCS_FORMDEFS_DATA
+    if '/api/categories/' in url:
+        if '/formdefs/' in url:
+            return WCS_CATEGORIES_FORMDEFS_DATA
+        return WCS_CATEGORIES_DATA
+    if '/api/user/forms' in url:
+        return WCS_USER_FORMS_DATA
+    if '/api/forms' in url:
+        return WCS_FORMS_DATA
+    if '/api/user/drafts' in url:
+        return WCS_USER_DRAFTS_DATA
+    return []
 
-    time.sleep(5)
 
-def teardown_module(module):
-    if WCS_PID:
-        os.kill(WCS_PID, 9)
-        shutil.rmtree(WCS_DIR)
+def mocked_requests_send(request, **kwargs):
+    request_url = urlparse.urlparse(request.url)
+    data = copy.deepcopy(get_data_from_url(request_url.path))
+    for elem in data:
+        for key in ['url', 'form_url_backoffice']:
+            if key not in elem:
+                continue
+            elem_url = elem[key]
+            elem[key] = f'{request_url.scheme}://{request_url.netloc}{elem_url}'
 
-
-def check_wcs_open(url):
-    session = requests.Session()
-    scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
-    path = '/login/'
-    login_url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
-    resp = session.post(login_url, data={'username': 'user', 'password': 'user'})
-    resp = session.get(url)
-    assert resp.status_code == 200
+    return MockedRequestResponse(content=json.dumps({'data': data}))
 
 
 @pytest.fixture
@@ -264,8 +141,9 @@ def context():
     ctx['request'].session = {}
     return ctx
 
-@wcs_present
-def test_form_cell_setup():
+
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_form_cell_setup(mock_send):
     cell = WcsFormCell()
     form_class = cell.get_default_form_class()
     form = form_class()
@@ -280,8 +158,8 @@ def test_form_cell_setup():
             (u'other:third-form-title', u'test2 : third form title')]
 
 
-@wcs_present
-def test_form_cell_save_cache():
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_form_cell_save_cache(mock_send):
     page = Page(title='xxx', slug='test_form_cell_save_cache', template_name='standard')
     page.save()
     cell = WcsFormCell(page=page, placeholder='content', order=0)
@@ -291,7 +169,7 @@ def test_form_cell_save_cache():
     assert cell.cached_title == 'form title'
     assert cell.get_additional_label() == 'form title'
     # make sure cached attributes are removed from serialized pages
-    assert not 'cached_' in json.dumps(page.get_serialized_page())
+    assert 'cached_' not in json.dumps(page.get_serialized_page())
 
     # check content provided to search engine
     assert cell.render_for_search() == ''
@@ -309,7 +187,6 @@ def test_form_cell_save_cache():
     assert WcsFormCell.objects.get(id=cell.id).cached_title == 'form title'
 
 
-@wcs_present
 def test_form_cell_validity():
     page = Page.objects.create(title='xxx', slug='test_form_cell_save_cache', template_name='standard')
     cell = WcsFormCell.objects.create(page=page, placeholder='content', order=0)
@@ -335,7 +212,6 @@ def test_form_cell_validity():
     assert validity_info.invalid_since is not None
 
 
-@wcs_present
 def test_form_cell_load():
     page = Page(title='xxx', slug='test_form_cell_save_cache', template_name='standard')
     page.save()
@@ -353,8 +229,8 @@ def test_form_cell_load():
     assert cell.cached_title == 'form title'
 
 
-@wcs_present
-def test_category_cell_save_cache():
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_category_cell_save_cache(mock_send):
     page = Page(title='xxx', slug='test_category_cell_save_cache', template_name='standard')
     page.save()
     cell = WcsCategoryCell(page=page, placeholder='content', order=0)
@@ -365,7 +241,6 @@ def test_category_cell_save_cache():
     assert cell.get_additional_label() == 'Test 3'
 
 
-@wcs_present
 def test_category_cell_validity():
     page = Page.objects.create(title='xxx', slug='test_category_cell_save_cache', template_name='standard')
     cell = WcsCategoryCell.objects.create(page=page, placeholder='content', order=0)
@@ -391,8 +266,8 @@ def test_category_cell_validity():
     assert validity_info.invalid_since is not None
 
 
-@wcs_present
-def test_form_cell_render():
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_form_cell_render(mock_send):
     page = Page(title='xxx', slug='test_form_cell_render', template_name='standard')
     page.save()
     cell = WcsFormCell(page=page, placeholder='content', order=0)
@@ -402,8 +277,9 @@ def test_form_cell_render():
     assert 'http://127.0.0.1:8999/form-title/tryauth' in result
     assert 'form title' in result
 
-@wcs_present
-def test_current_forms_cell_setup():
+
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_current_forms_cell_setup(mock_send):
     cell = WcsCurrentFormsCell()
     form_class = cell.get_default_form_class()
     form = form_class()
@@ -423,8 +299,9 @@ def test_current_forms_cell_setup():
     cell.done_forms = True
     assert cell.get_additional_label() == 'All Sites - Done Forms'
 
-@wcs_present
-def test_current_forms_cell_render(context):
+
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_current_forms_cell_render(mock_send, context):
     page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
     page.save()
     cell = WcsCurrentFormsCell(page=page, placeholder='content', order=0)
@@ -437,15 +314,18 @@ def test_current_forms_cell_render(context):
     with pytest.raises(NothingInCacheException):
         result = cell.render(context)
 
-    context['synchronous'] = True # to get fresh content
+    context['synchronous'] = True  # to get fresh content
 
     # default is to get current forms from all wcs sites
     result = cell.render(context)
-    assert 'http://127.0.0.1:8999/form-title/1/' in result
-    assert 'http://127.0.0.1:8999/form-title/22/' in result
-    assert not 'http://127.0.0.1:8999/form-title/8/' in result
-    assert 'http://127.0.0.2:8999/form-title/1/' in result
-    assert 'http://127.0.0.2:8999/form-title/22/' in result
+    assert 'http://127.0.0.1:8999/form/1/' in result
+    assert 'http://127.0.0.1:8999/form/2/' not in result  # no title
+    assert 'http://127.0.0.1:8999/form/3/' not in result  # not readable
+    assert 'http://127.0.0.1:8999/form/4/' not in result  # done
+    assert 'http://127.0.0.2:8999/form/1/' in result
+    assert 'http://127.0.0.2:8999/form/2/' not in result
+    assert 'http://127.0.0.2:8999/form/3/' not in result
+    assert 'http://127.0.0.2:8999/form/4/' not in result
 
     # done forms
     cell.current_forms = False
@@ -453,18 +333,10 @@ def test_current_forms_cell_render(context):
     cell.include_drafts = False
     cell.save()
     result = cell.render(context)
-    assert not 'http://127.0.0.1:8999/form-title/1/' in result
-    assert 'http://127.0.0.1:8999/form-title/8/' in result
-
-    data = cell.get_data(context)
-    assert data['default']['data'][0]['site_slug'] == 'default'
-    assert data['other']['data'][0]['site_slug'] == 'other'
-
-    # check flat list
-    extra_context = cell.get_cell_extra_context(context)
-    assert len(extra_context['forms']) == 10
-    assert len([x for x in extra_context['forms'] if x['site_slug'] == 'default']) == 5
-    assert len([x for x in extra_context['forms'] if x['site_slug'] == 'other']) == 5
+    assert 'http://127.0.0.1:8999/form/1/' not in result  # wip
+    assert 'http://127.0.0.1:8999/form/4/' in result  # done
+    assert 'http://127.0.0.2:8999/form/1/' not in result  # wip
+    assert 'http://127.0.0.2:8999/form/4/' in result  # done
 
     # limit to a category
     cell.categories = {'data': ['default:test-3']}
@@ -472,13 +344,13 @@ def test_current_forms_cell_render(context):
     assert len(extra_context['forms']) == 0
     cell.categories = {'data': ['default:test-9']}
     extra_context = cell.get_cell_extra_context(context)
-    assert len(extra_context['forms']) == 5
+    assert len(extra_context['forms']) == 1
 
     # check both category limit and all forms
     cell.current_forms = True
     cell.done_forms = True
     extra_context = cell.get_cell_extra_context(context)
-    assert len(extra_context['forms']) == 8
+    assert len(extra_context['forms']) == 2
 
     # check both category limit and no forms
     cell.current_forms = False
@@ -516,8 +388,8 @@ def test_current_forms_cell_render(context):
     assert 'There are no done forms' in result
 
 
-@wcs_present
-def test_current_forms_cell_validity(context):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_current_forms_cell_validity(mock_send, context):
     page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
     cell = WcsCurrentFormsCell.objects.create(page=page, placeholder='content', order=0)
     context['request'].user = MockUser()
@@ -533,8 +405,8 @@ def test_current_forms_cell_validity(context):
     assert ValidityInfo.objects.exists() is False
 
 
-@wcs_present
-def test_current_forms_cell_check_validity(context):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_current_forms_cell_check_validity(mock_send, context):
     page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
     cell = WcsCurrentFormsCell.objects.create(page=page, placeholder='content', order=0)
 
@@ -564,8 +436,8 @@ def test_current_forms_cell_check_validity(context):
     assert validity_info.invalid_since is not None
 
 
-@wcs_present
-def test_current_forms_cell_render_single_site(context):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_current_forms_cell_render_single_site(mock_send, context):
     page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
     page.save()
     cell = WcsCurrentFormsCell(page=page, placeholder='content', order=0)
@@ -579,16 +451,14 @@ def test_current_forms_cell_render_single_site(context):
     with pytest.raises(NothingInCacheException):
         result = cell.render(context)
 
-    context['synchronous'] = True # to get fresh content
+    context['synchronous'] = True  # to get fresh content
 
     result = cell.render(context)
-    assert 'http://127.0.0.1:8999/form-title/1/' in result
-    assert 'http://127.0.0.1:8999/form-title/22/' in result
-    assert 'http://127.0.0.2:8999/form-title/1/' not in result
-    assert 'http://127.0.0.2:8999/form-title/22/' not in result
+    assert 'http://127.0.0.1:8999/form/1/' in result
+    assert 'http://127.0.0.2:8999/form/1/' not in result
 
-@wcs_present
-def test_current_forms_unknown_name_id(caplog, context):
+
+def test_current_forms_unknown_name_id(context):
     page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
     page.save()
     cell = WcsCurrentFormsCell(page=page, placeholder='content', order=0)
@@ -600,16 +470,17 @@ def test_current_forms_unknown_name_id(caplog, context):
     # query should fail as nothing is cached
     cache.clear()
     with pytest.raises(NothingInCacheException):
-        result = cell.render(context)
+        cell.render(context)
 
-    context['synchronous'] = True # to get fresh content
+    context['synchronous'] = True  # to get fresh content
 
-    result = cell.render(context)
-    assert 'http://127.0.0.1:8999/' not in result
-    assert len(caplog.records) == 0
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        cell.render(context)
+    assert requests_get.call_args_list[0][0][0] == '/api/users/xyz/forms?limit=100&sort=desc'
 
 
-@wcs_present
 def test_care_forms_cell_setup():
     cell = WcsCareFormsCell()
     form_class = cell.get_default_form_class()
@@ -621,8 +492,8 @@ def test_care_forms_cell_setup():
     assert cell.get_additional_label() == 'test'
 
 
-@wcs_present
-def test_care_forms_cell_render(context):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_care_forms_cell_render(mock_send, context):
     page = Page(title='xxx', slug='test_care_forms_cell_render', template_name='standard')
     page.save()
     cell = WcsCareFormsCell(page=page, placeholder='content', order=0)
@@ -637,33 +508,13 @@ def test_care_forms_cell_render(context):
 
     context['synchronous'] = True  # to get fresh content
 
-    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
-        response1 = {'err': 0, 'data': [
-            {
-                'form_receipt_datetime': '2019-10-17T16:46:03',
-                'form_url_backoffice': 'http://127.0.0.1:8999/backoffice/management/foobar/1/',
-            },
-            {
-                'form_receipt_datetime': '2019-10-17T16:46:04',
-                'form_url_backoffice': 'http://127.0.0.1:8999/backoffice/management/foobar/2/',
-            },
-        ]}
-        response2 = {'err': 0, 'data': [
-            {
-                'form_receipt_datetime': '2019-10-17T16:46:05',
-                'form_url_backoffice': 'http://127.0.0.2:8999/backoffice/management/foobar/42/',
-            },
-        ]}
-        mock_json = mock.Mock(status_code=200)
-        mock_json.json.side_effect = [response1, response2]
-        requests_get.return_value = mock_json
-
-        result = cell.render(context)
+    result = cell.render(context)
 
     assert 'http://127.0.0.1:8999/backoffice/management/foobar/1' in result
     assert 'http://127.0.0.1:8999/backoffice/management/foobar/2' in result
     assert '"http://127.0.0.1:8999/backoffice/management/"' in result
-    assert 'http://127.0.0.2:8999/backoffice/management/foobar/42' in result
+    assert 'http://127.0.0.2:8999/backoffice/management/foobar/1' in result
+    assert 'http://127.0.0.2:8999/backoffice/management/foobar/2' in result
     assert '"http://127.0.0.2:8999/backoffice/management/"' in result
 
     data = cell.get_data(context)
@@ -671,7 +522,6 @@ def test_care_forms_cell_render(context):
     assert 'other' in data
 
 
-@wcs_present
 def test_care_forms_cell_validity(context):
     page = Page.objects.create(title='xxx', slug='test_care_forms_cell_render', template_name='standard')
     cell = WcsCareFormsCell.objects.create(page=page, placeholder='content', order=0)
@@ -698,8 +548,8 @@ def test_care_forms_cell_validity(context):
     assert validity_info.invalid_since is not None
 
 
-@wcs_present
-def test_care_forms_cell_render_single_site(context):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_care_forms_cell_render_single_site(mock_send, context):
     page = Page(title='xxx', slug='test_care_forms_cell_render', template_name='standard')
     page.save()
     cell = WcsCareFormsCell(page=page, placeholder='content', order=0)
@@ -724,8 +574,8 @@ def test_care_forms_cell_render_single_site(context):
     assert 'other' not in data
 
 
-@wcs_present
-def test_forms_of_category_cell_setup():
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_forms_of_category_cell_setup(mock_send):
     cell = WcsFormsOfCategoryCell()
     form_class = cell.get_default_form_class()
     form = form_class()
@@ -736,8 +586,8 @@ def test_forms_of_category_cell_setup():
             (u'other:test-9', u'test2 : Test 9')]
 
 
-@wcs_present
-def test_forms_of_category_cell_render(context):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_forms_of_category_cell_render(mock_send, context):
     page = Page(title='xxx', slug='test_forms_of_category_cell_render', template_name='standard')
     page.save()
     cell = WcsFormsOfCategoryCell(page=page, placeholder='content', order=0)
@@ -785,17 +635,18 @@ def test_forms_of_category_cell_render(context):
     assert len(list(cell.get_external_links_data())) == 2
 
     # existing category, but empty
-    cell.category_reference = 'default:test-1'
-    cell.save()
-    result = cell.render(context)
-    assert '<h2>' not in result
-    context['combo_display_even_empty_categories'] = True
-    result = cell.render(context)
-    assert '<h2>' in result
-    context.pop('combo_display_even_empty_categories')
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        cell.render(context)
+        result = cell.render(context)
+        assert '<h2>' not in result
+        context['combo_display_even_empty_categories'] = True
+        result = cell.render(context)
+        assert '<h2>' in result
+        context.pop('combo_display_even_empty_categories')
 
 
-@wcs_present
 def test_forms_of_category_cell_validity(context):
     page = Page.objects.create(title='xxx', slug='test_forms_of_category_cell_render', template_name='standard')
     cell = WcsFormsOfCategoryCell.objects.create(page=page, placeholder='content', order=0)
@@ -836,7 +687,6 @@ def test_forms_of_category_cell_validity(context):
     assert validity_info.invalid_since is not None
 
 
-@wcs_present
 def test_forms_of_category_cell_check_validity(context):
     page = Page.objects.create(title='xxx', slug='test_forms_of_category_cell_render', template_name='standard')
     cell = WcsFormsOfCategoryCell.objects.create(page=page, placeholder='content', order=0)
@@ -856,54 +706,72 @@ def test_forms_of_category_cell_check_validity(context):
     assert validity_info.invalid_since is not None
 
 
-@wcs_present
 def test_current_drafts_cell_render_unlogged(context):
     page = Page(title='xxx', slug='test_current_drafts_cell_render', template_name='standard')
     page.save()
     cell = WcsCurrentDraftsCell(page=page, placeholder='content', order=0)
     cell.save()
-    context['synchronous'] = True # to get fresh content
-    result = cell.render(context)
-    assert not 'http://127.0.0.1:8999/third-form-title' in result # no form
+    context['synchronous'] = True  # to get fresh content
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        result = cell.render(context)
+    assert requests_get.call_args_list[0][0][0] == '/api/user/drafts'
+    assert 'http://127.0.0.1:8999/third-form-title' not in result  # no form
 
 
-@wcs_present
-def test_current_drafts_cell_render_logged_in(context):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_current_drafts_cell_render_logged_in(mock_send, context):
     page = Page(title='xxx', slug='test_current_drafts_cell_render', template_name='standard')
     page.save()
     cell = WcsCurrentDraftsCell(page=page, placeholder='content', order=0)
     cell.save()
-    context['synchronous'] = True # to get fresh content
+    context['synchronous'] = True  # to get fresh content
 
     context['request'].user = MockUser()
 
     # default is to get current forms from all wcs sites
     result = cell.render(context)
-    assert 'http://127.0.0.1:8999/third-form-title/1' in result
-    for url in re.findall(r'href=[\'"]?([^\'" >]+)', result):
-        check_wcs_open(url)
+    assert 'http://127.0.0.1:8999/form/1/' in result
+    assert 'http://127.0.0.1:8999/form/2/' not in result  # no title
+    assert 'http://127.0.0.1:8999/form/3/' in result
+    assert 'http://127.0.0.1:8999/form/4/' not in result  # done
+    assert 'http://127.0.0.2:8999/form/1/' in result
+    assert 'http://127.0.0.2:8999/form/2/' not in result
+    assert 'http://127.0.0.2:8999/form/3/' in result
+    assert 'http://127.0.0.2:8999/form/4/' not in result
 
     # check flat list
     extra_context = cell.get_cell_extra_context(context)
-    assert len(extra_context['drafts']) == 2
-    assert len([x for x in extra_context['drafts'] if x['site_slug'] == 'default']) == 1
-    assert len([x for x in extra_context['drafts'] if x['site_slug'] == 'other']) == 1
+    assert len(extra_context['drafts']) == 8
+    assert len([x for x in extra_context['drafts'] if x['site_slug'] == 'default']) == 4
+    assert len([x for x in extra_context['drafts'] if x['site_slug'] == 'other']) == 4
 
     # limit to a category
     cell.categories = {'data': ['default:test-3']}
     extra_context = cell.get_cell_extra_context(context)
-    assert len(extra_context['drafts']) == 1
+    assert len(extra_context['drafts']) == 0
     cell.categories = {'data': ['default:test-9']}
     extra_context = cell.get_cell_extra_context(context)
-    assert len(extra_context['drafts']) == 0
+    assert len(extra_context['drafts']) == 2
 
     # check empty message
-    result = cell.render(context)
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        result = cell.render(context)
     assert 'There are no current drafts.' in result
 
+    context['request'].user = MockUserWithNameId()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        cell.render(context)
+    assert requests_get.call_args_list[0][0][0] == '/api/users/xyz/drafts'
 
-@wcs_present
-def test_current_drafts_cell_check_validity(context):
+
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_current_drafts_cell_check_validity(mock_send, context):
     page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
     cell = WcsCurrentDraftsCell.objects.create(page=page, placeholder='content', order=0)
 
@@ -933,9 +801,8 @@ def test_current_drafts_cell_check_validity(context):
     assert validity_info.invalid_since is not None
 
 
-@wcs_present
-def test_manager_forms_of_category_cell(app, admin_user):
-    Page.objects.all().delete()
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_manager_forms_of_category_cell(mock_send, app, admin_user):
     page = Page(title='One', slug='one', template_name='standard')
     page.save()
     app = login(app)
@@ -953,9 +820,8 @@ def test_manager_forms_of_category_cell(app, admin_user):
     resp = resp.forms[0].submit()
     assert resp.status_int == 302
 
-@wcs_present
+
 def test_manager_current_forms(app, admin_user):
-    Page.objects.all().delete()
     page = Page(title='One', slug='one', template_name='standard')
     page.save()
     app = login(app)
@@ -990,9 +856,7 @@ def test_manager_current_forms(app, admin_user):
         settings.KNOWN_SERVICES = temp_settings
 
 
-@wcs_present
 def test_tracking_code_cell(app, nocache):
-    Page.objects.all().delete()
     page = Page(title='One', slug='index', template_name='standard')
     page.save()
     cell = TrackingCodeInputCell(page=page, placeholder='content', order=0)
@@ -1000,28 +864,49 @@ def test_tracking_code_cell(app, nocache):
 
     resp = app.get('/')
     resp.form['code'] = 'FOOBAR'
-    resp = resp.form.submit()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        resp = resp.form.submit()
+    assert len(requests_get.call_args_list) == 2
+    assert requests_get.call_args_list[0][0][0] == '/api/code/FOOBAR'
+    assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
+    assert requests_get.call_args_list[1][0][0] == '/api/code/FOOBAR'
+    assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
     assert resp.status_code == 302
     resp = resp.follow()
     assert '<li class="error">The tracking code could not been found.</li>' in resp.text
 
     resp = app.get('/')
     resp.form['code'] = 'FOO?BAR?bad<code>'
-    resp = resp.form.submit()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        resp = resp.form.submit()
+    assert requests_get.call_args_list[0][0][0] == '/api/code/FOO%3FBAR%3FBAD%3CCODE%3E'
     assert resp.status_code == 302
     resp = resp.follow()
     assert '<li class="error">The tracking code could not been found.</li>' in resp.text
 
     resp = app.get('/')
     resp.form['code'] = 'CNPHNTFB'
-    resp = resp.form.submit()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        requests_get.return_value = MockedRequestResponse(content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'}))
+        resp = resp.form.submit()
     assert resp.status_code == 302
     assert resp.location == 'http://127.0.0.2:8999/code/CNPHNTFB/load'
 
     # space/case
     resp = app.get('/')
     resp.form['code'] = ' cnphntfb'
-    resp = resp.form.submit()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        requests_get.side_effect = [
+            mock.Mock(status_code=200),
+            MockedRequestResponse(content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'}))
+        ]
+        resp = resp.form.submit()
+    assert requests_get.call_args_list[0][0][0] == '/api/code/CNPHNTFB'
+    assert requests_get.call_args_list[1][0][0] == '/api/code/CNPHNTFB'
     assert resp.status_code == 302
     assert resp.location == 'http://127.0.0.2:8999/code/CNPHNTFB/load'
 
@@ -1030,7 +915,12 @@ def test_tracking_code_cell(app, nocache):
     cell.save()
     resp = app.get('/')
     resp.form['code'] = 'CNPHNTFB'
-    resp = resp.form.submit()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        resp = resp.form.submit()
+    assert len(requests_get.call_args_list) == 1
+    assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
     resp = resp.follow()
     assert '<li class="error">The tracking code could not been found.</li>' in resp.text
 
@@ -1038,13 +928,19 @@ def test_tracking_code_cell(app, nocache):
     resp = app.get('/')
     resp.form['url'] = 'http://example.org/'
     resp.form['code'] = 'CNPHNTFB'
-    resp = resp.form.submit()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        resp = resp.form.submit()
     assert resp.location == 'http://example.org/?unknown-tracking-code'
 
     resp = app.get('/')
     resp.form['url'] = 'http://example.org/?foo=bar'
     resp.form['code'] = 'CNPHNTFB'
-    resp = resp.form.submit()
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        resp = resp.form.submit()
     assert resp.location == 'http://example.org/?foo=bar&unknown-tracking-code'
 
     # redirect to an unknown site
@@ -1067,8 +963,8 @@ def test_tracking_code_cell(app, nocache):
     resp = app.post(reverse('wcs-tracking-code'), params={'cell': cell.id}, status=400)
 
 
-@wcs_present
-def test_cell_assets(settings, app, admin_user):
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_cell_assets(mock_send, settings, app, admin_user):
     page = Page.objects.create(title='xxx', slug='test_cell_assets', template_name='standard')
     cell1 = WcsFormCell.objects.create(page=page, placeholder='content', order=0, formdef_reference=u'default:form-title')
 
@@ -1117,36 +1013,62 @@ def test_cell_assets(settings, app, admin_user):
     assert u'>Picture — %s (test)<' % cell1.get_label_for_asset() in resp.text
 
 
-@wcs_present
-def test_tracking_code_search(app, nocache):
+def test_tracking_code_search(settings, app, nocache):
     settings.TEMPLATE_VARS['is_portal_agent'] = True
-    assert len(app.get('/api/search/tracking-code/').json.get('data')) == 0
-    assert app.get('/api/search/tracking-code/').json.get('err') == 0
-    assert len(app.get('/api/search/tracking-code/?q=123').json.get('data')) == 0
-    assert len(app.get('/api/search/tracking-code/?q=BBCCDFF').json.get('data')) == 0
-    assert len(app.get('/api/search/tracking-code/?q=BBCCDDFF').json.get('data')) == 0
-    assert len(app.get('/api/search/tracking-code/?q=CNPHNTFB').json.get('data')) == 1
-    assert len(app.get('/api/search/tracking-code/?q=BBCCDDFFG').json.get('data')) == 0
-    assert len(app.get('/api/search/tracking-code/?q= cnphntfb').json.get('data')) == 1
-
-@wcs_present
-def test_tracking_code_search_rate_limit(app):
+
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        result = app.get('/api/search/tracking-code/').json
+        assert len(result.get('data')) == 0
+        assert result.get('err') == 0
+    assert requests_get.called is False  # no code
+
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        assert len(app.get('/api/search/tracking-code/?q=123').json.get('data')) == 0
+    assert requests_get.called is False  # no letters
+
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        assert len(app.get('/api/search/tracking-code/?q=BBCCDFF').json.get('data')) == 0
+    assert requests_get.called is False  # too short
+
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        assert len(app.get('/api/search/tracking-code/?q=BBCCDDFF').json.get('data')) == 0
+    assert len(requests_get.call_args_list) == 2
+    assert requests_get.call_args_list[0][0][0] == '/api/code/BBCCDDFF'
+    assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
+    assert requests_get.call_args_list[1][0][0] == '/api/code/BBCCDDFF'
+    assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
+
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        requests_get.return_value = MockedRequestResponse(content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'}))
+        assert len(app.get('/api/search/tracking-code/?q=CNPHNTFB').json.get('data')) == 1
+    assert requests_get.call_args_list[0][0][0] == '/api/code/CNPHNTFB'
+
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        assert len(app.get('/api/search/tracking-code/?q=BBCCDDFFG').json.get('data')) == 0
+    assert requests_get.called is False  # too long
+
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        requests_get.side_effect = [
+            mock.Mock(status_code=200),
+            MockedRequestResponse(content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'}))
+        ]
+        assert len(app.get('/api/search/tracking-code/?q= cnphntfb').json.get('data')) == 1
+    assert requests_get.call_args_list[0][0][0] == '/api/code/CNPHNTFB'
+
+
+def test_tracking_code_search_rate_limit(settings, app):
     settings.TEMPLATE_VARS['is_portal_agent'] = True
-    for i in range(3):
-        assert app.get('/api/search/tracking-code/?q=BBCCDDFF').json.get('err') == 0
-    for i in range(3):  # make sure we hit ratelimit
-        app.get('/api/search/tracking-code/?q=BBCCDDFF')
+    settings.WCS_TRACKING_CODE_RATE_LIMIT = '0/s'
     assert app.get('/api/search/tracking-code/?q=BBCCDDFF').json.get('err') == 1
 
-    Page.objects.all().delete()
     page = Page(title='One', slug='index', template_name='standard')
     page.save()
     cell = TrackingCodeInputCell(page=page, placeholder='content', order=0)
     cell.save()
 
     resp = app.get('/')
-    for i in range(3):  # make sure we hit ratelimit
-        app.get('/api/search/tracking-code/?q=BBCCDDFF')
     resp.form['code'] = 'FOOBAR'
     resp = resp.form.submit()
     assert resp.status_code == 302
@@ -1154,14 +1076,11 @@ def test_tracking_code_search_rate_limit(app):
     assert '<li class="error">Looking up tracking code is currently rate limited.</li>' in resp.text
 
     resp = app.get('/')
-    for i in range(3):  # make sure we hit ratelimit
-        app.get('/api/search/tracking-code/?q=BBCCDDFF')
     resp.form['code'] = 'FOOBAR'
     resp.form['url'] = 'http://example.org/'
     resp = resp.form.submit(status=403)
 
 
-@wcs_present
 def test_wcs_search_engines(app):
     settings.TEMPLATE_VARS['is_portal_agent'] = True
     search_engines = engines.get_engines()
@@ -1173,7 +1092,6 @@ def test_wcs_search_engines(app):
     assert len([x for x in search_engines.keys() if x.startswith('formdata:')]) == 0
 
 
-@wcs_present
 def test_backoffice_submission_cell_render(context):
     page = Page(title='xxx', slug='test_backoffice_submission_cell_render', template_name='standard')
     page.save()
@@ -1183,36 +1101,23 @@ def test_backoffice_submission_cell_render(context):
 
     context['synchronous'] = True  # to get fresh content
 
-    result = cell.render(context)
-    assert '/backoffice/submission/a-private-form/' not in result
-    assert context['all_formdefs'] == {}
-    assert 'h2' not in result
-
-    context['request'].user = MockUser()
-
-    result = cell.render(context)
-    assert '/backoffice/submission/a-private-form/' not in result
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        mock_json = mock.Mock(status_code=200)
+        requests_get.return_value = mock_json
+        result = cell.render(context)
+    assert requests_get.call_args_list[0][0][0] == '/api/formdefs/?backoffice-submission=on'
     assert context['all_formdefs'] == {}
     assert 'h2' not in result
 
-    class MockUser2(MockUser):
-        email = 'foo2@example.net'
-    context['request'].user = MockUser2()
-
-    result = cell.render(context)
+    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
+        requests_get.return_value = MockedRequestResponse(content=json.dumps(
+            {'data': [{'backoffice_submission_url': '/backoffice/submission/a-private-form/', 'title': 'Foo'}]}))
+        result = cell.render(context)
     assert '/backoffice/submission/a-private-form/' in result
     assert list(context['all_formdefs'].keys()) == ['default']
     assert 'h2' in result
 
-    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
-        # empty response
-        mock_json = mock.Mock(status_code=200)
-        requests_get.return_value = mock_json
-        result = cell.render(context)
-    assert '/backoffice/submission/a-private-form/' not in result
-
 
-@wcs_present
 def test_manager_link_list_cell_duplicate():
     page = Page.objects.create(title='xxx', slug='new', template_name='standard')
     cell = LinkListCell.objects.create(order=0, page=page)
@@ -1236,9 +1141,8 @@ def test_manager_link_list_cell_duplicate():
     assert new_item.cached_json == item.cached_json
 
 
-@wcs_present
-def test_manager_add_edit_delete_list_link_item(app, admin_user):
-    Page.objects.all().delete()
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_manager_add_edit_delete_list_link_item(mock_send, app, admin_user):
     page = Page.objects.create(title='One', slug='one', template_name='standard')
     cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
     app = login(app)
@@ -1273,7 +1177,6 @@ def test_manager_add_edit_delete_list_link_item(app, admin_user):
     assert WcsFormCell.objects.count() == 0
 
 
-@wcs_present
 def test_import_export_pages_with_links():
     page = Page(title=u'bar', slug='bar', order=1)
     page.save()
@@ -1289,7 +1192,6 @@ def test_import_export_pages_with_links():
     )
 
     site_export = [x.get_serialized_page() for x in Page.objects.all()]
-    Page.objects.all().delete()
 
     Page.load_serialized_pages(site_export)
 
@@ -1322,7 +1224,6 @@ def test_list_of_links_with_form_render(app):
     assert 'keyword-bar' in resp
 
 
-@wcs_present
 def test_view_page_with_wcs_cells_num_queries(app, admin_user):
     page = Page.objects.create(title=u'bar', slug='index', order=1)
     for i in range(0, 15):
@@ -1342,7 +1243,6 @@ def test_view_page_with_wcs_cells_num_queries(app, admin_user):
         assert len(ctx.captured_queries) == 61
 
 
-@wcs_present
 def test_hourly():
     appconfig = apps.get_app_config('wcs')
     page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
@@ -1358,9 +1258,8 @@ def test_hourly():
             assert hasattr(klass, 'check_validity') is False
 
 
-@wcs_present
-def test_search_external_forms_links(context):
-
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_search_external_forms_links(mock_send, context):
     page = Page(title='xxx', slug='test_forms_of_category_cell_search',
                 template_name='standard')
     page.save()
diff --git a/tox.ini b/tox.ini
index 2c727b8..1066464 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,7 +5,6 @@ envlist = coverage-py3-django111-pylint,py3-django22
 [testenv]
 usedevelop = True
 setenv =
-  WCS_MANAGE={toxworkdir}/wcs/wcsctl.py
   DJANGO_SETTINGS_MODULE=combo.settings
   COMBO_SETTINGS_FILE=tests/settings.py
   TOX_WORK_DIR={toxworkdir}
@@ -32,7 +31,6 @@ deps =
   git+http://git.entrouvert.org/debian/django-ckeditor.git
 commands =
   ./getlasso3.sh
-  ./get_wcs.sh
   python manage.py compilemessages
   py.test {env:COVERAGE:} {posargs: --junitxml=junit-{envname}.xml tests/}
   pylint: ./pylint.sh combo/
-- 
2.20.1

