authentic/tests/test_manager_journal.py

893 lines
32 KiB
Python

# authentic2 - versatile identity manager
# Copyright (C) 2010-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/>.
import datetime
import mock
from authentic2.custom_user.models import User
from authentic2.a2_rbac.utils import get_default_ou
from authentic2.a2_rbac.models import Role
from authentic2.models import Service
from authentic2.apps.journal.models import Event, _registry
from authentic2.journal import journal
from django.contrib.sessions.models import Session
from django.utils.timezone import make_aware
import pytest
from .utils import login, text_content
def test_journal_authorization(app, db, admin):
response = login(app, admin, path='/manage/')
assert 'Journal' not in response
app.get('/manage/journal/', status=403)
@pytest.fixture(autouse=True)
def events(db, freezer):
session1 = Session(session_key="1234")
session2 = Session(session_key="abcd")
ou = get_default_ou()
user = User.objects.create(
username="user", email="user@example.com", ou=ou, uuid="1" * 32, first_name='Johnny', last_name='doe'
)
agent = User.objects.create(username="agent", email="agent@example.com", ou=ou, uuid="2" * 32)
role_user = Role.objects.create(name="role1", ou=ou)
role_agent = Role.objects.create(name="role2", ou=ou)
service = Service.objects.create(name="service")
class EventFactory:
date = make_aware(datetime.datetime(2020, 1, 1))
def __call__(self, name, **kwargs):
freezer.move_to(self.date)
journal.record(name, **kwargs)
assert Event.objects.latest("timestamp").type.name == name
self.date += datetime.timedelta(hours=1)
make = EventFactory()
make("user.registration.request", email=user.email)
make(
"user.registration", user=user, session=session1, service=service, how="franceconnect",
)
make("user.logout", user=user, session=session1)
make("user.login.failure", username="user")
make("user.login.failure", username="agent")
make("user.login", user=user, session=session1, how="password")
make("user.password.change", user=user, session=session1)
edit_profile_form = mock.Mock()
edit_profile_form.initial = {'email': "user@example.com", 'first_name': "John"}
edit_profile_form.changed_data = ["first_name"]
edit_profile_form.cleaned_data = {'first_name': "Jane"}
make("user.profile.edit", user=user, session=session1, form=edit_profile_form)
make("user.service.sso.authorization", user=user, session=session1, service=service)
make("user.service.sso", user=user, session=session1, service=service, how="password")
make("user.service.sso.unauthorization", user=user, session=session1, service=service)
make("user.deletion", user=user, session=session1, service=service)
make("user.password.reset.request", email="USER@example.com", user=user)
make("user.password.reset.failure", email="USER@example.com")
make("user.password.reset", user=user)
make("user.login", user=agent, session=session2, how="saml")
create_form = mock.Mock(spec=["instance"])
create_form.instance = user
make("manager.user.creation", user=agent, session=session2, form=create_form)
edit_form = mock.Mock(spec=["instance", "initial", "changed_data", "cleaned_data"])
edit_form.instance = user
edit_form.initial = {'email': "user@example.com", 'first_name': "John"}
edit_form.changed_data = ["first_name"]
edit_form.cleaned_data = {'first_name': "Jane"}
make("manager.user.profile.edit", user=agent, session=session2, form=edit_form)
change_email_form = mock.Mock(spec=["instance", "cleaned_data"])
change_email_form.instance = user
change_email_form.cleaned_data = {'new_email': "jane@example.com"}
make(
"manager.user.email.change.request", user=agent, session=session2, form=change_email_form,
)
password_change_form = mock.Mock(spec=["instance", "cleaned_data"])
password_change_form.instance = user
password_change_form.cleaned_data = {'generate_password': False, 'send_mail': False}
make(
"manager.user.password.change", user=agent, session=session2, form=password_change_form,
)
password_change_form.cleaned_data["send_mail"] = True
make(
"manager.user.password.change", user=agent, session=session2, form=password_change_form,
)
make(
"manager.user.password.reset.request", user=agent, session=session2, target_user=user,
)
make(
"manager.user.password.change.force", user=agent, session=session2, target_user=user,
)
make(
"manager.user.password.change.unforce", user=agent, session=session2, target_user=user,
)
make("manager.user.activation", user=agent, session=session2, target_user=user)
make("manager.user.deactivation", user=agent, session=session2, target_user=user)
make("manager.user.deletion", user=agent, session=session2, target_user=user)
make(
"manager.user.sso.authorization.deletion",
user=agent,
session=session2,
service=service,
target_user=user,
)
make("manager.role.creation", user=agent, session=session2, role=role_user)
role_edit_form = mock.Mock(spec=["instance", "initial", "changed_data", "cleaned_data"])
role_edit_form.instance = role_user
role_edit_form.initial = {'name': role_user.name}
role_edit_form.changed_data = ["name"]
role_edit_form.cleaned_data = {'name': "changed role name"}
make(
"manager.role.edit", user=agent, session=session2, role=role_user, form=role_edit_form,
)
make("manager.role.deletion", user=agent, session=session2, role=role_user)
make(
"manager.role.membership.grant", user=agent, session=session2, role=role_user, member=user,
)
make(
"manager.role.membership.removal", user=agent, session=session2, role=role_user, member=user,
)
make(
"manager.role.inheritance.addition", user=agent, session=session2, parent=role_agent, child=role_user,
)
make(
"manager.role.inheritance.removal", user=agent, session=session2, parent=role_agent, child=role_user,
)
make(
"manager.role.administrator.role.addition",
user=agent,
session=session2,
role=role_user,
admin_role=role_agent,
)
make(
"manager.role.administrator.role.removal",
user=agent,
session=session2,
role=role_user,
admin_role=role_agent,
)
make(
"manager.role.administrator.user.addition",
user=agent,
session=session2,
role=role_user,
admin_user=user,
)
make(
"manager.role.administrator.user.removal",
user=agent,
session=session2,
role=role_user,
admin_user=user,
)
# verify we created at least one event for each type
assert set(Event.objects.values_list("type__name", flat=True)) == set(_registry)
return locals()
def extract_journal(response):
rows = []
seen_event_ids = set()
while True:
for tr in response.pyquery("tr[data-event-type]"):
# page can overlap when they contain less than 20 items (to prevent orphan rows)
event_id = tr.attrib["data-event-id"]
if event_id not in seen_event_ids:
rows.append(response.pyquery(tr))
seen_event_ids.add(event_id)
if "Previous page" not in response:
break
response = response.click("Previous page", index=0)
rows.reverse()
content = [
{
'timestamp': text_content(row.find(".journal-list--timestamp-column")[0]).strip(),
'type': row[0].attrib["data-event-type"],
'user': text_content(row.find(".journal-list--user-column")[0]).strip(),
'message': text_content(row.find(".journal-list--message-column")[0]),
}
for row in rows
]
return content
def test_global_journal(app, superuser, events):
response = login(app, user=superuser, path="/manage/")
# remove event about admin login
Event.objects.filter(user=superuser).delete()
response = response.click(href="journal")
content = extract_journal(response)
assert content == [
{
'message': 'registration request with email "user@example.com"',
'timestamp': 'Jan. 1, 2020, midnight',
'type': 'user.registration.request',
'user': '-',
},
{
'message': 'registration using franceconnect',
'timestamp': 'Jan. 1, 2020, 1 a.m.',
'type': 'user.registration',
'user': 'Johnny doe',
},
{
'message': 'logout',
'timestamp': 'Jan. 1, 2020, 2 a.m.',
'type': 'user.logout',
'user': 'Johnny doe',
},
{
'message': 'login failure with username "user"',
'timestamp': 'Jan. 1, 2020, 3 a.m.',
'type': 'user.login.failure',
'user': '-',
},
{
'message': 'login failure with username "agent"',
'timestamp': 'Jan. 1, 2020, 4 a.m.',
'type': 'user.login.failure',
'user': '-',
},
{
'message': 'login using password',
'timestamp': 'Jan. 1, 2020, 5 a.m.',
'type': 'user.login',
'user': 'Johnny doe',
},
{
'message': 'password change',
'timestamp': 'Jan. 1, 2020, 6 a.m.',
'type': 'user.password.change',
'user': 'Johnny doe',
},
{
'message': 'profile edit (first name)',
'timestamp': 'Jan. 1, 2020, 7 a.m.',
'type': 'user.profile.edit',
'user': 'Johnny doe',
},
{
'message': 'authorization of single sign on with "service"',
'timestamp': 'Jan. 1, 2020, 8 a.m.',
'type': 'user.service.sso.authorization',
'user': 'Johnny doe',
},
{
'message': 'service single sign on with "service"',
'timestamp': 'Jan. 1, 2020, 9 a.m.',
'type': 'user.service.sso',
'user': 'Johnny doe',
},
{
'message': 'unauthorization of single sign on with "service"',
'timestamp': 'Jan. 1, 2020, 10 a.m.',
'type': 'user.service.sso.unauthorization',
'user': 'Johnny doe',
},
{
'message': 'user deletion',
'timestamp': 'Jan. 1, 2020, 11 a.m.',
'type': 'user.deletion',
'user': 'Johnny doe',
},
{
'message': 'password reset request with email "user@example.com"',
'timestamp': 'Jan. 1, 2020, noon',
'type': 'user.password.reset.request',
'user': 'Johnny doe',
},
{
'message': 'password reset failure with email "USER@example.com"',
'timestamp': 'Jan. 1, 2020, 1 p.m.',
'type': 'user.password.reset.failure',
'user': '-',
},
{
'message': 'password reset',
'timestamp': 'Jan. 1, 2020, 2 p.m.',
'type': 'user.password.reset',
'user': 'Johnny doe',
},
{
'message': 'login using SAML',
'timestamp': 'Jan. 1, 2020, 3 p.m.',
'type': 'user.login',
'user': 'agent',
},
{
'message': 'creation of user "Johnny doe"',
'timestamp': 'Jan. 1, 2020, 4 p.m.',
'type': 'manager.user.creation',
'user': 'agent',
},
{
'message': 'edit of user "Johnny doe" (first name)',
'timestamp': 'Jan. 1, 2020, 5 p.m.',
'type': 'manager.user.profile.edit',
'user': 'agent',
},
{
'message': 'email change of user "Johnny doe" for email address "jane@example.com"',
'timestamp': 'Jan. 1, 2020, 6 p.m.',
'type': 'manager.user.email.change.request',
'user': 'agent',
},
{
'message': 'password change of user "Johnny doe"',
'timestamp': 'Jan. 1, 2020, 7 p.m.',
'type': 'manager.user.password.change',
'user': 'agent',
},
{
'message': 'password change of user "Johnny doe" and notification by mail',
'timestamp': 'Jan. 1, 2020, 8 p.m.',
'type': 'manager.user.password.change',
'user': 'agent',
},
{
'message': 'password reset request of "Johnny doe" sent to "user@example.com"',
'timestamp': 'Jan. 1, 2020, 9 p.m.',
'type': 'manager.user.password.reset.request',
'user': 'agent',
},
{
'message': 'mandatory password change at next login set for user "Johnny doe"',
'timestamp': 'Jan. 1, 2020, 10 p.m.',
'type': 'manager.user.password.change.force',
'user': 'agent',
},
{
'message': 'mandatory password change at next login unset for user "Johnny doe"',
'timestamp': 'Jan. 1, 2020, 11 p.m.',
'type': 'manager.user.password.change.unforce',
'user': 'agent',
},
{
'message': 'activation of user "Johnny doe"',
'timestamp': 'Jan. 2, 2020, midnight',
'type': 'manager.user.activation',
'user': 'agent',
},
{
'message': 'deactivation of user "Johnny doe"',
'timestamp': 'Jan. 2, 2020, 1 a.m.',
'type': 'manager.user.deactivation',
'user': 'agent',
},
{
'message': 'deletion of user "Johnny doe"',
'timestamp': 'Jan. 2, 2020, 2 a.m.',
'type': 'manager.user.deletion',
'user': 'agent',
},
{
'message': 'deletion of authorization of single sign on with "service" of ' 'user "Johnny doe"',
'timestamp': 'Jan. 2, 2020, 3 a.m.',
'type': 'manager.user.sso.authorization.deletion',
'user': 'agent',
},
{
'message': 'creation of role "role1"',
'timestamp': 'Jan. 2, 2020, 4 a.m.',
'type': 'manager.role.creation',
'user': 'agent',
},
{
'message': 'edit of role "role1" (name)',
'timestamp': 'Jan. 2, 2020, 5 a.m.',
'type': 'manager.role.edit',
'user': 'agent',
},
{
'message': 'deletion of role "role1"',
'timestamp': 'Jan. 2, 2020, 6 a.m.',
'type': 'manager.role.deletion',
'user': 'agent',
},
{
'message': 'membership grant to user "user (111111)" in role "role1"',
'timestamp': 'Jan. 2, 2020, 7 a.m.',
'type': 'manager.role.membership.grant',
'user': 'agent',
},
{
'message': 'membership removal of user "user (111111)" from role "role1"',
'timestamp': 'Jan. 2, 2020, 8 a.m.',
'type': 'manager.role.membership.removal',
'user': 'agent',
},
{
'message': 'inheritance addition from parent role "role2" to child role ' '"role1"',
'timestamp': 'Jan. 2, 2020, 9 a.m.',
'type': 'manager.role.inheritance.addition',
'user': 'agent',
},
{
'message': 'inheritance removal from parent role "role2" to child role ' '"role1"',
'timestamp': 'Jan. 2, 2020, 10 a.m.',
'type': 'manager.role.inheritance.removal',
'user': 'agent',
},
{
'message': 'addition of role "role2" as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, 11 a.m.',
'type': 'manager.role.administrator.role.addition',
'user': 'agent',
},
{
'message': 'removal of role "role2" as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, noon',
'type': 'manager.role.administrator.role.removal',
'user': 'agent',
},
{
'message': 'addition of user "user (111111)" as administrator of role ' '"role1"',
'timestamp': 'Jan. 2, 2020, 1 p.m.',
'type': 'manager.role.administrator.user.addition',
'user': 'agent',
},
{
'message': 'removal of user "user (111111)" as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, 2 p.m.',
'type': 'manager.role.administrator.user.removal',
'user': 'agent',
},
]
def test_user_journal(app, superuser, events):
response = login(app, user=superuser, path="/manage/")
user = User.objects.get(username="user")
response = app.get("/manage/users/%s/journal/" % user.id)
content = extract_journal(response)
assert content == [
{
'message': 'registration using franceconnect',
'timestamp': 'Jan. 1, 2020, 1 a.m.',
'type': 'user.registration',
'user': 'Johnny doe',
},
{
'message': 'logout',
'timestamp': 'Jan. 1, 2020, 2 a.m.',
'type': 'user.logout',
'user': 'Johnny doe',
},
{
'message': 'login using password',
'timestamp': 'Jan. 1, 2020, 5 a.m.',
'type': 'user.login',
'user': 'Johnny doe',
},
{
'message': 'password change',
'timestamp': 'Jan. 1, 2020, 6 a.m.',
'type': 'user.password.change',
'user': 'Johnny doe',
},
{
'message': 'profile edit (first name)',
'timestamp': 'Jan. 1, 2020, 7 a.m.',
'type': 'user.profile.edit',
'user': 'Johnny doe',
},
{
'message': 'authorization of single sign on with "service"',
'timestamp': 'Jan. 1, 2020, 8 a.m.',
'type': 'user.service.sso.authorization',
'user': 'Johnny doe',
},
{
'message': 'service single sign on with "service"',
'timestamp': 'Jan. 1, 2020, 9 a.m.',
'type': 'user.service.sso',
'user': 'Johnny doe',
},
{
'message': 'unauthorization of single sign on with "service"',
'timestamp': 'Jan. 1, 2020, 10 a.m.',
'type': 'user.service.sso.unauthorization',
'user': 'Johnny doe',
},
{
'message': 'user deletion',
'timestamp': 'Jan. 1, 2020, 11 a.m.',
'type': 'user.deletion',
'user': 'Johnny doe',
},
{
'message': 'password reset request with email "user@example.com"',
'timestamp': 'Jan. 1, 2020, noon',
'type': 'user.password.reset.request',
'user': 'Johnny doe',
},
{
'message': 'password reset',
'timestamp': 'Jan. 1, 2020, 2 p.m.',
'type': 'user.password.reset',
'user': 'Johnny doe',
},
{
'message': 'creation by administrator',
'timestamp': 'Jan. 1, 2020, 4 p.m.',
'type': 'manager.user.creation',
'user': 'agent',
},
{
'message': 'edit by administrator (first name)',
'timestamp': 'Jan. 1, 2020, 5 p.m.',
'type': 'manager.user.profile.edit',
'user': 'agent',
},
{
'message': 'email change for email address "jane@example.com" requested by administrator',
'timestamp': 'Jan. 1, 2020, 6 p.m.',
'type': 'manager.user.email.change.request',
'user': 'agent',
},
{
'message': 'password change by administrator',
'timestamp': 'Jan. 1, 2020, 7 p.m.',
'type': 'manager.user.password.change',
'user': 'agent',
},
{
'message': 'password change by administrator and notification by mail',
'timestamp': 'Jan. 1, 2020, 8 p.m.',
'type': 'manager.user.password.change',
'user': 'agent',
},
{
'message': "password reset request by administrator sent to " '"user@example.com"',
'timestamp': 'Jan. 1, 2020, 9 p.m.',
'type': 'manager.user.password.reset.request',
'user': 'agent',
},
{
'message': 'mandatory password change at next login set by administrator',
'timestamp': 'Jan. 1, 2020, 10 p.m.',
'type': 'manager.user.password.change.force',
'user': 'agent',
},
{
'message': 'mandatory password change at next login unset by administrator',
'timestamp': 'Jan. 1, 2020, 11 p.m.',
'type': 'manager.user.password.change.unforce',
'user': 'agent',
},
{
'message': 'activation by administrator',
'timestamp': 'Jan. 2, 2020, midnight',
'type': 'manager.user.activation',
'user': 'agent',
},
{
'message': 'deactivation by administrator',
'timestamp': 'Jan. 2, 2020, 1 a.m.',
'type': 'manager.user.deactivation',
'user': 'agent',
},
{
'message': 'deletion by administrator',
'timestamp': 'Jan. 2, 2020, 2 a.m.',
'type': 'manager.user.deletion',
'user': 'agent',
},
{
'message': 'deletion of authorization of single sign on with "service" by ' "administrator",
'timestamp': 'Jan. 2, 2020, 3 a.m.',
'type': 'manager.user.sso.authorization.deletion',
'user': 'agent',
},
{
'message': 'membership grant in role "role1"',
'timestamp': 'Jan. 2, 2020, 7 a.m.',
'type': 'manager.role.membership.grant',
'user': 'agent',
},
{
'message': 'membership removal from role "role1"',
'timestamp': 'Jan. 2, 2020, 8 a.m.',
'type': 'manager.role.membership.removal',
'user': 'agent',
},
{
'message': 'addition as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, 1 p.m.',
'type': 'manager.role.administrator.user.addition',
'user': 'agent',
},
{
'message': 'removal as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, 2 p.m.',
'type': 'manager.role.administrator.user.removal',
'user': 'agent',
},
]
def test_role_journal(app, superuser, events):
response = login(app, user=superuser, path="/manage/")
role1 = Role.objects.get(name="role1")
role2 = Role.objects.get(name="role2")
response = app.get("/manage/roles/%s/journal/" % role1.id)
content = extract_journal(response)
assert content == [
{
'message': 'creation',
'timestamp': 'Jan. 2, 2020, 4 a.m.',
'type': 'manager.role.creation',
'user': 'agent',
},
{
'message': 'edit (name)',
'timestamp': 'Jan. 2, 2020, 5 a.m.',
'type': 'manager.role.edit',
'user': 'agent',
},
{
'message': 'deletion',
'timestamp': 'Jan. 2, 2020, 6 a.m.',
'type': 'manager.role.deletion',
'user': 'agent',
},
{
'message': 'membership grant to user "user (111111)"',
'timestamp': 'Jan. 2, 2020, 7 a.m.',
'type': 'manager.role.membership.grant',
'user': 'agent',
},
{
'message': 'membership removal of user "user (111111)"',
'timestamp': 'Jan. 2, 2020, 8 a.m.',
'type': 'manager.role.membership.removal',
'user': 'agent',
},
{
'message': 'inheritance addition from parent role "role2"',
'timestamp': 'Jan. 2, 2020, 9 a.m.',
'type': 'manager.role.inheritance.addition',
'user': 'agent',
},
{
'message': 'inheritance removal from parent role "role2"',
'timestamp': 'Jan. 2, 2020, 10 a.m.',
'type': 'manager.role.inheritance.removal',
'user': 'agent',
},
{
'message': 'addition of role "role2" as administrator',
'timestamp': 'Jan. 2, 2020, 11 a.m.',
'type': 'manager.role.administrator.role.addition',
'user': 'agent',
},
{
'message': 'removal of role "role2" as administrator',
'timestamp': 'Jan. 2, 2020, noon',
'type': 'manager.role.administrator.role.removal',
'user': 'agent',
},
{
'message': 'addition of user "user (111111)" as administrator',
'timestamp': 'Jan. 2, 2020, 1 p.m.',
'type': 'manager.role.administrator.user.addition',
'user': 'agent',
},
{
'message': 'removal of user "user (111111)" as administrator',
'timestamp': 'Jan. 2, 2020, 2 p.m.',
'type': 'manager.role.administrator.user.removal',
'user': 'agent',
},
]
response = app.get("/manage/roles/%s/journal/" % role2.id)
content = extract_journal(response)
assert content == [
{
'message': 'inheritance addition to child role "role1"',
'timestamp': 'Jan. 2, 2020, 9 a.m.',
'type': 'manager.role.inheritance.addition',
'user': 'agent',
},
{
'message': 'inheritance removal to child role "role1"',
'timestamp': 'Jan. 2, 2020, 10 a.m.',
'type': 'manager.role.inheritance.removal',
'user': 'agent',
},
{
'message': 'addition as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, 11 a.m.',
'type': 'manager.role.administrator.role.addition',
'user': 'agent',
},
{
'message': 'removal as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, noon',
'type': 'manager.role.administrator.role.removal',
'user': 'agent',
},
]
def test_roles_journal(app, superuser, events):
response = login(app, user=superuser, path='/manage/')
response = response.click('Role')
response = response.click('Journal')
content = extract_journal(response)
assert content == [
{
'message': 'creation of role "role1"',
'timestamp': 'Jan. 2, 2020, 4 a.m.',
'type': 'manager.role.creation',
'user': 'agent',
},
{
'message': 'edit of role "role1" (name)',
'timestamp': 'Jan. 2, 2020, 5 a.m.',
'type': 'manager.role.edit',
'user': 'agent',
},
{
'message': 'deletion of role "role1"',
'timestamp': 'Jan. 2, 2020, 6 a.m.',
'type': 'manager.role.deletion',
'user': 'agent',
},
{
'message': 'membership grant to user "user (111111)" in role "role1"',
'timestamp': 'Jan. 2, 2020, 7 a.m.',
'type': 'manager.role.membership.grant',
'user': 'agent',
},
{
'message': 'membership removal of user "user (111111)" from role "role1"',
'timestamp': 'Jan. 2, 2020, 8 a.m.',
'type': 'manager.role.membership.removal',
'user': 'agent',
},
{
'message': 'inheritance addition from parent role "role2" to child role ' '"role1"',
'timestamp': 'Jan. 2, 2020, 9 a.m.',
'type': 'manager.role.inheritance.addition',
'user': 'agent',
},
{
'message': 'inheritance removal from parent role "role2" to child role ' '"role1"',
'timestamp': 'Jan. 2, 2020, 10 a.m.',
'type': 'manager.role.inheritance.removal',
'user': 'agent',
},
{
'message': 'addition of role "role2" as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, 11 a.m.',
'type': 'manager.role.administrator.role.addition',
'user': 'agent',
},
{
'message': 'removal of role "role2" as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, noon',
'type': 'manager.role.administrator.role.removal',
'user': 'agent',
},
{
'message': 'addition of user "user (111111)" as administrator of role ' '"role1"',
'timestamp': 'Jan. 2, 2020, 1 p.m.',
'type': 'manager.role.administrator.user.addition',
'user': 'agent',
},
{
'message': 'removal of user "user (111111)" as administrator of role "role1"',
'timestamp': 'Jan. 2, 2020, 2 p.m.',
'type': 'manager.role.administrator.user.removal',
'user': 'agent',
},
]
def test_date_navigation(app, superuser, events):
response = login(app, user=superuser, path="/manage/journal/")
response = response.click('2020')
response = response.click('January')
response = response.click('1')
response = response.click('January 2020')
response = response.click('2020')
response = response.click('All dates')
def test_search(app, superuser, events):
response = login(app, user=superuser, path="/manage/journal/")
response.form.set('search', 'event:registration')
response = response.form.submit()
assert len(response.pyquery('tbody tr')) == 1
response.form.set('search', 'username:agent event:login')
response = response.form.submit()
assert len(response.pyquery('tbody tr')) == 1
assert all(
'agent' == text_content(node) for node in response.pyquery('tbody tr td.journal-list--user-column')
)
response.form.set('search', 'uuid:%s event:reset' % events['user'].uuid)
response = response.form.submit()
assert len(response.pyquery('tbody tr')) == 1
response.form.set('search', 'session:1234')
response = response.form.submit()
assert len(response.pyquery('tbody tr')) == 9
assert all(
text_content(node) == 'Johnny doe'
for node in response.pyquery('tbody tr td.journal-list--user-column')
)
response.form.set('search', 'email:jane@example.com')
response = response.form.submit()
assert (
text_content(response.pyquery('tbody tr td.journal-list--message-column')[0]).strip()
== 'email change of user "Johnny doe" for email address "jane@example.com"'
)
response.form.set('search', 'jane@example.com')
response = response.form.submit()
assert (
text_content(response.pyquery('tbody tr td.journal-list--message-column')[0]).strip()
== 'email change of user "Johnny doe" for email address "jane@example.com"'
)
response.form.set('search', 'johny doe event:login')
response = response.form.submit()
pq = response.pyquery
assert [
list(map(text_content, p))
for p in zip(pq('tbody td.journal-list--user-column'), pq('tbody td.journal-list--message-column'))
] == [['Johnny doe', 'login using password']]