Munge stuff into a consistent event data type

We store our audit history in two ways:

  1. A list of versions of a service
  2. A list of events to do with API keys

In the future there could be auditing data which we want to display that
is stored in other formats (for example the event table).

This commit adds some objects which wrap around the different types of
auditing data, and expose a consistent interface to them. This
architecture will let us:
- write clean code in the presentation layer to display these events on
  a page
- add more types of events in the future by subclassing the `Event` data
  type, without having to rewrite anything in the presentation layer
This commit is contained in:
Chris Hill-Scott
2019-10-18 16:09:39 +01:00
parent 055f000020
commit 59b4d60c91
11 changed files with 367 additions and 121 deletions

View File

@@ -1,8 +1,22 @@
from tests.conftest import SERVICE_ONE_ID
from tests.conftest import SERVICE_ONE_ID, normalize_spaces
def test_history(
client_request,
mock_get_service_history,
):
client_request.get('main.history', service_id=SERVICE_ONE_ID)
page = client_request.get('main.history', service_id=SERVICE_ONE_ID)
assert normalize_spaces(
page.select_one('main').text
) == (
'Service and API key history '
'11 November at 12:12pm 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6'
' Revoked the Bad key API key '
'11 November at 11:11am 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6'
' Created an API key called Bad key '
'10 October at 11:10am 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6'
' Created an API key called Good key '
'10 October at 11:10am 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6'
' Created this service and called it Example service'
)

View File

@@ -0,0 +1,89 @@
import pytest
from app.models.event import ServiceEvent
from tests.conftest import sample_uuid
@pytest.mark.parametrize('key, value_from, value_to, expected', (
('restricted', True, False, (
'Made this service live'
)),
('restricted', False, True, (
'Put this service back into trial mode'
)),
('active', False, True, (
'Unsuspended this service'
)),
('active', True, False, (
'Deleted this service'
)),
('contact_link', 'x', 'y', (
'Set the contact details for this service to y'
)),
('email_branding', 'foo', 'bar', (
'Updated this services email branding'
)),
('inbound_api', 'foo', 'bar', (
'Updated the callback for received text messages'
)),
('letter_branding', None, sample_uuid(), (
'Updated the logo on this services letters'
)),
('letter_branding', sample_uuid(), None, (
'Removed the logo from this services letters'
)),
('letter_contact_block', None, sample_uuid(), (
'Updated the default letter contact block for this service'
)),
('message_limit', 1, 2, (
'Increased this services daily message limit from 1 to 2'
)),
('message_limit', 2, 1, (
'Reduced this services daily message limit from 2 to 1'
)),
('name', 'Old', 'New', (
'Renamed this service from Old to New'
)),
('permissions', ['a', 'b', 'c'], ['a', 'b', 'c', 'd'], (
'Added d to this services permissions'
)),
('permissions', ['a', 'b', 'c'], ['a', 'b'], (
'Removed c from this services permissions'
)),
('permissions', ['a', 'b', 'c'], ['c', 'd', 'e'], (
'Removed a and b from this services permissions, added d and e'
)),
('prefix_sms', True, False, (
'Set text messages to not start with the name of this service'
)),
('prefix_sms', False, True, (
'Set text messages to start with the name of this service'
)),
('research_mode', True, False, (
'Took this service out of research mode'
)),
('research_mode', False, True, (
'Put this service into research mode'
)),
('service_callback_api', 'foo', 'bar', (
'Updated the callback for delivery receipts'
)),
))
def test_service_event(
key,
value_from,
value_to,
expected,
):
event = ServiceEvent(
{
'created_at': 'foo',
'updated_at': 'bar',
'created_by_id': sample_uuid(),
},
key,
value_from,
value_to,
)
assert event.relevant is True
assert str(event) == expected

View File

@@ -3505,8 +3505,39 @@ def mock_get_service_and_organisation_counts(mocker):
@pytest.fixture(scope='function')
def mock_get_service_history(mocker):
return mocker.patch('app.service_api_client.get_service_history', return_value={'data': {
'service_history': [],
'api_key_history': [],
return mocker.patch('app.service_api_client.get_service_history', return_value={
'service_history': [
{
'name': 'Example service',
'created_at': '2010-10-10T10:10:10.000000Z',
'updated_at': None,
'created_by_id': sample_uuid(),
},
{
'created_at': '2010-10-10T10:10:10.000000Z',
'updated_at': '2012-12-12T12:12:12.000000Z',
'created_by_id': uuid4(),
},
],
'api_key_history': [
{
'name': 'Good key',
'updated_at': None,
'created_at': '2010-10-10T10:10:10.000000Z',
'created_by_id': sample_uuid(),
},
{
'name': 'Bad key',
'updated_at': '2012-11-11T12:12:12.000000Z',
'created_at': '2011-11-11T11:11:11.000000Z',
'created_by_id': sample_uuid(),
},
{
'name': 'Bad key',
'updated_at': None,
'created_at': '2011-11-11T11:11:11.000000Z',
'created_by_id': sample_uuid(),
},
],
'events': [],
}})
})