diff --git a/exception/client_exception.py b/exception/client_exception.py index 8b4d0acb..e252c5af 100644 --- a/exception/client_exception.py +++ b/exception/client_exception.py @@ -8,7 +8,7 @@ def __init__(self, event_id, *args): def __str__(self): # Optionally customize the string representation for this specific error - return f"{self.message}: Event ID {self.event_id} could not be located." + return f"Event not found: Event ID {self.event_id} could not be located." class InvalidArgumentError(FireAppException): @@ -17,4 +17,4 @@ def __init__(self, *args): def __str__(self): # Optionally customize the string representation for this specific error - return f"{self.message}: unexpected values in the payload" + return f"InvalidArgumentError: unexpected values in the payload" diff --git a/repository/volunteer_unavailability_v2.py b/repository/volunteer_unavailability_v2.py index c0c69c73..50f141a3 100644 --- a/repository/volunteer_unavailability_v2.py +++ b/repository/volunteer_unavailability_v2.py @@ -12,24 +12,26 @@ def __init__(self): pass def edit_event(self, session, userId, eventId, title=None, start=None, end=None, periodicity=None): - now = datetime.now(timezone.utc) + now = datetime.now() event = session.query(UnavailabilityTime).filter(UnavailabilityTime.eventId == eventId, - UnavailabilityTime.userId == userId).first() + UnavailabilityTime.userId == userId, + UnavailabilityTime.status != 0).first() if event is None: raise EventNotFoundError(eventId) - # validate user input - if start is not None and start < now: - raise InvalidArgumentError() - if end is not None and (end < now or end < start): - raise InvalidArgumentError() + actual_start = start if start is not None else event.start + actual_end = end if end is not None else event.end + if actual_end < actual_start: + raise InvalidArgumentError("The end time must not be before the start time.") + if actual_start < now: + raise InvalidArgumentError("The start time must not be in the past.") + if actual_end < now: + raise InvalidArgumentError("The end time must not be in the past.") # Edit fields with new values + event.start = actual_start + event.end = actual_end if title is not None: event.title = title - if start is not None: - event.start = start - if end is not None: - event.end = end - if end is not None: + if periodicity is not None: event.periodicity = periodicity session.commit() diff --git a/tests/functional/test_unavailability.py b/tests/functional/test_unavailability.py index e1cb6845..93db8aaf 100644 --- a/tests/functional/test_unavailability.py +++ b/tests/functional/test_unavailability.py @@ -3,14 +3,14 @@ def test_create_unavailability_consecutive_event_id(test_client, create_user): payload_1 = { "title": "All Day Event", "periodicity": 0, - "start": "2024-03-02T00:00:00Z", - "end": "2024-03-02T23:59:59Z" + "start": "2024-03-02T00:00:00", + "end": "2024-03-02T23:59:59" } payload_2 = { "title": "All Day Event", "periodicity": 0, - "start": "2024-03-03T00:00:00Z", - "end": "2024-03-03T23:59:59Z" + "start": "2024-03-03T00:00:00", + "end": "2024-03-03T23:59:59" } response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", json=payload_1 @@ -28,8 +28,8 @@ def test_create_unavailability_same_time_interval(test_client, create_user): payload = { "title": "All Day Event", "periodicity": 0, - "start": "2024-03-02T00:00:00Z", - "end": "2024-03-02T23:59:59Z" + "start": "2024-03-02T00:00:00", + "end": "2024-03-02T23:59:59" } response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", json=payload @@ -48,8 +48,8 @@ def test_create_unavailability_nonexistent_user_id(test_client): payload = { "title": "All Day Event", "periodicity": 0, - "start": "2024-03-02T00:00:00Z", - "end": "2024-03-02T23:59:59Z" + "start": "2024-03-02T00:00:00", + "end": "2024-03-02T23:59:59" } response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", json=payload @@ -62,8 +62,8 @@ def test_create_unavailability_end_before_start(test_client, create_user): payload = { "title": "All Day Event", "periodicity": 0, - "start": "2024-03-02T00:00:00Z", - "end": "2024-03-01T23:59:59Z" + "start": "2024-03-02T00:00:00", + "end": "2024-03-01T23:59:59" } response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", json=payload @@ -76,14 +76,14 @@ def test_create_unavailability_end_before_start(test_client, create_user): # payload_1 = { # "title": "All Day Event", # "periodicity": 0, -# "start": "2024-03-03T00:00:00Z", -# "end": "2024-03-04T23:59:59Z" +# "start": "2024-03-03T00:00:00", +# "end": "2024-03-04T23:59:59" # } # payload_2 = { # "title": "All Day Event", # "periodicity": 0, -# "start": "2024-03-01T00:00:00Z", -# "end": "2024-03-05T23:59:59Z" +# "start": "2024-03-01T00:00:00", +# "end": "2024-03-05T23:59:59" # } # response_1 = test_client.post(f"/v2/volunteers/{user_id}/unavailability", # json=payload_1 @@ -93,8 +93,8 @@ def test_create_unavailability_end_before_start(test_client, create_user): # ) # assert response_1.status_code == 200 # assert response_2.status_code == 400 - - +# +# # def test_merge_overlapping_unavailability_intervals(test_client, create_user): # user_id = create_user # payload_1 = { diff --git a/tests/functional/test_unavailability_edit.py b/tests/functional/test_unavailability_edit.py new file mode 100644 index 00000000..27bf3a30 --- /dev/null +++ b/tests/functional/test_unavailability_edit.py @@ -0,0 +1,165 @@ +from datetime import datetime, timedelta + +now = datetime.now() +def test_update_unavailability_successful(test_client, create_user): + user_id = create_user + start = now + timedelta(days=1) + end = start + timedelta(hours=23, minutes=59, seconds=59) + payload_1 = { + "title": "All Day Event", + "periodicity": 0, + "start": start.isoformat(), + "end": end.isoformat() + } + create_response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", + json=payload_1 + ) + event_id = create_response.json['eventId'] + new_details = { + "title": "Updated Event", + "start": (start + timedelta(days=1)).isoformat(), + "end": (end + timedelta(days=1)).isoformat(), + "periodicity": 1 + } + edit_response = test_client.put(f"/v2/volunteers/{user_id}/unavailability/{event_id}", + json=new_details) + assert create_response.status_code == 200 + assert edit_response.status_code == 200 + assert edit_response.json == {"message": "Updated successfully"} + + +def test_update_unavailability_event_not_found(test_client, create_user): + user_id = create_user + event_id = -1 + start = now + timedelta(days=10) + end = start + timedelta(hours=23, minutes=59, seconds=59) + new_details = { + "title": "Nonexistent Event", + "start": start.isoformat(), + "end": end.isoformat() + } + edit_response = test_client.put(f"/v2/volunteers/{user_id}/unavailability/{event_id}", + json=new_details) + assert edit_response.status_code == 404 + # assert response.json == {"message": f"Event {event_id} can not be found"} + +def test_update_unavailability_with_invalid_data_changeboth_endtime_earlier_than_starttime(test_client, create_user): + user_id = create_user + start = now + timedelta(days=1) + end = start + timedelta(hours=23, minutes=59, seconds=59) + payload_1 = { + "title": "All Day Event", + "periodicity": 0, + "start": start.isoformat(), + "end": end.isoformat() + } + create_response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", + json=payload_1 + ) + event_id = create_response.json['eventId'] + invalid_details = { + "title": "Invalid Time Range", + "start": (start + timedelta(days=3)).isoformat(), # start time is later than end time + "end": (end + timedelta(days=1)).isoformat() + } + edit_response = test_client.put(f"/v2/volunteers/{user_id}/unavailability/{event_id}", + json=invalid_details) + assert create_response.status_code == 200 + assert edit_response.status_code == 400 + # assert edit_response.json == {"message": "Invalid argument from the payload"} + +def test_update_unavailability_with_invalid_data_changestart_endtime_earlier_than_starttime(test_client, create_user): + user_id = create_user + start = now + timedelta(days=1) + end = start + timedelta(hours=23, minutes=59, seconds=59) + payload_1 = { + "title": "All Day Event", + "periodicity": 0, + "start": start.isoformat(), + "end": end.isoformat() + } + create_response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", + json=payload_1 + ) + event_id = create_response.json['eventId'] + invalid_details = { + "title": "Invalid Start time for Later than Original End Time", + "start": (start + timedelta(days=3)).isoformat() + } + edit_response = test_client.put(f"/v2/volunteers/{user_id}/unavailability/{event_id}", + json=invalid_details) + assert create_response.status_code == 200 + assert edit_response.status_code == 400 + # assert edit_response.json == {"message": "Invalid argument from the payload"} + +def test_update_unavailability_with_invalid_data_changeend_endtime_earlier_than_starttime(test_client, create_user): + user_id = create_user + start = now + timedelta(days=2) + end = start + timedelta(hours=23, minutes=59, seconds=59) + payload_1 = { + "title": "All Day Event", + "periodicity": 0, + "start": start.isoformat(), + "end": end.isoformat() + } + create_response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", + json=payload_1 + ) + event_id = create_response.json['eventId'] + invalid_details = { + "title": "Invalid End time for Earlier than Original Start Time", + "end": (start - timedelta(days=1)).isoformat() + } + edit_response = test_client.put(f"/v2/volunteers/{user_id}/unavailability/{event_id}", + json=invalid_details) + assert create_response.status_code == 200 + assert edit_response.status_code == 400 + # assert edit_response.json == {"message": "Invalid argument from the payload"} + +def test_update_unavailability_with_invalid_data_starttime_in_the_past(test_client, create_user): + user_id = create_user + start = now + timedelta(days=2) + end = start + timedelta(hours=23, minutes=59, seconds=59) + payload_1 = { + "title": "All Day Event", + "periodicity": 0, + "start": start.isoformat(), + "end": end.isoformat() + } + create_response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", + json=payload_1 + ) + event_id = create_response.json['eventId'] + invalid_details = { + "title": "Meaningless Start Time", + "start": (now - timedelta(days=1)).isoformat() + } + edit_response = test_client.put(f"/v2/volunteers/{user_id}/unavailability/{event_id}", + json=invalid_details) + assert create_response.status_code == 200 + assert edit_response.status_code == 400 + # assert edit_response.json == {"message": "Invalid argument from the payload"} + +def test_update_unavailability_with_invalid_data_endtime_in_the_past(test_client, create_user): + user_id = create_user + start = now - timedelta(days=10) + end = now + timedelta(days=10) + payload_1 = { + "title": "Twenty Days Event", + "periodicity": 0, + "start": start.isoformat(), + "end": end.isoformat() + } + create_response = test_client.post(f"/v2/volunteers/{user_id}/unavailability", + json=payload_1 + ) + event_id = create_response.json['eventId'] + invalid_details = { + "title": "Meaningless End Time", + "end": (now - timedelta(days=1)).isoformat() + } + edit_response = test_client.put(f"/v2/volunteers/{user_id}/unavailability/{event_id}", + json=invalid_details) + assert create_response.status_code == 200 + assert edit_response.status_code == 400 + # assert edit_response.json == {"message": "Invalid argument from the payload"} \ No newline at end of file diff --git a/tests/functional/test_unavailability_get.py b/tests/functional/test_unavailability_get.py index 4147df27..ffbdbd1a 100644 --- a/tests/functional/test_unavailability_get.py +++ b/tests/functional/test_unavailability_get.py @@ -3,8 +3,8 @@ def test_get_volunteer_unavailability_success(test_client, create_user): payload_1 = { "title": "All Day Event", "periodicity": 0, - "start": "2024-05-02T00:00:00Z", - "end": "2024-05-02T23:59:59Z" + "start": "2025-05-02T00:00:00", + "end": "2025-05-02T23:59:59" } test_client.post(f"/v2/volunteers/{user_id}/unavailability", json=payload_1 @@ -29,8 +29,8 @@ def test_get_volunteer_unavailability_invalid_user(test_client): payload = { "title": "All Day Event", "periodicity": 0, - "start": "2024-03-02T00:00:00Z", - "end": "2024-03-02T23:59:59Z" + "start": "2025-03-02T00:00:00", + "end": "2025-03-02T23:59:59" } test_client.post(f"/v2/volunteers/{user_id}/unavailability", json=payload