Merge pull request #2368 from alphagov/richer-orgs

Use ‘organisations‘ table to store info about organisations (not YAML)
This commit is contained in:
Chris Hill-Scott
2019-03-08 14:57:21 +00:00
committed by GitHub
9 changed files with 390 additions and 21 deletions

View File

@@ -1,3 +1,4 @@
import datetime
import uuid
import pytest
@@ -5,6 +6,7 @@ from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from app.dao.organisation_dao import (
dao_get_organisations,
dao_get_organisation_by_email_address,
dao_get_organisation_by_id,
dao_get_organisation_by_service_id,
dao_get_organisation_services,
@@ -16,7 +18,14 @@ from app.dao.organisation_dao import (
)
from app.models import Organisation
from tests.app.db import create_organisation, create_service, create_user
from tests.app.db import (
create_domain,
create_email_branding,
create_letter_branding,
create_organisation,
create_service,
create_user,
)
def test_get_organisations_gets_all_organisations_alphabetically_with_active_organisations_first(
@@ -47,19 +56,67 @@ def test_get_organisation_by_id_gets_correct_organisation(notify_db, notify_db_s
assert organisation_from_db == organisation
def test_update_organisation(notify_db, notify_db_session):
updated_name = 'new name'
def test_update_organisation(
notify_db,
notify_db_session,
):
create_organisation()
organisation = Organisation.query.one()
user = create_user()
email_branding = create_email_branding()
letter_branding = create_letter_branding()
data = {
'name': 'new name',
"crown": True,
"organisation_type": 'local',
"agreement_signed": True,
"agreement_signed_at": datetime.datetime.utcnow(),
"agreement_signed_by_id": user.id,
"agreement_signed_version": 999.99,
"letter_branding_id": letter_branding.id,
"email_branding_id": email_branding.id,
}
for attribute, value in data.items():
assert getattr(organisation, attribute) != value
dao_update_organisation(organisation.id, **data)
organisation = Organisation.query.one()
for attribute, value in data.items():
assert getattr(organisation, attribute) == value
@pytest.mark.parametrize('domain_list, expected_domains', (
(['abc', 'def'], {'abc', 'def'}),
(['ABC', 'DEF'], {'abc', 'def'}),
([], set()),
(None, {'123', '456'}),
pytest.param(
['abc', 'ABC'], {'abc'},
marks=pytest.mark.xfail(raises=IntegrityError)
),
))
def test_update_organisation_domains_lowercases(
notify_db,
notify_db_session,
domain_list,
expected_domains,
):
create_organisation()
organisation = Organisation.query.one()
assert organisation.name != updated_name
# Seed some domains
dao_update_organisation(organisation.id, domains=['123', '456'])
dao_update_organisation(organisation.id, **{'name': updated_name})
# This should overwrite the seeded domains
dao_update_organisation(organisation.id, domains=domain_list)
organisation = Organisation.query.one()
assert organisation.name == updated_name
assert {domain.domain for domain in organisation.domains} == expected_domains
def test_add_service_to_organisation(notify_db, notify_db_session, sample_service, sample_organisation):
@@ -171,3 +228,30 @@ def test_add_user_to_organisation_when_user_does_not_exist(sample_organisation):
def test_add_user_to_organisation_when_organisation_does_not_exist(sample_user):
with pytest.raises(expected_exception=SQLAlchemyError):
dao_add_user_to_organisation(organisation_id=uuid.uuid4(), user_id=sample_user.id)
@pytest.mark.parametrize('domain, expected_org', (
('unknown.gov.uk', False),
('example.gov.uk', True),
))
def test_get_organisation_by_email_address(
admin_request,
sample_user,
domain,
expected_org,
):
org = create_organisation()
create_domain('example.gov.uk', org.id)
create_domain('test.gov.uk', org.id)
another_org = create_organisation(name='Another')
create_domain('cabinet-office.gov.uk', another_org.id)
create_domain('cabinetoffice.gov.uk', another_org.id)
found_org = dao_get_organisation_by_email_address('test@{}'.format(domain))
if expected_org:
assert found_org is org
else:
assert found_org is None

View File

@@ -4,7 +4,7 @@ from datetime import datetime
import pytest
from freezegun import freeze_time
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import FlushError, NoResultFound
from sqlalchemy.orm.exc import NoResultFound
from app import db
from app.dao.inbound_numbers_dao import (
@@ -167,9 +167,9 @@ def test_cannot_create_service_with_no_user(notify_db_session):
message_limit=1000,
restricted=False,
created_by=user)
with pytest.raises(FlushError) as excinfo:
with pytest.raises(ValueError) as excinfo:
dao_create_service(service, None)
assert "Can't flush None value found in collection Service.users" in str(excinfo.value)
assert "Can't create a service without a user" in str(excinfo.value)
def test_should_add_user_to_service(notify_db_session):

View File

@@ -52,7 +52,8 @@ from app.models import (
Complaint,
InvitedUser,
TemplateFolder,
LetterBranding
LetterBranding,
Domain,
)
@@ -506,6 +507,16 @@ def create_annual_billing(
return annual_billing
def create_domain(domain, organisation_id):
domain = Domain(domain=domain, organisation_id=organisation_id)
db.session.add(domain)
db.session.commit()
return domain
def create_organisation(name='test_org_1', active=True):
data = {
'name': name,

View File

@@ -32,10 +32,29 @@ def test_get_organisation_by_id(admin_request, notify_db_session):
organisation_id=org.id
)
assert set(response.keys()) == {'id', 'name', 'active'}
assert set(response.keys()) == {
'id',
'name',
'active',
'crown',
'organisation_type',
'agreement_signed',
'agreement_signed_at',
'agreement_signed_by_id',
'agreement_signed_version',
'letter_branding_id',
'email_branding_id',
}
assert response['id'] == str(org.id)
assert response['name'] == 'test_org_1'
assert response['active'] is True
assert response['crown'] is None
assert response['organisation_type'] is None
assert response['agreement_signed'] is None
assert response['agreement_signed_by_id'] is None
assert response['agreement_signed_version'] is None
assert response['letter_branding_id'] is None
assert response['email_branding_id'] is None
def test_post_create_organisation(admin_request, notify_db_session):
@@ -91,12 +110,27 @@ def test_post_create_organisation_with_missing_name_gives_validation_error(admin
assert response['errors'][0]['message'] == 'name is a required property'
def test_post_update_organisation_updates_fields(admin_request, notify_db_session):
@pytest.mark.parametrize('agreement_signed', (
None, True, False
))
@pytest.mark.parametrize('crown', (
None, True, False
))
def test_post_update_organisation_updates_fields(
admin_request,
notify_db_session,
agreement_signed,
crown,
):
org = create_organisation()
data = {
'name': 'new organisation name',
'active': False
'active': False,
'agreement_signed': agreement_signed,
'crown': crown,
}
assert org.agreement_signed is None
assert org.crown is None
admin_request.post(
'organisation.update_organisation',
@@ -111,6 +145,39 @@ def test_post_update_organisation_updates_fields(admin_request, notify_db_sessio
assert organisation[0].id == org.id
assert organisation[0].name == data['name']
assert organisation[0].active == data['active']
assert organisation[0].agreement_signed == agreement_signed
assert organisation[0].crown == crown
assert organisation[0].domains == []
@pytest.mark.parametrize('domain_list', (
['example.com'],
['example.com', 'example.org', 'example.net'],
[],
))
def test_post_update_organisation_updates_domains(
admin_request,
notify_db_session,
domain_list,
):
org = create_organisation(name='test_org_2')
data = {
'domains': domain_list,
}
admin_request.post(
'organisation.update_organisation',
_data=data,
organisation_id=org.id,
_expected_status=204
)
organisation = Organisation.query.all()
assert len(organisation) == 1
assert [
domain.domain for domain in organisation[0].domains
] == domain_list
def test_post_update_organisation_raises_400_on_existing_org_name(

View File

@@ -44,7 +44,9 @@ from tests.app.db import (
create_inbound_number,
create_service_sms_sender,
create_service_with_defined_sms_sender,
create_letter_branding
create_letter_branding,
create_organisation,
create_domain,
)
from tests.app.db import create_user
@@ -253,6 +255,55 @@ def test_create_service(admin_request, sample_user):
assert service_sms_senders[0].sms_sender == current_app.config['FROM_NUMBER']
@pytest.mark.parametrize('domain, expected_org', (
(None, False),
('', False),
('unknown.gov.uk', False),
('unknown-example.gov.uk', False),
('example.gov.uk', True),
('test.gov.uk', True),
('test.example.gov.uk', True),
))
def test_create_service_with_domain_sets_organisation(
admin_request,
sample_user,
domain,
expected_org,
):
red_herring_org = create_organisation(name='Sub example')
create_domain('specific.example.gov.uk', red_herring_org.id)
create_domain('aaaaaaaa.example.gov.uk', red_herring_org.id)
org = create_organisation()
create_domain('example.gov.uk', org.id)
create_domain('test.gov.uk', org.id)
another_org = create_organisation(name='Another')
create_domain('cabinet-office.gov.uk', another_org.id)
create_domain('cabinetoffice.gov.uk', another_org.id)
sample_user.email_address = 'test@{}'.format(domain)
data = {
'name': 'created service',
'user_id': str(sample_user.id),
'message_limit': 1000,
'restricted': False,
'active': False,
'email_from': 'created.service',
'created_by': str(sample_user.id),
'service_domain': domain,
}
json_resp = admin_request.post('service.create_service', _data=data, _expected_status=201)
if expected_org:
assert json_resp['data']['organisation'] == str(org.id)
else:
assert json_resp['data']['organisation'] is None
def test_create_service_with_domain_sets_letter_branding(admin_request, sample_user):
letter_branding = create_letter_branding(
name='test domain', filename='test-domain', domain='test.domain'