wcs/tests/admin_pages/test_logged_errors.py

456 lines
15 KiB
Python

import datetime
import pytest
from wcs.carddef import CardDef
from wcs.formdef import FormDef
from wcs.qommon.http_request import HTTPRequest
from wcs.workflows import Workflow
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
from .test_all import create_superuser
@pytest.fixture
def pub(request):
pub = create_temporary_pub()
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub.cfg['identification'] = {'methods': ['password']}
pub.cfg['language'] = {'language': 'en'}
pub.write_cfg()
return pub
def teardown_module(module):
clean_temporary_pub()
def test_studio_home(pub):
create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/studio/')
assert 'Recent errors' in resp.text
def test_listing_paginations(pub):
FormDef.wipe()
CardDef.wipe()
Workflow.wipe()
formdef = FormDef()
formdef.name = 'foo'
formdef.store()
formdef2 = FormDef()
formdef2.name = 'foo 2'
formdef2.store()
carddef = CardDef()
carddef.name = 'bar'
carddef.store()
carddef2 = CardDef()
carddef2.name = 'bar 2'
carddef2.store()
workflow = Workflow()
workflow.name = 'blah'
workflow.store()
workflow2 = Workflow()
workflow2.name = 'blah 2'
workflow2.store()
# FormDef errors
for i in range(0, 21):
error = pub.loggederror_class()
error.summary = 'FormDef Workflow Logged Error n°%s' % i
error.formdef_class = 'FormDef'
error.formdef_id = formdef.id
error.workflow_id = workflow.id
error.first_occurence_timestamp = datetime.datetime.now()
error.store()
error = pub.loggederror_class()
error.summary = 'FormDef 2 Workflow 2 Logged Error n°%s' % i
error.formdef_class = 'FormDef'
error.formdef_id = formdef2.id
error.workflow_id = workflow2.id
error.first_occurence_timestamp = datetime.datetime.now()
error.store()
# CardDef errors
for i in range(0, 21):
error = pub.loggederror_class()
error.summary = 'CardDef Workflow Logged Error n°%s' % i
error.formdef_class = 'CardDef'
error.formdef_id = carddef.id
error.workflow_id = workflow.id
error.first_occurence_timestamp = datetime.datetime.now()
error.store()
error = pub.loggederror_class()
error.summary = 'CardDef 2 Workflow 2 Logged Error n°%s' % i
error.formdef_class = 'CardDef'
error.formdef_id = carddef2.id
error.workflow_id = workflow2.id
error.first_occurence_timestamp = datetime.datetime.now()
error.store()
# workflow-only errors
for i in range(0, 21):
error = pub.loggederror_class()
error.summary = 'Workflow Logged Error n°%s' % i
error.workflow_id = workflow.id
error.first_occurence_timestamp = datetime.datetime.now()
error.store()
error = pub.loggederror_class()
error.summary = 'Workflow 2 Logged Error n°%s' % i
error.workflow_id = workflow2.id
error.first_occurence_timestamp = datetime.datetime.now()
error.store()
# standalone error
error = pub.loggederror_class()
error.summary = 'Lonely Logged Error'
error.exception_class = 'Exception'
error.exception_message = 'foo bar'
error.first_occurence_timestamp = datetime.datetime.now()
error.occurences_count = 17654032
error.store()
create_superuser(pub)
app = login(get_app(pub))
# all errors
# default pagination
resp = app.get('/backoffice/studio/logged-errors/')
assert '1-20/67' in resp.text
assert resp.text.count('Lonely Logged Error') == 1
assert '<span class="extra-info">- Exception (foo bar)</span>' in resp.text
assert '<span class="badge">17,654,032</span>' in resp.text
assert resp.text.count('Logged Error n°') == 19
resp = resp.click(href=r'\?offset=60')
assert '61-67/67' in resp.text
assert resp.text.count('Logged Error n°') == 7
# change pagination
resp = app.get('/backoffice/studio/logged-errors/?offset=0&limit=50')
assert '1-50/67' in resp.text
assert resp.text.count('Lonely Logged Error') == 1
assert resp.text.count('Logged Error n°') == 49
resp = resp.click('<!--Next Page-->')
assert '51-67/67' in resp.text
assert resp.text.count('Logged Error n°') == 17
# formdef errors
resp = app.get('/backoffice/forms/%s/' % formdef.id)
assert '21 errors' in resp
resp = app.get('/backoffice/forms/%s/logged-errors/' % formdef.id)
assert '1-20/21' in resp.text
assert resp.text.count('FormDef Workflow Logged Error n°') == 20
resp = resp.click('<!--Next Page-->')
assert '21-21/21' in resp.text
assert resp.text.count('FormDef Workflow Logged Error n°') == 1
# carddef errors
resp = app.get('/backoffice/cards/%s/' % carddef.id)
assert '21 errors' in resp
resp = app.get('/backoffice/cards/%s/logged-errors/' % carddef.id)
assert '1-20/21' in resp.text
assert resp.text.count('CardDef Workflow Logged Error n°') == 20
resp = resp.click('<!--Next Page-->')
assert '21-21/21' in resp.text
assert resp.text.count('CardDef Workflow Logged Error n°') == 1
# workflows errors
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
assert '63 errors' in resp
resp = app.get('/backoffice/workflows/%s/logged-errors/' % workflow.id)
assert '1-20/63' in resp.text
assert resp.text.count('Workflow Logged Error n°') == 20
resp = resp.click(href=r'\?offset=60')
assert '61-63/63' in resp.text
assert resp.text.count('Workflow Logged Error n°') == 3
def test_backoffice_access(pub):
FormDef.wipe()
CardDef.wipe()
Workflow.wipe()
formdef = FormDef()
formdef.name = 'foo'
formdef.store()
carddef = CardDef()
carddef.name = 'bar'
carddef.store()
workflow = Workflow()
workflow.name = 'blah'
workflow.store()
# FormDef error
error1 = pub.loggederror_class()
error1.summary = 'LoggedError'
error1.formdef_class = 'FormDef'
error1.formdef_id = formdef.id
error1.workflow_id = workflow.id
error1.first_occurence_timestamp = datetime.datetime.now()
error1.store()
# CardDef error
error2 = pub.loggederror_class()
error2.summary = 'LoggedError'
error2.formdef_class = 'CardDef'
error2.formdef_id = carddef.id
error2.workflow_id = workflow.id
error2.first_occurence_timestamp = datetime.datetime.now()
error2.store()
# workflow-only error
error3 = pub.loggederror_class()
error3.summary = 'LoggedError'
error3.workflow_id = workflow.id
error3.first_occurence_timestamp = datetime.datetime.now()
error3.store()
create_superuser(pub)
app = login(get_app(pub))
# check section link are not displayed if user has no access right
# formdefs are not accessible to current user
pub.cfg['admin-permissions'] = {'forms': ['X']}
pub.write_cfg()
resp = app.get('/backoffice/studio/logged-errors/')
assert resp.text.count('LoggedError') == 2
assert '<a href="%s/">' % error1.id not in resp.text
assert '<a href="%s/">' % error2.id in resp.text
assert '<a href="%s/">' % error3.id in resp.text
# carddefs are not accessible to current user
pub.cfg['admin-permissions'] = {'cards': ['X']}
pub.write_cfg()
resp = app.get('/backoffice/studio/logged-errors/')
assert resp.text.count('LoggedError') == 2
assert '<a href="%s/">' % error1.id in resp.text
assert '<a href="%s/">' % error2.id not in resp.text
assert '<a href="%s/">' % error3.id in resp.text
# workflows are not accessible to current user
pub.cfg['admin-permissions'] = {'workflows': ['X']}
pub.write_cfg()
resp = app.get('/backoffice/studio/logged-errors/')
assert resp.text.count('LoggedError') == 2
assert '<a href="%s/">' % error1.id in resp.text
assert '<a href="%s/">' % error2.id in resp.text
assert '<a href="%s/">' % error3.id not in resp.text
# mix formdefs & workflows
pub.cfg['admin-permissions'] = {'forms': ['X'], 'workflows': ['X']}
pub.write_cfg()
resp = app.get('/backoffice/studio/logged-errors/')
assert resp.text.count('LoggedError') == 1
assert '<a href="%s/">' % error1.id not in resp.text
assert '<a href="%s/">' % error2.id in resp.text
assert '<a href="%s/">' % error3.id not in resp.text
# mix all
pub.cfg['admin-permissions'] = {'forms': ['X'], 'cards': ['X'], 'workflows': ['X']}
pub.write_cfg()
resp = app.get('/backoffice/studio/logged-errors/', status=403)
def test_logged_error_404(pub):
create_superuser(pub)
app = login(get_app(pub))
# check non-existent id
app.get('/backoffice/studio/logged-errors/1', status=404)
# check invalid (non-integer) id
app.get('/backoffice/studio/logged-errors/null', status=404)
def test_logged_error_trace(pub):
create_superuser(pub)
app = login(get_app(pub))
logged_error = pub.record_error('Error')
resp = app.get(f'/backoffice/studio/logged-errors/{logged_error.id}/')
assert 'pub.record_error(\'Error' in resp.pyquery('.stack-trace--code')[0].text
assert '\n locals:' in resp.text
try:
raise ZeroDivisionError()
except Exception as e:
logged_error = pub.record_error('Exception', exception=e)
resp = app.get(f'/backoffice/studio/logged-errors/{logged_error.id}/')
assert 'pub.record_error(\'Exception' in resp.pyquery('.stack-trace--code')[0].text
assert '\n locals:' in resp.text
def test_logged_error_cleanup(pub):
create_superuser(pub)
FormDef.wipe()
CardDef.wipe()
Workflow.wipe()
pub.loggederror_class.wipe()
formdef = FormDef()
formdef.name = 'foo'
formdef.store()
carddef = CardDef()
carddef.name = 'bar'
carddef.store()
workflow = Workflow()
workflow.name = 'blah'
workflow.store()
# FormDef error
error1 = pub.loggederror_class()
error1.summary = 'LoggedError'
error1.formdef_class = 'FormDef'
error1.formdef_id = formdef.id
error1.workflow_id = workflow.id
error1.first_occurence_timestamp = error1.latest_occurence_timestamp = datetime.datetime.now()
error1.store()
# CardDef error
error2 = pub.loggederror_class()
error2.summary = 'LoggedError'
error2.formdef_class = 'CardDef'
error2.formdef_id = carddef.id
error2.workflow_id = workflow.id
error2.first_occurence_timestamp = error2.latest_occurence_timestamp = datetime.datetime.now()
error2.store()
# workflow-only error
error3 = pub.loggederror_class()
error3.summary = 'LoggedError'
error3.workflow_id = workflow.id
error3.first_occurence_timestamp = error3.latest_occurence_timestamp = datetime.datetime.now()
error3.store()
app = login(get_app(pub))
resp = app.get('/backoffice/studio/logged-errors/')
resp = resp.click('Cleanup')
resp = resp.form.submit('submit')
assert pub.loggederror_class().count() == 3 # nothing removed
# check there's a form error if nothing is checked
resp = app.get('/backoffice/studio/logged-errors/')
resp = resp.click('Cleanup')
resp.form['types$elementformdef'].checked = False
resp.form['types$elementcarddef'].checked = False
resp.form['types$elementothers'].checked = False
resp = resp.form.submit('submit')
assert resp.pyquery('[data-widget-name="types"].widget-with-error')
# check cleanup of only formdef errors
error1.first_occurence_timestamp = (
error1.latest_occurence_timestamp
) = datetime.datetime.now() - datetime.timedelta(days=280)
error1.store()
error2.first_occurence_timestamp = datetime.datetime.now() - datetime.timedelta(days=120)
error2.latest_occurence_timestamp = datetime.datetime.now() - datetime.timedelta(days=80)
error2.store()
error3.first_occurence_timestamp = (
error3.latest_occurence_timestamp
) = datetime.datetime.now() - datetime.timedelta(days=280)
error3.store()
resp = app.get('/backoffice/studio/logged-errors/')
resp = resp.click('Cleanup')
resp.form['types$elementcarddef'].checked = False
resp.form['types$elementothers'].checked = False
resp = resp.form.submit('submit')
assert {x.id for x in pub.loggederror_class().select()} == {error2.id, error3.id}
# check cleanup latest occurence value (error2 should not be cleaned)
resp = app.get('/backoffice/studio/logged-errors/')
resp = resp.click('Cleanup')
resp.form['latest_occurence'] = (datetime.datetime.now() - datetime.timedelta(days=100)).strftime(
'%Y-%m-%d'
)
resp = resp.form.submit('submit')
assert {x.id for x in pub.loggederror_class().select()} == {error2.id}
# check with a more recent date (error2 should be cleaned this time)
resp = app.get('/backoffice/studio/logged-errors/')
resp = resp.click('Cleanup')
resp.form['latest_occurence'] = (datetime.datetime.now() - datetime.timedelta(days=10)).strftime(
'%Y-%m-%d'
)
resp = resp.form.submit('submit')
assert {x.id for x in pub.loggederror_class().select()} == set()
# make formdefs not accessible to current user
pub.cfg['admin-permissions'] = {'forms': ['X']}
pub.write_cfg()
resp = app.get('/backoffice/studio/logged-errors/')
resp = resp.click('Cleanup')
assert [x.attrib['name'] for x in resp.pyquery('[type="checkbox"]')] == [
'types$elementcarddef',
'types$elementothers',
]
def test_logged_error_cleanup_from_filtered_page(pub):
create_superuser(pub)
FormDef.wipe()
CardDef.wipe()
Workflow.wipe()
pub.loggederror_class.wipe()
formdef = FormDef()
formdef.name = 'foo'
formdef.store()
carddef = CardDef()
carddef.name = 'bar'
carddef.store()
workflow = Workflow()
workflow.name = 'blah'
workflow.store()
# FormDef error
error1 = pub.loggederror_class()
error1.summary = 'LoggedError'
error1.formdef_class = 'FormDef'
error1.formdef_id = formdef.id
error1.first_occurence_timestamp = error1.latest_occurence_timestamp = datetime.datetime.now()
error1.store()
# CardDef error
error2 = pub.loggederror_class()
error2.summary = 'LoggedError'
error2.formdef_class = 'CardDef'
error2.formdef_id = carddef.id
error2.first_occurence_timestamp = error2.latest_occurence_timestamp = datetime.datetime.now()
error2.store()
# workflow-only error
error3 = pub.loggederror_class()
error3.summary = 'LoggedError'
error3.workflow_id = workflow.id
error3.first_occurence_timestamp = error3.latest_occurence_timestamp = datetime.datetime.now()
error3.store()
app = login(get_app(pub))
resp = app.get(formdef.get_admin_url() + 'logged-errors/')
resp = resp.click('Cleanup')
resp.form['latest_occurence'] = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime(
'%Y-%m-%d'
)
resp = resp.form.submit('submit')
assert not pub.loggederror_class.has_key(error1.id)
assert pub.loggederror_class.has_key(error2.id)
assert pub.loggederror_class.has_key(error3.id)
resp = app.get(workflow.get_admin_url() + 'logged-errors/')
resp = resp.click('Cleanup')
resp.form['latest_occurence'] = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime(
'%Y-%m-%d'
)
resp = resp.form.submit('submit')
assert not pub.loggederror_class.has_key(error1.id)
assert pub.loggederror_class.has_key(error2.id)
assert not pub.loggederror_class.has_key(error3.id)