From 01b10d1f6d78a107bf690a7cee48cfd6fbb6d0f6 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Tue, 17 Mar 2020 19:25:25 +0100
Subject: [PATCH 1/2] tests: add tests on main views.py (#40816)

---
 tests/conftest.py     |  44 +++++++++++
 tests/test_manager.py | 166 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 209 insertions(+), 1 deletion(-)

diff --git a/tests/conftest.py b/tests/conftest.py
index 3e5ba75..0e38d8b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -46,8 +46,52 @@ def mail_group(db, settings, user):
     group = Group.objects.create(name='mail')
     user.groups.add(group)
 
     # define authorization of mail group on mail channel
     channel_roles = getattr(settings, 'CHANNEL_ROLES', {})
     mail_roles = channel_roles.setdefault('mail', [])
     mail_roles.append('mail')
     return group
+
+
+@pytest.fixture
+def phone_group(db, settings, user):
+    from django.contrib.auth.models import Group
+
+    # add mail group to default user
+    group = Group.objects.create(name='phone')
+    user.groups.add(group)
+
+    # define authorization of phone group on phone channel
+    channel_roles = getattr(settings, 'CHANNEL_ROLES', {})
+    phone_roles = channel_roles.setdefault('phone', [])
+    phone_roles.append('phone')
+    return group
+
+
+@pytest.fixture
+def counter_group(db, settings, user):
+    from django.contrib.auth.models import Group
+
+    # add mail group to default user
+    group = Group.objects.create(name='counter')
+    user.groups.add(group)
+
+    # define authorization of counter group on counter channel
+    channel_roles = getattr(settings, 'CHANNEL_ROLES', {})
+    counter_roles = channel_roles.setdefault('counter', [])
+    counter_roles.append('counter')
+    return group
+
+
+@pytest.fixture
+def kb_group(db, settings, user):
+    from django.contrib.auth.models import Group
+
+    # add mail group to default user
+    group = Group.objects.create(name='kb')
+    user.groups.add(group)
+
+    # define authorization of kb group to manage then knowledge base
+    kb_manage_roles = getattr(settings, 'KB_MANAGE_ROLES', [])
+    kb_manage_roles.append('kb')
+    return group
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 49db243..259011a 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -9,19 +9,27 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-
+import httmock
+import mock
 import pytest
 
+from django.contrib.contenttypes.models import ContentType
+from django.core.files.base import ContentFile
+
+from welco.qualif.models import Association
+from welco.sources.mail.models import Mail
+
+
 def login(app, username='toto', password='toto'):
     login_page = app.get('/login/')
     login_form = login_page.forms[0]
     login_form['username'] = username
     login_form['password'] = password
     resp = login_form.submit()
     assert resp.status_int == 302
     return app
@@ -32,17 +40,173 @@ def logged_app(app, user):
     return login(app)
 
 
 def test_unlogged_access(app):
     # connect while not being logged in
     assert app.get('/', status=302).location.endswith('/login/?next=/')
 
 
+def test_no_channel_access(logged_app):
+    logged_app.get('/', status=403)
+
+
 def test_access(logged_app, mail_group):
     resp = logged_app.get('/', status=302)
     assert resp.location == 'mail/'
 
 
 def test_logout(logged_app):
     app = logged_app
     app.get('/logout/')
     assert app.get('/', status=302).location.endswith('/login/?next=/')
+
+
+@mock.patch('welco.views.get_idps', return_value=[{'METADATA': '...'}])
+@mock.patch('welco.views.resolve_url', return_value='foo-url')
+def test_mellon_idp_redirections(mocked_resolv_url, mocked_get_idps, app):
+    resp = app.get('/login/', status=302)
+    assert resp.location == 'foo-url'
+    resp = app.get('/login/?next=http://foo/?bar', status=302)
+    assert resp.location == 'foo-url?next=http%3A//foo/%3Fbar'
+    resp = app.get('/logout/', status=302)
+    assert resp.location == 'foo-url'
+
+
+def test_mail_view(app, user, mail_group):
+    resp = app.get('/mail/', status=302)
+    assert resp.location == '/login/?next=/mail/'
+    app.set_user(user.username)
+    resp = app.get('/mail/', status=200)
+    assert resp.html.find('h2').text == 'Mails'
+
+
+def test_no_channel_access_on_mail_view(app, user):
+    app.set_user(user.username)
+    app.get('/mail/', status=403)
+
+
+def test_phone_view(app, user, phone_group):
+    resp = app.get('/phone/', status=302)
+    assert resp.location == '/login/?next=/phone/'
+    app.set_user(user.username)
+    resp = app.get('/phone/', status=200)
+    assert resp.html.find('h2').text == 'Phone Call'
+
+
+def test_counter_view(app, user, counter_group):
+    resp = app.get('/counter/', status=302)
+    assert resp.location == '/login/?next=/counter/'
+    app.set_user(user.username)
+    resp = app.get('/counter/', status=200)
+    assert resp.html.find('h2').text == 'Counter'
+
+
+def test_kb_view(app, user, kb_group):
+    resp = app.get('/kb/', status=302)
+    assert resp.location == '/login/?next=/kb/'
+    app.set_user(user.username)
+    resp = app.get('/kb/', status=200)
+    assert resp.html.find('h2').text == 'Knowledge Base'
+
+
+def test_wcs_summary_view(app, mail_group, user):
+    mail = Mail.objects.create(content=ContentFile('foo', name='bar.txt'))
+    source_type = ContentType.objects.get_for_model(Mail).pk
+
+    resp = app.get(
+        '/ajax/summary/%s/%s/?callback=spam' % (source_type, mail.pk),
+        status=302)
+    assert resp.location.startswith('/login/?next=')
+
+    app.set_user(user.username)
+    resp = app.get(
+        '/ajax/summary/%s/%s/?callback=spam' % (source_type, mail.pk),
+        status=200)
+    assert resp.content_type == 'application/javascript'
+    assert 'bar' in resp.text
+    assert resp.text.startswith('spam({')
+
+
+def test_remove_association_view(app, mail_group, user):
+    mail = Mail.objects.create(content=ContentFile('foo', name='bar.txt'))
+    source_type = ContentType.objects.get_for_model(Mail).pk
+    association = Association.objects.create(
+        source_type=ContentType.objects.get(id=source_type),
+        source_pk=mail.pk)
+    assert Association.objects.filter(id=association.pk).count() == 1
+
+    resp = app.get('/ajax/remove-association/%s' % association.pk, status=302)
+    assert resp.location.startswith('/login/?next=')
+
+    app.set_user(user.username)
+    resp = app.get('/ajax/remove-association/%s' % association.pk, status=302)
+    assert resp.location == '/'
+    assert Association.objects.filter(id=association.pk).count() == 0
+
+
+def test_create_formdata_view(settings, app, mail_group, user):
+    settings.KNOWN_SERVICES = {
+        'wcs': {
+            'demarches': {
+                'url': 'http://wcs.example.net/',
+            }
+        }
+    }
+    mail = Mail.objects.create(content=ContentFile('foo', name='bar.txt'))
+    source_type = ContentType.objects.get_for_model(Mail).pk
+    association = Association.objects.create(
+        source_type=ContentType.objects.get(id=source_type),
+        source_pk=mail.pk)
+
+    resp = app.get('/ajax/create-formdata/%s' % association.pk, status=302)
+    assert resp.location.startswith('/login/?next=')
+
+    app.set_user(user.username)
+    resp = app.get('/ajax/create-formdata/%s' % association.pk, status=200)
+    assert resp.content_type == 'application/json'
+    assert resp.json == {'err': 1}
+
+    resp = app.post('/ajax/create-formdata/%s' % association.pk, status=200)
+    assert resp.json == {'err': 1, 'msg': "'NoneType' object has no attribute 'split'"}
+
+    association.formdef_reference = 'demarches:bar'
+    association.save()
+
+    @httmock.urlmatch(netloc='wcs.example.net', path='/api/formdefs/bar/schema', method='GET')
+    def response_get(url, request):
+        headers = {'content-type': 'application/json'}
+        content = {}
+        return httmock.response(200, content, headers)
+
+    @httmock.urlmatch(netloc='wcs.example.net', path='/api/formdefs/bar/submit', method='POST')
+    def response_post(url, request):
+        headers = {'content-type': 'application/json'}
+        content = {
+            'err': 0,
+            'data': {
+                'id': 42,
+                'backoffice_url': 'http://example.net',
+            }}
+        return httmock.response(200, content, headers)
+
+    with httmock.HTTMock(response_get, response_post):
+        resp = app.post('/ajax/create-formdata/%s' % association.pk, status=200)
+    assert resp.content_type == 'application/json'
+    assert resp.json == {
+        'result': 'ok',
+        'url': 'http://wcs.example.net/backoffice/management/bar/42/',
+    }
+
+
+def test_menu_json_view(app, user, mail_group, phone_group, counter_group, kb_group):
+    resp = app.get('/menu.json', status=302)
+    assert resp.location.startswith('/login/?next=')
+
+    app.set_user(user.username)
+    resp = app.get('/menu.json', status=200)
+    assert resp.content_type == 'application/json'
+    assert sorted([x['label'] for x in resp.json]) == [
+        'Call Center', 'Counter', 'Knowledge Base', 'Mails']
+
+    resp = app.get('/menu.json?callback=foo', status=200)
+    assert resp.content_type == 'application/javascript'
+    assert resp.text.startswith('foo([{')
-- 
2.25.1

