Files
notifications-api/tests/app/service/test_archived_service.py
Leo Hemsted 6181c60f75 remove usage of notify_db fixture in unit tests
* notify_db fixture creates the database connection and ensures the test
  db exists and has migrations applied etc. It will run once per session
  (test run).
* notify_db_session fixture runs after your test finishes and deletes
  all non static (eg type table) data.

In unit tests that hit the database (ie: most of them), 99% of the time
we will need to use notify_db_session to ensure everything is reset. The
only time we don't need to use it is when we're querying things such as
"ensure get X works when database is empty". This is such a low
percentage of tests that it's easier for us to just use
notify_db_session every time, and ensure that all our tests run much
more consistently, at the cost of a small bit of performance when
running tests.

We used to use notify_db to access the session object for manually
adding, committing, etc. To dissuade usage of that fixture I've moved
that to the `notify_db_session`. I've then removed all uses of notify_db
that I could find in the codebase.

As a note, if you're writing a test that uses a `sample_x` fixture, all
of those fixtures rely on notify_db_session so you'll get the teardown
functionality for free. If you're just calling eg `create_x` db.py
functions, then you'll need to make you add notify_db_session fixture to
your test, even if you aren't manually accessing the session.
2022-05-04 11:36:54 +01:00

128 lines
4.7 KiB
Python

import uuid
from datetime import datetime
import pytest
from freezegun import freeze_time
from app import db
from app.dao.api_key_dao import expire_api_key
from app.dao.services_dao import dao_archive_service, dao_fetch_service_by_id
from app.dao.templates_dao import dao_update_template
from app.models import Service
from tests import create_admin_authorization_header, unwrap_function
from tests.app.db import create_api_key, create_template
def test_archive_only_allows_post(client, notify_db_session):
auth_header = create_admin_authorization_header()
response = client.get('/service/{}/archive'.format(uuid.uuid4()), headers=[auth_header])
assert response.status_code == 405
def test_archive_service_errors_with_bad_service_id(client, notify_db_session):
auth_header = create_admin_authorization_header()
response = client.post('/service/{}/archive'.format(uuid.uuid4()), headers=[auth_header])
assert response.status_code == 404
def test_deactivating_inactive_service_does_nothing(client, sample_service):
auth_header = create_admin_authorization_header()
sample_service.active = False
response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
assert response.status_code == 204
assert sample_service.name == 'Sample service'
@pytest.fixture
def archived_service(client, notify_db_session, sample_service):
create_template(sample_service, template_name='a')
create_template(sample_service, template_name='b')
create_api_key(sample_service)
create_api_key(sample_service)
notify_db_session.commit()
auth_header = create_admin_authorization_header()
response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
assert response.status_code == 204
assert response.data == b''
return sample_service
@freeze_time('2018-07-07 12:00:00')
def test_deactivating_service_changes_name_and_email(client, sample_service):
auth_header = create_admin_authorization_header()
client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
archived_service = dao_fetch_service_by_id(sample_service.id)
assert archived_service.name == '_archived_2018-07-07_Sample service'
assert archived_service.email_from == '_archived_2018-07-07_sample.service'
def test_deactivating_service_revokes_api_keys(archived_service):
assert len(archived_service.api_keys) == 2
for key in archived_service.api_keys:
assert key.expiry_date is not None
assert key.version == 2
def test_deactivating_service_archives_templates(archived_service):
assert len(archived_service.templates) == 2
for template in archived_service.templates:
assert template.archived is True
assert template.version == 2
def test_deactivating_service_creates_history(archived_service):
ServiceHistory = Service.get_history_model()
history = ServiceHistory.query.filter_by(
id=archived_service.id
).order_by(
ServiceHistory.version.desc()
).first()
assert history.version == 2
assert history.active is False
@pytest.fixture
def archived_service_with_deleted_stuff(client, sample_service):
with freeze_time('2001-01-01'):
template = create_template(sample_service, template_name='a')
api_key = create_api_key(sample_service)
expire_api_key(sample_service.id, api_key.id)
template.archived = True
dao_update_template(template)
with freeze_time('2002-02-02'):
auth_header = create_admin_authorization_header()
response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
assert response.status_code == 204
assert response.data == b''
return sample_service
def test_deactivating_service_doesnt_affect_existing_archived_templates(archived_service_with_deleted_stuff):
assert archived_service_with_deleted_stuff.templates[0].archived is True
assert archived_service_with_deleted_stuff.templates[0].updated_at == datetime(2001, 1, 1, 0, 0, 0)
assert archived_service_with_deleted_stuff.templates[0].version == 2
def test_deactivating_service_doesnt_affect_existing_revoked_api_keys(archived_service_with_deleted_stuff):
assert archived_service_with_deleted_stuff.api_keys[0].expiry_date == datetime(2001, 1, 1, 0, 0, 0)
assert archived_service_with_deleted_stuff.api_keys[0].version == 2
def test_deactivating_service_rolls_back_everything_on_error(sample_service, sample_api_key, sample_template):
unwrapped_deactive_service = unwrap_function(dao_archive_service)
unwrapped_deactive_service(sample_service.id)
assert sample_service in db.session.dirty
assert sample_api_key in db.session.dirty
assert sample_template in db.session.dirty