Remove domain columns from branding table

This relationship is via the `Organisation` now; we don’t use this
column to fudge a relationship based on the user’s email address and the
matching something in these columns.
This commit is contained in:
Chris Hill-Scott
2019-04-12 15:53:17 +01:00
parent a39ed098b8
commit ee966668bd
14 changed files with 23 additions and 195 deletions
-8
View File
@@ -11,14 +11,6 @@ def dao_get_letter_branding_by_name(letter_branding_name):
return LetterBranding.query.filter_by(name=letter_branding_name).first() return LetterBranding.query.filter_by(name=letter_branding_name).first()
def dao_get_letter_branding_by_domain(domain):
if not domain:
return None
return LetterBranding.query.filter(
LetterBranding.domain == domain
).first()
def dao_get_all_letter_branding(): def dao_get_all_letter_branding():
return LetterBranding.query.order_by(LetterBranding.name).all() return LetterBranding.query.order_by(LetterBranding.name).all()
@@ -9,7 +9,6 @@ post_create_email_branding_schema = {
"name": {"type": "string"}, "name": {"type": "string"},
"text": {"type": ["string", "null"]}, "text": {"type": ["string", "null"]},
"logo": {"type": ["string", "null"]}, "logo": {"type": ["string", "null"]},
"domain": {"type": ["string", "null"]},
"brand_type": {"enum": BRANDING_TYPES}, "brand_type": {"enum": BRANDING_TYPES},
}, },
"required": ["name"] "required": ["name"]
@@ -24,7 +23,6 @@ post_update_email_branding_schema = {
"name": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]},
"text": {"type": ["string", "null"]}, "text": {"type": ["string", "null"]},
"logo": {"type": ["string", "null"]}, "logo": {"type": ["string", "null"]},
"domain": {"type": ["string", "null"]},
"brand_type": {"enum": BRANDING_TYPES}, "brand_type": {"enum": BRANDING_TYPES},
}, },
"required": [] "required": []
+1 -18
View File
@@ -1,5 +1,4 @@
from flask import Blueprint, current_app, jsonify, request from flask import Blueprint, jsonify, request
from sqlalchemy.exc import IntegrityError
from app.dao.email_branding_dao import ( from app.dao.email_branding_dao import (
dao_create_email_branding, dao_create_email_branding,
@@ -19,22 +18,6 @@ email_branding_blueprint = Blueprint('email_branding', __name__)
register_errors(email_branding_blueprint) register_errors(email_branding_blueprint)
@email_branding_blueprint.errorhandler(IntegrityError)
def handle_integrity_error(exc):
"""
Handle integrity errors caused by the unique constraint on domain
"""
if 'domain' in str(exc):
return jsonify(
result='error',
message={'name': ["Duplicate domain '{}'".format(
exc.params.get('domain')
)]}
), 400
current_app.logger.exception(exc)
return jsonify(result='error', message="Internal server error"), 500
@email_branding_blueprint.route('', methods=['GET']) @email_branding_blueprint.route('', methods=['GET'])
def get_email_branding_options(): def get_email_branding_options():
email_branding_options = [o.serialize() for o in dao_get_email_branding_options()] email_branding_options = [o.serialize() for o in dao_get_email_branding_options()]
+1 -1
View File
@@ -22,7 +22,7 @@ def handle_integrity_error(exc):
""" """
Handle integrity errors caused by the unique constraint Handle integrity errors caused by the unique constraint
""" """
for col in {'domain', 'name', 'filename'}: for col in {'name', 'filename'}:
if 'letter_branding_{}_key'.format(col) in str(exc): if 'letter_branding_{}_key'.format(col) in str(exc):
return jsonify( return jsonify(
result='error', result='error',
@@ -5,7 +5,6 @@ post_letter_branding_schema = {
"properties": { "properties": {
"name": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]},
"filename": {"type": ["string", "null"]}, "filename": {"type": ["string", "null"]},
"domain": {"type": ["string", "null"]},
}, },
"required": ("name", "filename", "domain") "required": ("name", "filename")
} }
-4
View File
@@ -221,7 +221,6 @@ class EmailBranding(db.Model):
logo = db.Column(db.String(255), nullable=True) logo = db.Column(db.String(255), nullable=True)
name = db.Column(db.String(255), unique=True, nullable=False) name = db.Column(db.String(255), unique=True, nullable=False)
text = db.Column(db.String(255), nullable=True) text = db.Column(db.String(255), nullable=True)
domain = db.Column(db.Text, unique=True, nullable=True)
brand_type = db.Column( brand_type = db.Column(
db.String(255), db.String(255),
db.ForeignKey('branding_type.name'), db.ForeignKey('branding_type.name'),
@@ -237,7 +236,6 @@ class EmailBranding(db.Model):
"logo": self.logo, "logo": self.logo,
"name": self.name, "name": self.name,
"text": self.text, "text": self.text,
"domain": self.domain,
"brand_type": self.brand_type "brand_type": self.brand_type
} }
@@ -258,14 +256,12 @@ class LetterBranding(db.Model):
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
name = db.Column(db.String(255), unique=True, nullable=False) name = db.Column(db.String(255), unique=True, nullable=False)
filename = db.Column(db.String(255), unique=True, nullable=False) filename = db.Column(db.String(255), unique=True, nullable=False)
domain = db.Column(db.Text, unique=True, nullable=True)
def serialize(self): def serialize(self):
return { return {
"id": str(self.id), "id": str(self.id),
"name": self.name, "name": self.name,
"filename": self.filename, "filename": self.filename,
"domain": self.domain,
} }
+3 -4
View File
@@ -27,7 +27,6 @@ from app.dao.fact_notification_status_dao import (
fetch_stats_for_all_services_by_date_range, fetch_monthly_template_usage_for_service fetch_stats_for_all_services_by_date_range, fetch_monthly_template_usage_for_service
) )
from app.dao.inbound_numbers_dao import dao_allocate_number_for_service from app.dao.inbound_numbers_dao import dao_allocate_number_for_service
from app.dao.letter_branding_dao import dao_get_letter_branding_by_domain
from app.dao.organisation_dao import dao_get_organisation_by_service_id from app.dao.organisation_dao import dao_get_organisation_by_service_id
from app.dao.service_data_retention_dao import ( from app.dao.service_data_retention_dao import (
fetch_service_data_retention, fetch_service_data_retention,
@@ -186,7 +185,8 @@ def create_service():
if not data.get('user_id'): if not data.get('user_id'):
errors = {'user_id': ['Missing data for required field.']} errors = {'user_id': ['Missing data for required field.']}
raise InvalidRequest(errors, status_code=400) raise InvalidRequest(errors, status_code=400)
domain = data.pop('service_domain', None) data.pop('service_domain', None)
# validate json with marshmallow # validate json with marshmallow
service_schema.load(data) service_schema.load(data)
@@ -195,8 +195,7 @@ def create_service():
# unpack valid json into service object # unpack valid json into service object
valid_service = Service.from_json(data) valid_service = Service.from_json(data)
letter_branding = dao_get_letter_branding_by_domain(domain) dao_create_service(valid_service, user)
dao_create_service(valid_service, user, letter_branding=letter_branding)
return jsonify(data=service_schema.dump(valid_service).data), 201 return jsonify(data=service_schema.dump(valid_service).data), 201
+2 -8
View File
@@ -53,13 +53,7 @@ def test_update_email_branding(notify_db, notify_db_session):
assert email_branding[0].name == updated_name assert email_branding[0].name == updated_name
def test_domain_cant_be_empty_string(notify_db, notify_db_session): def test_email_branding_has_no_domain(notify_db, notify_db_session):
create_email_branding() create_email_branding()
email_branding = EmailBranding.query.all() email_branding = EmailBranding.query.all()
assert email_branding[0].domain is None assert not hasattr(email_branding, 'domain')
dao_update_email_branding(email_branding[0], domain='')
email_branding = EmailBranding.query.all()
assert email_branding[0].domain is None
+3 -20
View File
@@ -4,7 +4,6 @@ import pytest
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from app.dao.letter_branding_dao import ( from app.dao.letter_branding_dao import (
dao_get_letter_branding_by_domain,
dao_get_all_letter_branding, dao_get_all_letter_branding,
dao_create_letter_branding, dao_create_letter_branding,
dao_update_letter_branding, dao_update_letter_branding,
@@ -26,30 +25,16 @@ def test_dao_get_letter_brand_by_id_raises_exception_if_does_not_exist(notify_db
dao_get_letter_branding_by_id(uuid.uuid4()) dao_get_letter_branding_by_id(uuid.uuid4())
def test_dao_get_letter_branding_by_domain_returns_none_if_no_matching_domains(notify_db_session):
result = dao_get_letter_branding_by_domain(domain="test.domain")
assert not result
def test_dao_get_letter_branding_by_domain_returns_correct_brand_for_domain(notify_db_session):
create_letter_branding(domain='gov.uk')
test_domain_branding = create_letter_branding(
name='test domain', filename='test-domain', domain='test.domain'
)
result = dao_get_letter_branding_by_domain(domain='test.domain')
result == test_domain_branding
def test_dao_get_all_letter_branding(notify_db_session): def test_dao_get_all_letter_branding(notify_db_session):
hm_gov = create_letter_branding() hm_gov = create_letter_branding()
test_domain = create_letter_branding( test_branding = create_letter_branding(
name='test domain', filename='test-domain', domain='test.domain' name='test branding', filename='test-branding',
) )
results = dao_get_all_letter_branding() results = dao_get_all_letter_branding()
assert hm_gov in results assert hm_gov in results
assert test_domain in results assert test_branding in results
assert len(results) == 2 assert len(results) == 2
@@ -60,7 +45,6 @@ def test_dao_get_all_letter_branding_returns_empty_list_if_no_brands_exist(notif
def test_dao_create_letter_branding(notify_db_session): def test_dao_create_letter_branding(notify_db_session):
data = { data = {
'name': 'test-logo', 'name': 'test-logo',
'domain': 'test.co.uk',
'filename': 'test-logo' 'filename': 'test-logo'
} }
assert LetterBranding.query.count() == 0 assert LetterBranding.query.count() == 0
@@ -70,7 +54,6 @@ def test_dao_create_letter_branding(notify_db_session):
new_letter_branding = LetterBranding.query.first() new_letter_branding = LetterBranding.query.first()
assert new_letter_branding.name == data['name'] assert new_letter_branding.name == data['name']
assert new_letter_branding.domain == data['domain']
assert new_letter_branding.filename == data['name'] assert new_letter_branding.filename == data['name']
+1 -1
View File
@@ -106,7 +106,7 @@ def test_create_service_with_letter_branding(notify_db_session):
user = create_user() user = create_user()
create_letter_branding() create_letter_branding()
letter_branding = create_letter_branding( letter_branding = create_letter_branding(
name='test domain', filename='test-domain', domain='test.domain' name='test domain', filename='test-domain',
) )
assert Service.query.count() == 0 assert Service.query.count() == 0
service = Service(name="service_name", service = Service(name="service_name",
+1 -2
View File
@@ -774,10 +774,9 @@ def create_template_folder(service, name='foo', parent=None):
return tf return tf
def create_letter_branding(name='HM Government', filename='hm-government', domain=None): def create_letter_branding(name='HM Government', filename='hm-government'):
test_domain_branding = LetterBranding(name=name, test_domain_branding = LetterBranding(name=name,
filename=filename, filename=filename,
domain=domain,
) )
db.session.add(test_domain_branding) db.session.add(test_domain_branding)
db.session.commit() db.session.commit()
+3 -33
View File
@@ -34,7 +34,7 @@ def test_get_email_branding_by_id(admin_request, notify_db, notify_db_session):
) )
assert set(response['email_branding'].keys()) == {'colour', 'logo', 'name', 'id', 'text', assert set(response['email_branding'].keys()) == {'colour', 'logo', 'name', 'id', 'text',
'domain', 'brand_type'} 'brand_type'}
assert response['email_branding']['colour'] == '#FFFFFF' assert response['email_branding']['colour'] == '#FFFFFF'
assert response['email_branding']['logo'] == '/path/image.png' assert response['email_branding']['logo'] == '/path/image.png'
assert response['email_branding']['name'] == 'Some Org' assert response['email_branding']['name'] == 'Some Org'
@@ -48,7 +48,6 @@ def test_post_create_email_branding(admin_request, notify_db_session):
'name': 'test email_branding', 'name': 'test email_branding',
'colour': '#0000ff', 'colour': '#0000ff',
'logo': '/images/test_x2.png', 'logo': '/images/test_x2.png',
'domain': 'gov.uk',
'brand_type': BRANDING_ORG 'brand_type': BRANDING_ORG
} }
response = admin_request.post( response = admin_request.post(
@@ -60,7 +59,6 @@ def test_post_create_email_branding(admin_request, notify_db_session):
assert data['colour'] == response['data']['colour'] assert data['colour'] == response['data']['colour']
assert data['logo'] == response['data']['logo'] assert data['logo'] == response['data']['logo']
assert data['name'] == response['data']['text'] assert data['name'] == response['data']['text']
assert data['domain'] == response['data']['domain']
assert data['brand_type'] == response['data']['brand_type'] assert data['brand_type'] == response['data']['brand_type']
@@ -69,7 +67,6 @@ def test_post_create_email_branding_without_brand_type_defaults(admin_request, n
'name': 'test email_branding', 'name': 'test email_branding',
'colour': '#0000ff', 'colour': '#0000ff',
'logo': '/images/test_x2.png', 'logo': '/images/test_x2.png',
'domain': 'gov.uk',
} }
response = admin_request.post( response = admin_request.post(
'email_branding.create_email_branding', 'email_branding.create_email_branding',
@@ -181,8 +178,8 @@ def test_post_create_email_branding_returns_400_when_name_is_missing(admin_reque
({'name': 'test email_branding 1'}), ({'name': 'test email_branding 1'}),
({'logo': 'images/text_x3.png', 'colour': '#ffffff'}), ({'logo': 'images/text_x3.png', 'colour': '#ffffff'}),
({'logo': 'images/text_x3.png'}), ({'logo': 'images/text_x3.png'}),
({'logo': 'images/text_x3.png', 'domain': 'gov.uk'}), ({'logo': 'images/text_x3.png'}),
({'logo': 'images/text_x3.png', 'brand_type': 'org'}), ({'logo': 'images/text_x3.png'}),
]) ])
def test_post_update_email_branding_updates_field(admin_request, notify_db_session, data_update): def test_post_update_email_branding_updates_field(admin_request, notify_db_session, data_update):
data = { data = {
@@ -273,30 +270,3 @@ def test_update_email_branding_reject_invalid_brand_type(admin_request, notify_d
) )
assert response['errors'][0]['message'] == 'brand_type NOT A TYPE is not one of [org, both, org_banner]' assert response['errors'][0]['message'] == 'brand_type NOT A TYPE is not one of [org, both, org_banner]'
def test_400_for_duplicate_domain(admin_request, notify_db_session):
branding_1 = create_email_branding(name='first brand')
branding_2 = create_email_branding(name='second brand')
admin_request.post(
'email_branding.update_email_branding',
_data={'domain': 'example.com', },
email_branding_id=branding_1.id,
)
response = admin_request.post(
'email_branding.update_email_branding',
_data={'domain': 'example.com'},
email_branding_id=branding_2.id,
_expected_status=400,
)
assert response['result'] == 'error'
assert response['message']['name'] == ["Duplicate domain 'example.com'"]
response = admin_request.post(
'email_branding.create_email_branding',
_data={'domain': 'example.com', 'name': 'another brand'},
_expected_status=400,
)
assert response['result'] == 'error'
assert response['message']['name'] == ["Duplicate domain 'example.com'"]
@@ -8,8 +8,8 @@ from tests.app.db import create_letter_branding
def test_get_all_letter_brands(client, notify_db_session): def test_get_all_letter_brands(client, notify_db_session):
hm_gov = create_letter_branding() hm_gov = create_letter_branding()
test_domain_branding = create_letter_branding( test_branding = create_letter_branding(
name='test domain', filename='test-domain', domain='test.domain' name='test branding', filename='test-branding',
) )
response = client.get('/letter-branding', headers=[create_authorization_header()]) response = client.get('/letter-branding', headers=[create_authorization_header()])
assert response.status_code == 200 assert response.status_code == 200
@@ -18,8 +18,8 @@ def test_get_all_letter_brands(client, notify_db_session):
for brand in json_response: for brand in json_response:
if brand['id'] == str(hm_gov.id): if brand['id'] == str(hm_gov.id):
assert hm_gov.serialize() == brand assert hm_gov.serialize() == brand
elif brand['id'] == str(test_domain_branding.id): elif brand['id'] == str(test_branding.id):
assert test_domain_branding.serialize() == brand assert test_branding.serialize() == brand
else: else:
assert False assert False
@@ -27,7 +27,7 @@ def test_get_all_letter_brands(client, notify_db_session):
def test_get_letter_branding_by_id(client, notify_db_session): def test_get_letter_branding_by_id(client, notify_db_session):
hm_gov = create_letter_branding() hm_gov = create_letter_branding()
create_letter_branding( create_letter_branding(
name='test domain', filename='test-domain', domain='test.domain' name='test domain', filename='test-domain'
) )
response = client.get('/letter-branding/{}'.format(hm_gov.id), headers=[create_authorization_header()]) response = client.get('/letter-branding/{}'.format(hm_gov.id), headers=[create_authorization_header()])
@@ -43,7 +43,6 @@ def test_get_letter_branding_by_id_returns_404_if_does_not_exist(client, notify_
def test_create_letter_branding(client, notify_db_session): def test_create_letter_branding(client, notify_db_session):
form = { form = {
'name': 'super brand', 'name': 'super brand',
'domain': 'super.brand',
'filename': 'super-brand' 'filename': 'super-brand'
} }
@@ -57,37 +56,16 @@ def test_create_letter_branding(client, notify_db_session):
json_response = json.loads(response.get_data(as_text=True)) json_response = json.loads(response.get_data(as_text=True))
letter_brand = LetterBranding.query.get(json_response['id']) letter_brand = LetterBranding.query.get(json_response['id'])
assert letter_brand.name == form['name'] assert letter_brand.name == form['name']
assert letter_brand.domain == form['domain']
assert letter_brand.filename == form['filename'] assert letter_brand.filename == form['filename']
def test_create_letter_branding_returns_400_if_domain_already_exists(client, notify_db_session):
create_letter_branding(name='duplicate', domain='duplicate', filename='duplicate')
form = {
'name': 'super brand',
'domain': 'duplicate',
'filename': 'super-brand',
}
response = client.post(
'/letter-branding',
headers=[('Content-Type', 'application/json'), create_authorization_header()],
data=json.dumps(form)
)
assert response.status_code == 400
json_resp = json.loads(response.get_data(as_text=True))
assert json_resp['message'] == {'domain': ["Domain already in use"]}
def test_update_letter_branding_returns_400_when_integrity_error_is_thrown( def test_update_letter_branding_returns_400_when_integrity_error_is_thrown(
client, notify_db_session client, notify_db_session
): ):
create_letter_branding(name='duplicate', domain='duplicate', filename='duplicate') create_letter_branding(name='duplicate', filename='duplicate')
brand_to_update = create_letter_branding(name='super brand', domain='super brand', filename='super brand') brand_to_update = create_letter_branding(name='super brand', filename='super brand')
form = { form = {
'name': 'duplicate', 'name': 'duplicate',
'domain': 'super brand',
'filename': 'super-brand', 'filename': 'super-brand',
} }
-63
View File
@@ -349,69 +349,6 @@ def test_create_service_inherits_branding_from_organisation(
assert json_resp['data']['letter_branding'] == str(letter_branding.id) assert json_resp['data']['letter_branding'] == str(letter_branding.id)
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'
)
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': letter_branding.domain
}
json_resp = admin_request.post('service.create_service', _data=data, _expected_status=201)
assert json_resp['data']['letter_branding'] == str(letter_branding.id)
assert json_resp['data']['letter_logo_filename'] == str(letter_branding.filename)
def test_create_service_with_no_domain_doesnt_set_letter_branding(admin_request, sample_user):
create_letter_branding(name='no domain', filename='no-domain', domain=None)
create_letter_branding(name='test domain', filename='test-domain', domain='test.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': None
}
json_resp = admin_request.post('service.create_service', _data=data, _expected_status=201)
assert json_resp['data']['letter_branding'] is None
assert json_resp['data']['letter_logo_filename'] is None
def test_get_service_by_id_returns_letter_branding(
client, sample_service
):
letter_branding = create_letter_branding(
name='test domain', filename='test-domain', domain='test.domain'
)
data = {
'letter_branding': str(letter_branding.id)
}
client.post(
'/service/{}'.format(sample_service.id),
data=json.dumps(data),
headers=[('Content-Type', 'application/json'), create_authorization_header()]
)
resp = client.get('/service/{}'.format(sample_service.id),
headers=[('Content-Type', 'application/json'), create_authorization_header()])
json_resp = resp.json
assert json_resp['data']['name'] == sample_service.name
assert json_resp['data']['id'] == str(sample_service.id)
assert json_resp['data']['letter_branding'] == str(letter_branding.id)
assert json_resp['data']['letter_logo_filename'] == 'test-domain'
def test_should_not_create_service_with_missing_user_id_field(notify_api, fake_uuid): def test_should_not_create_service_with_missing_user_id_field(notify_api, fake_uuid):
with notify_api.test_request_context(): with notify_api.test_request_context():
with notify_api.test_client() as client: with notify_api.test_client() as client: