Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add session custom form validations #7112

Merged
merged 5 commits into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions app/api/helpers/custom_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ def get_schema(form_fields):
return type('DynamicSchema', (marshmallow.Schema,), attrs)


def validate_custom_form_constraints(form, obj):
def validate_custom_form_constraints(form, obj, relationship_fields):
form_fields = CustomForms.query.filter_by(
form=form, event_id=obj.event_id, is_included=True,
).all()
required_form_fields = filter(lambda field: field.is_required, form_fields)
missing_required_fields = []
for field in required_form_fields:
if field.identifier in relationship_fields:
continue
if not field.is_complex:
if not getattr(obj, field.identifier):
missing_required_fields.append(field.identifier)
Expand All @@ -62,11 +64,11 @@ def validate_custom_form_constraints(form, obj):
return data if data else None


def validate_custom_form_constraints_request(form, schema, obj, data):
def validate_custom_form_constraints_request(form, schema, obj, data, field_overrides=[]):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use mutable data structures for argument defaults. They are created during function definition time. All calls to the function reuse this one instance of that data structure, persisting changes between them.

new_obj = type(obj)(**object_as_dict(obj))
relationship_fields = get_relationships(schema)
for key, value in data.items():
if hasattr(new_obj, key) and key not in relationship_fields:
setattr(new_obj, key, value)

return validate_custom_form_constraints(form, new_obj)
return validate_custom_form_constraints(form, new_obj, relationship_fields)
23 changes: 11 additions & 12 deletions app/api/schema/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def validate_fields(self, data, original_data):
if 'event' not in data:
data['event'] = session.event_id

if data['starts_at'] and data['ends_at']:
if data.get('starts_at') and data.get('ends_at'):
if data['starts_at'] >= data['ends_at']:
raise UnprocessableEntityError(
{'pointer': '/data/attributes/ends-at'},
Expand All @@ -64,20 +64,19 @@ def validate_fields(self, data, original_data):
"starts-at should be after current date-time",
)

if 'state' in data:
if data['state'] not in ('draft', 'pending'):
if not has_access('is_coorganizer', event_id=data['event']):
raise ForbiddenError(
{'source': ''}, 'Co-organizer access is required.'
)

if 'track' in data:
if data.get('state') and data['state'] not in ('draft', 'pending'):
if not has_access('is_coorganizer', event_id=data['event']):
raise ForbiddenError({'source': ''}, 'Co-organizer access is required.')
raise ForbiddenError(
{'pointer': '/data/attributes/state'},
'Co-organizer access is required.',
)

if 'microlocation' in data:
if not has_access('is_coorganizer', event_id=data['event']):
raise ForbiddenError({'source': ''}, 'Co-organizer access is required.')
raise ForbiddenError(
{'pointer': '/relationships/microlocation'},
'Co-organizer access is required.',
)

validate_complex_fields_json(self, data, original_data)

Expand All @@ -100,7 +99,7 @@ def validate_fields(self, data, original_data):
choices=["pending", "accepted", "confirmed", "rejected", "draft"]
),
allow_none=True,
default='draft',
missing='draft',
)
created_at = fields.DateTime(dump_only=True)
deleted_at = fields.DateTime(dump_only=True)
Expand Down
13 changes: 11 additions & 2 deletions app/api/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from app.api.bootstrap import api
from app.api.events import Event
from app.api.helpers.custom_forms import validate_custom_form_constraints_request
from app.api.helpers.db import get_count, safe_query, safe_query_kwargs, save_to_db
from app.api.helpers.errors import ForbiddenError
from app.api.helpers.files import make_frontend_url
Expand Down Expand Up @@ -52,6 +53,10 @@ def before_post(self, args, kwargs, data):
):
raise ForbiddenError({'pointer': ''}, "Sessions are disabled for this Event")

data['complex_field_values'] = validate_custom_form_constraints_request(
'session', self.schema, Session(event_id=data['event']), data
)

def after_create_object(self, session, data, view_kwargs):
"""
method to send email for creation of new session
Expand Down Expand Up @@ -166,7 +171,7 @@ def before_update_object(self, session, data, view_kwargs):
:param view_kwargs:
:return:
"""
if data.get('is_locked') != session.is_locked:
if session.is_locked:
if not (
has_access('is_admin')
or has_access('is_organizer', event_id=session.event_id)
Expand All @@ -176,7 +181,7 @@ def before_update_object(self, session, data, view_kwargs):
"You don't have enough permissions to change this property",
)

if session.is_locked and data.get('is_locked') == session.is_locked:
if session.is_locked and data.get('is_locked') != session.is_locked:
raise ForbiddenError(
{'source': '/data/attributes/is-locked'},
"Locked sessions cannot be edited",
Expand All @@ -187,6 +192,10 @@ def before_update_object(self, session, data, view_kwargs):
{'source': ''}, "Cannot edit session after the call for speaker is ended"
)

data['complex_field_values'] = validate_custom_form_constraints_request(
'session', self.resource.schema, session, data
)

def after_update_object(self, session, data, view_kwargs):
""" Send email if session accepted or rejected """

Expand Down
2 changes: 1 addition & 1 deletion app/api/speakers.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def before_post(self, args, kwargs, data=None):
)

data['complex_field_values'] = validate_custom_form_constraints_request(
'speaker', SpeakerSchema, Speaker(event_id=data['event']), data
'speaker', self.schema, Speaker(event_id=data['event']), data
)

def after_create_object(self, speaker, data, view_kwargs):
Expand Down
Empty file.
Loading