2020-03-18 09:05:14 +01:00
|
|
|
# welco - multichannel request processing
|
|
|
|
# Copyright (C) 2020 Entr'ouvert
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
|
|
# under the terms of the GNU Affero General Public License as published
|
|
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2020-03-17 19:25:25 +01:00
|
|
|
import httmock
|
|
|
|
import mock
|
2020-03-18 09:05:14 +01:00
|
|
|
import pytest
|
|
|
|
|
2020-03-17 19:25:25 +01:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2020-03-18 09:05:14 +01:00
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
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=/')
|
|
|
|
|
|
|
|
|
2020-03-17 19:25:25 +01:00
|
|
|
def test_no_channel_access(logged_app):
|
|
|
|
logged_app.get('/', status=403)
|
|
|
|
|
|
|
|
|
2020-03-18 09:05:14 +01:00
|
|
|
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=/')
|
2020-03-17 19:25:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
@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',
|
2021-01-11 20:10:12 +01:00
|
|
|
},
|
2020-03-17 19:25:25 +01:00
|
|
|
}
|
|
|
|
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([{')
|