mirror of
https://github.com/GSA/notifications-api.git
synced 2026-05-07 01:28:26 -04:00
Merge pull request #2190 from alphagov/template-folders
add TemplateFolder model
This commit is contained in:
@@ -706,6 +706,27 @@ class TemplateProcessTypes(db.Model):
|
||||
name = db.Column(db.String(255), primary_key=True)
|
||||
|
||||
|
||||
class TemplateFolder(db.Model):
|
||||
__tablename__ = 'template_folder'
|
||||
|
||||
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), nullable=False)
|
||||
name = db.Column(db.String, nullable=False)
|
||||
parent_id = db.Column(UUID(as_uuid=True), db.ForeignKey('template_folder.id'), nullable=True)
|
||||
|
||||
service = db.relationship('Service')
|
||||
parent = db.relationship('TemplateFolder', remote_side=[id], backref='children')
|
||||
|
||||
|
||||
template_folder_map = db.Table(
|
||||
'template_folder_map',
|
||||
db.Model.metadata,
|
||||
# template_id is a primary key as a template can only belong in one folder
|
||||
db.Column('template_id', UUID(as_uuid=True), db.ForeignKey('templates.id'), primary_key=True, nullable=False),
|
||||
db.Column('template_folder_id', UUID(as_uuid=True), db.ForeignKey('template_folder.id'), nullable=False),
|
||||
)
|
||||
|
||||
|
||||
PRECOMPILED_TEMPLATE_NAME = 'Pre-compiled PDF'
|
||||
|
||||
|
||||
@@ -837,6 +858,15 @@ class Template(TemplateBase):
|
||||
service = db.relationship('Service', backref='templates')
|
||||
version = db.Column(db.Integer, default=0, nullable=False)
|
||||
|
||||
folder = db.relationship(
|
||||
'TemplateFolder',
|
||||
secondary=template_folder_map,
|
||||
uselist=False,
|
||||
# eagerly load the folder whenever the template object is fetched
|
||||
lazy='joined',
|
||||
backref=db.backref('templates', lazy='dynamic')
|
||||
)
|
||||
|
||||
def get_link(self):
|
||||
# TODO: use "/v2/" route once available
|
||||
return url_for(
|
||||
|
||||
@@ -205,12 +205,12 @@ class ServiceSchema(BaseSchema):
|
||||
created_by = field_for(models.Service, 'created_by', required=True)
|
||||
organisation_type = field_for(models.Service, 'organisation_type')
|
||||
dvla_organisation = field_for(models.Service, 'dvla_organisation')
|
||||
letter_logo_filename = fields.Method(method_name='get_letter_logo_filename')
|
||||
letter_logo_filename = fields.Method(serialize='get_letter_logo_filename')
|
||||
permissions = fields.Method("service_permissions")
|
||||
email_branding = field_for(models.Service, 'email_branding')
|
||||
organisation = field_for(models.Service, 'organisation')
|
||||
override_flag = False
|
||||
letter_contact_block = fields.Method(method_name="get_letter_contact")
|
||||
letter_contact_block = fields.Method(serialize="get_letter_contact")
|
||||
|
||||
def get_letter_logo_filename(self, service):
|
||||
return service.dvla_organisation.filename
|
||||
|
||||
@@ -9,6 +9,7 @@ from app import db, version
|
||||
status = Blueprint('status', __name__)
|
||||
|
||||
|
||||
@status.route('/', methods=['GET'])
|
||||
@status.route('/_status', methods=['GET', 'POST'])
|
||||
def show_status():
|
||||
if request.args.get('simple', None):
|
||||
|
||||
39
migrations/versions/0242_template_folders.py
Normal file
39
migrations/versions/0242_template_folders.py
Normal file
@@ -0,0 +1,39 @@
|
||||
"""
|
||||
|
||||
Revision ID: 0242_template_folders
|
||||
Revises: 0241_another_letter_org
|
||||
Create Date: 2018-10-26 16:00:40.173840
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
revision = '0242_template_folders'
|
||||
down_revision = '0241_another_letter_org'
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('template_folder',
|
||||
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||
sa.Column('service_id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||
sa.Column('name', sa.String(), nullable=False),
|
||||
sa.Column('parent_id', postgresql.UUID(as_uuid=True), nullable=True),
|
||||
sa.ForeignKeyConstraint(['parent_id'], ['template_folder.id'], ),
|
||||
sa.ForeignKeyConstraint(['service_id'], ['services.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('template_folder_map',
|
||||
sa.Column('template_id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||
sa.Column('template_folder_id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||
sa.ForeignKeyConstraint(['template_folder_id'], ['template_folder.id'], ),
|
||||
sa.ForeignKeyConstraint(['template_id'], ['templates.id'], ),
|
||||
sa.PrimaryKeyConstraint('template_id')
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_table('template_folder_map')
|
||||
op.drop_table('template_folder')
|
||||
# ### end Alembic commands ###
|
||||
@@ -11,19 +11,16 @@ from app.dao.api_key_dao import expire_api_key
|
||||
from app.dao.templates_dao import dao_update_template
|
||||
|
||||
from tests import create_authorization_header, unwrap_function
|
||||
from tests.app.conftest import (
|
||||
sample_template as create_template,
|
||||
sample_api_key as create_api_key
|
||||
)
|
||||
from tests.app.db import create_template, create_api_key
|
||||
|
||||
|
||||
def test_archive_only_allows_post(client):
|
||||
def test_archive_only_allows_post(client, notify_db_session):
|
||||
auth_header = create_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):
|
||||
def test_archive_service_errors_with_bad_service_id(client, notify_db_session):
|
||||
auth_header = create_authorization_header()
|
||||
response = client.post('/service/{}/archive'.format(uuid.uuid4()), headers=[auth_header])
|
||||
assert response.status_code == 404
|
||||
@@ -38,11 +35,13 @@ def test_deactivating_inactive_service_does_nothing(client, sample_service):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def archived_service(client, notify_db, notify_db_session, sample_service):
|
||||
create_template(notify_db, notify_db_session, template_name='a')
|
||||
create_template(notify_db, notify_db_session, template_name='b')
|
||||
create_api_key(notify_db, notify_db_session)
|
||||
create_api_key(notify_db, notify_db_session)
|
||||
def archived_service(client, notify_db, 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_authorization_header()
|
||||
response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
|
||||
@@ -83,10 +82,10 @@ def test_deactivating_service_creates_history(archived_service):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def archived_service_with_deleted_stuff(client, notify_db, notify_db_session, sample_service):
|
||||
def archived_service_with_deleted_stuff(client, sample_service):
|
||||
with freeze_time('2001-01-01'):
|
||||
template = create_template(notify_db, notify_db_session, template_name='a')
|
||||
api_key = create_api_key(notify_db, notify_db_session)
|
||||
template = create_template(sample_service, template_name='a')
|
||||
api_key = create_api_key(sample_service)
|
||||
|
||||
expire_api_key(sample_service.id, api_key.id)
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import pytest
|
||||
from flask import json
|
||||
|
||||
|
||||
def test_get_status_all_ok(client):
|
||||
path = '/_status'
|
||||
@pytest.mark.parametrize('path', ['/', '/_status'])
|
||||
def test_get_status_all_ok(client, notify_db_session, path):
|
||||
response = client.get(path)
|
||||
assert response.status_code == 200
|
||||
resp_json = json.loads(response.get_data(as_text=True))
|
||||
|
||||
@@ -132,7 +132,7 @@ def os_environ():
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
# Copied from https://gist.github.com/pfctdayelise/5719730
|
||||
idparametrize = getattr(metafunc.function, 'idparametrize', None)
|
||||
idparametrize = metafunc.definition.get_closest_marker('idparametrize')
|
||||
if idparametrize:
|
||||
argnames, testdata = idparametrize.args
|
||||
ids, argvalues = zip(*sorted(testdata.items()))
|
||||
|
||||
Reference in New Issue
Block a user