From df41bdc8de65ed4a10582c1ee92bbf970436f42a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 18 Mar 2022 09:46:37 +0100
Subject: [PATCH 02/65] misc: add __init__ file to tests dir (#62099)

---
 tests/__init__.py                |   0
 tests/conftest.py                |   3 +-
 tests/test_actesweb.py           |   4 +-
 tests/test_address.py            |  12 +--
 tests/test_adict.py              |  12 +--
 tests/test_airquality.py         |   6 +-
 tests/test_api.py                |   2 +-
 tests/test_api_access.py         |   2 +-
 tests/test_api_entreprise.py     |   2 +-
 tests/test_api_particulier.py    |   4 +-
 tests/test_arcgis.py             |  24 +++--
 tests/test_arpege_ecp.py         |  46 ++++-----
 tests/test_astech.py             |  46 +++++----
 tests/test_astregs.py            |   4 +-
 tests/test_atos_genesys.py       |  62 +++++------
 tests/test_availability.py       |   4 +-
 tests/test_base_adresse.py       |  64 ++++++------
 tests/test_caluire_axel.py       |   4 +-
 tests/test_cartads_cs.py         |   4 +-
 tests/test_cityweb.py            |   4 +-
 tests/test_clicrdv.py            |   2 +-
 tests/test_cmis.py               |   2 +-
 tests/test_cryptor.py            |  14 +--
 tests/test_csv_datasource.py     |   2 +-
 tests/test_dpark.py              |   2 +-
 tests/test_esirius.py            |   8 +-
 tests/test_esirius_swi.py        |   4 +-
 tests/test_feeds.py              |   8 +-
 tests/test_franceconnect_data.py |   6 +-
 tests/test_gdema.py              |  24 ++---
 tests/test_generic_endpoint.py   |  20 ++--
 tests/test_gesbac.py             |   2 +-
 tests/test_greco.py              |   8 +-
 tests/test_grenoble_gru.py       |   6 +-
 tests/test_isere_ens.py          |  60 +++++------
 tests/test_jobs.py               |  16 +--
 tests/test_jsonresponse.py       |   2 +-
 tests/test_lille_kimoce.py       |  32 +++---
 tests/test_lille_urban_card.py   |  32 +++---
 tests/test_maelis.py             |  36 +++----
 tests/test_mdel.py               |   4 +-
 tests/test_mdel_ddpacs.py        |   4 +-
 tests/test_mdph13.py             |   4 +-
 tests/test_misc.py               |   4 +-
 tests/test_okina.py              |  66 ++++++------
 tests/test_opendatasoft.py       |  40 +++----
 tests/test_opengis.py            |  82 ++++++++-------
 tests/test_phonecalls.py         |  14 +--
 tests/test_photon.py             |  22 ++--
 tests/test_plone_restapi.py      |  98 +++++++++---------
 tests/test_proxylogger.py        |  14 +--
 tests/test_requests.py           |   4 +-
 tests/test_rsa13.py              |   4 +-
 tests/test_sector.py             |   6 +-
 tests/test_sigerly.py            |   6 +-
 tests/test_sms.py                |  34 +++---
 tests/test_solis.py              | 172 ++++++++++++++++---------------
 tests/test_solis_afi_mss.py      |   8 +-
 tests/test_strasbourg_eu.py      |   8 +-
 tests/test_tcl.py                |   8 +-
 tests/test_teamnet_axel.py       |   4 +-
 tests/test_toulouse_axel.py      |   4 +-
 tests/test_toulouse_smart.py     |   8 +-
 tests/test_vivaticket.py         |  68 ++++++------
 tests/wcs/test_sp_fr.py          |   4 +-
 65 files changed, 657 insertions(+), 628 deletions(-)
 create mode 100644 tests/__init__.py

diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/conftest.py b/tests/conftest.py
index c307ec5c..0b5ca739 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -7,7 +7,8 @@ from django.core.cache import cache
 from django.core.files import File
 from django.utils import six
 from httmock import HTTMock, remember_called, response, urlmatch
-from utils import make_resource
+
+from tests.utils import make_resource
 
 if six.PY2:
     collect_ignore = ['wcs/']
diff --git a/tests/test_actesweb.py b/tests/test_actesweb.py
index 3c03e186..b22954bb 100644
--- a/tests/test_actesweb.py
+++ b/tests/test_actesweb.py
@@ -23,9 +23,9 @@ import shutil
 import stat
 
 import pytest
-import utils
 from django.utils import six
 
+import tests.utils
 from passerelle.apps.actesweb.models import ActesWeb
 
 
@@ -41,7 +41,7 @@ def get_file_from_test_base_dir(filename):
 
 @pytest.fixture
 def actesweb(db):
-    return utils.make_resource(ActesWeb, **{'slug': 'test'})
+    return tests.utils.make_resource(ActesWeb, **{'slug': 'test'})
 
 
 PAYLOAD = [
diff --git a/tests/test_address.py b/tests/test_address.py
index 1c483ef4..841ed63c 100644
--- a/tests/test_address.py
+++ b/tests/test_address.py
@@ -18,10 +18,10 @@ import json
 
 import mock
 import pytest
-import utils
 from django.core.files import File
 from django.utils.six import StringIO
 
+import tests.utils
 from passerelle.apps.base_adresse.models import BaseAdresse
 from passerelle.apps.sector.models import SectorResource
 
@@ -216,7 +216,7 @@ CSV = """street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,
 
 @pytest.fixture
 def sector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         SectorResource.objects.create(
             slug='ecole',
             title='Secteur scolaire',
@@ -228,14 +228,14 @@ def sector(db):
 
 @pytest.fixture
 def base_adresse(db):
-    return utils.setup_access_rights(BaseAdresse.objects.create(slug='base-adresse', zipcode='75114'))
+    return tests.utils.setup_access_rights(BaseAdresse.objects.create(slug='base-adresse', zipcode='75114'))
 
 
 @mock.patch('passerelle.utils.Request.get')
 def test_sectorization(mocked_get, app, base_adresse, sector):
     assert base_adresse.sectors.count() == 0
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps(BAN), status_code=200)
-    url = utils.generic_endpoint_url('base-adresse', 'search', slug=base_adresse.slug)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(BAN), status_code=200)
+    url = tests.utils.generic_endpoint_url('base-adresse', 'search', slug=base_adresse.slug)
     addresses = app.get(url, params={'q': 'foo'}, status=200).json
     assert len(addresses) == 8
     for address in addresses:
@@ -267,7 +267,7 @@ def test_sectorization(mocked_get, app, base_adresse, sector):
     assert addresses[7]['sectors'] == {}
     assert addresses[7]['sectorization_error'] == 'missing street_id in address'
 
-    url = utils.generic_endpoint_url('base-adresse', 'sectors', slug=base_adresse.slug)
+    url = tests.utils.generic_endpoint_url('base-adresse', 'sectors', slug=base_adresse.slug)
     for params in (None, {'id': 'ecole'}, {'q': 'scolaire'}):
         sectors = app.get(url, params=params, status=200).json
         assert sectors['err'] == 0
diff --git a/tests/test_adict.py b/tests/test_adict.py
index 2c2da5ca..94224801 100644
--- a/tests/test_adict.py
+++ b/tests/test_adict.py
@@ -2,8 +2,8 @@ import json
 
 import mock
 import pytest
-import utils
 
+import tests.utils
 from passerelle.contrib.adict.models import Adict
 
 FAKE_FEATURE_INFO = json.dumps(
@@ -28,7 +28,7 @@ FAKE_FEATURE_INFO = json.dumps(
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         Adict.objects.create(
             slug='test',
             service_root_url='http://adict.example.net/',
@@ -40,9 +40,9 @@ def connector(db):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_feature_info(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('adict', 'feature_info', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('adict', 'feature_info', slug=connector.slug)
     assert endpoint == '/adict/test/feature_info'
-    mocked_get.return_value = utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200)
     resp = app.get(endpoint, params={'lat': '48.570472877', 'lon': '7.75659804'})
     assert mocked_get.call_args[0][0] == 'http://adict.example.net/api/v1.0/secteurs'
     assert mocked_get.call_args[1]['params']['x'] == '7.75659804'
@@ -52,9 +52,9 @@ def test_feature_info(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_no_feature_info(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('adict', 'feature_info', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('adict', 'feature_info', slug=connector.slug)
     assert endpoint == '/adict/test/feature_info'
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps({'features': []}), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps({'features': []}), status_code=200)
     resp = app.get(endpoint, params={'lat': '48.570472877', 'lon': '7.75659804'})
     assert resp.json['err'] == 1
     assert resp.json['err_msg'] == 'not found'
diff --git a/tests/test_airquality.py b/tests/test_airquality.py
index 22634562..ce09ffc0 100644
--- a/tests/test_airquality.py
+++ b/tests/test_airquality.py
@@ -2,9 +2,9 @@
 
 import freezegun
 import pytest
-import utils
 from httmock import HTTMock, response
 
+import tests.utils
 from passerelle.apps.airquality.models import AirQuality
 
 SAMPLE_RESPONSE = {
@@ -69,7 +69,7 @@ def mocked_http(url, request):
 
 @freezegun.freeze_time('2020-12-21')
 def test_airquality_details(app, airquality):
-    endpoint = utils.generic_endpoint_url('airquality', 'details', slug=airquality.slug)
+    endpoint = tests.utils.generic_endpoint_url('airquality', 'details', slug=airquality.slug)
     assert endpoint == '/airquality/atmo/details'
     with HTTMock(mocked_http):
         resp = app.get(endpoint + '/fr/lyon/', status=200)
@@ -78,5 +78,5 @@ def test_airquality_details(app, airquality):
 
 
 def test_airquality_details_unknown_city(app, airquality):
-    endpoint = utils.generic_endpoint_url('airquality', 'details', slug=airquality.slug)
+    endpoint = tests.utils.generic_endpoint_url('airquality', 'details', slug=airquality.slug)
     resp = app.get(endpoint + '/fr/paris/', status=404)
diff --git a/tests/test_api.py b/tests/test_api.py
index 51bf84cb..8b8eb90c 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -19,10 +19,10 @@ import pytest
 from django.contrib.contenttypes.models import ContentType
 from django.test import override_settings
 from django.urls import reverse
-from test_manager import login
 
 from passerelle.apps.ovh.models import OVHSMSGateway
 from passerelle.base.models import AccessRight, ApiUser, Job
+from tests.test_manager import login
 
 pytestmark = pytest.mark.django_db
 
diff --git a/tests/test_api_access.py b/tests/test_api_access.py
index d700492c..e3bd5417 100644
--- a/tests/test_api_access.py
+++ b/tests/test_api_access.py
@@ -2,12 +2,12 @@ import re
 import sys
 
 import pytest
-import utils
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.test import override_settings
 from django.urls import reverse
 
+import tests.utils
 from passerelle.apps.oxyd.models import OxydSMSGateway
 from passerelle.base import signature
 from passerelle.base.models import AccessRight, ApiUser, ResourceLog
diff --git a/tests/test_api_entreprise.py b/tests/test_api_entreprise.py
index 236c95cc..cec6e5e1 100644
--- a/tests/test_api_entreprise.py
+++ b/tests/test_api_entreprise.py
@@ -21,9 +21,9 @@ import pytest
 import requests
 from django.utils import timezone
 from httmock import HTTMock, response, urlmatch
-from utils import FakedResponse, make_resource
 
 from passerelle.apps.api_entreprise.models import APIEntreprise
+from tests.utils import FakedResponse, make_resource
 
 ETABLISSEMENTS_RESPONSE = {
     "etablissement": {
diff --git a/tests/test_api_particulier.py b/tests/test_api_particulier.py
index 24ed99e3..6ce7f7fd 100644
--- a/tests/test_api_particulier.py
+++ b/tests/test_api_particulier.py
@@ -22,11 +22,11 @@ import pytest
 import requests
 from django.urls import reverse
 from httmock import HTTMock, response, urlmatch
-from test_manager import login
-from utils import endpoint_get, make_resource
 
 from passerelle.apps.api_particulier.models import APIParticulier
 from passerelle.base.models import ResourceLog
+from tests.test_manager import login
+from tests.utils import endpoint_get, make_resource
 
 SVAIR_RESPONSE = {
     "declarant1": {
diff --git a/tests/test_arcgis.py b/tests/test_arcgis.py
index 8dfc3121..95c9ccde 100644
--- a/tests/test_arcgis.py
+++ b/tests/test_arcgis.py
@@ -5,15 +5,15 @@ import json
 
 import mock
 import pytest
-import utils
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ValidationError
-from test_manager import login
 
+import tests.utils
 from passerelle.apps.arcgis.models import ArcGIS, Query, SqlFormatter, validate_where
 from passerelle.base.models import AccessRight, ApiUser
 from passerelle.utils import import_site
+from tests.test_manager import login
 
 pytestmark = pytest.mark.django_db
 
@@ -89,12 +89,12 @@ def arcgis():
 
 
 def test_arcgis_mapservice_query(app, arcgis):
-    endpoint = utils.generic_endpoint_url('arcgis', 'mapservice-query', slug=arcgis.slug)
+    endpoint = tests.utils.generic_endpoint_url('arcgis', 'mapservice-query', slug=arcgis.slug)
     assert endpoint == '/arcgis/test/mapservice-query'
     params = {'folder': 'fold', 'service': 'serv', 'layer': '1'}
 
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=STATES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=STATES, status_code=200)
 
         resp = app.get(endpoint, params=params, status=403)
         assert requests_get.call_count == 0
@@ -241,7 +241,7 @@ def test_arcgis_mapservice_query(app, arcgis):
 
     # call errors
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=STATES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=STATES, status_code=200)
         resp = app.get(endpoint, params={}, status=400)
         assert requests_get.call_count == 0
         assert resp.json['err'] == 1
@@ -343,7 +343,9 @@ def test_query_q_method(arcgis, query, rf):
         'meta': {},
     }
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=json.dumps(arcgis_response), status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(
+            content=json.dumps(arcgis_response), status_code=200
+        )
         assert query.q(rf.get('/', data={'adress': "AVENUE D'ANNAM"}), full=True) == {
             "data": [
                 {
@@ -370,11 +372,11 @@ def test_query_q_method(arcgis, query, rf):
 
 
 def test_q_endpoint(arcgis, query, app):
-    endpoint = utils.generic_endpoint_url('arcgis', 'q/adresses/', slug=arcgis.slug)
+    endpoint = tests.utils.generic_endpoint_url('arcgis', 'q/adresses/', slug=arcgis.slug)
     assert endpoint == '/arcgis/test/q/adresses/'
 
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=STATES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=STATES, status_code=200)
 
         resp = app.get(endpoint, params={}, status=403)
         assert requests_get.call_count == 0
@@ -406,7 +408,7 @@ def test_tile_endpoint(arcgis, app):
     assert arcgis.base_url == 'https://arcgis.example.net/'
 
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content='', status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content='', status_code=200)
 
         resp = app.get('/arcgis/test/tile/layer1/13/4258/2991.png')
         assert requests_get.call_count == 1
@@ -419,7 +421,7 @@ def test_tile_endpoint(arcgis, app):
 
     # test layer and folders
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content='', status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content='', status_code=200)
 
         resp = app.get('/arcgis/test/tile/layer1/foo/bar/13/4258/2991.png')
         assert requests_get.call_count == 1
@@ -434,7 +436,7 @@ def test_tile_endpoint(arcgis, app):
     arcgis.base_url = 'https://arcgis.example.net'
     arcgis.save()
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content='', status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content='', status_code=200)
 
         resp = app.get('/arcgis/test/tile/layer1/13/4258/2991.png')
         assert requests_get.call_count == 1
diff --git a/tests/test_arpege_ecp.py b/tests/test_arpege_ecp.py
index 500184d8..0975714f 100644
--- a/tests/test_arpege_ecp.py
+++ b/tests/test_arpege_ecp.py
@@ -4,9 +4,9 @@ import json
 
 import mock
 import pytest
-import utils
 from django.urls import reverse
 
+import tests.utils
 from passerelle.apps.arpege_ecp.models import ArpegeECP
 from passerelle.utils.jsonresponse import APIError
 
@@ -65,12 +65,12 @@ def connector(db):
     resource = ArpegeECP.objects.create(
         slug='test', webservice_base_url='http://arpege.net', hawk_auth_id='id', hawk_auth_key='secret'
     )
-    return utils.setup_access_rights(resource)
+    return tests.utils.setup_access_rights(resource)
 
 
 @mock.patch('passerelle.utils.Request.get')
 def test_check_status(mocked_get, connector):
-    mocked_get.return_value = utils.FakedResponse(content=FAKE_HELLO_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_HELLO_RESPONSE, status_code=200)
     resp = connector.check_status()
     assert resp['data'] == u'InteropAPI v1 (c) Arpège 2017'
 
@@ -79,34 +79,34 @@ def test_check_status(mocked_get, connector):
 def test_check_status(mocked_get, connector):
     hello_response = json.loads(FAKE_HELLO_RESPONSE)
     del hello_response['Data']
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps(hello_response), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(hello_response), status_code=200)
     with pytest.raises(Exception) as error:
         resp = connector.check_status()
     assert str(error.value) == 'Invalid credentials'
 
 
 def test_get_access_token(connector):
-    with utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE):
+    with tests.utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE):
         token = connector.get_access_token('nameid')
     assert token == '0f86353f2d87b8b78aaaacc2ecc763e287ded44f773289a5e336546a251718b3'
 
-    with utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE, status_code=404):
+    with tests.utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE, status_code=404):
         with pytest.raises(APIError) as error:
             token = connector.get_access_token('nameid')
 
     assert ' 404 ' in str(error.value)
 
-    with utils.mock_url(response="content", status_code=200):
+    with tests.utils.mock_url(response="content", status_code=200):
         with pytest.raises(APIError) as error:
             token = connector.get_access_token('nameid')
     assert 'no JSON content' in str(error.value)
 
-    with utils.mock_url(response="content", status_code=200):
+    with tests.utils.mock_url(response="content", status_code=200):
         with pytest.raises(APIError) as error:
             token = connector.get_access_token('nameid')
     assert 'no JSON content' in str(error.value)
 
-    with utils.mock_url(
+    with tests.utils.mock_url(
         response='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Auth FAIL"}', status_code=200
     ):
         with pytest.raises(APIError) as error:
@@ -128,8 +128,8 @@ def test_get_user_forms(mocked_post, mocked_get, app, connector):
     )
     assert endpoint == '/arpege-ecp/test/api/users/nameid/forms'
 
-    mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content=FAKE_USER_DEMANDS_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_USER_DEMANDS_RESPONSE, status_code=200)
     resp = app.get(endpoint)
     result = resp.json
     assert resp.json['data']
@@ -160,8 +160,8 @@ def test_get_user_forms_failure(mocked_post, mocked_get, app, connector):
         },
     )
 
-    mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(
+    mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(
         content='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Failed to get demands"}',
         status_code=200,
     )
@@ -182,8 +182,8 @@ def test_get_user_forms_failure_404(app, connector):
         },
     )
 
-    with utils.mock_url(url='/LoginParSubOIDC', response=FAKE_LOGIN_OIDC_RESPONSE):
-        with utils.mock_url(url='/DemandesUsager', status_code=404):
+    with tests.utils.mock_url(url='/LoginParSubOIDC', response=FAKE_LOGIN_OIDC_RESPONSE):
+        with tests.utils.mock_url(url='/DemandesUsager', status_code=404):
             resp = app.get(endpoint)
             result = resp.json
             assert result['err'] == 1
@@ -204,8 +204,8 @@ def test_get_user_forms_failure_no_json(mocked_post, mocked_get, app, connector)
         },
     )
 
-    mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content='content', status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content='content', status_code=200)
     resp = app.get(endpoint)
     result = resp.json
     assert result['err'] == 1
@@ -228,8 +228,8 @@ def test_get_user_forms_failure_no_json(mocked_post, mocked_get, app, connector)
     demands_response = json.loads(FAKE_USER_DEMANDS_RESPONSE)
     demands_response['Data']['results'][0]['data_administratives']['date_depot'] = None
 
-    mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps(demands_response), status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(demands_response), status_code=200)
     resp = app.get(endpoint)
     result = resp.json
     assert result['err'] == 1
@@ -251,8 +251,8 @@ def test_get_user_forms_failure_no_token(mocked_post, mocked_get, app, connector
 
     token_response = json.loads(FAKE_LOGIN_OIDC_RESPONSE)
     del token_response['Data']['AccessToken']
-    mocked_post.return_value = utils.FakedResponse(content=json.dumps(token_response), status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content='content', status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=json.dumps(token_response), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content='content', status_code=200)
     resp = app.get(endpoint)
     result = resp.json
     assert result['err'] == 1
@@ -274,8 +274,8 @@ def test_get_user_forms_failure_wrong_token(mocked_post, mocked_get, app, connec
 
     token_response = json.loads(FAKE_LOGIN_OIDC_RESPONSE)
     token_response['Data']['AccessToken'] = None
-    mocked_post.return_value = utils.FakedResponse(content=json.dumps(token_response), status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content='content', status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=json.dumps(token_response), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content='content', status_code=200)
     resp = app.get(endpoint)
     result = resp.json
     assert result['err'] == 1
diff --git a/tests/test_astech.py b/tests/test_astech.py
index 5833a69e..74bf1b02 100644
--- a/tests/test_astech.py
+++ b/tests/test_astech.py
@@ -18,18 +18,18 @@
 
 import mock
 import pytest
-import utils
 from django.urls import reverse
 from requests import Request
 from requests.exceptions import ConnectionError
 
+import tests.utils
 from passerelle.apps.astech.models import ASTech
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def setup(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         ASTech.objects.create(
             slug='test',
             base_url='https://astech.example.net/app.php/',
@@ -82,7 +82,7 @@ POSITIONS_RESPONSE = """
 
 @mock.patch("passerelle.utils.Request.request")
 def test_connections(mocked_request, app, setup):
-    mocked_request.return_value = utils.FakedResponse(content=CONNECTION_RESPONSE, status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content=CONNECTION_RESPONSE, status_code=200)
     endpoint = reverse(
         "generic-endpoint",
         kwargs={"connector": "astech", "slug": setup.slug, "endpoint": "connections"},
@@ -104,7 +104,7 @@ def test_connections(mocked_request, app, setup):
     assert response.json["data"]["default"] == "TEST"
 
     # bad response
-    mocked_request.return_value = utils.FakedResponse(
+    mocked_request.return_value = tests.utils.FakedResponse(
         content='{"msg": "not found"}', status_code=404, reason="Not Found"
     )
     response = app.get(endpoint)
@@ -113,14 +113,16 @@ def test_connections(mocked_request, app, setup):
     assert response.json["err_desc"] == "AS-TECH response: 404 Not Found"
     assert response.json["data"]["error"]["status"] == 404
     assert response.json["data"]["error"]["content"]["msg"] == "not found"
-    mocked_request.return_value = utils.FakedResponse(content="crash", status_code=500, reason="Crashhhh")
+    mocked_request.return_value = tests.utils.FakedResponse(
+        content="crash", status_code=500, reason="Crashhhh"
+    )
     response = app.get(endpoint)
     assert response.json["err"] == 1
     assert response.json["err_class"].endswith("APIError")
     assert response.json["err_desc"] == "AS-TECH response: 500 Crashhhh"
     assert response.json["data"]["error"]["status"] == 500
     assert response.json["data"]["error"]["content"] == "crash"
-    mocked_request.return_value = utils.FakedResponse(content="not json", status_code=200, reason="OK")
+    mocked_request.return_value = tests.utils.FakedResponse(content="not json", status_code=200, reason="OK")
     response = app.get(endpoint)
     assert response.json["err"] == 1
     assert response.json["err_class"].endswith("APIError")
@@ -135,8 +137,8 @@ def test_connections(mocked_request, app, setup):
 @mock.patch("passerelle.utils.Request.request")
 def test_authorization(mocked_request, app, setup):
     mocked_request.side_effect = [
-        utils.FakedResponse(content=CONNECTION_RESPONSE, status_code=200),
-        utils.FakedResponse(content=AUTH_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=CONNECTION_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=AUTH_RESPONSE, status_code=200),
     ]
     endpoint = reverse(
         "generic-endpoint",
@@ -166,7 +168,7 @@ def test_services(mocked_auth, mocked_request, app, setup):
         kwargs={"connector": "astech", "slug": setup.slug, "endpoint": "services"},
     )
 
-    mocked_request.return_value = utils.FakedResponse(content=SERVICES_RESPONSE, status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content=SERVICES_RESPONSE, status_code=200)
     response = app.get(endpoint)
     assert mocked_request.call_count == 1
     assert mocked_request.call_args[0][0] == 'post'
@@ -190,7 +192,7 @@ def test_companies(mocked_auth, mocked_request, app, setup):
         kwargs={"connector": "astech", "slug": setup.slug, "endpoint": "companies"},
     )
 
-    mocked_request.return_value = utils.FakedResponse(content=COMPANIES_RESPONSE, status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content=COMPANIES_RESPONSE, status_code=200)
     response = app.get(endpoint)
     assert mocked_request.call_count == 1
     assert mocked_request.call_args[0][0] == 'post'
@@ -214,8 +216,8 @@ def test_labels(mocked_auth, mocked_request, app, setup):
     )
 
     mocked_request.side_effect = [
-        utils.FakedResponse(content=COMPANY_RESPONSE, status_code=200),
-        utils.FakedResponse(content=LABELS_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=COMPANY_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=LABELS_RESPONSE, status_code=200),
     ]
     response = app.get(endpoint, status=200)
     assert mocked_request.call_count == 2
@@ -233,7 +235,7 @@ def test_labels(mocked_auth, mocked_request, app, setup):
     ]
 
     mocked_request.reset_mock(side_effect=True)
-    mocked_request.return_value = utils.FakedResponse(content=LABELS_RESPONSE, status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content=LABELS_RESPONSE, status_code=200)
     response = app.get(endpoint + '?company=42', status=200)
     assert mocked_request.call_count == 1
     assert mocked_request.call_args[0][0] == 'post'
@@ -253,8 +255,8 @@ def test_parameter(mocked_auth, mocked_request, app, setup):
     )
 
     mocked_request.side_effect = [
-        utils.FakedResponse(content=COMPANY_RESPONSE, status_code=200),
-        utils.FakedResponse(content=PARAMETER_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=COMPANY_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=PARAMETER_RESPONSE, status_code=200),
     ]
     response = app.get(endpoint + '?name=LIBELDEMDEF', status=200)
     assert mocked_request.call_count == 2
@@ -266,7 +268,7 @@ def test_parameter(mocked_auth, mocked_request, app, setup):
     assert response.json['data']['LIBELDEMDEF'] == 'O'
 
     mocked_request.reset_mock(side_effect=True)
-    mocked_request.return_value = utils.FakedResponse(content=PARAMETER_RESPONSE, status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content=PARAMETER_RESPONSE, status_code=200)
     response = app.get(endpoint + '?name=LIBELDEMDEF&company=00', status=200)
     assert mocked_request.call_count == 1
     assert mocked_request.call_args[0][0] == 'get'
@@ -286,7 +288,7 @@ def test_create_demand(mocked_auth, mocked_request, app, setup):
         kwargs={"connector": "astech", "slug": setup.slug, "endpoint": "create-demand"},
     )
 
-    mocked_request.return_value = utils.FakedResponse(content=CREATE_DEMAND_RESPONSE, status_code=201)
+    mocked_request.return_value = tests.utils.FakedResponse(content=CREATE_DEMAND_RESPONSE, status_code=201)
     demand = {
         'company': '99',
         'service': '11',
@@ -325,7 +327,7 @@ def test_create_demand(mocked_auth, mocked_request, app, setup):
     assert response.json['data']['demand_id'] == '000000000001234'
 
     # mock invalid AS-TECH response
-    mocked_request.return_value = utils.FakedResponse(content='{"foo":"bar"}', status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content='{"foo":"bar"}', status_code=200)
     response = app.post_json(endpoint, params=demand, status=200)
     assert mocked_request.call_count == 2
     assert response.json['err'] == 1
@@ -342,7 +344,7 @@ def test_create_demand(mocked_auth, mocked_request, app, setup):
         "generic-endpoint",
         kwargs={"connector": "astech", "slug": setup.slug, "endpoint": "add-document"},
     )
-    mocked_request.return_value = utils.FakedResponse(content=ADD_DOCUMENT_RESPONSE, status_code=201)
+    mocked_request.return_value = tests.utils.FakedResponse(content=ADD_DOCUMENT_RESPONSE, status_code=201)
     document = {
         'demand_id': '000000000001234',
         'title': 'test document',
@@ -373,7 +375,7 @@ def test_positions(mocked_auth, mocked_request, app, setup):
         "generic-endpoint",
         kwargs={"connector": "astech", "slug": setup.slug, "endpoint": "demand-position"},
     )
-    mocked_request.return_value = utils.FakedResponse(content=POSITION_RESPONSE, status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content=POSITION_RESPONSE, status_code=200)
     response = app.get(endpoint + '?demand_id=000000000001234', status=200)
     assert mocked_request.call_count == 1
     assert mocked_request.call_args[0][0] == 'get'
@@ -388,7 +390,7 @@ def test_positions(mocked_auth, mocked_request, app, setup):
     }
 
     # invalid AS-TECH response
-    mocked_request.return_value = utils.FakedResponse(content='{"foo":"bar"}', status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content='{"foo":"bar"}', status_code=200)
     response = app.get(endpoint + '?demand_id=000000000001234', status=200)
     assert mocked_request.call_count == 2
     assert response.json['err'] == 1
@@ -403,7 +405,7 @@ def test_positions(mocked_auth, mocked_request, app, setup):
         "generic-endpoint",
         kwargs={"connector": "astech", "slug": setup.slug, "endpoint": "demand-all-positions"},
     )
-    mocked_request.return_value = utils.FakedResponse(content=POSITIONS_RESPONSE, status_code=200)
+    mocked_request.return_value = tests.utils.FakedResponse(content=POSITIONS_RESPONSE, status_code=200)
     response = app.get(endpoint, status=200)
     assert mocked_request.call_count == 1
     assert mocked_request.call_args[0][0] == 'get'
diff --git a/tests/test_astregs.py b/tests/test_astregs.py
index 8cd24732..cab28cb4 100644
--- a/tests/test_astregs.py
+++ b/tests/test_astregs.py
@@ -6,12 +6,12 @@ import re
 
 import mock
 import pytest
-import utils
 from django.utils.encoding import force_bytes, force_str, force_text
 from django.utils.http import urlencode
 from requests import Request
 from requests.exceptions import ConnectionError
 
+import tests.utils
 from passerelle.apps.astregs.models import AstreGS, Link
 
 BASE_URL = 'https://test-ws-astre-gs.departement06.fr/axis2/services/'
@@ -57,7 +57,7 @@ def contact_side_effect(wsdl_url, **kwargs):
 
 @pytest.fixture
 def connector(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         AstreGS,
         title='Test',
         slug='test',
diff --git a/tests/test_atos_genesys.py b/tests/test_atos_genesys.py
index d48533cc..90737854 100644
--- a/tests/test_atos_genesys.py
+++ b/tests/test_atos_genesys.py
@@ -3,9 +3,9 @@
 import os
 
 import pytest
-import utils
 from django.utils.http import urlencode
 
+import tests.utils
 from passerelle.apps.atos_genesys.models import Link, Resource
 
 FAKE_URL = 'https://sirus.fr/'
@@ -13,7 +13,7 @@ FAKE_URL = 'https://sirus.fr/'
 
 @pytest.fixture
 def genesys(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         Resource, title='Test 1', slug='test1', description='Connecteur de test', webservice_base_url=FAKE_URL
     )
 
@@ -23,7 +23,7 @@ def mock_codifications_ok():
     response = open(
         os.path.join(os.path.dirname(__file__), 'data', 'genesys_select_codifications.xml')
     ).read()
-    with utils.mock_url(FAKE_URL, response) as mock:
+    with tests.utils.mock_url(FAKE_URL, response) as mock:
         yield mock
 
 
@@ -43,7 +43,7 @@ def test_base_url_normalization(db):
 
 
 def test_ws_categories(app, genesys, mock_codifications_ok):
-    url = utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
     response = app.get(url)
     assert response.json['err'] == 0
     assert response.json['data']
@@ -51,7 +51,7 @@ def test_ws_categories(app, genesys, mock_codifications_ok):
 
 
 def test_ws_codifications(app, genesys, mock_codifications_ok):
-    url = utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
     url += '/MOT_APA/'
     response = app.get(url)
     assert response.json['err'] == 0
@@ -64,7 +64,7 @@ def test_ws_codifications_failure(app, genesys, mock_500):
 
     cache.clear()
 
-    url = utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
     url += '/MOT_APA/'
     response = app.get(url)
     assert response.json['err'] == 1
@@ -77,8 +77,8 @@ RESPONSE_UNKNOWN_LOGIN = '''<return><ROWSET><ROW>
 
 
 def test_ws_link_unknown_appairage(app, genesys):
-    url = utils.generic_endpoint_url('atos-genesys', 'link', slug=genesys.slug)
-    with utils.mock_url(FAKE_URL, RESPONSE_UNKNOWN_LOGIN):
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'link', slug=genesys.slug)
+    with tests.utils.mock_url(FAKE_URL, RESPONSE_UNKNOWN_LOGIN):
         response = app.post(
             url
             + '?'
@@ -99,9 +99,9 @@ RESPONSE_CREATED = '''<return><ROWSET><ROW>
 
 
 def test_ws_link_created(app, genesys):
-    url = utils.generic_endpoint_url('atos-genesys', 'link', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'link', slug=genesys.slug)
     assert Link.objects.count() == 0
-    with utils.mock_url(FAKE_URL, RESPONSE_CREATED):
+    with tests.utils.mock_url(FAKE_URL, RESPONSE_CREATED):
         response = app.post(
             url
             + '?'
@@ -115,8 +115,8 @@ def test_ws_link_created(app, genesys):
     assert response.json['new']
     assert Link.objects.filter(name_id='zob', id_per='789', resource=genesys).count() == 1
 
-    with utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
-        dossiers_url = utils.generic_endpoint_url('atos-genesys', 'dossiers', slug=genesys.slug)
+    with tests.utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
+        dossiers_url = tests.utils.generic_endpoint_url('atos-genesys', 'dossiers', slug=genesys.slug)
         response = app.get(
             dossiers_url
             + '?'
@@ -127,7 +127,7 @@ def test_ws_link_created(app, genesys):
             )
         )
 
-    url = utils.generic_endpoint_url('atos-genesys', 'unlink', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'unlink', slug=genesys.slug)
     response = app.post(
         url
         + '?'
@@ -151,8 +151,8 @@ RESPONSE_SELECT_USAGER = open(
 def test_ws_dossiers(app, genesys):
     link = Link.objects.create(resource=genesys, name_id='zob', id_per='1234')
 
-    url = utils.generic_endpoint_url('atos-genesys', 'dossiers', slug=genesys.slug)
-    with utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'dossiers', slug=genesys.slug)
+    with tests.utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
         response = app.get(
             url
             + '?'
@@ -177,7 +177,7 @@ def test_ws_dossiers(app, genesys):
 
     link2 = Link.objects.create(resource=genesys, name_id='zob', id_per='4567')
 
-    with utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
+    with tests.utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
         response = app.get(
             url
             + '?'
@@ -199,7 +199,7 @@ def test_ws_dossiers(app, genesys):
         assert response.json['data'][1]['id'] == str(link2.id)
         assert response.json['data'][1]['text'] == u'%s - John DOE' % link2.id_per
 
-    with utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
+    with tests.utils.mock_url(FAKE_URL, RESPONSE_SELECT_USAGER):
         response = app.get(
             url
             + '?'
@@ -305,12 +305,12 @@ RESPONSE_SELECT_USAGER_NO_CONTACTS = '''<?xml version="1.0"?>
 
 
 def test_ws_search(app, genesys):
-    url = utils.generic_endpoint_url('atos-genesys', 'search', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'search', slug=genesys.slug)
 
-    with utils.mock_url(
+    with tests.utils.mock_url(
         FAKE_URL + 'WSUsagerPublik/services/PublikService/chercheBeneficiaire', RESPONSE_SEARCH
     ):
-        with utils.mock_url(
+        with tests.utils.mock_url(
             FAKE_URL + 'WSUsagerPublik/services/PublikService/selectUsager', RESPONSE_SELECT_USAGER
         ):
             response = app.get(
@@ -360,10 +360,10 @@ def test_ws_search(app, genesys):
         },
     ]
 
-    with utils.mock_url(
+    with tests.utils.mock_url(
         FAKE_URL + 'WSUsagerPublik/services/PublikService/chercheBeneficiaire', RESPONSE_SEARCH
     ):
-        with utils.mock_url(
+        with tests.utils.mock_url(
             FAKE_URL + 'WSUsagerPublik/services/PublikService/selectUsager', RESPONSE_SELECT_USAGER
         ):
             response = app.get(
@@ -381,10 +381,10 @@ def test_ws_search(app, genesys):
             assert response.json['err'] == 1
             assert response.json['err_desc'] == 'not-found'
 
-    with utils.mock_url(
+    with tests.utils.mock_url(
         FAKE_URL + 'WSUsagerPublik/services/PublikService/chercheBeneficiaire', RESPONSE_SEARCH
     ):
-        with utils.mock_url(
+        with tests.utils.mock_url(
             FAKE_URL + 'WSUsagerPublik/services/PublikService/selectUsager', RESPONSE_SELECT_USAGER
         ):
             response = app.get(
@@ -401,10 +401,10 @@ def test_ws_search(app, genesys):
             assert response.json['err'] == 1
             assert response.json['err_desc'] == 'not-found'
 
-    with utils.mock_url(
+    with tests.utils.mock_url(
         FAKE_URL + 'WSUsagerPublik/services/PublikService/chercheBeneficiaire', RESPONSE_SEARCH
     ):
-        with utils.mock_url(
+        with tests.utils.mock_url(
             FAKE_URL + 'WSUsagerPublik/services/PublikService/selectUsager',
             RESPONSE_SELECT_USAGER_NO_CONTACTS,
         ):
@@ -424,10 +424,10 @@ def test_ws_search(app, genesys):
 
 
 def test_ws_link_by_id_per(app, genesys):
-    url = utils.generic_endpoint_url('atos-genesys', 'link-by-id-per', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'link-by-id-per', slug=genesys.slug)
 
     assert Link.objects.count() == 0
-    with utils.mock_url(
+    with tests.utils.mock_url(
         FAKE_URL + 'WSUsagerPublik/services/PublikService/selectUsager', RESPONSE_SELECT_USAGER
     ):
         response = app.post(
@@ -448,12 +448,12 @@ def test_ws_link_by_id_per(app, genesys):
     assert data['new']
     assert data['link_id'] == link.pk
 
-    url = utils.generic_endpoint_url('atos-genesys', 'search', slug=genesys.slug)
+    url = tests.utils.generic_endpoint_url('atos-genesys', 'search', slug=genesys.slug)
 
-    with utils.mock_url(
+    with tests.utils.mock_url(
         FAKE_URL + 'WSUsagerPublik/services/PublikService/chercheBeneficiaire', RESPONSE_SEARCH
     ):
-        with utils.mock_url(
+        with tests.utils.mock_url(
             FAKE_URL + 'WSUsagerPublik/services/PublikService/selectUsager', RESPONSE_SELECT_USAGER
         ):
             response = app.get(
diff --git a/tests/test_availability.py b/tests/test_availability.py
index 2cf8b2c3..e41aa602 100644
--- a/tests/test_availability.py
+++ b/tests/test_availability.py
@@ -1,9 +1,9 @@
 # -*- coding: utf-8 -*-
 
 import pytest
-import utils
 from httmock import HTTMock, all_requests
 
+import tests.utils
 from passerelle.apps.feeds.models import Feed
 
 FEED_EXAMPLE = u"""<?xml version="1.0" encoding="UTF-8"?>
@@ -42,7 +42,7 @@ FEED_EXAMPLE = u"""<?xml version="1.0" encoding="UTF-8"?>
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(Feed.objects.create(slug='test', url='http://example.net/'))
+    return tests.utils.setup_access_rights(Feed.objects.create(slug='test', url='http://example.net/'))
 
 
 @all_requests
diff --git a/tests/test_base_adresse.py b/tests/test_base_adresse.py
index a0b5167f..695529e8 100644
--- a/tests/test_base_adresse.py
+++ b/tests/test_base_adresse.py
@@ -6,12 +6,12 @@ import os
 
 import mock
 import pytest
-import utils
 from django.core.management import call_command
 from django.core.management.base import CommandError
 from django.utils.six.moves.urllib.parse import urljoin
 from requests.exceptions import ConnectionError, HTTPError
 
+import tests.utils
 from passerelle.apps.base_adresse.models import (
     AddressCacheModel,
     BaseAdresse,
@@ -88,29 +88,33 @@ FAKE_API_GEO_REGIONS = json.dumps(
 
 @pytest.fixture
 def base_adresse(db):
-    return utils.setup_access_rights(BaseAdresse.objects.create(slug='base-adresse', zipcode='73'))
+    return tests.utils.setup_access_rights(BaseAdresse.objects.create(slug='base-adresse', zipcode='73'))
 
 
 @pytest.fixture
 def base_adresse_97x(db):
-    return utils.setup_access_rights(BaseAdresse.objects.create(slug='base-adresse-97x', zipcode='97425'))
+    return tests.utils.setup_access_rights(
+        BaseAdresse.objects.create(slug='base-adresse-97x', zipcode='97425')
+    )
 
 
 @pytest.fixture
 def base_adresse_corsica(db):
-    return utils.setup_access_rights(BaseAdresse.objects.create(slug='base-adresse', zipcode='20000, 20100 '))
+    return tests.utils.setup_access_rights(
+        BaseAdresse.objects.create(slug='base-adresse', zipcode='20000, 20100 ')
+    )
 
 
 @pytest.fixture
 def base_adresse_multiple(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         BaseAdresse.objects.create(slug='base-adresse', zipcode='73, 73100, 97425,20000 ')
     )
 
 
 @pytest.fixture
 def base_adresse_coordinates(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         BaseAdresse.objects.create(slug='base-adresse', latitude=1.2, longitude=2.1)
     )
 
@@ -184,9 +188,9 @@ def mock_update_streets():
 
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_search(mocked_get, app, base_adresse):
-    endpoint = utils.generic_endpoint_url('base-adresse', 'search', slug=base_adresse.slug)
+    endpoint = tests.utils.generic_endpoint_url('base-adresse', 'search', slug=base_adresse.slug)
     assert endpoint == '/base-adresse/base-adresse/search'
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
     data = resp.json[0]
     assert data['lat'] == '47.474633'
@@ -198,8 +202,8 @@ def test_base_adresse_search(mocked_get, app, base_adresse):
 def test_base_adresse_search_path(mocked_get, app, base_adresse):
     base_adresse.service_url = 'http://example.net/path/'
     base_adresse.save()
-    endpoint = utils.generic_endpoint_url('base-adresse', 'search', slug=base_adresse.slug)
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
+    endpoint = tests.utils.generic_endpoint_url('base-adresse', 'search', slug=base_adresse.slug)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
     assert mocked_get.call_args[0][0].startswith('http://example.net/path/search/?')
     data = resp.json[0]
@@ -257,7 +261,7 @@ def test_base_adresse_search_api_error(mocked_get, app, base_adresse):
     def raise_for_status():
         raise HTTPError("400 Client Error: Bad Request for url: xxx")
 
-    response = utils.FakedResponse(content=json.dumps({'title': 'error'}), status_code=400)
+    response = tests.utils.FakedResponse(content=json.dumps({'title': 'error'}), status_code=400)
     response.raise_for_status = raise_for_status
     mocked_get.return_value = response
     resp = app.get('/base-adresse/%s/search' % base_adresse.slug, params={'q': 'plop'}, status=200)
@@ -309,7 +313,7 @@ def test_base_adresse_reverse_having_several(mocked_get, app, base_adresse):
         }
     )
     faked_content = json.dumps(content)
-    mocked_get.return_value = utils.FakedResponse(content=faked_content, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=faked_content, status_code=200)
     resp = app.get('/base-adresse/%s/reverse?lon=-0.593775&lat=47.474633' % base_adresse.slug)
     data = resp.json
     assert data['address']['road'] == 'Rue Roger Halope'
@@ -317,7 +321,7 @@ def test_base_adresse_reverse_having_several(mocked_get, app, base_adresse):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_reverse_path(mocked_get, app, base_adresse):
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps({'features': []}), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps({'features': []}), status_code=200)
     base_adresse.service_url = 'http://example.net/path/'
     base_adresse.save()
     app.get('/base-adresse/%s/reverse?lon=-0.593775&lat=47.474633' % base_adresse.slug)
@@ -434,7 +438,7 @@ def test_base_adresse_streets_get_by_codes(app, base_adresse, street):
 def test_base_adresse_command_update(mocked_get, db, base_adresse):
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
     call_command('cron', 'daily')
     mocked_get.assert_called_once_with(
         'https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-73.ndjson.gz'
@@ -462,7 +466,7 @@ def test_base_adresse_command_job_update(mocked_get, db, base_adresse):
     base_adresse.update_api_geo_data = lambda: None
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
     # check the job added at save() downloads streets
     base_adresse.jobs()
     mocked_get.assert_called_once_with(
@@ -488,7 +492,7 @@ def test_base_adresse_command_update_97x(mocked_get, db, base_adresse_97x):
     base_adresse_97x.update_api_geo_data = lambda: None
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
     call_command('cron', 'daily')
     mocked_get.assert_called_once_with(
         'https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-974.ndjson.gz'
@@ -502,7 +506,7 @@ def test_base_adresse_command_update_corsica(mocked_get, db, base_adresse_corsic
     base_adresse_corsica.update_api_geo_data = lambda: None
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
     call_command('cron', 'daily')
     assert mocked_get.call_count == 2
     mocked_get.assert_any_call(
@@ -520,7 +524,7 @@ def test_base_adresse_command_update_multiple(mocked_get, db, base_adresse_multi
     base_adresse_multiple.update_api_geo_data = lambda: None
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
     call_command('cron', 'daily')
     assert mocked_get.call_count == 4
     mocked_get.assert_any_call(
@@ -691,7 +695,7 @@ def test_base_adresse_regions(app, base_adresse, region):
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_command_update_geo(mocked_get, db, base_adresse, base_adresse_97x):
     return_values = [
-        utils.FakedResponse(content=content, status_code=200)
+        tests.utils.FakedResponse(content=content, status_code=200)
         for content in (FAKE_API_GEO_REGIONS, FAKE_API_GEO_DEPARTMENTS, FAKE_API_GEO) * 2
     ]
     mocked_get.side_effect = return_values
@@ -758,7 +762,7 @@ def test_base_adresse_command_update_geo(mocked_get, db, base_adresse, base_adre
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_command_update_geo_delete(mocked_get, db, base_adresse):
     return_values = [
-        utils.FakedResponse(content=content, status_code=200)
+        tests.utils.FakedResponse(content=content, status_code=200)
         for content in (FAKE_API_GEO_REGIONS, FAKE_API_GEO_DEPARTMENTS, FAKE_API_GEO)
     ]
     mocked_get.side_effect = return_values
@@ -767,7 +771,7 @@ def test_base_adresse_command_update_geo_delete(mocked_get, db, base_adresse):
 
     new_fake_api_geo = json.dumps([FAKE_API_GEO_LIST[1]])
     return_values = [
-        utils.FakedResponse(content=content, status_code=200)
+        tests.utils.FakedResponse(content=content, status_code=200)
         for content in (FAKE_API_GEO_REGIONS, FAKE_API_GEO_DEPARTMENTS, new_fake_api_geo)
     ]
     mocked_get.side_effect = return_values
@@ -779,7 +783,7 @@ def test_base_adresse_command_update_geo_delete(mocked_get, db, base_adresse):
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_command_job_update_geo(mocked_get, db, base_adresse):
     return_values = [
-        utils.FakedResponse(content=content, status_code=200)
+        tests.utils.FakedResponse(content=content, status_code=200)
         for content in (FAKE_API_GEO_REGIONS, FAKE_API_GEO_DEPARTMENTS, FAKE_API_GEO)
     ]
     mocked_get.side_effect = return_values
@@ -796,18 +800,18 @@ def test_base_adresse_command_job_update_geo(mocked_get, db, base_adresse):
 @pytest.mark.usefixtures('mock_update_streets')
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_command_update_geo_invalid(mocked_get, db, base_adresse):
-    mocked_get.return_value = utils.FakedResponse(content='{}', status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content='{}', status_code=200)
     with pytest.raises(CommandError):
         call_command('cron', 'daily')
     assert mocked_get.call_count == 1
     assert not RegionModel.objects.exists()
 
-    mocked_get.return_value = utils.FakedResponse(content=FAKE_API_GEO, status_code=500)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_API_GEO, status_code=500)
     call_command('cron', 'daily')
     assert mocked_get.call_count == 4
     assert not RegionModel.objects.exists()
 
-    mocked_get.return_value = utils.FakedResponse(content='not-json', status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content='not-json', status_code=200)
     call_command('cron', 'daily')
     assert mocked_get.call_count == 7
     assert not RegionModel.objects.exists()
@@ -831,9 +835,9 @@ def test_base_adresse_command_update_geo_no_connection(mocked_get, db, base_adre
 
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_addresses(mocked_get, app, base_adresse):
-    endpoint = utils.generic_endpoint_url('base-adresse', 'addresses', slug=base_adresse.slug)
+    endpoint = tests.utils.generic_endpoint_url('base-adresse', 'addresses', slug=base_adresse.slug)
     assert endpoint == '/base-adresse/base-adresse/addresses'
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
     data = resp.json['data'][0]
     assert data['lat'] == '47.474633'
@@ -953,8 +957,8 @@ def test_base_adresse_addresses_clean_cache(app, base_adresse, freezer, mock_api
 
 @mock.patch('passerelle.utils.Request.get')
 def test_base_adresse_addresses_data_change(mocked_get, app, base_adresse):
-    endpoint = utils.generic_endpoint_url('base-adresse', 'addresses', slug=base_adresse.slug)
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
+    endpoint = tests.utils.generic_endpoint_url('base-adresse', 'addresses', slug=base_adresse.slug)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
 
     # one user selects an address
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
@@ -964,7 +968,7 @@ def test_base_adresse_addresses_data_change(mocked_get, app, base_adresse):
     # another requests the same while upstream data has been updated
     new_content = json.loads(FAKED_CONTENT)
     new_content['features'][0]['properties']['label'] = 'changed'
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps(new_content), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(new_content), status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
 
     # first user saves the form, data should not have changed
diff --git a/tests/test_caluire_axel.py b/tests/test_caluire_axel.py
index cc12823d..6daa37c6 100644
--- a/tests/test_caluire_axel.py
+++ b/tests/test_caluire_axel.py
@@ -23,9 +23,9 @@ from contextlib import contextmanager
 import freezegun
 import mock
 import pytest
-import utils
 import xmlschema
 
+import tests.utils
 from passerelle.contrib.caluire_axel import schemas
 from passerelle.contrib.caluire_axel.models import CaluireAxel, Link
 from passerelle.contrib.utils.axel import AxelError, OperationResult, json_date_format, xml_date_format
@@ -47,7 +47,7 @@ XML_RESPONSE_TEMPLATE = '''<?xml version="1.0"?>
 
 @pytest.fixture
 def resource(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         CaluireAxel, slug='test', wsdl_url='http://example.net/AXEL_WS/AxelWS.php?wsdl'
     )
 
diff --git a/tests/test_cartads_cs.py b/tests/test_cartads_cs.py
index 7ad87f5b..f741c4b0 100644
--- a/tests/test_cartads_cs.py
+++ b/tests/test_cartads_cs.py
@@ -7,11 +7,11 @@ from collections import OrderedDict
 
 import mock
 import pytest
-import utils
 from django.core.files.storage import default_storage
 from django.test import override_settings
 from httmock import HTTMock
 
+import tests.utils
 from passerelle.apps.cartads_cs.models import CartaDSCS, CartaDSDossier, CartaDSFile
 from passerelle.base.models import Job
 from passerelle.compat import json_loads
@@ -19,7 +19,7 @@ from passerelle.compat import json_loads
 
 @pytest.fixture
 def connector(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         CartaDSCS,
         title='Test',
         slug='test',
diff --git a/tests/test_cityweb.py b/tests/test_cityweb.py
index 2d5f234d..854e3260 100644
--- a/tests/test_cityweb.py
+++ b/tests/test_cityweb.py
@@ -24,11 +24,11 @@ import zipfile
 
 import mock
 import pytest
-import utils
 from django.core.files.storage import default_storage
 from lxml import etree
 from lxml import objectify as xobject
 
+import tests.utils
 from passerelle.apps.cityweb.cityweb import DateType
 from passerelle.apps.cityweb.models import CityWeb
 from passerelle.utils.jsonresponse import APIError
@@ -46,7 +46,7 @@ def get_file_from_test_base_dir(filename):
 
 @pytest.fixture
 def setup(db):
-    return utils.setup_access_rights(CityWeb.objects.create(slug='test'))
+    return tests.utils.setup_access_rights(CityWeb.objects.create(slug='test'))
 
 
 PAYLOAD = [
diff --git a/tests/test_clicrdv.py b/tests/test_clicrdv.py
index bee821be..a0a44077 100644
--- a/tests/test_clicrdv.py
+++ b/tests/test_clicrdv.py
@@ -3,10 +3,10 @@ import pytest
 from django.contrib.contenttypes.models import ContentType
 from django.utils.six.moves.urllib import parse as urlparse
 from requests.exceptions import HTTPError
-from test_manager import login
 
 from passerelle.apps.clicrdv.models import ClicRdv
 from passerelle.base.models import AccessRight, ApiUser
+from tests.test_manager import login
 
 
 @pytest.fixture
diff --git a/tests/test_cmis.py b/tests/test_cmis.py
index 5b3284a2..ef1e88de 100644
--- a/tests/test_cmis.py
+++ b/tests/test_cmis.py
@@ -20,10 +20,10 @@ from django.urls import reverse
 from django.utils.encoding import force_bytes, force_text
 from django.utils.six.moves.urllib import error as urllib2
 from mock import Mock, call
-from test_manager import login
 
 from passerelle.apps.cmis.models import CmisConnector
 from passerelle.base.models import AccessRight, ApiUser, ResourceLog
+from tests.test_manager import login
 
 
 def b64encode(content):
diff --git a/tests/test_cryptor.py b/tests/test_cryptor.py
index 14ac6b6d..38444c7e 100644
--- a/tests/test_cryptor.py
+++ b/tests/test_cryptor.py
@@ -3,11 +3,11 @@
 import base64
 
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ValidationError
 from django.utils.encoding import force_text
 
+import tests.utils
 from passerelle.apps.cryptor.models import CryptedFile, Cryptor
 from passerelle.base.models import AccessRight, ApiUser
 
@@ -77,14 +77,14 @@ def test_cryptor_bad_keys(db):
 
 
 def test_cryptor_restricted_access(app, cryptor):
-    endpoint = utils.generic_endpoint_url('cryptor', 'file-encrypt', slug=cryptor.slug)
+    endpoint = tests.utils.generic_endpoint_url('cryptor', 'file-encrypt', slug=cryptor.slug)
     assert endpoint == '/cryptor/test/file-encrypt'
     resp = app.get(endpoint, status=405)
     resp = app.post_json(endpoint, params={"foo": "bar"}, status=403)
     assert resp.json['err'] == 1
     assert 'PermissionDenied' in resp.json['err_class']
 
-    endpoint = utils.generic_endpoint_url('cryptor', 'file-decrypt', slug=cryptor.slug) + '/uuid'
+    endpoint = tests.utils.generic_endpoint_url('cryptor', 'file-decrypt', slug=cryptor.slug) + '/uuid'
     assert endpoint == '/cryptor/test/file-decrypt/uuid'
     resp = app.post_json(endpoint, params={"foo": "bar"}, status=405)
     resp = app.get(endpoint, status=403)
@@ -103,7 +103,7 @@ def test_cryptor_bad_requests(app, cryptor):
         codename='can_decrypt', apiuser=api, resource_type=obj_type, resource_pk=cryptor.pk
     )
 
-    endpoint = utils.generic_endpoint_url('cryptor', 'file-encrypt', slug=cryptor.slug)
+    endpoint = tests.utils.generic_endpoint_url('cryptor', 'file-encrypt', slug=cryptor.slug)
     for bad_payload in (
         'error',
         {"foo": "bar"},
@@ -115,7 +115,7 @@ def test_cryptor_bad_requests(app, cryptor):
         resp = app.post_json(endpoint, params=bad_payload, status=400)
         assert resp.json['err'] == 1
 
-    endpoint = utils.generic_endpoint_url('cryptor', 'file-decrypt', slug=cryptor.slug)
+    endpoint = tests.utils.generic_endpoint_url('cryptor', 'file-decrypt', slug=cryptor.slug)
     endpoint = endpoint + '/bad-uuid'
     resp = app.get(endpoint, status=404)
 
@@ -131,7 +131,7 @@ def test_cryptor_encrypt_decrypt(app, cryptor):
     )
 
     # encrypt
-    endpoint = utils.generic_endpoint_url('cryptor', 'file-encrypt', slug=cryptor.slug)
+    endpoint = tests.utils.generic_endpoint_url('cryptor', 'file-encrypt', slug=cryptor.slug)
     content = force_text(base64.b64encode(b'this is foo and bar'))
     payload = {"file": {"filename": "foo.txt", "content_type": "text/plain", "content": content}}
 
@@ -161,7 +161,7 @@ def test_cryptor_encrypt_decrypt(app, cryptor):
     assert resp.json['err_desc'] == 'missing public key'
 
     # decrypt
-    endpoint = utils.generic_endpoint_url('cryptor', 'file-decrypt', slug=cryptor.slug)
+    endpoint = tests.utils.generic_endpoint_url('cryptor', 'file-decrypt', slug=cryptor.slug)
     endpoint = endpoint + '/' + str(cfile.uuid)
     resp = app.get(endpoint, status=200)
     assert resp.content_type == 'text/plain'
diff --git a/tests/test_csv_datasource.py b/tests/test_csv_datasource.py
index a5bfd2d4..455fa4ab 100644
--- a/tests/test_csv_datasource.py
+++ b/tests/test_csv_datasource.py
@@ -37,11 +37,11 @@ from django.utils.encoding import force_bytes, force_str, force_text
 from django.utils.six import StringIO
 from django.utils.six.moves.urllib.parse import urlencode
 from django.utils.timezone import now
-from test_manager import login
 
 from passerelle.apps.csvdatasource.models import CsvDataSource, Query, TableRow, upload_to
 from passerelle.base.models import AccessRight, ApiUser
 from passerelle.compat import json_loads
+from tests.test_manager import login
 
 data = """121;69981;DELANOUE;Eliot;H
 525;6;DANIEL WILLIAMS;Shanone;F
diff --git a/tests/test_dpark.py b/tests/test_dpark.py
index f444c356..9d3a5daa 100644
--- a/tests/test_dpark.py
+++ b/tests/test_dpark.py
@@ -7,12 +7,12 @@ import httmock
 import mock
 import pytest
 from django.utils.encoding import force_text
-from utils import make_resource
 from zeep.exceptions import Fault as WebFault
 from zeep.exceptions import TransportError
 
 from passerelle.contrib.dpark.models import DPark, Pairing
 from passerelle.utils.jsonresponse import APIError
+from tests.utils import make_resource
 
 SLUG = 'test'
 WSDL_URL = 'https://example.net/dpark?wsdl'
diff --git a/tests/test_esirius.py b/tests/test_esirius.py
index 7e53d048..6b23ee6b 100644
--- a/tests/test_esirius.py
+++ b/tests/test_esirius.py
@@ -19,14 +19,14 @@ import json
 
 import httmock
 import pytest
-import utils
 from Cryptodome.Cipher import DES
 from Cryptodome.Util.Padding import pad, unpad
 from django.utils.encoding import force_bytes
-from test_manager import login
 
+import tests.utils
 from passerelle.apps.esirius.models import ESirius
 from passerelle.utils.jsonresponse import APIError
+from tests.test_manager import login
 
 CREATE_APPOINTMENT_PAYLOAD = {
     'beginDate': '2021-02-24',
@@ -80,7 +80,7 @@ GET_APPOINTMENT_RESPONSE = '''
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         ESirius.objects.create(
             slug='test', secret_id='xxx', secret_key='yyy', base_url='https://esirius.example.net'
         )
@@ -88,7 +88,7 @@ def connector(db):
 
 
 def get_endpoint(name):
-    return utils.generic_endpoint_url('esirius', name)
+    return tests.utils.generic_endpoint_url('esirius', name)
 
 
 @pytest.mark.freeze_time('2021-01-26 15:13:6.880')  # epoch + 1611673986.88 s
diff --git a/tests/test_esirius_swi.py b/tests/test_esirius_swi.py
index e2f10f7a..b9dc00c6 100644
--- a/tests/test_esirius_swi.py
+++ b/tests/test_esirius_swi.py
@@ -18,8 +18,8 @@ import os
 
 import mock
 import pytest
-import utils
 
+import tests.utils
 from passerelle.contrib.esirius_swi.models import ESiriusSwi
 from passerelle.contrib.esirius_swi.utils import compute_status
 
@@ -45,7 +45,7 @@ def v1_service_wsdl():
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         ESiriusSwi.objects.create(
             slug='test', base_url='https://example.org/eSirius/webservices/sitewaitingindicator/'
         )
diff --git a/tests/test_feeds.py b/tests/test_feeds.py
index 7b3d53c3..5a27e5ff 100644
--- a/tests/test_feeds.py
+++ b/tests/test_feeds.py
@@ -2,8 +2,8 @@
 
 import mock
 import pytest
-import utils
 
+import tests.utils
 from passerelle.apps.feeds.models import Feed
 
 FEED_EXAMPLE = u"""<?xml version="1.0" encoding="UTF-8"?>
@@ -42,13 +42,13 @@ FEED_EXAMPLE = u"""<?xml version="1.0" encoding="UTF-8"?>
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(Feed.objects.create(slug='test', url='http://example.net/'))
+    return tests.utils.setup_access_rights(Feed.objects.create(slug='test', url='http://example.net/'))
 
 
 @mock.patch('passerelle.utils.Request.get')
 def test_feed(mocked_get, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content=FEED_EXAMPLE, status=200)
-    endpoint = utils.generic_endpoint_url('feeds', 'json', slug=connector.slug)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FEED_EXAMPLE, status=200)
+    endpoint = tests.utils.generic_endpoint_url('feeds', 'json', slug=connector.slug)
     assert endpoint == '/feeds/test/json'
     resp = app.get(endpoint)
     assert resp.json['data']['feed']['title']
diff --git a/tests/test_franceconnect_data.py b/tests/test_franceconnect_data.py
index 9a2cb470..4484df43 100644
--- a/tests/test_franceconnect_data.py
+++ b/tests/test_franceconnect_data.py
@@ -18,15 +18,15 @@ import json
 from urllib.parse import parse_qs, urlparse, urlunparse
 
 import pytest
-import utils
-from test_rsa13 import mock_response
 
+import tests.utils
 from passerelle.apps.franceconnect_data.models import Resource
+from tests.test_rsa13 import mock_response
 
 
 @pytest.fixture
 def fc(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         Resource,
         slug='test',
         fc_platform_slug='prod',
diff --git a/tests/test_gdema.py b/tests/test_gdema.py
index 103f911d..b20dc47f 100644
--- a/tests/test_gdema.py
+++ b/tests/test_gdema.py
@@ -3,9 +3,9 @@ import json
 
 import mock
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 
+import tests.utils
 from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.gdema.models import Gdema
 
@@ -68,10 +68,10 @@ def gdema(db):
 
 
 def test_gdema_services_and_typologies(app, gdema):
-    endpoint = utils.generic_endpoint_url('gdema', 'referentiel', slug=gdema.slug)
+    endpoint = tests.utils.generic_endpoint_url('gdema', 'referentiel', slug=gdema.slug)
     assert endpoint == '/gdema/test/referentiel'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=SERVICES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=SERVICES, status_code=200)
         resp = app.get(endpoint + '/service/', status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/referentiel/service'
@@ -106,10 +106,10 @@ def test_gdema_services_and_typologies(app, gdema):
 
 
 def test_gdema_referentiel(app, gdema):
-    endpoint = utils.generic_endpoint_url('gdema', 'referentiel', slug=gdema.slug)
+    endpoint = tests.utils.generic_endpoint_url('gdema', 'referentiel', slug=gdema.slug)
     assert endpoint == '/gdema/test/referentiel'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=CIVILITY, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=CIVILITY, status_code=200)
         resp = app.get(endpoint + '/civility/', status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/referentiel/civility'
@@ -120,7 +120,7 @@ def test_gdema_referentiel(app, gdema):
         assert resp.json['data'][0]['text'] == 'Monsieur'
 
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content='404', status_code=404)
+        requests_get.return_value = tests.utils.FakedResponse(content='404', status_code=404)
         resp = app.get(endpoint + '/nothing/', status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/referentiel/nothing'
@@ -132,10 +132,10 @@ def test_gdema_referentiel(app, gdema):
 
 
 def test_gdema_get_request(app, gdema):
-    endpoint = utils.generic_endpoint_url('gdema', 'get-request', slug=gdema.slug)
+    endpoint = tests.utils.generic_endpoint_url('gdema', 'get-request', slug=gdema.slug)
     assert endpoint == '/gdema/test/get-request'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=REQUEST, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=REQUEST, status_code=200)
         resp = app.get(endpoint + '/1/', status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/request/1'
@@ -149,10 +149,10 @@ def test_gdema_get_request(app, gdema):
         assert resp.json['data']['Handler']['CivilityId'] == '0'
         assert resp.json['data']['ReceptDate'] == '2006-12-13T00:00:00+01:00'
 
-    endpoint = utils.generic_endpoint_url('gdema', 'get-request-state', slug=gdema.slug)
+    endpoint = tests.utils.generic_endpoint_url('gdema', 'get-request-state', slug=gdema.slug)
     assert endpoint == '/gdema/test/get-request-state'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=REQUEST_STATE, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=REQUEST_STATE, status_code=200)
         resp = app.get(endpoint + '/1/', status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/request/1/state'
@@ -162,10 +162,10 @@ def test_gdema_get_request(app, gdema):
 
 
 def test_gdema_create_request(app, gdema):
-    endpoint = utils.generic_endpoint_url('gdema', 'create-request', slug=gdema.slug)
+    endpoint = tests.utils.generic_endpoint_url('gdema', 'create-request', slug=gdema.slug)
     assert endpoint == '/gdema/test/create-request'
     with mock.patch('passerelle.utils.Request.post') as requests_post:
-        requests_post.return_value = utils.FakedResponse(content=REQUEST, status_code=200)
+        requests_post.return_value = tests.utils.FakedResponse(content=REQUEST, status_code=200)
         resp = app.post_json(endpoint + '?raise=1', params=CREATE_INPUT, status=200)
         assert requests_post.call_count == 1
         assert requests_post.call_args[0][0] == 'https://gdema.example.net/api/request/create'
diff --git a/tests/test_generic_endpoint.py b/tests/test_generic_endpoint.py
index aba83252..7d5327b2 100644
--- a/tests/test_generic_endpoint.py
+++ b/tests/test_generic_endpoint.py
@@ -25,11 +25,10 @@ import warnings
 
 import mock
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
-from test_manager import login
 
+import tests.utils
 from passerelle.apps.api_particulier.models import APIParticulier
 from passerelle.apps.arcgis.models import ArcGIS
 from passerelle.apps.mdel.models import MDEL
@@ -43,16 +42,17 @@ from passerelle.base.models import (
 )
 from passerelle.contrib.stub_invoices.models import StubInvoicesConnector
 from passerelle.utils.api import endpoint
+from tests.test_manager import login
 
 
 @pytest.fixture
 def mdel(db):
-    return utils.setup_access_rights(MDEL.objects.create(slug='test'))
+    return tests.utils.setup_access_rights(MDEL.objects.create(slug='test'))
 
 
 @pytest.fixture
 def arcgis(db):
-    instance = utils.setup_access_rights(ArcGIS.objects.create(slug='test'))
+    instance = tests.utils.setup_access_rights(ArcGIS.objects.create(slug='test'))
     instance.set_log_level('DEBUG')
     return instance
 
@@ -91,7 +91,7 @@ def test_generic_payload_logging(caplog, app, mdel):
 @mock.patch('passerelle.utils.Request.get')
 def test_proxy_logger(mocked_get, caplog, app, arcgis):
     payload = open(os.path.join(os.path.dirname(__file__), 'data', 'nancy_arcgis', 'sigresponse.json')).read()
-    mocked_get.return_value = utils.FakedResponse(content=payload, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=payload, status_code=200)
 
     # simple logger
     arcgis.log_evel = 'DEBUG'
@@ -169,7 +169,7 @@ def test_proxy_logger(mocked_get, caplog, app, arcgis):
 @mock.patch('requests.Session.send')
 def test_proxy_logger_transaction_id(mocked_send, app, arcgis):
     payload = open(os.path.join(os.path.dirname(__file__), 'data', 'nancy_arcgis', 'sigresponse.json')).read()
-    mocked_send.return_value = utils.FakedResponse(content=payload, status_code=200)
+    mocked_send.return_value = tests.utils.FakedResponse(content=payload, status_code=200)
     arcgis.log_evel = 'DEBUG'
     arcgis.base_url = 'https://example.net/'
     arcgis.save()
@@ -185,7 +185,7 @@ def test_proxy_logger_transaction_id(mocked_send, app, arcgis):
 
 @mock.patch('passerelle.utils.Request.patch')
 def test_proxy_logger_on_405(mocked_patch, caplog, app, arcgis):
-    mocked_patch.return_value = utils.FakedResponse(status_code=500)
+    mocked_patch.return_value = tests.utils.FakedResponse(status_code=500)
 
     # simple logger
     arcgis.log_evel = 'WARNING'
@@ -716,7 +716,9 @@ def test_https_warnings(app, db, monkeypatch, httpbin_secure, relax_openssl):
 
     from passerelle.apps.arcgis.models import ArcGIS
 
-    resource = utils.make_resource(ArcGIS, base_url='https://example.com/', slug='gis', verify_cert=True)
+    resource = tests.utils.make_resource(
+        ArcGIS, base_url='https://example.com/', slug='gis', verify_cert=True
+    )
     with pytest.raises(SSLError):
         resource.requests.get(httpbin_secure.join('/get/'))
     resource.verify_cert = False
@@ -1030,7 +1032,7 @@ def test_generic_up_in_endpoints_ordering(db, app, connector_class, expected_ord
 
 
 def test_response_schema(db, app):
-    utils.make_resource(APIParticulier, slug='test', platform='test', api_key='xxx')
+    tests.utils.make_resource(APIParticulier, slug='test', platform='test', api_key='xxx')
     response = app.get('/api-particulier/test/')
     assert 'nombrePersonnesCharge' in response
 
diff --git a/tests/test_gesbac.py b/tests/test_gesbac.py
index 8d27665a..63fe5a15 100644
--- a/tests/test_gesbac.py
+++ b/tests/test_gesbac.py
@@ -21,10 +21,10 @@ import datetime
 import pytest
 from django.utils.encoding import force_bytes, force_str, force_text
 from django.utils.timezone import now
-from utils import make_resource
 
 from passerelle.apps.gesbac.models import Form, Gesbac
 from passerelle.utils import SFTP
+from tests.utils import make_resource
 
 
 @pytest.fixture
diff --git a/tests/test_greco.py b/tests/test_greco.py
index e7ebbc59..cb6c6a20 100644
--- a/tests/test_greco.py
+++ b/tests/test_greco.py
@@ -20,11 +20,11 @@ from base64 import b64encode
 
 import mock
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
 from django.utils.encoding import force_str
 
+import tests.utils
 from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.greco.models import Greco
 
@@ -46,19 +46,19 @@ def get_json_file(filename):
 
 
 def fake_xml_response(basename):
-    return utils.FakedResponse(
+    return tests.utils.FakedResponse(
         content=get_xml_file(basename),
         status_code=200,
         headers={'Content-Type': 'text/xml'},
     )
 
 
-TOKEN = utils.FakedResponse(
+TOKEN = tests.utils.FakedResponse(
     content=get_json_file('token'),
     status_code=200,
     headers={'Content-Type': 'application/json'},
 )
-RESP_503 = utils.FakedResponse(content='Service Unavailable', status_code=503)
+RESP_503 = tests.utils.FakedResponse(content='Service Unavailable', status_code=503)
 PING = fake_xml_response('ping')
 CREATE_OK = fake_xml_response('create_ok')
 CREATE_KO = fake_xml_response('create_ko')
diff --git a/tests/test_grenoble_gru.py b/tests/test_grenoble_gru.py
index 3bbe7a58..7dc9ba3d 100644
--- a/tests/test_grenoble_gru.py
+++ b/tests/test_grenoble_gru.py
@@ -21,15 +21,15 @@ import os
 import mock
 import pytest
 import six
-import utils
 from django.urls import reverse
 
+import tests.utils
 from passerelle.contrib.grenoble_gru.models import GrenobleGRU
 
 
 @pytest.fixture
 def setup(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         GrenobleGRU.objects.create(slug='test', base_url='https://itvvoirie-test.lametro.fr')
     )
 
@@ -120,7 +120,7 @@ Création de la demande via le webService de la commune de Grenoble
 @pytest.fixture(params=['01', '02', '10', '20', '21', '23', '4242'])
 def remote_response(request):
     text = six.text_type(request.param)
-    return utils.FakedResponse(index=request.param_index, text=text)
+    return tests.utils.FakedResponse(index=request.param_index, text=text)
 
 
 def test_contact_mode_typologies_list_with_invalid_xml(app, setup):
diff --git a/tests/test_isere_ens.py b/tests/test_isere_ens.py
index cb6e1303..7e84b161 100644
--- a/tests/test_isere_ens.py
+++ b/tests/test_isere_ens.py
@@ -21,16 +21,16 @@ import os
 
 import mock
 import pytest
-import utils
 from django.urls import reverse
 
+import tests.utils
 from passerelle.contrib.isere_ens.models import API_VERSION, IsereENS
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def setup(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         IsereENS.objects.create(slug="test", base_url="https://ens38.example.net/", token="toktok")
     )
 
@@ -148,7 +148,7 @@ API_VERSIONS = [vers[1] for vers in API_VERSION]
 def test_get_sites(mocked_get, app, setup, api_version):
     setup.api_version = api_version
     setup.save()
-    mocked_get.return_value = utils.FakedResponse(content=SITES_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=SITES_RESPONSE, status_code=200)
     endpoint = reverse(
         "generic-endpoint",
         kwargs={"connector": "isere-ens", "slug": setup.slug, "endpoint": "sites"},
@@ -176,7 +176,7 @@ def test_get_sites(mocked_get, app, setup, api_version):
     response = app.get(endpoint + "?kind=social")
     assert len(response.json["data"]) == 2
 
-    mocked_get.return_value = utils.FakedResponse(content=SD29B_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=SD29B_RESPONSE, status_code=200)
     response = app.get(endpoint + "?id=SD29b")
     assert mocked_get.call_args[0][0].endswith("api/" + api_version + "/site/SD29b")
     assert len(response.json["data"]) == 1
@@ -184,7 +184,7 @@ def test_get_sites(mocked_get, app, setup, api_version):
     assert response.json["data"][0]["dogs"] == "LEASH"
 
     # bad response for ENS API
-    mocked_get.return_value = utils.FakedResponse(content=SITE_404_RESPONSE, status_code=404)
+    mocked_get.return_value = tests.utils.FakedResponse(content=SITE_404_RESPONSE, status_code=404)
     response = app.get(endpoint + "?id=SD29x")
     assert mocked_get.call_args[0][0].endswith("api/" + api_version + "/site/SD29x")
     assert response.json["err"] == 1
@@ -192,7 +192,7 @@ def test_get_sites(mocked_get, app, setup, api_version):
     assert response.json["err_desc"].startswith("error status:404")
     assert response.json["data"]["status_code"] == 404
     assert response.json["data"]["json_content"]["message"] == "Site not found with code SD29x"
-    mocked_get.return_value = utils.FakedResponse(content="crash", status_code=500)
+    mocked_get.return_value = tests.utils.FakedResponse(content="crash", status_code=500)
     response = app.get(endpoint + "?id=foo500")
     assert mocked_get.call_args[0][0].endswith("api/" + api_version + "/site/foo500")
     assert response.json["err"] == 1
@@ -200,13 +200,13 @@ def test_get_sites(mocked_get, app, setup, api_version):
     assert response.json["err_class"].endswith("APIError")
     assert response.json["data"]["status_code"] == 500
     assert response.json["data"]["json_content"] is None
-    mocked_get.return_value = utils.FakedResponse(content=None, status_code=204)
+    mocked_get.return_value = tests.utils.FakedResponse(content=None, status_code=204)
     response = app.get(endpoint + "?id=foo204")
     assert mocked_get.call_args[0][0].endswith("api/" + api_version + "/site/foo204")
     assert response.json["err"] == 1
     assert response.json["err_class"].endswith("APIError")
     assert response.json["err_desc"] == "abnormal empty response"
-    mocked_get.return_value = utils.FakedResponse(content="not json", status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content="not json", status_code=200)
     response = app.get(endpoint + "?id=foo")
     assert mocked_get.call_args[0][0].endswith("api/" + api_version + "/site/foo")
     assert response.json["err"] == 1
@@ -219,7 +219,7 @@ def test_get_sites(mocked_get, app, setup, api_version):
 def test_get_animators(mocked_get, app, setup, api_version):
     setup.api_version = api_version
     setup.save()
-    mocked_get.return_value = utils.FakedResponse(content=ANIMATORS_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=ANIMATORS_RESPONSE, status_code=200)
     endpoint = reverse(
         "generic-endpoint",
         kwargs={"connector": "isere-ens", "slug": setup.slug, "endpoint": "animators"},
@@ -256,7 +256,7 @@ def test_get_site_calendar(mocked_get, app, setup, freezer, api_version):
     setup.api_version = api_version
     setup.save()
     freezer.move_to("2021-01-21 12:00:00")
-    mocked_get.return_value = utils.FakedResponse(content=SITE_CALENDAR_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=SITE_CALENDAR_RESPONSE, status_code=200)
     endpoint = reverse(
         "generic-endpoint",
         kwargs={
@@ -309,7 +309,7 @@ def test_get_site_calendar(mocked_get, app, setup, freezer, api_version):
 
 @mock.patch("passerelle.utils.Request.post")
 def test_post_book_v1(mocked_post, app, setup):
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
     endpoint = reverse(
         "generic-endpoint",
         kwargs={
@@ -350,14 +350,14 @@ def test_post_book_v1(mocked_post, app, setup):
     assert response.json["err"] == 0
     assert response.json["data"]["status"] == "BOOKING"
 
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE_OVERBOOKING, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE_OVERBOOKING, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/1.0.0/booking")
     assert mocked_post.call_count == 2
     assert response.json["err"] == 0
     assert response.json["data"]["status"] == "OVERBOOKING"
 
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE_REFUSED, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE_REFUSED, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/1.0.0/booking")
     assert mocked_post.call_count == 3
@@ -366,7 +366,7 @@ def test_post_book_v1(mocked_post, app, setup):
     assert response.json["err_desc"] == "booking status is REFUSED"
     assert response.json["data"]["status"] == "REFUSED"
 
-    mocked_post.return_value = utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/1.0.0/booking")
     assert mocked_post.call_count == 4
@@ -375,7 +375,7 @@ def test_post_book_v1(mocked_post, app, setup):
     assert response.json["err_desc"] == "response is not a dict"
     assert response.json["data"] == ["not", "a", "dict"]
 
-    mocked_post.return_value = utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/1.0.0/booking")
     assert mocked_post.call_count == 5
@@ -385,7 +385,7 @@ def test_post_book_v1(mocked_post, app, setup):
     assert response.json["data"] == {"foo": "bar"}
 
     book["animator"] = ""
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/1.0.0/booking")
     assert 'schoolAnimator' not in mocked_post.call_args.kwargs['json']['booking']
@@ -394,7 +394,7 @@ def test_post_book_v1(mocked_post, app, setup):
     assert response.json["data"]["status"] == "BOOKING"
 
     del book["animator"]
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/1.0.0/booking")
     assert 'schoolAnimator' not in mocked_post.call_args.kwargs['json']['booking']
@@ -414,7 +414,7 @@ def test_post_book_v1(mocked_post, app, setup):
 def test_post_book(mocked_post, app, setup, api_version):
     setup.api_version = api_version
     setup.save()
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
     endpoint = reverse(
         "generic-endpoint",
         kwargs={
@@ -460,14 +460,14 @@ def test_post_book(mocked_post, app, setup, api_version):
     assert mocked_post.call_args.kwargs['json']['projectCode'] == 'pc'
     assert response.json["err"] == 0
 
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE_OVERBOOKING, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE_OVERBOOKING, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/" + api_version + "/site/booking/school")
     assert mocked_post.call_count == 3
     assert response.json["err"] == 0
     assert response.json["data"]["status"] == "OVERBOOKING"
 
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE_REFUSED, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE_REFUSED, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/" + api_version + "/site/booking/school")
     assert mocked_post.call_count == 4
@@ -476,7 +476,7 @@ def test_post_book(mocked_post, app, setup, api_version):
     assert response.json["err_desc"] == "booking status is REFUSED"
     assert response.json["data"]["status"] == "REFUSED"
 
-    mocked_post.return_value = utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/" + api_version + "/site/booking/school")
     assert mocked_post.call_count == 5
@@ -485,7 +485,7 @@ def test_post_book(mocked_post, app, setup, api_version):
     assert response.json["err_desc"] == "response is not a dict"
     assert response.json["data"] == ["not", "a", "dict"]
 
-    mocked_post.return_value = utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/" + api_version + "/site/booking/school")
     assert mocked_post.call_count == 6
@@ -495,7 +495,7 @@ def test_post_book(mocked_post, app, setup, api_version):
     assert response.json["data"] == {"foo": "bar"}
 
     book["animator"] = ""
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/" + api_version + "/site/booking/school")
     assert 'schoolAnimator' not in mocked_post.call_args.kwargs['json']
@@ -504,7 +504,7 @@ def test_post_book(mocked_post, app, setup, api_version):
     assert response.json["data"]["status"] == "BOOKING"
 
     del book["animator"]
-    mocked_post.return_value = utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
     response = app.post_json(endpoint, params=book)
     assert mocked_post.call_args[0][0].endswith("api/" + api_version + "/site/booking/school")
     assert 'schoolAnimator' not in mocked_post.call_args.kwargs['json']
@@ -557,7 +557,7 @@ def test_get_booking_status(mocked_get, app, setup, api_version):
         },
     )
 
-    mocked_get.return_value = utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=BOOK_RESPONSE, status_code=200)
     response = app.get(endpoint + "?code=123")
     if api_version == '1.0.0':
         assert mocked_get.call_args[0][0].endswith("api/1.0.0/booking/123/status")
@@ -570,7 +570,7 @@ def test_get_booking_status(mocked_get, app, setup, api_version):
     response = app.get(endpoint, status=400)  # no code specified
     assert mocked_get.call_count == 1
 
-    mocked_get.return_value = utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
     response = app.get(endpoint + "?code=123")
     assert mocked_get.call_count == 2
     assert response.json["err"] == 1
@@ -578,7 +578,7 @@ def test_get_booking_status(mocked_get, app, setup, api_version):
     assert response.json["err_desc"] == "response is not a dict"
     assert response.json["data"] == ["not", "a", "dict"]
 
-    mocked_get.return_value = utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
     response = app.get(endpoint + "?code=123")
     assert mocked_get.call_count == 3
     assert response.json["err"] == 1
@@ -600,7 +600,7 @@ def test_cancel_booking(mocked_post, app, setup, api_version):
             "endpoint": "cancel-site-booking",
         },
     )
-    mocked_post.return_value = utils.FakedResponse(content=CANCEL_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=CANCEL_RESPONSE, status_code=200)
     response = app.delete(endpoint + "?code=123")
     if api_version == '1.0.0':
         assert response.json["err"] == 1
@@ -626,7 +626,7 @@ def test_cancel_booking(mocked_post, app, setup, api_version):
     response = app.get(endpoint, status=400)  # no code specified
     assert mocked_post.call_count == 3  # same as before
 
-    mocked_post.return_value = utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content="""["not", "a", "dict"]""", status_code=200)
     response = app.get(endpoint + "?code=123")
     assert mocked_post.call_count == 4
     assert response.json["err"] == 1
@@ -634,7 +634,7 @@ def test_cancel_booking(mocked_post, app, setup, api_version):
     assert response.json["err_desc"] == "response is not a dict"
     assert response.json["data"] == ["not", "a", "dict"]
 
-    mocked_post.return_value = utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content="""{"foo": "bar"}""", status_code=200)
     response = app.get(endpoint + "?code=123")
     assert mocked_post.call_count == 5
     assert response.json["err"] == 1
diff --git a/tests/test_jobs.py b/tests/test_jobs.py
index ebe5d504..10e6edb7 100644
--- a/tests/test_jobs.py
+++ b/tests/test_jobs.py
@@ -6,12 +6,12 @@ import os
 import isodate
 import mock
 import pytest
-import utils
 from django.core.management import call_command
-from test_base_adresse import StreetModel, base_adresse
 
+import tests.utils
 from passerelle.base.models import Job, ResourceLog, SkipJob
 from passerelle.utils.jsonresponse import APIError
+from tests.test_base_adresse import StreetModel, base_adresse
 
 
 @mock.patch('passerelle.utils.Request.get')
@@ -19,7 +19,7 @@ def test_jobs(mocked_get, app, base_adresse, freezer):
     Job.objects.all().delete()  # remove jobs automatically added at connector creation
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
 
     freezer.move_to('2019-01-01 00:00:00')
     job = base_adresse.add_job('update_streets_data')
@@ -30,7 +30,7 @@ def test_jobs(mocked_get, app, base_adresse, freezer):
     assert StreetModel.objects.count() == 3
 
     # don't delete streets if bano file is empty
-    mocked_get.return_value = utils.FakedResponse(content=b'', status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=b'', status_code=200)
     freezer.move_to('2019-01-01 12:00:00')
     job = base_adresse.add_job('update_streets_data')
     assert job.status == 'registered'
@@ -45,7 +45,7 @@ def test_jobs(mocked_get, app, base_adresse, freezer):
     assert StreetModel.objects.count() == 3
 
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
 
     StreetModel.objects.all().delete()
 
@@ -138,7 +138,7 @@ def test_jobs(mocked_get, app, base_adresse, freezer):
     with mock.patch('passerelle.apps.base_adresse.models.BaseAdresse.down') as down:
         down.side_effect = lambda: True
         with open(filepath, 'rb') as ban_file:
-            mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+            mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
         job = base_adresse.add_job('update_streets_data')
         assert job.status == 'registered'
 
@@ -150,7 +150,7 @@ def test_jobs(mocked_get, app, base_adresse, freezer):
 def test_runjob(mocked_get, app, base_adresse, freezer):
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
 
     freezer.move_to('2019-01-01 00:00:00')
     job = base_adresse.add_job('update_streets_data')
@@ -166,7 +166,7 @@ def test_jobs_api_error_log_level(mocked_get, app, base_adresse, freezer):
     Job.objects.all().delete()  # remove jobs automatically added at connector creation
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
-        mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
+        mocked_get.return_value = tests.utils.FakedResponse(content=ban_file.read(), status_code=200)
 
     job = base_adresse.add_job('update_streets_data')
     mocked_get.side_effect = Exception('hello')
diff --git a/tests/test_jsonresponse.py b/tests/test_jsonresponse.py
index 124d6b1f..695db56e 100644
--- a/tests/test_jsonresponse.py
+++ b/tests/test_jsonresponse.py
@@ -139,7 +139,7 @@ def test_jsonresponse_error_header():
     assert 'err_class' in data
     assert 'err' in data
     assert data['err'] == 1
-    assert data['err_class'] == 'test_jsonresponse.CustomException'
+    assert data['err_class'] == 'tests.test_jsonresponse.CustomException'
     assert result.status_code == 200
 
 
diff --git a/tests/test_lille_kimoce.py b/tests/test_lille_kimoce.py
index 9311b72b..34acd0b6 100644
--- a/tests/test_lille_kimoce.py
+++ b/tests/test_lille_kimoce.py
@@ -21,16 +21,16 @@ import os
 
 import mock
 import pytest
-import utils
 from django.urls import reverse
 
+import tests.utils
 from passerelle.contrib.lille_kimoce.models import Kimoce
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def setup(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         Kimoce.objects.create(
             slug='test', base_url='https://kimoce.mairie-lille.fr/api/', username='test', password='secret'
         )
@@ -191,9 +191,9 @@ TOKEN_ERROR_RESPONSE = """{"message": "Bad credentials"}"""
 @mock.patch('passerelle.utils.Request.post')
 def test_get_token(mocked_post, app, setup):
     with pytest.raises(APIError):
-        mocked_post.return_value = utils.FakedResponse(content=TOKEN_ERROR_RESPONSE, status_code=400)
+        mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_ERROR_RESPONSE, status_code=400)
         setup.get_token()
-    mocked_post.return_value = utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
     setup.get_token()
     assert mocked_post.call_count == 2
     assert "api/login_check" in mocked_post.call_args[0][0]
@@ -209,8 +209,8 @@ def test_get_token(mocked_post, app, setup):
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_categories(mocked_get, mocked_post, app, setup):
-    mocked_post.return_value = utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content=CATEGORIES_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=CATEGORIES_RESPONSE, status_code=200)
     endpoint = reverse(
         'generic-endpoint', kwargs={'connector': 'lille-kimoce', 'slug': setup.slug, 'endpoint': 'categories'}
     )
@@ -228,8 +228,8 @@ def test_get_categories(mocked_get, mocked_post, app, setup):
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_types(mocked_get, mocked_post, app, setup):
-    mocked_post.return_value = utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content=TYPES_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=TYPES_RESPONSE, status_code=200)
     endpoint = reverse(
         'generic-endpoint', kwargs={'connector': 'lille-kimoce', 'slug': setup.slug, 'endpoint': 'types'}
     )
@@ -250,8 +250,8 @@ def test_get_types(mocked_get, mocked_post, app, setup):
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_sub_types(mocked_get, mocked_post, app, setup):
-    mocked_post.return_value = utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content=SUB_TYPES_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=SUB_TYPES_RESPONSE, status_code=200)
     endpoint = reverse(
         'generic-endpoint', kwargs={'connector': 'lille-kimoce', 'slug': setup.slug, 'endpoint': 'subtypes'}
     )
@@ -272,8 +272,8 @@ def test_get_sub_types(mocked_get, mocked_post, app, setup):
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_streets(mocked_get, mocked_post, app, setup):
-    mocked_post.return_value = utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
-    mocked_get.return_value = utils.FakedResponse(content=STREETS_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=STREETS_RESPONSE, status_code=200)
     endpoint = reverse(
         'generic-endpoint', kwargs={'connector': 'lille-kimoce', 'slug': setup.slug, 'endpoint': 'streets'}
     )
@@ -282,7 +282,7 @@ def test_get_streets(mocked_get, mocked_post, app, setup):
     assert len(response.json['data']) == 3
     response = app.get(endpoint, params={'q': 'PLACE JosEPH'})
     assert mocked_get.call_args[1]['params']['streetAddress'] == 'PLACE JosEPH'
-    mocked_get.return_value = utils.FakedResponse(content=STREETS_RESPONSE, status_code=401)
+    mocked_get.return_value = tests.utils.FakedResponse(content=STREETS_RESPONSE, status_code=401)
     response = app.get(endpoint, params={'id': 'RUE de PAris'})
     assert mocked_get.call_args[1]['params']['streetAddress'] == 'RUE de PAris'
     for item in response.json['data']:
@@ -296,8 +296,8 @@ def test_get_streets(mocked_get, mocked_post, app, setup):
 @mock.patch('passerelle.utils.Request.post')
 def test_create_demand(mocked_post, app, setup):
     mocked_post.side_effect = [
-        utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200),
-        utils.FakedResponse(content=DEMAND_CREATION_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=DEMAND_CREATION_RESPONSE, status_code=200),
     ]
     data = {
         'category': '/api/categories/80',
@@ -327,7 +327,7 @@ def test_create_demand(mocked_post, app, setup):
     assert response.json['data'] == json.loads(DEMAND_CREATION_RESPONSE)
     assert mocked_post.call_count == 2
     data['picture1'] = {'content': 'base64encoded_picture'}
-    mocked_post.return_value = utils.FakedResponse(content=DEMAND_CREATION_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=DEMAND_CREATION_RESPONSE, status_code=200)
     mocked_post.side_effect = None
     response = app.post_json(endpoint, params=data)
     assert mocked_post.call_count == 3
diff --git a/tests/test_lille_urban_card.py b/tests/test_lille_urban_card.py
index 66b3278f..2257c2c2 100644
--- a/tests/test_lille_urban_card.py
+++ b/tests/test_lille_urban_card.py
@@ -4,9 +4,9 @@ import json
 
 import mock
 import pytest
-import utils
 from httmock import HTTMock
 
+import tests.utils
 from passerelle.compat import json_loads
 from passerelle.contrib.lille_urban_card.models import LilleUrbanCard
 from passerelle.utils.jsonresponse import APIError
@@ -14,7 +14,7 @@ from passerelle.utils.jsonresponse import APIError
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         LilleUrbanCard.objects.create(
             slug='test', base_url='http://localhost', username='test', password='secret'
         )
@@ -97,20 +97,20 @@ def mocked_http(url, request):
 @mock.patch('passerelle.utils.Request.post')
 def test_get_token(mocked_post, app, connector):
     with pytest.raises(APIError):
-        mocked_post.return_value = utils.FakedResponse(content=TOKEN_ERROR_RESPONSE, status_code=400)
+        mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_ERROR_RESPONSE, status_code=400)
         connector.get_token()
-    mocked_post.return_value = utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=TOKEN_RESPONSE, status_code=200)
     connector.get_token()
 
 
 def test_csp(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'csp', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'csp', slug=connector.slug)
     resp = app.get(endpoint)
     assert resp.json.get('data')
 
 
 def test_card_request(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'card_request', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'card_request', slug=connector.slug)
     with HTTMock(mocked_http):
         resp = app.post_json(
             endpoint,
@@ -172,14 +172,14 @@ def test_card_request(app, connector):
 
 
 def test_card_status(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'card_status', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'card_status', slug=connector.slug)
     with HTTMock(mocked_http):
         resp = app.get(endpoint + '?n_demande_clu=1234')
         assert resp.json['data']['statut_desc'] == 'CARTE_PRODUITE_EXPEDIEE'
 
 
 def test_add_subscriptions(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'add_subscriptions', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'add_subscriptions', slug=connector.slug)
     with HTTMock(mocked_http):
         resp = app.post_json(
             endpoint,
@@ -227,7 +227,7 @@ def test_add_subscriptions(app, connector):
 
 
 def test_code_change(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'code_change', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'code_change', slug=connector.slug)
     with HTTMock(mocked_http):
         resp = app.post_json(
             endpoint,
@@ -257,7 +257,7 @@ def test_code_change(app, connector):
 
 
 def test_code_check(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'code_check', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'code_check', slug=connector.slug)
     with HTTMock(mocked_http):
         resp = app.post_json(
             endpoint,
@@ -282,7 +282,7 @@ def test_code_check(app, connector):
 
 
 def test_card_info(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'card_info', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'card_info', slug=connector.slug)
     with HTTMock(mocked_http):
         resp = app.get(
             endpoint,
@@ -313,7 +313,7 @@ def test_card_info(app, connector):
 
 
 def test_card_revocation(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'card_revocation', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('lille-urban-card', 'card_revocation', slug=connector.slug)
     with HTTMock(mocked_http):
         resp = app.post_json(
             endpoint,
@@ -341,7 +341,9 @@ def test_card_revocation(app, connector):
 
 
 def test_subscription_revocation(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'subscription_revocation', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url(
+        'lille-urban-card', 'subscription_revocation', slug=connector.slug
+    )
     with HTTMock(mocked_http):
         resp = app.post_json(
             endpoint,
@@ -373,7 +375,9 @@ def test_subscription_revocation(app, connector):
 
 
 def test_subscription_renewal(app, connector):
-    endpoint = utils.generic_endpoint_url('lille-urban-card', 'subscription_renewal', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url(
+        'lille-urban-card', 'subscription_renewal', slug=connector.slug
+    )
     with HTTMock(mocked_http):
         resp = app.post_json(
             endpoint,
diff --git a/tests/test_maelis.py b/tests/test_maelis.py
index 89b14ea1..1036e5cf 100644
--- a/tests/test_maelis.py
+++ b/tests/test_maelis.py
@@ -5,10 +5,10 @@ import os
 
 import mock
 import pytest
-import utils
 from django.test import override_settings
 from django.utils.dateparse import parse_date
 
+import tests.utils
 from passerelle.apps.maelis.models import Link, Maelis
 from passerelle.apps.maelis.utils import (
     decompose_event,
@@ -51,10 +51,10 @@ def activity_service_wsdl():
 @pytest.fixture
 def catalog_mocked_get(activity_service_wsdl, family_service_wsdl):
     return (
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=family_service_wsdl, status_code=200, headers={'Content-Type': 'text/xml'}
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=activity_service_wsdl, status_code=200, headers={'Content-Type': 'text/xml'}
         ),
     )
@@ -63,10 +63,10 @@ def catalog_mocked_get(activity_service_wsdl, family_service_wsdl):
 @pytest.fixture
 def catalog_mocked_post():
     return (
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('readFamily.xml'), status_code=200, headers={'Content-Type': 'text/xml'}
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('readActivityListResponse.xml'),
             status_code=200,
             headers={'Content-Type': 'text/xml'},
@@ -76,7 +76,7 @@ def catalog_mocked_post():
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         Maelis.objects.create(
             slug='test', login='foo', password='bar', base_url='http://www3.sigec.fr/entrouvertws/services/'
         )
@@ -175,12 +175,12 @@ def test_activity_list(mocked_post, mocked_get, catalog_mocked_get, catalog_mock
 def test_update_coordinates(mocked_post, mocked_get, family_service_wsdl, connector, app):
     mocked_get.return_value = mock.Mock(content=family_service_wsdl)
     mocked_post.side_effect = (
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('updateCoordinatesResponse.xml'),
             status_code=200,
             headers={'Content-Type': 'text/xml'},
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('updateCoordinatesError.xml'),
             status_code=200,
             headers={'Content-Type': 'text/xml'},
@@ -323,26 +323,26 @@ def test_get_child_planning(
     connector,
 ):
     mocked_get.side_effect = (
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=family_service_wsdl, status_code=200, headers={'Content-Type': 'text/xml'}
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=activity_service_wsdl, status_code=200, headers={'Content-Type': 'text/xml'}
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=activity_service_wsdl, status_code=200, headers={'Content-Type': 'text/xml'}
         ),
     )
     mocked_post.side_effect = (
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('readFamily.xml'), status_code=200, headers={'Content-Type': 'text/xml'}
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('child_planning_readActivityListResponse.xml'),
             status_code=200,
             headers={'Content-Type': 'text/xml'},
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('child_planning_readChildMonthPlanningResponse.xml'),
             status_code=200,
             headers={'Content-Type': 'text/xml'},
@@ -429,10 +429,10 @@ def test_child_activities_errors(
 def test_subscribe(mocked_post, mocked_get, family_service_wsdl, connector, app):
     mocked_get.return_value = mock.Mock(content=family_service_wsdl)
     mocked_post.side_effect = (
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('readFamily.xml'), status_code=200, headers={'Content-Type': 'text/xml'}
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('subscribeActivityResult.xml'),
             status_code=200,
             headers={'Content-Type': 'text/xml'},
@@ -453,10 +453,10 @@ def test_subscribe(mocked_post, mocked_get, family_service_wsdl, connector, app)
 def test_unsubscribe(mocked_post, mocked_get, family_service_wsdl, connector, app):
     mocked_get.return_value = mock.Mock(content=family_service_wsdl)
     mocked_post.side_effect = (
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('readFamily.xml'), status_code=200, headers={'Content-Type': 'text/xml'}
         ),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(
             content=get_xml_file('deletesubscribe.xml'), status_code=200, headers={'Content-Type': 'text/xml'}
         ),
     )
diff --git a/tests/test_mdel.py b/tests/test_mdel.py
index cf0cb75f..9eb63567 100644
--- a/tests/test_mdel.py
+++ b/tests/test_mdel.py
@@ -24,9 +24,9 @@ import zipfile
 from xml.etree import ElementTree as etree
 
 import pytest
-import utils
 from lxml import etree as letree
 
+import tests.utils
 from passerelle.apps.mdel.mdel import AttachedFile, Description, Message, get_resource_base_dir
 from passerelle.apps.mdel.models import MDEL, Demand
 from passerelle.apps.mdel.utils import parse_date
@@ -64,7 +64,7 @@ def check_zip_file(zipdir, expected_files):
 
 @pytest.fixture
 def setup(db):
-    return utils.setup_access_rights(MDEL.objects.create(slug='test'))
+    return tests.utils.setup_access_rights(MDEL.objects.create(slug='test'))
 
 
 @pytest.fixture(
diff --git a/tests/test_mdel_ddpacs.py b/tests/test_mdel_ddpacs.py
index 9d391009..3d004e35 100644
--- a/tests/test_mdel_ddpacs.py
+++ b/tests/test_mdel_ddpacs.py
@@ -22,9 +22,9 @@ import logging
 import os
 
 import pytest
-import utils
 import xmlschema
 
+import tests.utils
 from passerelle.apps.mdel_ddpacs.models import Demand, Resource
 from passerelle.utils import json, sftp
 from passerelle.utils.zip import ZipTemplate, diff_zip
@@ -37,7 +37,7 @@ def build_response_zip(**kwargs):
 
 @pytest.fixture(autouse=True)
 def resource(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         Resource.objects.create(
             slug='test',
             code_insee='66666',
diff --git a/tests/test_mdph13.py b/tests/test_mdph13.py
index ba5da516..4157913f 100644
--- a/tests/test_mdph13.py
+++ b/tests/test_mdph13.py
@@ -24,8 +24,8 @@ import httmock
 import pytest
 import requests
 import requests.exceptions
-import utils
 
+import tests.utils
 from passerelle.contrib.mdph13.models import Link, MDPH13Resource
 from passerelle.utils.jsonresponse import APIError
 
@@ -197,7 +197,7 @@ SECRET_INVALIDE = {
 
 @pytest.fixture
 def mdph13(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         MDPH13Resource,
         title='Test 1',
         slug='test1',
diff --git a/tests/test_misc.py b/tests/test_misc.py
index a4dcd635..620ae9af 100644
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -11,12 +11,12 @@ from django.utils import timezone
 from django.utils.six import StringIO
 from mock import patch
 from requests.exceptions import ReadTimeout
-from test_manager import login
 
 from passerelle.apps.base_adresse.models import BaseAdresse
 from passerelle.apps.clicrdv.models import ClicRdv
 from passerelle.apps.opengis.models import OpenGIS
 from passerelle.base.models import ResourceLog
+from tests.test_manager import login
 
 
 def test_get_description_url_fields(db):
@@ -104,7 +104,7 @@ def email_handler():
 
 
 def test_trace_emails(app, settings, dummy_csv_datasource, email_handler, mailoutbox):
-    from utils import generic_endpoint_url
+    from tests.utils import generic_endpoint_url
 
     settings.ADMINS = [('admin', 'admin@example.net')]
 
diff --git a/tests/test_okina.py b/tests/test_okina.py
index 260fe14c..bd7612ec 100644
--- a/tests/test_okina.py
+++ b/tests/test_okina.py
@@ -3,9 +3,9 @@ import json
 
 import mock
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 
+import tests.utils
 from passerelle.apps.okina.models import Okina
 from passerelle.base.models import AccessRight, ApiUser
 
@@ -1647,10 +1647,10 @@ def okina(db):
 
 
 def test_okina_cities(app, okina):
-    endpoint = utils.generic_endpoint_url('okina', 'cities', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'cities', slug=okina.slug)
     assert endpoint == '/okina/test/cities'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=CITIES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=CITIES, status_code=200)
         resp = app.get(endpoint, status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/cities'
@@ -1663,7 +1663,7 @@ def test_okina_cities(app, okina):
         assert resp.json['data'][0]['text'] == 'ARDENTES (36120)'
         assert resp.json['data'][0]['lat'] is None
 
-        requests_get.return_value = utils.FakedResponse(content=CITIES_NEW, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=CITIES_NEW, status_code=200)
         resp = app.get(endpoint, status=200)
         assert requests_get.call_count == 2
         assert 'data' in resp.json
@@ -1676,10 +1676,10 @@ def test_okina_cities(app, okina):
 
 
 def test_okina_classes(app, okina):
-    endpoint = utils.generic_endpoint_url('okina', 'classes', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'classes', slug=okina.slug)
     assert endpoint == '/okina/test/classes'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=CLASSES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=CLASSES, status_code=200)
         resp = app.get(endpoint, status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/classes'
@@ -1690,11 +1690,11 @@ def test_okina_classes(app, okina):
 
 
 def test_okina_institutions(app, okina):
-    endpoint = utils.generic_endpoint_url('okina', 'institutions', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'institutions', slug=okina.slug)
     assert endpoint == '/okina/test/institutions'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         for content in (INSTITUTIONS, INSTITUTIONS_NEW):
-            requests_get.return_value = utils.FakedResponse(content=content, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=content, status_code=200)
             resp = app.get(endpoint, status=200)
             assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/institutions'
             assert resp.json['err'] == 0
@@ -1725,10 +1725,10 @@ def test_okina_institutions(app, okina):
 
 
 def test_okina_search(app, okina):
-    endpoint = utils.generic_endpoint_url('okina', 'search', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'search', slug=okina.slug)
     assert endpoint == '/okina/test/search'
     with mock.patch('passerelle.utils.Request.post') as requests_post:
-        requests_post.return_value = utils.FakedResponse(content=SEARCH, status_code=200)
+        requests_post.return_value = tests.utils.FakedResponse(content=SEARCH, status_code=200)
 
         # refuse anonymous access
         resp = app.get(endpoint + '?lat=46.828652&lon=1.701463&institution=277', status=403)
@@ -1771,10 +1771,10 @@ def test_okina_search(app, okina):
 
 
 def test_okina_stops_area(app, okina):
-    endpoint = utils.generic_endpoint_url('okina', 'stop-areas', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'stop-areas', slug=okina.slug)
     assert endpoint == '/okina/test/stop-areas'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=STOPS, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=STOPS, status_code=200)
         resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200)
         assert (
             requests_get.call_args[0][0]
@@ -1787,10 +1787,10 @@ def test_okina_stops_area(app, okina):
 
 
 def test_okina_ods(app, okina):
-    endpoint = utils.generic_endpoint_url('okina', 'origin-destinations', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'origin-destinations', slug=okina.slug)
     assert endpoint == '/okina/test/origin-destinations'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=ODS, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=ODS, status_code=200)
         resp = app.get(endpoint, status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods'
@@ -1801,7 +1801,7 @@ def test_okina_ods(app, okina):
         assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
         assert resp.json['data'][0]['vehicle_journey_id'] == '84'
 
-        requests_get.return_value = utils.FakedResponse(content=ODS, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=ODS, status_code=200)
         resp = app.get(endpoint + '/to-institution/276/', status=200)
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/institution/276'
         assert resp.json['err'] == 0
@@ -1811,7 +1811,7 @@ def test_okina_ods(app, okina):
         assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
         assert resp.json['data'][0]['vehicle_journey_id'] == '84'
 
-        requests_get.return_value = utils.FakedResponse(content=ODS_LINES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=ODS_LINES, status_code=200)
         resp = app.get(endpoint + '/from-stop-area/3282/to-institution/276/', status=200)
         assert (
             requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/institution/276/stop-area/3282'
@@ -1836,7 +1836,7 @@ def test_okina_ods(app, okina):
         assert resp.json['data'][2]['lines'][1]['id'] == '23'
         assert resp.json['data'][2]['lines'][1]['text'] == 'LIGNE 23'
 
-        requests_get.return_value = utils.FakedResponse(content=ODS_FULL, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=ODS_FULL, status_code=200)
         resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200)
         assert (
             requests_get.call_args[0][0]
@@ -1851,7 +1851,7 @@ def test_okina_ods(app, okina):
         assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
         assert resp.json['data'][0]['vehicle_journey_id'] == '84'
 
-        requests_get.return_value = utils.FakedResponse(content=ODS_FULL, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=ODS_FULL, status_code=200)
         resp = app.get(endpoint + '/from-city/36005/', status=200)
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/subscriberCity/36005'
         assert resp.json['err'] == 0
@@ -1865,10 +1865,10 @@ def test_okina_ods(app, okina):
 
 
 def test_okina_topology(app, okina):
-    endpoint = utils.generic_endpoint_url('okina', 'topology', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'topology', slug=okina.slug)
     assert endpoint == '/okina/test/topology'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=LINES, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=LINES, status_code=200)
         resp = app.get(endpoint + '/lines/', status=200)
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/lines'
         assert resp.json['err'] == 0
@@ -1876,7 +1876,7 @@ def test_okina_topology(app, okina):
         assert resp.json['data'][0]['id'] == '45'
         assert resp.json['data'][0]['text'] == '019 - 02 - VELLES LYCEES DE CHATEAUROUX'
 
-        requests_get.return_value = utils.FakedResponse(content=NETWORKS, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=NETWORKS, status_code=200)
         resp = app.get(endpoint + '/networks/', status=200)
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/networks'
         assert resp.json['err'] == 0
@@ -1884,7 +1884,7 @@ def test_okina_topology(app, okina):
         assert resp.json['data'][0]['id'] == '2'
         assert resp.json['data'][0]['text'] == u'réseau scolaire'
 
-        requests_get.return_value = utils.FakedResponse(content=VEHICLE_JOURNEYS, status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content=VEHICLE_JOURNEYS, status_code=200)
         resp = app.get(endpoint + '/vehicle-journeys/', status=200)
         assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/vehicle-journeys'
         assert resp.json['err'] == 0
@@ -1905,7 +1905,9 @@ def test_okina_errors(app, okina):
             (400, '[{"message": "bad request"}]'),
             (500, '<h1>Crash</h1>'),
         ):
-            requests_get.return_value = utils.FakedResponse(content=response[1], status_code=response[0])
+            requests_get.return_value = tests.utils.FakedResponse(
+                content=response[1], status_code=response[0]
+            )
             resp = app.get('/okina/test/cities', status=200)
             assert resp.json['err'] == 1
             if resp.json['data'] and 'status_code' in resp.json['data']:
@@ -1913,7 +1915,7 @@ def test_okina_errors(app, okina):
 
         # "normal" 401/403 response, ie problem with login/password
         for status_code in (401, 403):
-            requests_get.return_value = utils.FakedResponse(
+            requests_get.return_value = tests.utils.FakedResponse(
                 content='''{"message": "Invalid credentials",
                     "code": 4, "status" : %d}'''
                 % status_code,
@@ -1927,7 +1929,7 @@ def test_okina_errors(app, okina):
 def test_okina_suscribe(app, okina):
 
     for service in ('subscriber', 'subscription'):
-        endpoint = utils.generic_endpoint_url('okina', service, slug=okina.slug)
+        endpoint = tests.utils.generic_endpoint_url('okina', service, slug=okina.slug)
         assert endpoint == '/okina/test/%s' % service
         with mock.patch('passerelle.utils.Request.get') as requests_get:
             resp = app.post(endpoint, status=403)
@@ -1941,7 +1943,7 @@ def test_okina_suscribe(app, okina):
         codename='can_access', apiuser=api, resource_type=obj_type, resource_pk=okina.pk
     )
     for service in ('subscriber', 'subscription'):
-        endpoint = utils.generic_endpoint_url('okina', service, slug=okina.slug)
+        endpoint = tests.utils.generic_endpoint_url('okina', service, slug=okina.slug)
         assert endpoint == '/okina/test/%s' % service
         with mock.patch('passerelle.utils.Request.post') as requests_get:
             resp = app.post(endpoint, status=400)  # no payload
@@ -1956,16 +1958,16 @@ def test_okina_suscribe(app, okina):
             assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
             assert resp.json['err_desc'] == 'payload must be a dict'
 
-            requests_get.return_value = utils.FakedResponse(content='{"foo":"bar"}', status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content='{"foo":"bar"}', status_code=200)
             resp = app.post_json(endpoint, params={'x': 'y'})
             assert requests_get.call_count == 1
             assert resp.json['err'] == 0
             assert resp.json['data'] == {'foo': 'bar'}
 
     # multiple subscriptions
-    endpoint = utils.generic_endpoint_url('okina', 'subscription', slug=okina.slug)
+    endpoint = tests.utils.generic_endpoint_url('okina', 'subscription', slug=okina.slug)
     with mock.patch('passerelle.utils.Request.post') as requests_post:
-        requests_post.return_value = utils.FakedResponse(content='{"sub":"ok"}', status_code=200)
+        requests_post.return_value = tests.utils.FakedResponse(content='{"sub":"ok"}', status_code=200)
         resp = app.post_json(endpoint, params={'lineIds': '1 ,2, 3', 'foo': 'bar'})
         assert requests_post.call_count == 3
         assert json.loads(requests_post.call_args_list[0][1]['data']) == {'foo': 'bar', 'lineId': '1'}
@@ -1977,7 +1979,7 @@ def test_okina_suscribe(app, okina):
     # qrcode
     endpoint = '/okina/test/subscriber/123/qrcode'
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(
+        requests_get.return_value = tests.utils.FakedResponse(
             content='PNGfoo', headers={'Content-Type': 'image/png'}, status_code=200
         )
         resp = app.get(endpoint)
@@ -1985,7 +1987,7 @@ def test_okina_suscribe(app, okina):
         assert resp.headers['content-type'] == 'image/png'
         assert resp.content == b'PNGfoo'
 
-        requests_get.return_value = utils.FakedResponse(
+        requests_get.return_value = tests.utils.FakedResponse(
             content=QRCODE_400, headers={'Content-Type': 'application/json'}, status_code=400
         )
         resp = app.get(endpoint, status=200)
@@ -1995,7 +1997,7 @@ def test_okina_suscribe(app, okina):
             'Subscriber with ID 123 has no passcard number to generate qr code from.'
         )
 
-        requests_get.return_value = utils.FakedResponse(
+        requests_get.return_value = tests.utils.FakedResponse(
             content=QRCODE_404, headers={'Content-Type': 'application/json'}, status_code=404
         )
         resp = app.get(endpoint, status=200)
diff --git a/tests/test_opendatasoft.py b/tests/test_opendatasoft.py
index 1e2dde69..12aa52f7 100644
--- a/tests/test_opendatasoft.py
+++ b/tests/test_opendatasoft.py
@@ -19,13 +19,13 @@ import json
 
 import mock
 import pytest
-import utils
 from django.contrib.auth.models import User
 from requests.exceptions import ConnectionError
-from test_manager import login
 
+import tests.utils
 from passerelle.apps.opendatasoft.models import OpenDataSoft, Query
 from passerelle.utils import import_site
+from tests.test_manager import login
 
 pytestmark = pytest.mark.django_db
 
@@ -127,7 +127,7 @@ FAKED_CONTENT_ID_SEARCH = json.dumps(
 
 @pytest.fixture
 def connector():
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         OpenDataSoft.objects.create(
             slug='my_connector',
             service_url='http://www.example.net',
@@ -181,12 +181,12 @@ def test_export_import(query):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_search_empty_contents(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
     assert endpoint == '/opendatasoft/my_connector/search'
 
     # error returned by opendadasoft server
     json_response = json.dumps({'error': "The query is invalid : Field 00 doesn't exist"})
-    mocked_get.return_value = utils.FakedResponse(content=json_response, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json_response, status_code=200)
     resp = app.get(endpoint, status=200)
     assert resp.json['err']
     assert resp.json['err_desc'] == "The query is invalid : Field 00 doesn't exist"
@@ -194,7 +194,7 @@ def test_search_empty_contents(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_search(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
     assert endpoint == '/opendatasoft/my_connector/search'
     params = {
         'dataset': 'referentiel-adresse-test',
@@ -202,7 +202,7 @@ def test_search(mocked_get, app, connector):
         'sort': '-nom_rue',
         'limit': 3,
     }
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
     resp = app.get(endpoint, params=params, status=200)
     assert mocked_get.call_args[1]['params'] == {
         'apikey': 'my_secret',
@@ -230,7 +230,7 @@ def test_search(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_search_using_q(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
     assert endpoint == '/opendatasoft/my_connector/search'
     params = {
         'dataset': 'referentiel-adresse-test',
@@ -239,7 +239,7 @@ def test_search_using_q(mocked_get, app, connector):
         'limit': '3',
         'q': "rue de l'aubepine",
     }
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
     resp = app.get(endpoint, params=params, status=200)
     assert mocked_get.call_args[1]['params'] == {
         'apikey': 'my_secret',
@@ -267,14 +267,14 @@ def test_search_using_q(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_search_using_id(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
     assert endpoint == '/opendatasoft/my_connector/search'
     params = {
         'dataset': 'referentiel-adresse-test',
         'text_template': '{{numero}} {{nom_rue}} {{nom_commun}}',
         'id': '7cafcd5c692773e8b863587b2d38d6be82e023d8',
     }
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_ID_SEARCH, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT_ID_SEARCH, status_code=200)
     resp = app.get(endpoint, params=params, status=200)
     assert mocked_get.call_args[1]['params'] == {
         'apikey': 'my_secret',
@@ -291,7 +291,7 @@ def test_query_q(mocked_get, app, query):
     params = {
         'limit': 3,
     }
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
     resp = app.get(endpoint, params=params, status=200)
     assert mocked_get.call_args[1]['params'] == {
         'apikey': 'my_secret',
@@ -325,7 +325,7 @@ def test_query_q_using_q(mocked_get, app, query):
     params = {
         'q': "rue de l'aubepine",
     }
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
     resp = app.get(endpoint, params=params, status=200)
     assert mocked_get.call_args[1]['params'] == {
         'apikey': 'my_secret',
@@ -359,7 +359,7 @@ def test_query_q_using_id(mocked_get, app, query):
     params = {
         'id': '7cafcd5c692773e8b863587b2d38d6be82e023d8',
     }
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_ID_SEARCH, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT_ID_SEARCH, status_code=200)
     resp = app.get(endpoint, params=params, status=200)
     assert mocked_get.call_args[1]['params'] == {
         'apikey': 'my_secret',
@@ -437,7 +437,7 @@ def test_query_q_having_original_fields(mocked_get, app, query):
     content['records'][0]['fields']['text'] = 'original text'
     query.text_template = '{{id}} - {{original_id}} - {{original_text}}'
     query.save()
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps(content), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(content), status_code=200)
     resp = app.get(endpoint, params=params, status=200)
     assert resp.json['data'][0]['original_id'] == 'original id'
     assert resp.json['data'][0]['original_text'] == 'original text'
@@ -448,31 +448,31 @@ def test_query_q_having_original_fields(mocked_get, app, query):
 
 
 def test_call_search_errors(app, connector):
-    endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
     assert endpoint == '/opendatasoft/my_connector/search'
     url = connector.service_url + '/api/records/1.0/search/'
 
     # Connection error
     exception = ConnectionError('Remote end closed connection without response')
-    with utils.mock_url(url=url, exception=exception):
+    with tests.utils.mock_url(url=url, exception=exception):
         resp = app.get(endpoint)
     assert resp.json['err']
     assert resp.json['err_desc'] == 'OpenDataSoft error: Remote end closed connection without response'
 
     # API error, provides HTTP status code
-    with utils.mock_url(url=url, response='{"error": "Unknown dataset: foo"}', status_code=404):
+    with tests.utils.mock_url(url=url, response='{"error": "Unknown dataset: foo"}', status_code=404):
         resp = app.get(endpoint)
     assert resp.json['err']
     assert resp.json['err_desc'] == 'Unknown dataset: foo'
 
     # HTTP error
-    with utils.mock_url(url=url, response='not a json content', reason='Not Found', status_code=404):
+    with tests.utils.mock_url(url=url, response='not a json content', reason='Not Found', status_code=404):
         resp = app.get(endpoint)
     assert resp.json['err']
     assert 'OpenDataSoft error: 404 Client Error: Not Found' in resp.json['err_desc']
 
     # bad JSON response
-    with utils.mock_url(url=url, response='not a json content', status_code=200):
+    with tests.utils.mock_url(url=url, response='not a json content', status_code=200):
         resp = app.get(endpoint)
     assert resp.json['err']
     assert resp.json['err_desc'] == 'OpenDataSoft error: bad JSON response'
diff --git a/tests/test_opengis.py b/tests/test_opengis.py
index 1b7c8291..bfee1afe 100644
--- a/tests/test_opengis.py
+++ b/tests/test_opengis.py
@@ -2,14 +2,14 @@ import json
 
 import mock
 import pytest
-import utils
 from django.contrib.auth.models import User
 from django.core.management import call_command
-from test_manager import login
 
+import tests.utils
 from passerelle.apps.opengis.models import FeatureCache, OpenGIS, Query
 from passerelle.base.models import Job
 from passerelle.utils import import_site
+from tests.test_manager import login
 
 pytestmark = pytest.mark.django_db
 
@@ -357,7 +357,7 @@ FAKE_GEOLOCATED_FEATURE_CIRCLE = {
 
 @pytest.fixture
 def connector():
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         OpenGIS.objects.create(
             slug='test', wms_service_url='http://example.net/wms', wfs_service_url='http://example.net/wfs'
         )
@@ -382,46 +382,46 @@ def query(connector):
 def geoserver_responses(url, **kwargs):
     if kwargs['params'].get('request') == 'GetCapabilities':
         assert kwargs['params'].get('service')
-        return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
-    return utils.FakedResponse(status_code=200, content=FAKE_FEATURES_JSON)
+        return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
+    return tests.utils.FakedResponse(status_code=200, content=FAKE_FEATURES_JSON)
 
 
 def geoserver_responses_v1_0_0(url, **kwargs):
     if kwargs['params'].get('request') == 'GetCapabilities':
         assert kwargs['params'].get('service')
-        return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES_V1_0_0)
-    return utils.FakedResponse(status_code=200, content=FAKE_FEATURES_JSON)
+        return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES_V1_0_0)
+    return tests.utils.FakedResponse(status_code=200, content=FAKE_FEATURES_JSON)
 
 
 def geoserver_responses_errors(url, **kwargs):
     if kwargs['params'].get('request') == 'GetCapabilities':
-        return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
-    return utils.FakedResponse(status_code=200, content=FAKE_ERROR)
+        return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
+    return tests.utils.FakedResponse(status_code=200, content=FAKE_ERROR)
 
 
 def geoserver_responses_errors_unparsable(url, **kwargs):
     if kwargs['params'].get('request') == 'GetCapabilities':
-        return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
-    return utils.FakedResponse(status_code=200, content=FAKE_ERROR[:10])
+        return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
+    return tests.utils.FakedResponse(status_code=200, content=FAKE_ERROR[:10])
 
 
 def geoserver_geolocated_responses(url, **kwargs):
     if kwargs['params'].get('request') == 'GetCapabilities':
-        return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
-    return utils.FakedResponse(status_code=200, content=FAKE_GEOLOCATED_FEATURE)
+        return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
+    return tests.utils.FakedResponse(status_code=200, content=FAKE_GEOLOCATED_FEATURE)
 
 
 def geoserver_circle_responses(url, **kwargs):
     if kwargs['params'].get('request') == 'GetCapabilities':
-        return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
-    return utils.FakedResponse(status_code=200, content=json.dumps(FAKE_GEOLOCATED_FEATURE_CIRCLE))
+        return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
+    return tests.utils.FakedResponse(status_code=200, content=json.dumps(FAKE_GEOLOCATED_FEATURE_CIRCLE))
 
 
 @mock.patch('passerelle.utils.Request.get')
 def test_feature_info(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'feature_info', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'feature_info', slug=connector.slug)
     assert endpoint == '/opengis/test/feature_info'
-    mocked_get.return_value = utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200)
     resp = app.get(endpoint, params={'lat': '45.796890', 'lon': '4.784140'})
     assert (
         mocked_get.call_args[1]['params']['bbox']
@@ -450,9 +450,9 @@ def test_feature_info(mocked_get, app, connector):
     ],
 )
 def test_feature_info_bad_request(mocked_get, app, connector, lat, lon):
-    endpoint = utils.generic_endpoint_url('opengis', 'feature_info', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'feature_info', slug=connector.slug)
     assert endpoint == '/opengis/test/feature_info'
-    mocked_get.return_value = utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200)
     resp = app.get(endpoint, params={'lat': lat, 'lon': lon})
     assert resp.json['err'] == 1
     assert resp.json['err_desc'] == 'Bad coordinates format'
@@ -460,9 +460,11 @@ def test_feature_info_bad_request(mocked_get, app, connector, lat, lon):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_tile(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'tile', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'tile', slug=connector.slug)
     assert endpoint == '/opengis/test/tile'
-    mocked_get.return_value = utils.FakedResponse(content=b'\x89PNG\r\n\x1a\n\x00\x00...', status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(
+        content=b'\x89PNG\r\n\x1a\n\x00\x00...', status_code=200
+    )
     resp = app.get(endpoint + '/16/33650/23378.png')
     assert mocked_get.call_args[1]['params']['crs'] == 'EPSG:3857'
     assert (
@@ -481,7 +483,7 @@ def test_tile(mocked_get, app, connector):
 def test_get_feature_with_no_wfs_url(mocked_get, app, connector):
     connector.wfs_service_url = ''
     connector.save()
-    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
     assert endpoint == '/opengis/test/features'
     mocked_get.side_effect = geoserver_responses
     resp = app.get(endpoint, params={'type_names': 'ref_metro_limites_communales', 'property_name': 'nom'})
@@ -492,7 +494,7 @@ def test_get_feature_with_no_wfs_url(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_get_feature(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
     assert endpoint == '/opengis/test/features'
     mocked_get.side_effect = geoserver_responses
     resp = app.get(endpoint, params={'type_names': 'ref_metro_limites_communales', 'property_name': 'nom'})
@@ -509,7 +511,7 @@ def test_get_feature(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_get_filtered_feature(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
     mocked_get.side_effect = geoserver_responses
     app.get(
         endpoint,
@@ -524,7 +526,7 @@ def test_get_filtered_feature(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_get_filtered_by_property_feature(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
     mocked_get.side_effect = geoserver_responses
     params = {
         'type_names': 'ref_metro_limites_communales',
@@ -550,7 +552,7 @@ def test_get_filtered_by_property_feature(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_get_feature_error(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
     assert endpoint == '/opengis/test/features'
     mocked_get.side_effect = geoserver_responses_errors
     resp = app.get(endpoint, params={'type_names': 'ref_metro_limites_communales', 'property_name': 'nom'})
@@ -568,7 +570,7 @@ def test_get_feature_error(mocked_get, app, connector):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_get_feature_error2(mocked_get, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
     assert endpoint == '/opengis/test/features'
     mocked_get.side_effect = geoserver_responses_errors_unparsable
     resp = app.get(endpoint, params={'type_names': 'ref_metro_limites_communales', 'property_name': 'nom'})
@@ -590,7 +592,7 @@ def test_get_feature_error2(mocked_get, app, connector):
 )
 @mock.patch('passerelle.utils.Request.get')
 def test_typename_parameter_upgrade(mocked_get, server_responses, version, typename_label, app, connector):
-    endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'features', slug=connector.slug)
     assert endpoint == '/opengis/test/features'
     mocked_get.side_effect = server_responses
     resp = app.get(endpoint, params={'type_names': '...', 'property_name': '...'})
@@ -604,16 +606,16 @@ def test_reverse_geocoding(mocked_get, app, connector):
     connector.search_radius = 45
     connector.projection = 'EPSG:3945'
     connector.save()
-    endpoint = utils.generic_endpoint_url('opengis', 'reverse', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'reverse', slug=connector.slug)
     assert endpoint == '/opengis/test/reverse'
 
     def side_effect(url, **kwargs):
         if kwargs['params'].get('request') == 'GetCapabilities':
-            return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
+            return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
         return mock.DEFAULT
 
     mocked_get.side_effect = side_effect
-    mocked_get.return_value = utils.FakedResponse(content=FAKE_GEOLOCATED_FEATURE, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_GEOLOCATED_FEATURE, status_code=200)
     resp = app.get(endpoint, params={'lat': '45.1893469606986', 'lon': '5.72462060798'})
     assert (
         mocked_get.call_args[1]['params']['cql_filter']
@@ -640,7 +642,7 @@ def test_reverse_geocoding(mocked_get, app, connector):
     connector.projection = 'EPSG:4326'
     connector.search_radius = 10
     connector.save()
-    mocked_get.return_value = utils.FakedResponse(content='{"features": []}', status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content='{"features": []}', status_code=200)
     resp = app.get(endpoint, params={'lat': '45.183784', 'lon': '5.714885'})
     assert (
         mocked_get.call_args[1]['params']['cql_filter']
@@ -649,7 +651,7 @@ def test_reverse_geocoding(mocked_get, app, connector):
     assert resp.json['err'] == 1
     assert resp.json['err_desc'] == 'Unable to geocode'
 
-    mocked_get.return_value = utils.FakedResponse(status_code=404, content='{}', ok=False)
+    mocked_get.return_value = tests.utils.FakedResponse(status_code=404, content='{}', ok=False)
     resp = app.get(endpoint, params={'lat': '45.183784', 'lon': '5.714885'})
     assert resp.json['err'] == 1
     assert resp.json['err_desc'] == 'Webservice returned status code 404'
@@ -708,7 +710,7 @@ def test_opengis_query_computed_properties(mocked_get, app, connector, query):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_opengis_query_q_endpoint(mocked_get, app, connector, query):
-    endpoint = utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
     assert endpoint == '/opengis/test/query/test_query/'
     mocked_get.side_effect = geoserver_geolocated_responses
     query.update_cache()
@@ -737,8 +739,8 @@ def test_opengis_query_cache_update_change(mocked_get, app, connector, query):
 
     def new_response(url, **kwargs):
         if kwargs['params'].get('request') == 'GetCapabilities':
-            return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
-        return utils.FakedResponse(
+            return tests.utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES)
+        return tests.utils.FakedResponse(
             content='{"features": [{"properties": {}, "geometry": {"coordinates": [1, 1], "type": "Point"}}]}',
             status_code=200,
         )
@@ -750,7 +752,7 @@ def test_opengis_query_cache_update_change(mocked_get, app, connector, query):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_opengis_query_q_endpoint_cache_empty(mocked_get, app, connector, query):
-    endpoint = utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
     assert not FeatureCache.objects.exists()
     resp = app.get(endpoint)
 
@@ -818,7 +820,7 @@ def test_opengis_query_endpoint_documentation(mocked_get, app, connector, query)
 
 @mock.patch('passerelle.utils.Request.get')
 def test_opengis_query_text_search(mocked_get, app, connector, query):
-    endpoint = utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
     mocked_get.side_effect = geoserver_geolocated_responses
     query.update_cache()
 
@@ -852,7 +854,7 @@ def test_opengis_query_text_search(mocked_get, app, connector, query):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_opengis_query_circle_filtering(mocked_get, app, connector, query):
-    endpoint = utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
     mocked_get.side_effect = geoserver_circle_responses
     query.update_cache()
 
@@ -874,7 +876,7 @@ def test_opengis_query_circle_filtering(mocked_get, app, connector, query):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_opengis_query_data_filter(mocked_get, app, connector, query):
-    endpoint = utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('opengis', 'query/test_query/', slug=connector.slug)
     mocked_get.side_effect = geoserver_geolocated_responses
     query.update_cache()
 
diff --git a/tests/test_phonecalls.py b/tests/test_phonecalls.py
index 7408624f..2689fc83 100644
--- a/tests/test_phonecalls.py
+++ b/tests/test_phonecalls.py
@@ -1,10 +1,10 @@
 import re
 
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 from django.utils.timezone import now, timedelta
 
+import tests.utils
 from passerelle.apps.phonecalls.models import Call, PhoneCalls
 from passerelle.base.models import AccessRight, ApiUser
 
@@ -21,11 +21,11 @@ def phonecalls(db):
 
 
 def test_phonecalls_start_stop(app, phonecalls):
-    start_endpoint = utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
+    start_endpoint = tests.utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
     assert start_endpoint == '/phonecalls/test/call-start'
-    stop_endpoint = utils.generic_endpoint_url('phonecalls', 'call-stop', slug=phonecalls.slug)
+    stop_endpoint = tests.utils.generic_endpoint_url('phonecalls', 'call-stop', slug=phonecalls.slug)
     assert stop_endpoint == '/phonecalls/test/call-stop'
-    calls_endpoint = utils.generic_endpoint_url('phonecalls', 'calls', slug=phonecalls.slug)
+    calls_endpoint = tests.utils.generic_endpoint_url('phonecalls', 'calls', slug=phonecalls.slug)
     assert calls_endpoint == '/phonecalls/test/calls'
 
     resp = app.get(start_endpoint, status=403)
@@ -212,7 +212,7 @@ def test_phonecalls_start_redirect(app, phonecalls):
     phonecalls.save()
 
     assert Call.objects.count() == 0
-    start_endpoint = utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
+    start_endpoint = tests.utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
     resp = app.get(
         start_endpoint,
         status=302,
@@ -227,7 +227,7 @@ def test_phonecalls_start_newtab(app, phonecalls):
     phonecalls.save()
 
     assert Call.objects.count() == 0
-    start_endpoint = utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
+    start_endpoint = tests.utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
     resp = app.get(
         start_endpoint,
         status=200,
@@ -242,7 +242,7 @@ def test_phonecalls_add_callee(app, phonecalls):
     phonecalls.redirect_url = 'https://portail-agent.publik/'
     phonecalls.save()
 
-    start_endpoint = utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
+    start_endpoint = tests.utils.generic_endpoint_url('phonecalls', 'call-start', slug=phonecalls.slug)
     resp = app.get(
         start_endpoint,
         status=302,
diff --git a/tests/test_photon.py b/tests/test_photon.py
index a2a521ba..e2c47fb2 100644
--- a/tests/test_photon.py
+++ b/tests/test_photon.py
@@ -19,11 +19,11 @@ import json
 
 import mock
 import pytest
-import utils
 from django.core.management import call_command
 from httmock import HTTMock, remember_called, response, urlmatch
 from requests.exceptions import ConnectionError, HTTPError
 
+import tests.utils
 from passerelle.apps.photon.models import AddressCacheModel, Photon
 
 CONTENT = {
@@ -93,7 +93,7 @@ def mock_photon_reverse():
 
 @pytest.fixture
 def photon(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         Photon.objects.create(
             slug='test',
             service_url='http://example.net/path/',
@@ -103,8 +103,8 @@ def photon(db):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_photon_search(mocked_get, app, photon):
-    endpoint = utils.generic_endpoint_url('photon', 'search', slug=photon.slug)
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
+    endpoint = tests.utils.generic_endpoint_url('photon', 'search', slug=photon.slug)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
     assert mocked_get.call_args[0][0].startswith('http://example.net/path/api/?')
     data = resp.json[0]
@@ -169,7 +169,7 @@ def test_photon_api_error(mocked_get, app, photon):
     def raise_for_status():
         raise HTTPError("400 Client Error: Bad Request for url: xxx")
 
-    response = utils.FakedResponse(content=json.dumps({'title': 'error'}), status_code=400)
+    response = tests.utils.FakedResponse(content=json.dumps({'title': 'error'}), status_code=400)
     response.raise_for_status = raise_for_status
     mocked_get.return_value = response
     resp = app.get('/photon/%s/search' % photon.slug, params={'q': 'plop'}, status=200)
@@ -183,7 +183,7 @@ def test_photon_api_error(mocked_get, app, photon):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_photon_reverse_path(mocked_get, app, photon):
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps({'features': []}), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps({'features': []}), status_code=200)
     app.get('/photon/%s/reverse?lon=4.8522272&lat=45.7587414' % photon.slug)
     assert mocked_get.call_args[0][0].startswith('http://example.net/path/reverse/?')
 
@@ -199,9 +199,9 @@ def test_photon_reverse(app, photon, mock_photon_reverse):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_photon_addresses(mocked_get, app, photon):
-    endpoint = utils.generic_endpoint_url('photon', 'addresses', slug=photon.slug)
+    endpoint = tests.utils.generic_endpoint_url('photon', 'addresses', slug=photon.slug)
     assert endpoint == '/photon/test/addresses'
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
     data = resp.json['data'][0]
     assert data['lat'] == '45.7587414'
@@ -273,8 +273,8 @@ def test_photon_addresses_cache_err(app, photon, mock_photon_search):
 
 @mock.patch('passerelle.utils.Request.get')
 def test_photon_addresses_data_change(mocked_get, app, photon):
-    endpoint = utils.generic_endpoint_url('photon', 'addresses', slug=photon.slug)
-    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
+    endpoint = tests.utils.generic_endpoint_url('photon', 'addresses', slug=photon.slug)
+    mocked_get.return_value = tests.utils.FakedResponse(content=FAKED_CONTENT, status_code=200)
 
     # one user selects an address
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
@@ -284,7 +284,7 @@ def test_photon_addresses_data_change(mocked_get, app, photon):
     # another requests the same while upstream data has been updated
     new_content = json.loads(FAKED_CONTENT)
     new_content['features'][0]['properties']['housenumber'] = 'changed'
-    mocked_get.return_value = utils.FakedResponse(content=json.dumps(new_content), status_code=200)
+    mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(new_content), status_code=200)
     resp = app.get(endpoint, params={'q': 'plop'}, status=200)
 
     # first user saves the form, data should not have changed
diff --git a/tests/test_plone_restapi.py b/tests/test_plone_restapi.py
index 9de7dcf9..156e1ae0 100644
--- a/tests/test_plone_restapi.py
+++ b/tests/test_plone_restapi.py
@@ -19,13 +19,13 @@ import json
 import os
 
 import pytest
-import utils
 from requests.exceptions import ConnectionError
-from test_manager import login
 
+import tests.utils
 from passerelle.apps.plone_restapi.models import PloneRestApi, Query
 from passerelle.utils import import_site
 from passerelle.utils.jsonresponse import APIError
+from tests.test_manager import login
 
 pytestmark = pytest.mark.django_db
 
@@ -51,7 +51,7 @@ def json_get_data(filename):
 
 @pytest.fixture
 def connector():
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         PloneRestApi.objects.create(
             slug='my_connector',
             service_url='http://www.example.net',
@@ -66,7 +66,7 @@ def connector():
 
 @pytest.fixture
 def token(connector):
-    with utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE) as mocked:
+    with tests.utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE) as mocked:
         yield mocked
 
 
@@ -210,9 +210,9 @@ def test_adapt_record(connector, token):
 
 def test_get_token(app, connector):
     with pytest.raises(APIError):
-        with utils.mock_url(url=connector.token_ws_url, response=TOKEN_ERROR_RESPONSE, status_code=404):
+        with tests.utils.mock_url(url=connector.token_ws_url, response=TOKEN_ERROR_RESPONSE, status_code=404):
             connector.get_token()
-    with utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE) as mocked:
+    with tests.utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE) as mocked:
         result = connector.get_token()
         assert mocked.handlers[0].call['count'] == 1
         assert 'secret' in mocked.handlers[0].call['requests'][0].body
@@ -227,35 +227,35 @@ def test_get_token(app, connector):
 
 def test_check_status(app, connector):
     url = connector.service_url + '/@types'
-    with utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE):
-        with utils.mock_url(url=url, response={}):
+    with tests.utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE):
+        with tests.utils.mock_url(url=url, response={}):
             connector.check_status()
 
     # idp not responding
-    with utils.mock_url(url=connector.token_ws_url, response={}, status_code=503):
+    with tests.utils.mock_url(url=connector.token_ws_url, response={}, status_code=503):
         with pytest.raises(APIError):
             connector.check_status()
 
     # plone not responding
-    with utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE):
-        with utils.mock_url(url=url, response={}, status_code=503):
+    with tests.utils.mock_url(url=connector.token_ws_url, response=TOKEN_RESPONSE):
+        with tests.utils.mock_url(url=url, response={}, status_code=503):
             with pytest.raises(APIError):
                 connector.check_status()
 
     # without idp
     connector.token_ws_url = ''
     connector.save()
-    with utils.mock_url(url=url, response={}):
+    with tests.utils.mock_url(url=url, response={}):
         connector.check_status()
 
     # plone not responding
-    with utils.mock_url(url=url, response={}, status_code=503):
+    with tests.utils.mock_url(url=url, response={}, status_code=503):
         with pytest.raises(APIError):
             connector.check_status()
 
 
 def test_fetch(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/fetch'
     url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
     params = {
@@ -263,7 +263,7 @@ def test_fetch(app, connector, token):
         'uri': 'braine-l-alleud',
         'text_template': '{{ title }} ({{ topics.0.title }})',
     }
-    with utils.mock_url(url=url, response=json_get_data('fetch')):
+    with tests.utils.mock_url(url=url, response=json_get_data('fetch')):
         resp = app.get(endpoint, params=params)
     assert not resp.json['err']
     assert resp.json['data']['id'] == 'dccd85d12cf54b6899dff41e5a56ee7f'
@@ -276,7 +276,7 @@ def test_basic_auth(app, connector, token):
     connector.basic_auth_username = 'jsmith'
     connector.basic_auth_password = 'secret2'
     connector.save()
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/fetch'
     url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
     params = {
@@ -284,7 +284,7 @@ def test_basic_auth(app, connector, token):
         'uri': 'braine-l-alleud',
         'text_template': '{{ title }} ({{ topics.0.title }})',
     }
-    with utils.mock_url(url=url, response=json_get_data('fetch')) as mocked_get:
+    with tests.utils.mock_url(url=url, response=json_get_data('fetch')) as mocked_get:
         resp = app.get(endpoint, params=params)
         assert mocked_get.handlers[0].call['count'] == 1
         assert 'Basic' in mocked_get.handlers[0].call['requests'][0].headers['Authorization']
@@ -297,7 +297,7 @@ def test_basic_auth(app, connector, token):
 def test_request_anonymously(app, connector, token):
     connector.token_ws_url = ''
     connector.save()
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/fetch'
     url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
     params = {
@@ -305,7 +305,7 @@ def test_request_anonymously(app, connector, token):
         'uri': 'braine-l-alleud',
         'text_template': '{{ title }} ({{ topics.0.title }})',
     }
-    with utils.mock_url(url=url, response=json_get_data('fetch')):
+    with tests.utils.mock_url(url=url, response=json_get_data('fetch')):
         resp = app.get(endpoint, params=params)
     assert not resp.json['err']
     assert resp.json['data']['id'] == 'dccd85d12cf54b6899dff41e5a56ee7f'
@@ -322,7 +322,7 @@ def test_request_anonymously(app, connector, token):
     ],
 )
 def test_request_error(app, connector, token, exception, status_code, response, err_desc):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'fetch', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/fetch'
     url = connector.service_url + '/braine-l-alleud/plop'
     params = {
@@ -330,17 +330,17 @@ def test_request_error(app, connector, token, exception, status_code, response,
         'uri': 'braine-l-alleud',
         'text_template': '{{ title }} ({{ PLONE_type }})',
     }
-    with utils.mock_url(url=url, response=response, status_code=status_code, exception=exception):
+    with tests.utils.mock_url(url=url, response=response, status_code=status_code, exception=exception):
         resp = app.get(endpoint, params=params)
     assert resp.json['err']
     assert err_desc in resp.json['err_desc']
 
 
 def test_get_content_types(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'get_content_types', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'get_content_types', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/get_content_types'
     url = connector.service_url + '//@types'
-    with utils.mock_url(url=url, response=json_get_data('get_content_types')):
+    with tests.utils.mock_url(url=url, response=json_get_data('get_content_types')):
         resp = app.get(endpoint)
     assert not resp.json['err']
     assert len(resp.json['data']) == 10
@@ -348,17 +348,17 @@ def test_get_content_types(app, connector, token):
     assert resp.json['data'][2]['text'] == 'Contact'
 
     url = connector.service_url + '/belleville/citoyens/@types'
-    with utils.mock_url(url=url, response=json_get_data('get_content_types')):
+    with tests.utils.mock_url(url=url, response=json_get_data('get_content_types')):
         resp = app.get(endpoint + '?uri=belleville/citoyens')
     assert not resp.json['err']
 
 
 def test_get_content_type(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'get_content_type', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'get_content_type', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/get_content_type'
     url = connector.service_url + '/@types/imio.directory.Contact'
     params = {'id': 'imio.directory.Contact'}
-    with utils.mock_url(url=url, response=json_get_data('get_content_type')):
+    with tests.utils.mock_url(url=url, response=json_get_data('get_content_type')):
         resp = app.get(endpoint, params=params)
     assert not resp.json['err']
     assert resp.json['data']['title'] == 'Contact'
@@ -371,11 +371,11 @@ def test_get_content_type(app, connector, token):
 
 
 def test_get_field_choices(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'get_field_choices', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'get_field_choices', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/get_field_choices'
     url = connector.service_url + '/@vocabularies/imio.smartweb.vocabulary.Topics'
     params = {'id': 'imio.smartweb.vocabulary.Topics'}
-    with utils.mock_url(url=url, response=json_get_data('get_field_choices')) as mocked_get:
+    with tests.utils.mock_url(url=url, response=json_get_data('get_field_choices')) as mocked_get:
         resp = app.get(endpoint, params=params)
     assert 'b_size=999999' in mocked_get.handlers[0].call['requests'][1].url
     assert not resp.json['err']
@@ -385,7 +385,7 @@ def test_get_field_choices(app, connector, token):
 
 
 def test_create(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'create', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'create', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/create'
     url = connector.service_url + '/braine-l-alleud'
     payload = {
@@ -397,7 +397,7 @@ def test_create(app, connector, token):
         'topics/0/token': 'tourism',
         'image': {'filename': 'foo.jpg', 'content_type': 'image/jpeg', 'content': '...'},
     }
-    with utils.mock_url(url=url, response=json_get_data('fetch'), status_code=201) as mocked:
+    with tests.utils.mock_url(url=url, response=json_get_data('fetch'), status_code=201) as mocked:
         resp = app.post_json(endpoint + '?uri=braine-l-alleud&publish=false', params=payload)
         body = json.loads(mocked.handlers[0].call['requests'][1].body)
         assert body['topics'] == [{'title': 'Tourisme', 'token': 'tourism'}]
@@ -417,7 +417,7 @@ def test_create(app, connector, token):
 
 
 def test_create_and_publish(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'create', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'create', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/create'
     url = connector.service_url + '/braine-l-alleud'
     payload = {
@@ -430,8 +430,10 @@ def test_create_and_publish(app, connector, token):
         'image': {'filename': 'foo.jpg', 'content_type': 'image/jpeg', 'content': '...'},
     }
     publish_url = url + '/%s/@workflow/publish' % 'dccd85d12cf54b6899dff41e5a56ee7f'
-    with utils.mock_url(url=url, response=json_get_data('fetch'), status_code=201) as mocked:
-        with utils.mock_url(url=publish_url, response=json_get_data('workflow_publish'), status_code=200):
+    with tests.utils.mock_url(url=url, response=json_get_data('fetch'), status_code=201) as mocked:
+        with tests.utils.mock_url(
+            url=publish_url, response=json_get_data('workflow_publish'), status_code=200
+        ):
 
             resp = app.post_json(endpoint + '?uri=braine-l-alleud&publish=true', params=payload)
             body = json.loads(mocked.handlers[0].call['requests'][1].body)
@@ -452,7 +454,7 @@ def test_create_and_publish(app, connector, token):
 
 
 def test_create_wrong_payload(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'create', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'create', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/create'
     url = connector.service_url + '/braine-l-alleud'
     payload = 'not json'
@@ -463,7 +465,7 @@ def test_create_wrong_payload(app, connector, token):
 
 
 def test_update(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'update', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'update', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/update'
     url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
     query_string = '?uri=braine-l-alleud&uid=dccd85d12cf54b6899dff41e5a56ee7f'
@@ -472,7 +474,7 @@ def test_update(app, connector, token):
         'topics/0/token': 'social',
         'image': {'filename': 'foo.jpg', 'content_type': 'image/jpeg', 'content': '...'},
     }
-    with utils.mock_url(url=url, response='', status_code=204) as mocked:
+    with tests.utils.mock_url(url=url, response='', status_code=204) as mocked:
         resp = app.post_json(endpoint + query_string, params=payload)
         body = json.loads(mocked.handlers[0].call['requests'][1].body)
         assert body['topics'] == [{'token': 'social'}]
@@ -488,7 +490,7 @@ def test_update(app, connector, token):
 
 
 def test_update_wrong_payload(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'update', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'update', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/update'
     url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
     query_string = '?uri=braine-l-alleud&uid=dccd85d12cf54b6899dff41e5a56ee7f'
@@ -500,18 +502,18 @@ def test_update_wrong_payload(app, connector, token):
 
 
 def test_remove(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'remove', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'remove', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/remove'
     url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
     query_string = '?uri=braine-l-alleud&uid=dccd85d12cf54b6899dff41e5a56ee7f'
-    with utils.mock_url(url=url, response='', status_code=204):
+    with tests.utils.mock_url(url=url, response='', status_code=204):
         resp = app.delete(endpoint + query_string)
     assert resp.json['data'] == {'uid': 'dccd85d12cf54b6899dff41e5a56ee7f', 'removed': True}
     assert not resp.json['err']
 
 
 def test_search(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'search', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/search'
     url = connector.service_url + '/braine-l-alleud/@search'
     params = {
@@ -522,7 +524,7 @@ def test_search(app, connector, token):
         'limit': 3,
     }
     qs = {}
-    with utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
+    with tests.utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
         resp = app.get(endpoint, params=params)
     assert token.handlers[0].call['count'] == 1
     assert qs == {'sort_on': 'UID', 'sort_order': 'descending', 'b_size': '3', 'fullobjects': 'y'}
@@ -545,7 +547,7 @@ def test_search(app, connector, token):
 
 
 def test_search_using_q(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'search', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/search'
     url = connector.service_url + '/braine-l-alleud/@search'
     params = {
@@ -557,7 +559,7 @@ def test_search_using_q(app, connector, token):
         'q': 'Página dentro',
     }
     qs = {}
-    with utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
+    with tests.utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
         resp = app.get(endpoint, params=params)
     assert qs == {
         'SearchableText': 'Página dentro',
@@ -585,7 +587,7 @@ def test_search_using_q(app, connector, token):
 
 
 def test_search_using_id(app, connector, token):
-    endpoint = utils.generic_endpoint_url('plone-restapi', 'search', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('plone-restapi', 'search', slug=connector.slug)
     assert endpoint == '/plone-restapi/my_connector/search'
     url = connector.service_url + '/braine-l-alleud/@search'
     params = {
@@ -594,7 +596,7 @@ def test_search_using_id(app, connector, token):
         'id': '9fbb2afd499e465983434f974fce8404',
     }
     qs = {}
-    with utils.mock_url(url=url, response=json_get_data('id_search'), qs=qs):
+    with tests.utils.mock_url(url=url, response=json_get_data('id_search'), qs=qs):
         resp = app.get(endpoint, params=params)
     assert qs == {'UID': '9fbb2afd499e465983434f974fce8404', 'fullobjects': 'y'}
     assert len(resp.json['data']) == 1
@@ -608,7 +610,7 @@ def test_query_q(app, query, token):
         'limit': 3,
     }
     qs = {}
-    with utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
+    with tests.utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
         resp = app.get(endpoint, params=params)
         assert qs == {
             'sort_on': 'UID',
@@ -630,7 +632,7 @@ def test_query_q_using_q(app, query, token):
         'q': 'Página dentro',
     }
     qs = {}
-    with utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
+    with tests.utils.mock_url(url=url, response=json_get_data('q_search'), qs=qs):
         resp = app.get(endpoint, params=params)
         assert qs == {
             'SearchableText': 'Página dentro',
@@ -653,7 +655,7 @@ def test_query_q_using_id(app, query, token):
         'id': '9fbb2afd499e465983434f974fce8404',
     }
     qs = {}
-    with utils.mock_url(url=url, response=json_get_data('id_search'), qs=qs):
+    with tests.utils.mock_url(url=url, response=json_get_data('id_search'), qs=qs):
         resp = app.get(endpoint, params=params)
     assert qs == {
         'UID': '9fbb2afd499e465983434f974fce8404',
diff --git a/tests/test_proxylogger.py b/tests/test_proxylogger.py
index ae51fe33..1555b41b 100644
--- a/tests/test_proxylogger.py
+++ b/tests/test_proxylogger.py
@@ -6,18 +6,18 @@ import logging
 
 import pytest
 import requests
-import utils
 from django.core.exceptions import ValidationError
 from django.utils.log import AdminEmailHandler
 from django.utils.six import PY2
 from httmock import HTTMock
-from test_availability import down_mock, up_mock
 
+import tests.utils
 from passerelle.apps.feeds.models import Feed
 from passerelle.base.models import ProxyLogger, ResourceLog
 from passerelle.contrib.stub_invoices.models import StubInvoicesConnector
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
+from tests.test_availability import down_mock, up_mock
 
 
 @pytest.fixture
@@ -302,7 +302,7 @@ def test_logged_requests_and_responses_max_size(app, db, monkeypatch, settings):
     # default configuration
     assert connector.logging_parameters.requests_max_size == None
     assert connector.logging_parameters.responses_max_size == None
-    with utils.mock_url(URL, service_response, headers=service_headers):
+    with tests.utils.mock_url(URL, service_response, headers=service_headers):
         app.post(url, params=user_payload, status=200)
     assert len(ResourceLog.objects.all()) == 3
 
@@ -327,7 +327,7 @@ def test_logged_requests_and_responses_max_size(app, db, monkeypatch, settings):
     connector.set_log_level('DEBUG')
     settings.LOGGED_CONTENT_TYPES_MESSAGES = 'foo/bar'  # log response content
     ResourceLog.objects.all().delete()
-    with utils.mock_url(URL, service_response, headers=service_headers):
+    with tests.utils.mock_url(URL, service_response, headers=service_headers):
         app.post(url, params=user_payload, status=200)
     assert len(ResourceLog.objects.all()) == 3
 
@@ -350,7 +350,7 @@ def test_logged_requests_and_responses_max_size(app, db, monkeypatch, settings):
     parameters.requests_max_size = 25
     parameters.save()
     ResourceLog.objects.all().delete()
-    with utils.mock_url(URL, service_response, headers=service_headers):
+    with tests.utils.mock_url(URL, service_response, headers=service_headers):
         app.post(url, params=user_payload, status=200)
     assert len(ResourceLog.objects.all()) == 3
 
@@ -371,7 +371,7 @@ def test_logged_requests_and_responses_max_size(app, db, monkeypatch, settings):
     parameters.responses_max_size = 25
     parameters.save()
     ResourceLog.objects.all().delete()
-    with utils.mock_url(URL, service_response, headers=service_headers):
+    with tests.utils.mock_url(URL, service_response, headers=service_headers):
         app.post(url, params=user_payload, status=200)
     assert len(ResourceLog.objects.all()) == 3
 
@@ -384,7 +384,7 @@ def test_logged_requests_and_responses_max_size(app, db, monkeypatch, settings):
 
 def test_proxy_logger_email_traceback(app, db, email_handler, settings, mailoutbox, connector, monkeypatch):
     settings.ADMINS = [('admin', 'admin@example.net')]
-    endpoint_url = utils.generic_endpoint_url('feeds', 'json', slug=connector.slug)
+    endpoint_url = tests.utils.generic_endpoint_url('feeds', 'json', slug=connector.slug)
 
     @endpoint()
     def json(self, request):
diff --git a/tests/test_requests.py b/tests/test_requests.py
index e860b570..e1d5f70c 100644
--- a/tests/test_requests.py
+++ b/tests/test_requests.py
@@ -4,14 +4,14 @@ import mock
 import mohawk
 import pytest
 import requests
-import utils
 from django.test import override_settings
 from httmock import HTTMock, response, urlmatch
 from urllib3.exceptions import ReadTimeoutError
-from utils import FakedResponse
 
+import tests.utils
 from passerelle.utils import CaseInsensitiveDict, Request, log_http_request
 from passerelle.utils.http_authenticators import HawkAuth
+from tests.utils import FakedResponse
 
 
 @pytest.fixture(autouse=True)
diff --git a/tests/test_rsa13.py b/tests/test_rsa13.py
index d7faf85a..09593fcc 100644
--- a/tests/test_rsa13.py
+++ b/tests/test_rsa13.py
@@ -23,14 +23,14 @@ from urllib.parse import parse_qs
 
 import httmock
 import pytest
-import utils
 
+import tests.utils
 from passerelle.contrib.rsa13.models import RSA13Resource
 
 
 @pytest.fixture
 def rsa13(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         RSA13Resource,
         title='Test',
         slug='test',
diff --git a/tests/test_sector.py b/tests/test_sector.py
index 4e6583e5..ef6a3eef 100644
--- a/tests/test_sector.py
+++ b/tests/test_sector.py
@@ -20,7 +20,6 @@ from posix import stat_result
 from stat import ST_MTIME
 
 import pytest
-import utils
 import webtest
 from django.core.exceptions import ValidationError
 from django.core.files import File
@@ -29,10 +28,11 @@ from django.urls import reverse
 from django.utils.encoding import force_str, force_text
 from django.utils.six import StringIO
 from django.utils.timezone import now
-from test_manager import login
 
+import tests.utils
 from passerelle.apps.sector.models import Sectorization, SectorResource
 from passerelle.base.models import AccessRight
+from tests.test_manager import login
 
 CSV = """street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,sector_name
 75114_1912,rue du Château,P,,, gs-moulin, Groupe Scolaire Moulin
@@ -77,7 +77,7 @@ pytestmark = pytest.mark.django_db
 
 @pytest.fixture
 def sector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         SectorResource.objects.create(
             slug='test',
             title='title',
diff --git a/tests/test_sigerly.py b/tests/test_sigerly.py
index 309e4e1f..36787e18 100644
--- a/tests/test_sigerly.py
+++ b/tests/test_sigerly.py
@@ -19,8 +19,8 @@ import os
 
 import httmock
 import pytest
-import utils
 
+import tests.utils
 from passerelle.contrib.sigerly.models import Sigerly
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'sigerly')
@@ -28,7 +28,7 @@ TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'sigerly')
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         Sigerly.objects.create(slug='test', base_url='https://sigerly.example.net')
     )
 
@@ -39,7 +39,7 @@ def json_get_data(filename):
 
 
 def get_endpoint(name):
-    return utils.generic_endpoint_url('sigerly', name)
+    return tests.utils.generic_endpoint_url('sigerly', name)
 
 
 @pytest.mark.parametrize(
diff --git a/tests/test_sms.py b/tests/test_sms.py
index 5b688457..33855fc0 100644
--- a/tests/test_sms.py
+++ b/tests/test_sms.py
@@ -19,21 +19,21 @@ import logging
 import isodate
 import mock
 import pytest
-import utils
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
 from django.utils.translation import ugettext as _
 from requests import RequestException
-from test_manager import login
-from utils import FakedResponse
 
+import tests.utils
 from passerelle.apps.choosit.models import ChoositSMSGateway
 from passerelle.apps.ovh.models import OVHSMSGateway
 from passerelle.apps.sfr_dmc.models import SfrDmcGateway
 from passerelle.base.models import AccessRight, ApiUser, Job, ResourceLog
 from passerelle.sms.models import SMSLog, SMSResource
 from passerelle.utils.jsonresponse import APIError
+from tests.test_manager import login
+from tests.utils import FakedResponse
 
 pytestmark = pytest.mark.django_db
 
@@ -165,7 +165,7 @@ def test_connectors(app, connector, freezer):
 
         # perform job
         freezer.move_to('2019-01-01 01:00:03')
-        with utils.mock_url(
+        with tests.utils.mock_url(
             connector.URL, test_vector.get('response', ''), test_vector.get('status_code', 200)
         ):
             connector.jobs()
@@ -196,7 +196,7 @@ def test_sms_legacy_retry_after_error(app, connector, freezer):
     assert Job.objects.exists()
     assert Job.objects.get().status == 'registered'
     assert not Job.objects.get().after_timestamp
-    with utils.mock_url(
+    with tests.utils.mock_url(
         url=connector.URL,
         response={'status': 429, 'message': 'Too much requests.\nPlease retry in 3 seconds.'},
     ):
@@ -204,12 +204,12 @@ def test_sms_legacy_retry_after_error(app, connector, freezer):
     assert Job.objects.get().status == 'registered'
     assert Job.objects.get().after_timestamp
 
-    with utils.mock_url(url=connector.URL, response={'status': 100, 'credit_left': 22}):
+    with tests.utils.mock_url(url=connector.URL, response={'status': 100, 'credit_left': 22}):
         connector.jobs()
     assert Job.objects.get().status == 'registered'
 
     freezer.move_to('2019-01-01 00:00:11')
-    with utils.mock_url(url=connector.URL, response={'status': 100, 'creditLeft': 22}):
+    with tests.utils.mock_url(url=connector.URL, response={'status': 100, 'creditLeft': 22}):
         connector.jobs()
     assert Job.objects.get().status == 'completed'
     assert SMSLog.objects.exists()
@@ -411,7 +411,7 @@ def test_ovh_new_api(app, freezer):
     }
     base_url = connector.API_URL % {'serviceName': 'sms-test42'}
     url = base_url + 'jobs/'
-    with utils.mock_url(url, resp, 200) as mocked:
+    with tests.utils.mock_url(url, resp, 200) as mocked:
         connector.jobs()
     job = Job.objects.get(id=job_id)
     assert job.status == 'completed'
@@ -469,7 +469,7 @@ def test_ovh_new_api_credit(app, freezer, admin_user):
         'creditsLeft': 123,
     }
     ovh_url = connector.API_URL % {'serviceName': 'sms-test42'}
-    with utils.mock_url(ovh_url, resp, 200) as mocked:
+    with tests.utils.mock_url(ovh_url, resp, 200) as mocked:
         connector.jobs()
     connector.refresh_from_db()
     assert connector.credit_left == 123
@@ -481,7 +481,7 @@ def test_ovh_new_api_credit(app, freezer, admin_user):
     resp = {
         'creditsLeft': 456,
     }
-    with utils.mock_url(ovh_url, resp, 200) as mocked:
+    with tests.utils.mock_url(ovh_url, resp, 200) as mocked:
         connector.hourly()
     assert connector.credit_left == 456
 
@@ -507,13 +507,13 @@ def test_ovh_alert_emails(app, freezer, mailoutbox):
     freezer.move_to('2019-01-01 00:00:00')
     resp = {'creditsLeft': 101}
     ovh_url = connector.API_URL % {'serviceName': 'sms-test42'}
-    with utils.mock_url(ovh_url, resp, 200) as mocked:
+    with tests.utils.mock_url(ovh_url, resp, 200) as mocked:
         connector.hourly()
     assert len(mailoutbox) == 0
 
     resp = {'creditsLeft': 99}
     ovh_url = connector.API_URL % {'serviceName': 'sms-test42'}
-    with utils.mock_url(ovh_url, resp, 200) as mocked:
+    with tests.utils.mock_url(ovh_url, resp, 200) as mocked:
         connector.hourly()
     assert len(mailoutbox) == 1
 
@@ -530,12 +530,12 @@ def test_ovh_alert_emails(app, freezer, mailoutbox):
     freezer.move_to('2019-01-01 12:00:00')
     resp = {'creditsLeft': 99}
     ovh_url = connector.API_URL % {'serviceName': 'sms-test42'}
-    with utils.mock_url(ovh_url, resp, 200) as mocked:
+    with tests.utils.mock_url(ovh_url, resp, 200) as mocked:
         connector.hourly()
     assert len(mailoutbox) == 0
 
     freezer.move_to('2019-01-02 01:00:07')
-    with utils.mock_url(ovh_url, resp, 200) as mocked:
+    with tests.utils.mock_url(ovh_url, resp, 200) as mocked:
         connector.hourly()
     assert len(mailoutbox) == 1
 
@@ -558,7 +558,7 @@ def test_ovh_token_request(admin_user, app):
         'consumerKey': 'xyz',
         'validationUrl': 'https://eu.api.ovh.com/auth/?credentialToken=iQ1joJE',
     }
-    with utils.mock_url(ovh_request_token_url, ovh_response, 302) as mocked:
+    with tests.utils.mock_url(ovh_request_token_url, ovh_response, 302) as mocked:
         resp = resp.click('request access')
     assert resp.url == 'https://eu.api.ovh.com/auth/?credentialToken=iQ1joJE'
 
@@ -587,12 +587,12 @@ def test_ovh_token_request_error(admin_user, app):
     ovh_request_token_url = 'https://eu.api.ovh.com/1.0/auth/credential'
     ovh_response = {'message': 'Invalid application key'}
 
-    with utils.mock_url(ovh_request_token_url, ovh_response, 401) as mocked:
+    with tests.utils.mock_url(ovh_request_token_url, ovh_response, 401) as mocked:
         resp = resp.click('request access').follow()
     assert 'error requesting token: Invalid application key.' in resp.text
 
     ovh_response = 'not-json'
-    with utils.mock_url(ovh_request_token_url, ovh_response, 401) as mocked:
+    with tests.utils.mock_url(ovh_request_token_url, ovh_response, 401) as mocked:
         resp = resp.click('request access').follow()
     assert 'error requesting token: bad JSON response' in resp.text
 
diff --git a/tests/test_solis.py b/tests/test_solis.py
index e2d6e1dd..3b8bf6ab 100644
--- a/tests/test_solis.py
+++ b/tests/test_solis.py
@@ -2,11 +2,11 @@
 
 import mock
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 from django.core.files import File
 from django.utils.six import StringIO
 
+import tests.utils
 from passerelle.apps.solis.models import Solis, SolisAPALink, SolisRSALink, unflat
 from passerelle.base.models import AccessRight, ApiUser
 
@@ -88,7 +88,7 @@ def solis(db):
 
 def test_solis_restricted_access(app, solis):
     for service in ('apa-link', 'apa-unlink', 'rsa-link', 'rsa-unlink'):
-        endpoint = utils.generic_endpoint_url('solis', service, slug=solis.slug)
+        endpoint = tests.utils.generic_endpoint_url('solis', service, slug=solis.slug)
         assert endpoint == '/solis/test/%s' % service
         with mock.patch('passerelle.utils.Request.post') as requests_post:
             with mock.patch('passerelle.utils.Request.get') as requests_get:
@@ -99,7 +99,7 @@ def test_solis_restricted_access(app, solis):
                 resp = app.get(endpoint, status=405)
                 assert requests_get.call_count == 0
     for service in ('apa-links', 'apa-user-info', 'apa-users', 'rsa-links', 'rsa-user-info'):
-        endpoint = utils.generic_endpoint_url('solis', service, slug=solis.slug)
+        endpoint = tests.utils.generic_endpoint_url('solis', service, slug=solis.slug)
         assert endpoint == '/solis/test/%s' % service
         with mock.patch('passerelle.utils.Request.get') as requests_get:
             with mock.patch('passerelle.utils.Request.post') as requests_post:
@@ -114,7 +114,7 @@ def test_solis_restricted_access(app, solis):
 @pytest.fixture
 def ping_response():
     response_request = mock.Mock(headers={'Accept': '*/*'}, body=None)
-    return utils.FakedResponse(
+    return tests.utils.FakedResponse(
         headers={'Content-Type': 'text/plain'}, status_code=200, request=response_request
     )
 
@@ -127,7 +127,7 @@ def test_solis_ping(app, solis, ping_response):
         codename='can_access', apiuser=api, resource_type=obj_type, resource_pk=solis.pk
     )
 
-    endpoint = utils.generic_endpoint_url('solis', 'ping', slug=solis.slug)
+    endpoint = tests.utils.generic_endpoint_url('solis', 'ping', slug=solis.slug)
     with mock.patch('passerelle.utils.RequestSession.request') as requests_get:
         for bad_content in (
             'error',
@@ -198,7 +198,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
     # link
     with mock.patch('passerelle.utils.Request.post') as requests_post:  # get solis token
         with mock.patch('passerelle.utils.Request.get') as requests_get:  # get solis informations
-            endpoint = utils.generic_endpoint_url('solis', 'apa-link', slug=solis.slug)
+            endpoint = tests.utils.generic_endpoint_url('solis', 'apa-link', slug=solis.slug)
             for params in (None, '', []):
                 resp = app.post_json(endpoint, params=params, status=200)
                 assert requests_post.call_count == 0
@@ -216,7 +216,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
                 assert resp.json['err'] == 1
                 assert 'missing user_id/code credentials' in resp.json['err_desc']
 
-            requests_post.return_value = utils.FakedResponse(content=APATOKEN_403, status_code=403)
+            requests_post.return_value = tests.utils.FakedResponse(content=APATOKEN_403, status_code=403)
             resp = app.post_json(
                 endpoint, params={'user_id': 'x', 'code': 'x', 'name_id': NAMEID}, status=200
             )
@@ -227,8 +227,8 @@ def test_solis_apa_link_infos_unlink(app, solis):
 
             assert SolisAPALink.objects.count() == 0
 
-            requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200)
-            requests_get.return_value = utils.FakedResponse(
+            requests_post.return_value = tests.utils.FakedResponse(content=APATOKEN, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(
                 content=APAINFOS['exportDonneesIndividu'], status_code=200
             )
             resp = app.post_json(
@@ -279,7 +279,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
         'Mme Pecile PYPPENNE (NPYNEZ)',
         'Mme Pecile PYPPENNE (NPYNEZ)',
     ]
-    endpoint = utils.generic_endpoint_url('solis', 'apa-links', slug=solis.slug)
+    endpoint = tests.utils.generic_endpoint_url('solis', 'apa-links', slug=solis.slug)
     resp = app.get(endpoint, status=400)  # missing name_id
     assert resp.json['err'] == 1
     endpoint += '?name_id=%s' % NAMEID
@@ -292,9 +292,9 @@ def test_solis_apa_link_infos_unlink(app, solis):
     changed_name = APAINFOS['exportDonneesIndividu'].replace('PYPPENNE', 'PEPONE')
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         with mock.patch('passerelle.utils.Request.post') as requests_post:
-            requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200)
-            requests_get.return_value = utils.FakedResponse(content=changed_name, status_code=200)
-            endpoint = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
+            requests_post.return_value = tests.utils.FakedResponse(content=APATOKEN, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=changed_name, status_code=200)
+            endpoint = tests.utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
             endpoint += '?name_id=%s&user_id=42' % NAMEID
             resp = app.get(endpoint, status=200)
             assert resp.json['err'] == 0
@@ -306,14 +306,14 @@ def test_solis_apa_link_infos_unlink(app, solis):
     for apa_endpoint in APAINFOS:
         with mock.patch('passerelle.utils.Request.get') as requests_get:
             with mock.patch('passerelle.utils.Request.post') as requests_post:
-                requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200)
+                requests_post.return_value = tests.utils.FakedResponse(content=APATOKEN, status_code=200)
 
-                endpoint_base = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
+                endpoint_base = tests.utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
                 resp = app.get(endpoint_base, status=400)  # missing name_id
                 assert resp.json['err'] == 1
 
                 endpoint = endpoint_base + '?name_id=%s&user_id=53&information=%s' % (NAMEID, apa_endpoint)
-                requests_get.return_value = utils.FakedResponse(
+                requests_get.return_value = tests.utils.FakedResponse(
                     content=APAINFOS[apa_endpoint], status_code=200
                 )
                 resp = app.get(endpoint, status=200)
@@ -324,7 +324,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
                 assert resp.json['data']
 
                 # solis api crash
-                requests_get.return_value = utils.FakedResponse(content='boum', status_code=500)
+                requests_get.return_value = tests.utils.FakedResponse(content='boum', status_code=500)
                 resp = app.get(endpoint, status=200)
                 assert requests_post.call_count == 2  # get a token
                 assert requests_get.call_count == 2  # get informations
@@ -333,7 +333,9 @@ def test_solis_apa_link_infos_unlink(app, solis):
                 assert resp.json['err_desc'].startswith('error status:500')
                 assert resp.json['data'] == {'json_content': None, 'status_code': 500}
 
-                requests_get.return_value = utils.FakedResponse(content='{"error":"foobar"}', status_code=500)
+                requests_get.return_value = tests.utils.FakedResponse(
+                    content='{"error":"foobar"}', status_code=500
+                )
                 resp = app.get(endpoint, status=200)
                 assert resp.json['err'] == 1
                 assert resp.json['err_desc'].startswith('error status:500')
@@ -350,12 +352,12 @@ def test_solis_apa_link_infos_unlink(app, solis):
     # get info about a specific request
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         with mock.patch('passerelle.utils.Request.post') as requests_post:
-            requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200)
-            endpoint_base = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
+            requests_post.return_value = tests.utils.FakedResponse(content=APATOKEN, status_code=200)
+            endpoint_base = tests.utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
 
             # via demandeUnitaire
             endpoint = endpoint_base + '?name_id=%s&user_id=53&information=demandeUnitaire&index=42' % NAMEID
-            requests_get.return_value = utils.FakedResponse(content=APAREQUEST, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=APAREQUEST, status_code=200)
             resp = app.get(endpoint, status=200)
             assert requests_post.call_count == 1  # get a token
             assert requests_get.call_count == 1  # get demandeUnitaire
@@ -367,7 +369,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
 
             requests_post.reset_mock()
             requests_get.reset_mock()
-            requests_get.return_value = utils.FakedResponse(content='nothing here', status_code=404)
+            requests_get.return_value = tests.utils.FakedResponse(content='nothing here', status_code=404)
             resp = app.get(endpoint, status=200)
             assert requests_post.call_count == 1  # get a token
             assert requests_get.call_count == 1  # get demandeUnitaire
@@ -398,7 +400,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
                     NAMEID,
                     information,
                 )
-                requests_get.return_value = utils.FakedResponse(
+                requests_get.return_value = tests.utils.FakedResponse(
                     content=APAINFOS[information], status_code=200
                 )
                 resp = app.get(endpoint, status=200)
@@ -423,9 +425,9 @@ def test_solis_apa_link_infos_unlink(app, solis):
     change_info = APAINFOS['exportDonneesIndividu'].replace('PYPPENNE', 'PEPPYNE')
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         with mock.patch('passerelle.utils.Request.post') as requests_post:
-            requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200)
-            requests_get.return_value = utils.FakedResponse(content=change_info, status_code=200)
-            endpoint = utils.generic_endpoint_url('solis', 'apa-users', slug=solis.slug)
+            requests_post.return_value = tests.utils.FakedResponse(content=APATOKEN, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=change_info, status_code=200)
+            endpoint = tests.utils.generic_endpoint_url('solis', 'apa-users', slug=solis.slug)
             endpoint += '?name_id=%s' % NAMEID
             resp = app.get(endpoint, status=200)
             assert resp.json['err'] == 0
@@ -441,7 +443,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
             ]
 
     # unlink
-    endpoint = utils.generic_endpoint_url('solis', 'apa-unlink', slug=solis.slug)
+    endpoint = tests.utils.generic_endpoint_url('solis', 'apa-unlink', slug=solis.slug)
     for bad_params in ({}, {'user_id': '42'}, {'name_id': NAMEID}):
         resp = app.post_json(endpoint, params=bad_params, status=200)
         assert resp.json['err'] == 1
@@ -466,7 +468,7 @@ def test_solis_apa_link_infos_unlink(app, solis):
     assert SolisAPALink.objects.count() == 1
 
     # can not get informations from unlinked user
-    endpoint = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
+    endpoint = tests.utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
     endpoint += '?name_id=%s&user_id=42' % NAMEID
     resp = app.get(endpoint, status=200)
     assert resp.json['err'] == 1
@@ -483,8 +485,8 @@ def test_solis_referentiels(app, solis):
     )
 
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=DEPARTEMENTS, status_code=200)
-        url = utils.generic_endpoint_url('solis', 'referential', slug=solis.slug)
+        requests_get.return_value = tests.utils.FakedResponse(content=DEPARTEMENTS, status_code=200)
+        url = tests.utils.generic_endpoint_url('solis', 'referential', slug=solis.slug)
 
         resp = app.get(url + '/trans/departement/', status=200)
         assert requests_get.call_count == 1
@@ -533,7 +535,7 @@ def test_solis_referentiels(app, solis):
         assert 'codePays=79' in called_url
         assert 'foo=bar' not in called_url
 
-        requests_get.return_value = utils.FakedResponse(
+        requests_get.return_value = tests.utils.FakedResponse(
             content='{"nada":0}', status_code=404, reason='Not found'
         )
         resp = app.get(url + '/foo/bar/', status=200)
@@ -542,7 +544,7 @@ def test_solis_referentiels(app, solis):
         assert resp.json['err_desc'] == "error status:404 'Not found', content:'{\"nada\":0}'"
         assert resp.json['data'] == {'json_content': {'nada': 0}, 'status_code': 404}
 
-        requests_get.return_value = utils.FakedResponse(content='crash', status_code=500, reason='boum')
+        requests_get.return_value = tests.utils.FakedResponse(content='crash', status_code=500, reason='boum')
         resp = app.get(url + '/foo/bar/', status=200)
         assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/foo/bar')
         assert resp.json['err'] == 1
@@ -550,7 +552,7 @@ def test_solis_referentiels(app, solis):
         assert resp.json['data'] == {'json_content': None, 'status_code': 500}
 
         # optimized trans/lieu search
-        requests_get.return_value = utils.FakedResponse(content='{"lieux":[]}', status_code=200)
+        requests_get.return_value = tests.utils.FakedResponse(content='{"lieux":[]}', status_code=200)
         resp = app.get(url + '/trans/lieu/', status=200)
         assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/trans/lieu')
         resp = app.get(url + '/trans/lieu/?codeDepartement=1&codeCommune=2&q=search', status=200)
@@ -569,26 +571,26 @@ def test_solis_referential_item(app, solis):
     )
 
     with mock.patch('passerelle.utils.Request.get') as requests_get:
-        requests_get.return_value = utils.FakedResponse(content=CIVI_INDIVIDU, status_code=200)
-        url = utils.generic_endpoint_url('solis', 'referential-item', slug=solis.slug)
+        requests_get.return_value = tests.utils.FakedResponse(content=CIVI_INDIVIDU, status_code=200)
+        url = tests.utils.generic_endpoint_url('solis', 'referential-item', slug=solis.slug)
         resp = app.get(url + '/civi/individu/4373/', status=200)
         assert requests_get.call_count == 1
         assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/civi/individu/4373/')
         assert resp.json['err'] == 0
         assert resp.json['data']['etatCivil']['nom'] == 'NOM'
 
-        requests_get.return_value = utils.FakedResponse(
+        requests_get.return_value = tests.utils.FakedResponse(
             content='{"nada":0}', status_code=404, reason='Not found'
         )
-        url = utils.generic_endpoint_url('solis', 'referential-item', slug=solis.slug)
+        url = tests.utils.generic_endpoint_url('solis', 'referential-item', slug=solis.slug)
         resp = app.get(url + '/civi/individu/424242/', status=200)
         assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/civi/individu/424242/')
         assert resp.json['err'] == 1
         assert resp.json['err_desc'] == "error status:404 'Not found', content:'{\"nada\":0}'"
         assert resp.json['data'] == {'json_content': {'nada': 0}, 'status_code': 404}
 
-        requests_get.return_value = utils.FakedResponse(content='["not a dict"]', status_code=200)
-        url = utils.generic_endpoint_url('solis', 'referential-item', slug=solis.slug)
+        requests_get.return_value = tests.utils.FakedResponse(content='["not a dict"]', status_code=200)
+        url = tests.utils.generic_endpoint_url('solis', 'referential-item', slug=solis.slug)
         resp = app.get(url + '/civi/individu/0/', status=200)
         assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/civi/individu/0/')
         assert resp.json['err'] == 1
@@ -612,11 +614,11 @@ def test_solis_apa_integration(app, solis):
     with mock.patch('passerelle.utils.Request.post') as requests_post:
 
         def integration_ok(*args, **kwargs):
-            return utils.FakedResponse(content='', status_code=204)
+            return tests.utils.FakedResponse(content='', status_code=204)
 
-        requests_post.return_value = utils.FakedResponse(content='', status_code=204)
+        requests_post.return_value = tests.utils.FakedResponse(content='', status_code=204)
         # requests_post.side_effect = [utils.FakedResponse(content='', status_code=204)]
-        url = utils.generic_endpoint_url('solis', 'apa-integration', slug=solis.slug)
+        url = tests.utils.generic_endpoint_url('solis', 'apa-integration', slug=solis.slug)
 
         demande = {
             "beneficiaire_demande_aide": "APAD",
@@ -656,8 +658,8 @@ def test_solis_apa_integration(app, solis):
         # add files
         requests_post.reset_mock()
         requests_post.side_effect = [
-            utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 3}', status_code=200),
-            utils.FakedResponse(content='', status_code=204),
+            tests.utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 3}', status_code=200),
+            tests.utils.FakedResponse(content='', status_code=204),
         ]
         demande['file:etat_civil_001.pdf'] = {
             'content': 'JVBERmZha2U=',
@@ -722,8 +724,8 @@ def test_solis_apa_integration(app, solis):
         # bad file
         requests_post.reset_mock()
         requests_post.side_effect = [
-            utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 0}', status_code=200),
-            utils.FakedResponse(content='', status_code=204),
+            tests.utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 0}', status_code=200),
+            tests.utils.FakedResponse(content='', status_code=204),
         ]
         resp = app.post_json(url, params=demande, status=200)
         requests_post.assert_called_once()  # don't try to post request
@@ -734,8 +736,8 @@ def test_solis_apa_integration(app, solis):
         # error on sending file
         requests_post.reset_mock()
         requests_post.side_effect = [
-            utils.FakedResponse(content='{"error": 1}', status_code=500),
-            utils.FakedResponse(content='', status_code=204),
+            tests.utils.FakedResponse(content='{"error": 1}', status_code=500),
+            tests.utils.FakedResponse(content='', status_code=204),
         ]
         resp = app.post_json(url, params=demande, status=200)
         requests_post.assert_called_once()  # don't try to post request
@@ -754,7 +756,7 @@ def test_solis_rsa_link_infos_unlink(app, solis):
     # link
     with mock.patch('passerelle.utils.Request.post') as requests_post:  # get solis token
         with mock.patch('passerelle.utils.Request.get') as requests_get:  # get solis informations
-            endpoint = utils.generic_endpoint_url('solis', 'rsa-link', slug=solis.slug)
+            endpoint = tests.utils.generic_endpoint_url('solis', 'rsa-link', slug=solis.slug)
             for params in (None, '', []):
                 resp = app.post_json(endpoint, params=params, status=200)
                 assert requests_post.call_count == 0
@@ -779,7 +781,7 @@ def test_solis_rsa_link_infos_unlink(app, solis):
                 assert resp.json['err'] == 1
                 assert 'missing user_id/code credentials' in resp.json['err_desc']
 
-            requests_post.return_value = utils.FakedResponse(content=RSATOKEN_403, status_code=403)
+            requests_post.return_value = tests.utils.FakedResponse(content=RSATOKEN_403, status_code=403)
             resp = app.post_json(
                 endpoint, params={'user_id': 'x', 'code': 'x', 'name_id': NAMEID}, status=200
             )
@@ -790,8 +792,8 @@ def test_solis_rsa_link_infos_unlink(app, solis):
 
             assert SolisRSALink.objects.count() == 0
 
-            requests_post.return_value = utils.FakedResponse(content=RSATOKEN, status_code=200)
-            requests_get.return_value = utils.FakedResponse(content=CIVI_INDIVIDU, status_code=200)
+            requests_post.return_value = tests.utils.FakedResponse(content=RSATOKEN, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=CIVI_INDIVIDU, status_code=200)
             resp = app.post_json(
                 endpoint, params={'name_id': NAMEID, 'user_id': '4273', 'code': 'foo'}, status=200
             )
@@ -851,7 +853,7 @@ def test_solis_rsa_link_infos_unlink(app, solis):
     # verify recorded names after link
     assert [x['text'] for x in SolisRSALink.objects.values('text')] == ['MME Prenom NOM', 'MME Prenom NOM']
 
-    endpoint = utils.generic_endpoint_url('solis', 'rsa-links', slug=solis.slug)
+    endpoint = tests.utils.generic_endpoint_url('solis', 'rsa-links', slug=solis.slug)
     resp = app.get(endpoint, status=400)  # missing name_id
     assert resp.json['err'] == 1
     endpoint += '?name_id=%s' % NAMEID
@@ -864,9 +866,9 @@ def test_solis_rsa_link_infos_unlink(app, solis):
     changed_name = CIVI_INDIVIDU.replace('Prenom', 'Postnom')
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         with mock.patch('passerelle.utils.Request.post') as requests_post:
-            requests_post.return_value = utils.FakedResponse(content=RSATOKEN, status_code=200)
-            requests_get.return_value = utils.FakedResponse(content=changed_name, status_code=200)
-            endpoint = utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
+            requests_post.return_value = tests.utils.FakedResponse(content=RSATOKEN, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=changed_name, status_code=200)
+            endpoint = tests.utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
             endpoint += '?name_id=%s&user_id=4242' % NAMEID
             resp = app.get(endpoint, status=200)
             assert resp.json['err'] == 0
@@ -877,14 +879,14 @@ def test_solis_rsa_link_infos_unlink(app, solis):
     # get referential for a linked user
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         with mock.patch('passerelle.utils.Request.post') as requests_post:
-            requests_post.return_value = utils.FakedResponse(content=RSATOKEN, status_code=200)
+            requests_post.return_value = tests.utils.FakedResponse(content=RSATOKEN, status_code=200)
 
-            endpoint_base = utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
+            endpoint_base = tests.utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
             resp = app.get(endpoint_base, status=400)  # missing name_id
             assert resp.json['err'] == 1
 
             endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires' % NAMEID
-            requests_get.return_value = utils.FakedResponse(content=RSAALLOCATAIRES, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=RSAALLOCATAIRES, status_code=200)
             resp = app.get(endpoint, status=200)
             assert requests_post.call_count == 1  # get a token
             assert requests_get.call_count == 1  # get informations
@@ -893,7 +895,7 @@ def test_solis_rsa_link_infos_unlink(app, solis):
             assert resp.json['data']
 
             # solis api crash
-            requests_get.return_value = utils.FakedResponse(content='boum', status_code=500)
+            requests_get.return_value = tests.utils.FakedResponse(content='boum', status_code=500)
             resp = app.get(endpoint, status=200)
             assert requests_post.call_count == 2  # get a token
             assert requests_get.call_count == 2  # get informations
@@ -902,7 +904,9 @@ def test_solis_rsa_link_infos_unlink(app, solis):
             assert resp.json['err_desc'].startswith('error status:500')
             assert resp.json['data'] == {'json_content': None, 'status_code': 500}
 
-            requests_get.return_value = utils.FakedResponse(content='{"error":"foobar"}', status_code=500)
+            requests_get.return_value = tests.utils.FakedResponse(
+                content='{"error":"foobar"}', status_code=500
+            )
             resp = app.get(endpoint, status=200)
             assert resp.json['err'] == 1
             assert resp.json['err_desc'].startswith('error status:500')
@@ -919,10 +923,10 @@ def test_solis_rsa_link_infos_unlink(app, solis):
     # get actions, with filters
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         with mock.patch('passerelle.utils.Request.post') as requests_post:
-            requests_post.return_value = utils.FakedResponse(content=RSATOKEN, status_code=200)
-            endpoint_base = utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
+            requests_post.return_value = tests.utils.FakedResponse(content=RSATOKEN, status_code=200)
+            endpoint_base = tests.utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
             endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=actions' % NAMEID
-            requests_get.return_value = utils.FakedResponse(content=RSA_ACTIONS, status_code=200)
+            requests_get.return_value = tests.utils.FakedResponse(content=RSA_ACTIONS, status_code=200)
             resp = app.get(endpoint, status=200)
             assert requests_post.call_count == 1  # get a token
             assert requests_get.call_count == 1  # get actions
@@ -952,9 +956,9 @@ def test_solis_rsa_link_infos_unlink(app, solis):
 
             requests_get.reset_mock()
             requests_get.side_effect = [
-                utils.FakedResponse(status_code=200, content=RSA_ACTIONS),  # base info
-                utils.FakedResponse(status_code=200, content='{"nom":"Structure1"}'),  # link 1
-                utils.FakedResponse(status_code=200, content='{"nom":"Structure2"}'),  # link 2
+                tests.utils.FakedResponse(status_code=200, content=RSA_ACTIONS),  # base info
+                tests.utils.FakedResponse(status_code=200, content='{"nom":"Structure1"}'),  # link 1
+                tests.utils.FakedResponse(status_code=200, content='{"nom":"Structure2"}'),  # link 2
             ]
             filtered = endpoint + '&links'
             resp = app.get(filtered, status=200)
@@ -968,13 +972,13 @@ def test_solis_rsa_link_infos_unlink(app, solis):
     # get referential for a linked user with links
     with mock.patch('passerelle.utils.Request.get') as requests_get:
         with mock.patch('passerelle.utils.Request.post') as requests_post:
-            requests_post.return_value = utils.FakedResponse(content=RSATOKEN, status_code=200)
-            endpoint_base = utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
+            requests_post.return_value = tests.utils.FakedResponse(content=RSATOKEN, status_code=200)
+            endpoint_base = tests.utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
 
             requests_get.side_effect = [
-                utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES),  # base info
-                utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),  # link 1
-                utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),
+                tests.utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES),  # base info
+                tests.utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),  # link 1
+                tests.utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),
             ]  # link 2
             endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires&links' % NAMEID
             resp = app.get(endpoint, status=200)
@@ -988,10 +992,10 @@ def test_solis_rsa_link_infos_unlink(app, solis):
             requests_post.reset_mock()
             requests_get.reset_mock()
             requests_get.side_effect = [
-                utils.FakedResponse(status_code=200, content=RSA_3LINKS),  # base info
-                utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),  # link 1
-                utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),  # link 2.1
-                utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),
+                tests.utils.FakedResponse(status_code=200, content=RSA_3LINKS),  # base info
+                tests.utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),  # link 1
+                tests.utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),  # link 2.1
+                tests.utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),
             ]  # link 2.2
             endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=evaluations&links' % NAMEID
             resp = app.get(endpoint, status=200)
@@ -1006,8 +1010,8 @@ def test_solis_rsa_link_infos_unlink(app, solis):
             requests_post.reset_mock()
             requests_get.reset_mock()
             requests_get.side_effect = [
-                utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES),  # base info
-                utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),
+                tests.utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES),  # base info
+                tests.utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU),
             ]  # link 1
             endpoint = (
                 endpoint_base
@@ -1024,9 +1028,9 @@ def test_solis_rsa_link_infos_unlink(app, solis):
             requests_post.reset_mock()
             requests_get.reset_mock()
             requests_get.side_effect = [
-                utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES),  # base info
-                utils.FakedResponse(status_code=404, content='{"foo": "bar"}'),  # link 1
-                utils.FakedResponse(status_code=500, content='boom'),
+                tests.utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES),  # base info
+                tests.utils.FakedResponse(status_code=404, content='{"foo": "bar"}'),  # link 1
+                tests.utils.FakedResponse(status_code=500, content='boom'),
             ]  # link 2
             endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires&links' % NAMEID
             resp = app.get(endpoint, status=200)
@@ -1043,7 +1047,7 @@ def test_solis_rsa_link_infos_unlink(app, solis):
             ):
                 requests_post.reset_mock()
                 requests_get.reset_mock()
-                requests_get.side_effect = [utils.FakedResponse(status_code=200, content=content)]
+                requests_get.side_effect = [tests.utils.FakedResponse(status_code=200, content=content)]
                 endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires&links' % NAMEID
                 resp = app.get(endpoint, status=200)
                 assert requests_post.call_count == 1  # get a token
@@ -1053,7 +1057,7 @@ def test_solis_rsa_link_infos_unlink(app, solis):
                 assert 'content' not in resp.json['data']['rsa_links']['etatCivil']
 
     # unlink
-    endpoint = utils.generic_endpoint_url('solis', 'rsa-unlink', slug=solis.slug)
+    endpoint = tests.utils.generic_endpoint_url('solis', 'rsa-unlink', slug=solis.slug)
     for bad_params in ({}, {'user_id': '4273'}, {'name_id': NAMEID}):
         resp = app.post_json(endpoint, params=bad_params, status=200)
         assert resp.json['err'] == 1
@@ -1078,7 +1082,7 @@ def test_solis_rsa_link_infos_unlink(app, solis):
     assert SolisRSALink.objects.count() == 1
 
     # can not get informations from unlinked user
-    endpoint = utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
+    endpoint = tests.utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
     endpoint += '?name_id=%s&user_id=4242' % NAMEID
     resp = app.get(endpoint, status=200)
     assert resp.json['err'] == 1
diff --git a/tests/test_solis_afi_mss.py b/tests/test_solis_afi_mss.py
index 311fe2de..ba00bd00 100644
--- a/tests/test_solis_afi_mss.py
+++ b/tests/test_solis_afi_mss.py
@@ -20,16 +20,16 @@ import os
 
 import mock
 import pytest
-import utils
 from django.utils.encoding import force_text
 
+import tests.utils
 from passerelle.contrib.solis_afi_mss.models import SolisAfiMss
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         SolisAfiMss.objects.create(
             slug='test',
             base_url='https://solis-afi-mss.example.net/',
@@ -54,7 +54,7 @@ def get_media_file(filename):
 
 
 def response(status_code, content):
-    return utils.FakedResponse(content=content, status_code=status_code)
+    return tests.utils.FakedResponse(content=content, status_code=status_code)
 
 
 IS_ALIVE = response(200, json_get_data('isAlive'))
@@ -83,7 +83,7 @@ GET_AIDES_PAR_AGENT_4 = response(200, json_get_data('getAidesParAgent_388405'))
 
 
 def get_endpoint(name):
-    return utils.generic_endpoint_url('solis-afi-mss', name)
+    return tests.utils.generic_endpoint_url('solis-afi-mss', name)
 
 
 @mock.patch('passerelle.utils.Request.get')
diff --git a/tests/test_strasbourg_eu.py b/tests/test_strasbourg_eu.py
index 459b9b99..91e779f4 100644
--- a/tests/test_strasbourg_eu.py
+++ b/tests/test_strasbourg_eu.py
@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
 
 import pytest
-import utils
 from django.contrib.contenttypes.models import ContentType
 from httmock import HTTMock, all_requests
 
+import tests.utils
 from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.strasbourg_eu.models import StrasbourgEu
 
@@ -183,7 +183,7 @@ def test_availability(strasbourg_eu):
 
 
 def test_interests(app, strasbourg_eu):
-    endpoint = utils.generic_endpoint_url('strasbourg-eu', 'interests', slug=strasbourg_eu.slug)
+    endpoint = tests.utils.generic_endpoint_url('strasbourg-eu', 'interests', slug=strasbourg_eu.slug)
     with HTTMock(interests_mock):
         resp = app.get(endpoint)
         assert len(resp.json['data']) == 2
@@ -214,7 +214,7 @@ def test_interests(app, strasbourg_eu):
 
 
 def test_notifications(app, strasbourg_eu, caplog):
-    endpoint = utils.generic_endpoint_url('strasbourg-eu', 'notifications', slug=strasbourg_eu.slug)
+    endpoint = tests.utils.generic_endpoint_url('strasbourg-eu', 'notifications', slug=strasbourg_eu.slug)
 
     with HTTMock(notifications_mock):
         resp = app.get(endpoint, status=400)
@@ -254,7 +254,7 @@ def test_notifications(app, strasbourg_eu, caplog):
 
 
 def test_favorites(app, strasbourg_eu):
-    endpoint = utils.generic_endpoint_url('strasbourg-eu', 'favorites', slug=strasbourg_eu.slug)
+    endpoint = tests.utils.generic_endpoint_url('strasbourg-eu', 'favorites', slug=strasbourg_eu.slug)
     with HTTMock(favorites_mock):
         resp = app.get(endpoint, status=400)
         resp = app.get(endpoint + '?name_id=xxx')
diff --git a/tests/test_tcl.py b/tests/test_tcl.py
index a06c65bf..1b4ba1dc 100644
--- a/tests/test_tcl.py
+++ b/tests/test_tcl.py
@@ -2,9 +2,9 @@ import copy
 
 import mock
 import pytest
-import utils
 from django.utils.six.moves.urllib import parse as urlparse
 
+import tests.utils
 from passerelle.contrib.tcl.models import Line, Stop, Tcl
 
 LIGNE_BUS = {
@@ -114,7 +114,7 @@ PASSAGES = {
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(Tcl.objects.create(slug='test'))
+    return tests.utils.setup_access_rights(Tcl.objects.create(slug='test'))
 
 
 def tcl_responses(url, **kwargs):
@@ -125,7 +125,7 @@ def tcl_responses(url, **kwargs):
         '/geojson/tclarret': ARRETS,
         '/tclpassagearret': PASSAGES,
     }.get(urlparse.urlparse(url).path)
-    return utils.FakedResponse(json=lambda: copy.deepcopy(content), status_code=200)
+    return tests.utils.FakedResponse(json=lambda: copy.deepcopy(content), status_code=200)
 
 
 @mock.patch('passerelle.utils.Request.get')
@@ -150,7 +150,7 @@ def test_cron(mocked_get, app, connector):
 def test_stop_info(mocked_get, app, connector):
     mocked_get.side_effect = tcl_responses
     connector.daily()
-    endpoint = utils.generic_endpoint_url('tcl', 'stop', slug=connector.slug)
+    endpoint = tests.utils.generic_endpoint_url('tcl', 'stop', slug=connector.slug)
     assert endpoint == '/tcl/test/stop'
     resp = app.get(endpoint + '/46026')
     assert resp.json['data']['nom'] == 'Place Guichard'
diff --git a/tests/test_teamnet_axel.py b/tests/test_teamnet_axel.py
index 95ad2a91..caedb70a 100644
--- a/tests/test_teamnet_axel.py
+++ b/tests/test_teamnet_axel.py
@@ -1,15 +1,15 @@
 import mock
 import pytest
-import utils
 from requests.exceptions import ConnectionError
 
+import tests.utils
 from passerelle.contrib.teamnet_axel.models import Link, TeamnetAxel
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def setup(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         TeamnetAxel,
         **{
             'slug': 'test',
diff --git a/tests/test_toulouse_axel.py b/tests/test_toulouse_axel.py
index 8752141f..14e4e364 100644
--- a/tests/test_toulouse_axel.py
+++ b/tests/test_toulouse_axel.py
@@ -29,10 +29,10 @@ import freezegun
 import jsonschema
 import mock
 import pytest
-import utils
 import xmlschema
 from django.core.cache import cache
 
+import tests.utils
 from passerelle.contrib.toulouse_axel import schemas
 from passerelle.contrib.toulouse_axel.models import Link, Lock, ToulouseAxel
 from passerelle.contrib.toulouse_axel.utils import (
@@ -50,7 +50,7 @@ from passerelle.utils.soap import SOAPError
 
 @pytest.fixture
 def resource(db):
-    return utils.make_resource(
+    return tests.utils.make_resource(
         ToulouseAxel, slug='test', wsdl_url='http://example.net/AXEL_WS/AxelWS.php?wsdl'
     )
 
diff --git a/tests/test_toulouse_smart.py b/tests/test_toulouse_smart.py
index 27139a07..d6e21b81 100644
--- a/tests/test_toulouse_smart.py
+++ b/tests/test_toulouse_smart.py
@@ -28,13 +28,12 @@ import httmock
 import lxml.etree as ET
 import mock
 import pytest
-import utils
 from django.db import connection
 from django.db.migrations.executor import MigrationExecutor
 from django.utils.encoding import force_text
 from requests.exceptions import ReadTimeout
-from test_manager import login
 
+import tests.utils
 from passerelle.base.models import Job
 from passerelle.contrib.toulouse_smart.models import (
     SmartRequest,
@@ -42,6 +41,7 @@ from passerelle.contrib.toulouse_smart.models import (
     WcsRequest,
     WcsRequestFile,
 )
+from tests.test_manager import login
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'toulouse_smart')
 
@@ -50,7 +50,7 @@ TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'toulouse_smart'
 def smart(db, settings):
     settings.TIME_ZONE = 'Europe/Paris'
     settings.USE_TZ = True
-    return utils.make_resource(
+    return tests.utils.make_resource(
         ToulouseSmartResource,
         title='Test',
         slug='test',
@@ -683,7 +683,7 @@ def test_create_intervention_client_error(mocked_uuid, app, freezer, smart):
 @mock.patch('passerelle.utils.RequestSession.request')
 @mock.patch("django.db.models.fields.UUIDField.get_default", return_value=UUID)
 def test_create_intervention_timeout(mocked_uuid, mocked_get, app, freezer, smart):
-    from utils import FakedResponse
+    from tests.utils import FakedResponse
 
     mocked_get.side_effect = [
         FakedResponse(
diff --git a/tests/test_vivaticket.py b/tests/test_vivaticket.py
index f93457c8..34a5076d 100644
--- a/tests/test_vivaticket.py
+++ b/tests/test_vivaticket.py
@@ -1,8 +1,8 @@
 # -*- coding: utf-8 -*-
 import mock
 import pytest
-import utils
 
+import tests.utils
 from passerelle.apps.vivaticket.models import VivaTicket
 from passerelle.utils.jsonresponse import APIError
 
@@ -216,7 +216,7 @@ SCHOOL_LEVELS_RESPONSE = """{
 
 @pytest.fixture
 def connector(db):
-    return utils.setup_access_rights(
+    return tests.utils.setup_access_rights(
         VivaTicket.objects.create(
             slug='test', login='foo', password='bar', url='http://example.net/vivaticket'
         )
@@ -226,9 +226,9 @@ def connector(db):
 @mock.patch('passerelle.utils.Request.post')
 def test_get_api_key(mocked_post, app, connector):
     with pytest.raises(APIError):
-        mocked_post.return_value = utils.FakedResponse(content=ERROR_RESPONSE, ok=False)
+        mocked_post.return_value = tests.utils.FakedResponse(content=ERROR_RESPONSE, ok=False)
         connector.get_apikey()
-    mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, ok=True)
+    mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, ok=True)
     connector.get_apikey()
     assert mocked_post.call_count == 2
     assert "Connect/PostConnect" in mocked_post.call_args[0][0]
@@ -244,9 +244,9 @@ def test_get_api_key(mocked_post, app, connector):
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_events(mocked_get, mocked_post, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content=EVENTS_RESPONSE, status_code=200)
-    mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
-    result = utils.endpoint_get('/vivaticket/test/events', app, connector, 'events')
+    mocked_get.return_value = tests.utils.FakedResponse(content=EVENTS_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
+    result = tests.utils.endpoint_get('/vivaticket/test/events', app, connector, 'events')
     assert mocked_post.call_count == 1
     assert mocked_get.call_args[1]['params']['key'] == "86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074"
     assert 'data' in result.json
@@ -258,48 +258,52 @@ def test_get_events(mocked_get, mocked_post, app, connector):
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_events_with_expired_key(mocked_get, mocked_post, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content=EVENTS_RESPONSE, status_code=401)
-    mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
-    utils.endpoint_get('/vivaticket/test/events', app, connector, 'events')
+    mocked_get.return_value = tests.utils.FakedResponse(content=EVENTS_RESPONSE, status_code=401)
+    mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
+    tests.utils.endpoint_get('/vivaticket/test/events', app, connector, 'events')
     assert mocked_post.call_count == 2
 
 
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_rooms(mocked_get, mocked_post, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
-    mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
-    result = utils.endpoint_get('/vivaticket/test/rooms', app, connector, 'rooms')
+    mocked_get.return_value = tests.utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
+    result = tests.utils.endpoint_get('/vivaticket/test/rooms', app, connector, 'rooms')
     assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
     assert 'data' in result.json
     for item in result.json['data']:
         assert 'id' in item
         assert 'text' in item
-    result = utils.endpoint_get('/vivaticket/test/rooms', app, connector, 'rooms', params={'event': '02'})
+    result = tests.utils.endpoint_get(
+        '/vivaticket/test/rooms', app, connector, 'rooms', params={'event': '02'}
+    )
     assert mocked_get.call_args[1]['params']['eventCategory'] == '02'
 
 
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_themes(mocked_get, mocked_post, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
-    mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
-    result = utils.endpoint_get('/vivaticket/test/themes', app, connector, 'themes')
+    mocked_get.return_value = tests.utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
+    result = tests.utils.endpoint_get('/vivaticket/test/themes', app, connector, 'themes')
     assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
     assert 'data' in result.json
     for item in result.json['data']:
         assert 'id' in item
         assert 'text' in item
-    result = utils.endpoint_get('/vivaticket/test/themes', app, connector, 'themes', params={'room': '001'})
+    result = tests.utils.endpoint_get(
+        '/vivaticket/test/themes', app, connector, 'themes', params={'room': '001'}
+    )
     assert mocked_get.call_args[1]['params']['room'] == '001'
 
 
 @mock.patch('passerelle.utils.Request.post')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_school_levels(mocked_get, mocked_post, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content=SCHOOL_LEVELS_RESPONSE, status_code=200)
-    mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
-    result = utils.endpoint_get('/vivaticket/test/school-levels', app, connector, 'school-levels')
+    mocked_get.return_value = tests.utils.FakedResponse(content=SCHOOL_LEVELS_RESPONSE, status_code=200)
+    mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
+    result = tests.utils.endpoint_get('/vivaticket/test/school-levels', app, connector, 'school-levels')
     assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
     assert 'data' in result.json
     for item in result.json['data']:
@@ -311,10 +315,10 @@ def test_get_school_levels(mocked_get, mocked_post, app, connector):
 @mock.patch('passerelle.utils.Request.put')
 @mock.patch('passerelle.utils.Request.get')
 def test_get_or_create_contact(mocked_get, mocked_put, mocked_post, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content='', ok=False)
+    mocked_get.return_value = tests.utils.FakedResponse(content='', ok=False)
     mocked_post.side_effect = [
-        utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
-        utils.FakedResponse(
+        tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(
             content='{"InternalCode": "0000000273", "ReturnCode": 0, "Error": null}', status_code=200
         ),
     ]
@@ -325,11 +329,11 @@ def test_get_or_create_contact(mocked_get, mocked_put, mocked_post, app, connect
     assert mocked_post.call_args[1]['json']['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
     assert mocked_post.call_args[1]['json']['Contact']['Email'] == 'foo@example.com'
     assert mocked_post.call_args[1]['json']['Contact']['ExternalCode'] == 'b48def645758b95537d4'
-    mocked_post.return_value = utils.FakedResponse(
+    mocked_post.return_value = tests.utils.FakedResponse(
         content='{"InternalCode": "0000000273", "ReturnCode": 0, "Error": null}', status_code=200
     )
-    mocked_get.return_value = utils.FakedResponse(content=CONTACT_RESPONSE, ok=True)
-    mocked_put.return_value = utils.FakedResponse(content='', status_code=204)
+    mocked_get.return_value = tests.utils.FakedResponse(content=CONTACT_RESPONSE, ok=True)
+    mocked_put.return_value = tests.utils.FakedResponse(content='', status_code=204)
     connector.get_or_create_contact({'email': 'foo@example.com'})
     mocked_put.assert_called()
     assert mocked_put.call_args[1]['params']['id'] == '0000000273'
@@ -341,8 +345,8 @@ def test_get_or_create_contact(mocked_get, mocked_put, mocked_post, app, connect
 @mock.patch('passerelle.utils.Request.put')
 @mock.patch('passerelle.utils.Request.get')
 def test_book(mocked_get, mocked_put, mocked_post, app, connector):
-    mocked_get.return_value = utils.FakedResponse(content=CONTACT_RESPONSE, status_code=200)
-    url = utils.generic_endpoint_url('vivaticket', 'book')
+    mocked_get.return_value = tests.utils.FakedResponse(content=CONTACT_RESPONSE, status_code=200)
+    url = tests.utils.generic_endpoint_url('vivaticket', 'book')
     payload = {'id': 'formid', 'email': 'foo@example.com'}
     response = app.post_json(url, params=payload, status=400)
     payload['start_datetime'] = '2019-01-15'
@@ -361,8 +365,8 @@ def test_book(mocked_get, mocked_put, mocked_post, app, connector):
     payload['end_datetime'] = '2019-01-15T11:00'
     # first return the API key, then the result of the booking creation
     mocked_post.side_effect = [
-        utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
-        utils.FakedResponse(content=BOOKING_RESPONSE),
+        tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
+        tests.utils.FakedResponse(content=BOOKING_RESPONSE),
         Exception(),
     ]
     response = app.post_json(url, params=payload)
@@ -379,7 +383,7 @@ def test_book(mocked_get, mocked_put, mocked_post, app, connector):
 
     # no more need to fake key response because the key is in cache
     mocked_post.side_effect = [
-        utils.FakedResponse(text='This external booking code already exists.', ok=False)
+        tests.utils.FakedResponse(text='This external booking code already exists.', ok=False)
     ]
     response = app.post_json(url, params=payload)
     assert response.json['err'] == 1
diff --git a/tests/wcs/test_sp_fr.py b/tests/wcs/test_sp_fr.py
index 46d40673..d41af7eb 100644
--- a/tests/wcs/test_sp_fr.py
+++ b/tests/wcs/test_sp_fr.py
@@ -17,8 +17,8 @@
 
 import mock
 import pytest
-import utils
 
+import tests.utils
 from passerelle.apps.sp_fr.models import Resource
 from passerelle.utils.sftp import SFTP
 from passerelle.utils.wcs import FormDefRef, get_wcs_choices
@@ -43,7 +43,7 @@ def spfr(settings, wcs_host, db, sftpserver):
             }
         }
     }
-    yield utils.make_resource(
+    yield tests.utils.make_resource(
         Resource,
         title='Test 1',
         slug='test1',
-- 
2.34.1

