From f5c2615dd8a8f5ad54564aa092ce7d53a52a8f9c Mon Sep 17 00:00:00 2001 From: iamareebjamal Date: Sat, 4 Jul 2020 20:05:56 +0530 Subject: [PATCH 1/5] feat: Add session custom form validations --- app/api/schema/sessions.py | 2 +- app/api/sessions.py | 9 +- tests/all/integration/api/session/__init__.py | 0 .../api/session/test_session_api.py | 160 ++++++++++++++++++ .../api/speaker/test_speaker_api.py | 1 + tests/factories/session.py | 16 +- tests/factories/track.py | 13 +- 7 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 tests/all/integration/api/session/__init__.py create mode 100644 tests/all/integration/api/session/test_session_api.py diff --git a/app/api/schema/sessions.py b/app/api/schema/sessions.py index d49d6efd1b..9684373a6a 100644 --- a/app/api/schema/sessions.py +++ b/app/api/schema/sessions.py @@ -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'}, diff --git a/app/api/sessions.py b/app/api/sessions.py index 7d2648f14f..362f601c0b 100644 --- a/app/api/sessions.py +++ b/app/api/sessions.py @@ -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 @@ -166,7 +167,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) @@ -176,7 +177,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", @@ -187,6 +188,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 """ diff --git a/tests/all/integration/api/session/__init__.py b/tests/all/integration/api/session/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/all/integration/api/session/test_session_api.py b/tests/all/integration/api/session/test_session_api.py new file mode 100644 index 0000000000..a6c4e24e88 --- /dev/null +++ b/tests/all/integration/api/session/test_session_api.py @@ -0,0 +1,160 @@ +import json + +from app.models.custom_form import CustomForms +from tests.factories.session import SessionSubFactory +from tests.factories.speakers_call import SpeakersCallSubFactory +from tests.factories.track import TrackSubFactory + + +def get_minimal_session(db, user): + session = SessionSubFactory( + subtitle=None, + level=None, + language=None, + short_abstract=None, + slides_url=None, + state=None, + is_locked=False, + creator_id=user.id, + ) + SpeakersCallSubFactory(event=session.event) + db.session.commit() + + return session + + +def test_edit_session_minimum_fields(db, client, user, jwt): + session = get_minimal_session(db, user) + + data = json.dumps( + { + 'data': { + 'type': 'session', + 'id': str(session.id), + "attributes": { + "title": "Kubernetes", + "subtitle": "The needlessly complicated orchestration platform", + }, + } + } + ) + + response = client.patch( + f'/v1/sessions/{session.id}', + content_type='application/vnd.api+json', + headers=jwt, + data=data, + ) + + db.session.refresh(session) + + assert response.status_code == 200 + assert session.title == 'Kubernetes' + assert session.subtitle == 'The needlessly complicated orchestration platform' + + +def get_simple_custom_form_session(db, user): + session = get_minimal_session(db, user) + CustomForms( + event=session.event, + form='session', + field_identifier='level', + type='number', + is_included=True, + is_required=True, + ) + CustomForms( + event=session.event, + form='session', + field_identifier='shortAbstract', + type='text', + is_included=True, + is_required=True, + ) + db.session.commit() + + return session + + +def test_edit_session_required_fields_missing(db, client, user, jwt): + session = get_simple_custom_form_session(db, user) + + data = json.dumps( + { + 'data': { + 'type': 'session', + 'id': str(session.id), + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "language": "English", + }, + } + } + ) + + response = client.patch( + f'/v1/sessions/{session.id}', + content_type='application/vnd.api+json', + headers=jwt, + data=data, + ) + + db.session.refresh(session) + + assert response.status_code == 422 + assert json.loads(response.data) == { + 'errors': [ + { + 'detail': "Missing required fields ['level', 'short_abstract']", + 'source': {'pointer': '/data/attributes'}, + 'status': 422, + 'title': 'Unprocessable Entity', + } + ], + 'jsonapi': {'version': '1.0'}, + } + + assert session.title != 'Move Away' + assert session.subtitle != 'Moooove' + assert session.language is None + + +def test_create_session_required_fields_missing(db, client, user, jwt): + session = get_simple_custom_form_session(db, user) + track = TrackSubFactory(event=session.event) + db.session.commit() + + data = json.dumps( + { + 'data': { + 'type': 'session', + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "language": "English", + }, + "relationships": { + "event": {"data": {"id": str(session.event_id), "type": "event"}}, + "track": {"data": {"id": str(track.id), "type": "track"}}, + }, + } + } + ) + + response = client.post( + '/v1/sessions', content_type='application/vnd.api+json', headers=jwt, data=data, + ) + + # assert response.status_code == 422 + assert json.loads(response.data) == { + 'errors': [ + { + 'detail': "Missing required fields ['level', 'short_abstract']", + 'source': {'pointer': '/data/attributes'}, + 'status': 422, + 'title': 'Unprocessable Entity', + } + ], + 'jsonapi': {'version': '1.0'}, + } diff --git a/tests/all/integration/api/speaker/test_speaker_api.py b/tests/all/integration/api/speaker/test_speaker_api.py index a3242e763f..75f3140d84 100644 --- a/tests/all/integration/api/speaker/test_speaker_api.py +++ b/tests/all/integration/api/speaker/test_speaker_api.py @@ -4,6 +4,7 @@ from app.models.speaker import Speaker from tests.factories.speaker import SpeakerSubFactory from tests.factories.speakers_call import SpeakersCallSubFactory +from tests.factories.track import TrackSubFactory def get_minimal_speaker(db, user): diff --git a/tests/factories/session.py b/tests/factories/session.py index b47928b90b..b72896d0b9 100644 --- a/tests/factories/session.py +++ b/tests/factories/session.py @@ -6,7 +6,7 @@ from tests.factories.event import EventFactoryBasic from tests.factories.microlocation import MicrolocationFactory from tests.factories.session_type import SessionTypeFactory -from tests.factories.track import TrackFactory +from tests.factories.track import TrackFactory, TrackSubFactory class SessionFactoryBase(BaseFactory): @@ -29,15 +29,19 @@ class Meta: state = "accepted" submitted_at = common.date_ is_mail_sent = True - event_id = 1 - session_type_id = 1 - track_id = 1 - microlocation_id = 1 -class SessionFactory(SessionFactoryBase): +class SessionSubFactory(SessionFactoryBase): + event = factory.SubFactory(EventFactoryBasic) + track = factory.SubFactory(TrackSubFactory) + +class SessionFactory(SessionFactoryBase): event = factory.RelatedFactory(EventFactoryBasic) session_type = factory.RelatedFactory(SessionTypeFactory) track = factory.RelatedFactory(TrackFactory) microlocation = factory.RelatedFactory(MicrolocationFactory) + event_id = 1 + session_type_id = 1 + track_id = 1 + microlocation_id = 1 diff --git a/tests/factories/track.py b/tests/factories/track.py index 93f8652965..f40fe3c3c2 100644 --- a/tests/factories/track.py +++ b/tests/factories/track.py @@ -6,12 +6,19 @@ from tests.factories.event import EventFactoryBasic -class TrackFactory(BaseFactory): +class TrackFactoryBase(BaseFactory): class Meta: model = Track - event = factory.RelatedFactory(EventFactoryBasic) - event_id = 1 name = common.string_ description = common.string_ color = "#0f0f0f" + + +class TrackSubFactory(TrackFactoryBase): + event = factory.SubFactory(EventFactoryBasic) + + +class TrackFactory(TrackFactoryBase): + event = factory.RelatedFactory(EventFactoryBasic) + event_id = 1 From 0ec3f7b083153ceed48f8e68b6467a28fb051490 Mon Sep 17 00:00:00 2001 From: iamareebjamal Date: Tue, 7 Jul 2020 05:30:30 +0530 Subject: [PATCH 2/5] fix --- app/api/schema/sessions.py | 4 - app/api/sessions.py | 4 + app/api/speakers.py | 2 +- .../api/session/test_session_api.py | 322 +++++++++++++++++- 4 files changed, 326 insertions(+), 6 deletions(-) diff --git a/app/api/schema/sessions.py b/app/api/schema/sessions.py index 9684373a6a..2e5c76e6a8 100644 --- a/app/api/schema/sessions.py +++ b/app/api/schema/sessions.py @@ -71,10 +71,6 @@ def validate_fields(self, data, original_data): {'source': ''}, 'Co-organizer access is required.' ) - if 'track' in data: - if not has_access('is_coorganizer', event_id=data['event']): - raise ForbiddenError({'source': ''}, '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.') diff --git a/app/api/sessions.py b/app/api/sessions.py index 362f601c0b..956bbe3a9e 100644 --- a/app/api/sessions.py +++ b/app/api/sessions.py @@ -53,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 diff --git a/app/api/speakers.py b/app/api/speakers.py index a7d99fb7a2..fbdbd30fe7 100644 --- a/app/api/speakers.py +++ b/app/api/speakers.py @@ -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): diff --git a/tests/all/integration/api/session/test_session_api.py b/tests/all/integration/api/session/test_session_api.py index a6c4e24e88..e567407aa7 100644 --- a/tests/all/integration/api/session/test_session_api.py +++ b/tests/all/integration/api/session/test_session_api.py @@ -1,6 +1,7 @@ import json from app.models.custom_form import CustomForms +from app.models.session import Session from tests.factories.session import SessionSubFactory from tests.factories.speakers_call import SpeakersCallSubFactory from tests.factories.track import TrackSubFactory @@ -146,7 +147,7 @@ def test_create_session_required_fields_missing(db, client, user, jwt): '/v1/sessions', content_type='application/vnd.api+json', headers=jwt, data=data, ) - # assert response.status_code == 422 + assert response.status_code == 422 assert json.loads(response.data) == { 'errors': [ { @@ -158,3 +159,322 @@ def test_create_session_required_fields_missing(db, client, user, jwt): ], 'jsonapi': {'version': '1.0'}, } + + +def test_edit_session_required_fields_complete(db, client, user, jwt): + session = get_simple_custom_form_session(db, user) + + data = json.dumps( + { + 'data': { + 'type': 'session', + 'id': str(session.id), + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "level": "456345678", + "short-abstract": "Speaking since birth", + "complex-field-values": { + "bojack": "horseman" + }, # Should be ignored and saved as None + }, + } + } + ) + + response = client.patch( + f'/v1/sessions/{session.id}', + content_type='application/vnd.api+json', + headers=jwt, + data=data, + ) + + db.session.refresh(session) + + assert response.status_code == 200 + + assert session.title == 'Move Away' + assert session.subtitle == 'Moooove' + assert session.level == '456345678' + assert session.short_abstract == 'Speaking since birth' + assert session.complex_field_values is None + + +def test_create_session_required_fields_complete(db, client, user, jwt): + session = get_simple_custom_form_session(db, user) + track = TrackSubFactory(event=session.event) + db.session.commit() + + data = json.dumps( + { + 'data': { + 'type': 'session', + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "level": "456345678", + "short-abstract": "Speaking since birth", + "complex-field-values": { + "bojack": "horseman" + }, # Should be ignored and saved as None + }, + "relationships": { + "event": {"data": {"id": str(session.event_id), "type": "event"}}, + "track": {"data": {"id": str(track.id), "type": "track"}}, + }, + } + } + ) + + response = client.post( + '/v1/sessions', content_type='application/vnd.api+json', headers=jwt, data=data, + ) + + assert response.status_code == 201 + + session = Session.query.get(json.loads(response.data)['data']['id']) + + assert session.title == 'Move Away' + assert session.subtitle == 'Moooove' + assert session.level == '456345678' + assert session.short_abstract == 'Speaking since birth' + assert session.complex_field_values is None + + +def get_complex_custom_form_session(db, user): + session = get_minimal_session(db, user) + CustomForms( + event=session.event, + form='session', + field_identifier='slidesUrl', + type='text', + is_included=True, + is_required=True, + ) + CustomForms( + event=session.event, + form='session', + field_identifier='bestFriend', + name='Best Friend', + type='text', + is_included=True, + is_required=True, + is_complex=True, + ) + CustomForms( + event=session.event, + form='session', + field_identifier='transFatContent', + name='Trans Fat Content', + type='number', + is_included=True, + is_required=False, + is_complex=True, + ) + db.session.commit() + + return session + + +def test_custom_form_complex_fields_missing_required(db, client, user, jwt): + session = get_complex_custom_form_session(db, user) + + data = json.dumps( + { + 'data': { + 'type': 'session', + 'id': str(session.id), + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "language": "English", + }, + } + } + ) + + response = client.patch( + f'/v1/sessions/{session.id}', + content_type='application/vnd.api+json', + headers=jwt, + data=data, + ) + + db.session.refresh(session) + + assert response.status_code == 422 + assert json.loads(response.data) == { + 'errors': [ + { + 'detail': "Missing required fields ['best_friend', 'slides_url']", + 'source': {'pointer': '/data/attributes'}, + 'status': 422, + 'title': 'Unprocessable Entity', + } + ], + 'jsonapi': {'version': '1.0'}, + } + + assert session.title != 'Move Away' + assert session.subtitle != 'Moooove' + assert session.language is None + + +def test_custom_form_create_complex_fields_missing_required(db, client, user, jwt): + session = get_complex_custom_form_session(db, user) + track = TrackSubFactory(event=session.event) + db.session.commit() + + data = json.dumps( + { + 'data': { + 'type': 'session', + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "language": "English", + }, + "relationships": { + "event": {"data": {"id": str(session.event_id), "type": "event"}}, + "track": {"data": {"id": str(track.id), "type": "track"}}, + }, + } + } + ) + + response = client.post( + '/v1/sessions', content_type='application/vnd.api+json', headers=jwt, data=data, + ) + + db.session.refresh(session) + + assert response.status_code == 422 + assert json.loads(response.data) == { + 'errors': [ + { + 'detail': "Missing required fields ['best_friend', 'slides_url']", + 'source': {'pointer': '/data/attributes'}, + 'status': 422, + 'title': 'Unprocessable Entity', + } + ], + 'jsonapi': {'version': '1.0'}, + } + + assert session.title != 'Move Away' + assert session.subtitle != 'Moooove' + assert session.language is None + + +def test_custom_form_complex_fields_complete(db, client, user, jwt): + session = get_complex_custom_form_session(db, user) + + data = json.dumps( + { + 'data': { + 'type': 'session', + 'id': str(session.id), + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "slides-url": "http://gypsie.com", + "complex-field-values": {"best-friend": "Tester"}, + }, + } + } + ) + + response = client.patch( + f'/v1/sessions/{session.id}', + content_type='application/vnd.api+json', + headers=jwt, + data=data, + ) + + db.session.refresh(session) + + assert response.status_code == 200 + + assert session.title == 'Move Away' + assert session.subtitle == 'Moooove' + assert session.slides_url == 'http://gypsie.com' + assert session.complex_field_values['best_friend'] == 'Tester' + + +def test_custom_form_create_complex_fields_complete(db, client, user, jwt): + session = get_complex_custom_form_session(db, user) + track = TrackSubFactory(event=session.event) + db.session.commit() + + data = json.dumps( + { + 'data': { + 'type': 'session', + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "slides-url": "http://gypsie.com", + "complex-field-values": {"best-friend": "Tester"}, + }, + "relationships": { + "event": {"data": {"id": str(session.event_id), "type": "event"}}, + "track": {"data": {"id": str(track.id), "type": "track"}}, + }, + } + } + ) + + response = client.post( + '/v1/sessions', content_type='application/vnd.api+json', headers=jwt, data=data, + ) + + session = Session.query.get(json.loads(response.data)['data']['id']) + + assert response.status_code == 201 + + assert session.title == 'Move Away' + assert session.subtitle == 'Moooove' + assert session.slides_url == 'http://gypsie.com' + assert session.complex_field_values['best_friend'] == 'Tester' + + +def test_ignore_complex_custom_form_fields(db, client, user, jwt): + """Test to see that extra data from complex JSON is dropped""" + session = get_complex_custom_form_session(db, user) + + data = json.dumps( + { + 'data': { + 'type': 'session', + 'id': str(session.id), + "attributes": { + "title": "Move Away", + "subtitle": "Moooove", + "slides-url": "http://gypsie.com", + "complex-field-values": { + "bestFriend": "Bester", + "transFat-content": 20.08, + "shalimar": "sophie", + }, + }, + } + } + ) + + response = client.patch( + f'/v1/sessions/{session.id}', + content_type='application/vnd.api+json', + headers=jwt, + data=data, + ) + + db.session.refresh(session) + + assert response.status_code == 200 + + assert session.title == 'Move Away' + assert session.subtitle == 'Moooove' + assert session.slides_url == 'http://gypsie.com' + assert session.complex_field_values['best_friend'] == 'Bester' + assert session.complex_field_values['trans_fat_content'] == 20.08 + assert session.complex_field_values.get('shalimar') is None From 634ac2ffa2c6537551e0b8617d9fab3a393e0c16 Mon Sep 17 00:00:00 2001 From: iamareebjamal Date: Tue, 7 Jul 2020 06:15:56 +0530 Subject: [PATCH 3/5] fix --- app/api/helpers/custom_forms.py | 8 +++++--- app/api/schema/sessions.py | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/app/api/helpers/custom_forms.py b/app/api/helpers/custom_forms.py index d1937db11c..8c9de98789 100644 --- a/app/api/helpers/custom_forms.py +++ b/app/api/helpers/custom_forms.py @@ -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) @@ -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=[]): 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) diff --git a/app/api/schema/sessions.py b/app/api/schema/sessions.py index 2e5c76e6a8..11b4d280ad 100644 --- a/app/api/schema/sessions.py +++ b/app/api/schema/sessions.py @@ -64,16 +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 data.get('state') and data['state'] not in ('draft', 'pending'): + if not has_access('is_coorganizer', event_id=data['event']): + 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) @@ -96,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) From abf73a8bbda55dd0b16c72ad133886a33fc9e4c9 Mon Sep 17 00:00:00 2001 From: iamareebjamal Date: Tue, 7 Jul 2020 06:19:14 +0530 Subject: [PATCH 4/5] fix --- .../integration/api/session/test_session_api.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/all/integration/api/session/test_session_api.py b/tests/all/integration/api/session/test_session_api.py index e567407aa7..748f20bed7 100644 --- a/tests/all/integration/api/session/test_session_api.py +++ b/tests/all/integration/api/session/test_session_api.py @@ -56,6 +56,14 @@ def test_edit_session_minimum_fields(db, client, user, jwt): def get_simple_custom_form_session(db, user): session = get_minimal_session(db, user) + CustomForms( + event=session.event, + form='session', + field_identifier='track', + type='text', + is_included=True, + is_required=True, + ) CustomForms( event=session.event, form='session', @@ -243,6 +251,14 @@ def test_create_session_required_fields_complete(db, client, user, jwt): def get_complex_custom_form_session(db, user): session = get_minimal_session(db, user) + CustomForms( + event=session.event, + form='session', + field_identifier='track', + type='text', + is_included=True, + is_required=True, + ) CustomForms( event=session.event, form='session', From c7317fe4cec8787c323853375ba85ef7529447b4 Mon Sep 17 00:00:00 2001 From: iamareebjamal Date: Tue, 7 Jul 2020 06:28:19 +0530 Subject: [PATCH 5/5] fix --- app/api/helpers/custom_forms.py | 2 +- .../integration/api/helpers/test_pentabarfxml.py | 8 ++++---- .../all/integration/api/speaker/test_speaker_api.py | 1 - tests/factories/session.py | 13 ++++++++----- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/api/helpers/custom_forms.py b/app/api/helpers/custom_forms.py index 8c9de98789..1d341e2cc6 100644 --- a/app/api/helpers/custom_forms.py +++ b/app/api/helpers/custom_forms.py @@ -64,7 +64,7 @@ def validate_custom_form_constraints(form, obj, relationship_fields): return data if data else None -def validate_custom_form_constraints_request(form, schema, obj, data, field_overrides=[]): +def validate_custom_form_constraints_request(form, schema, obj, data): new_obj = type(obj)(**object_as_dict(obj)) relationship_fields = get_relationships(schema) for key, value in data.items(): diff --git a/tests/all/integration/api/helpers/test_pentabarfxml.py b/tests/all/integration/api/helpers/test_pentabarfxml.py index b4badc5335..eff4ab530b 100644 --- a/tests/all/integration/api/helpers/test_pentabarfxml.py +++ b/tests/all/integration/api/helpers/test_pentabarfxml.py @@ -8,7 +8,7 @@ from tests.all.integration.utils import OpenEventLegacyTestCase from tests.factories.event import EventFactoryBasic from tests.factories.microlocation import MicrolocationFactoryBase -from tests.factories.session import SessionFactory, SessionFactoryBase +from tests.factories.session import SessionFactory, SessionFactoryBasic from tests.factories.speaker import SpeakerFactoryBase from tests.factories.user import UserFactory @@ -70,13 +70,13 @@ def test_export_with_multiple_sessions(self): SpeakerFactoryBase.build(name='Hong Phuc Dang', user_id=1), ] - SessionFactoryBase( + SessionFactoryBasic( title='Hot Session', starts_at=datetime(2019, 10, 15, 11, 30, 00), ends_at=datetime(2019, 10, 15, 12, 00, 54), ) - future_session = SessionFactoryBase( + future_session = SessionFactoryBasic( title='Future Session', starts_at=datetime(2019, 10, 16, 9, 15, 30), ends_at=datetime(2019, 10, 16, 10, 30, 45), @@ -87,7 +87,7 @@ def test_export_with_multiple_sessions(self): ] MicrolocationFactoryBase(name='Assembly Hall') - end_session = SessionFactoryBase( + end_session = SessionFactoryBasic( title='Bye Bye Session', starts_at=datetime(2019, 10, 16, 11, 30, 20), ends_at=datetime(2019, 10, 16, 13, 00, 30), diff --git a/tests/all/integration/api/speaker/test_speaker_api.py b/tests/all/integration/api/speaker/test_speaker_api.py index 75f3140d84..a3242e763f 100644 --- a/tests/all/integration/api/speaker/test_speaker_api.py +++ b/tests/all/integration/api/speaker/test_speaker_api.py @@ -4,7 +4,6 @@ from app.models.speaker import Speaker from tests.factories.speaker import SpeakerSubFactory from tests.factories.speakers_call import SpeakersCallSubFactory -from tests.factories.track import TrackSubFactory def get_minimal_speaker(db, user): diff --git a/tests/factories/session.py b/tests/factories/session.py index b72896d0b9..5ce7c3e08c 100644 --- a/tests/factories/session.py +++ b/tests/factories/session.py @@ -36,12 +36,15 @@ class SessionSubFactory(SessionFactoryBase): track = factory.SubFactory(TrackSubFactory) -class SessionFactory(SessionFactoryBase): - event = factory.RelatedFactory(EventFactoryBasic) - session_type = factory.RelatedFactory(SessionTypeFactory) - track = factory.RelatedFactory(TrackFactory) - microlocation = factory.RelatedFactory(MicrolocationFactory) +class SessionFactoryBasic(SessionFactoryBase): event_id = 1 session_type_id = 1 track_id = 1 microlocation_id = 1 + + +class SessionFactory(SessionFactoryBasic): + event = factory.RelatedFactory(EventFactoryBasic) + session_type = factory.RelatedFactory(SessionTypeFactory) + track = factory.RelatedFactory(TrackFactory) + microlocation = factory.RelatedFactory(MicrolocationFactory)