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