def test_create_reservation_outside_of_schedule(tables, client, new_user,
                                                restriction):
    new_user.save()

    # Create a restriction and assign it to the user
    restriction.starts_at = '2101-01-01T10:00:00.000Z'
    restriction.ends_at = '2101-01-05T10:00:00.000Z'
    restriction.apply_to_user(new_user)

    # Create a schedule and assign it to the restriction
    schedule = RestrictionSchedule(schedule_days='1234567',
                                   hour_start=datetime.time(8, 0, 0),
                                   hour_end=datetime.time(10, 0, 0))
    schedule.save()
    restriction.add_schedule(schedule)

    # Create a resource and assign it to the restriction
    resource = Resource(id='0123456789012345678901234567890123456789')
    resource.save()
    restriction.apply_to_resource(resource)

    # Try to create reservation for a period not covered by the restriction.
    data = {
        'title': 'Test reservation',
        'description': 'Test reservation',
        'resourceId': '0123456789012345678901234567890123456789',
        'userId': new_user.id,
        'start': '2101-01-07T09:00:00.000Z',
        'end': '2101-01-07T10:30:00.000Z'
    }
    resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data))

    assert resp.status_code == HTTPStatus.FORBIDDEN
Beispiel #2
0
def create(schedule: Dict[str, Any]) -> Tuple[Content, HttpStatusCode]:
    try:
        days = [Weekday[day] for day in schedule['scheduleDays']]
        new_schedule = RestrictionSchedule(
            schedule_days=days,
            hour_start=datetime.strptime(schedule['hourStart'], "%H:%M").time(),
            hour_end=datetime.strptime(schedule['hourEnd'], "%H:%M").time()
        )
        new_schedule.save()
    except KeyError:
        # Invalid day
        content = {'msg': GENERAL['bad_request']}
        status = HTTPStatus.UNPROCESSABLE_ENTITY.value
    except AssertionError as e:
        content = {'msg': SCHEDULE['create']['failure']['invalid'].format(reason=e)}
        status = HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        content = {'msg': GENERAL['internal_error'] + str(e)}
        status = HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content = {
            'msg': SCHEDULE['create']['success'],
            'schedule': new_schedule.as_dict()
        }
        status = HTTPStatus.CREATED.value
    finally:
        return content, status
Beispiel #3
0
def test_delete_schedule(tables, client, active_schedule):
    id = active_schedule.id
    resp = client.delete(ENDPOINT + '/' + str(id), headers=HEADERS)

    assert resp.status_code == HTTPStatus.OK
    with pytest.raises(NoResultFound):
        RestrictionSchedule.get(id)
Beispiel #4
0
def test_schedule_creation(tables):
    schedule_expression = '12345'
    starts_at = datetime.time(8, 0, 0)
    ends_at = datetime.time(15, 0, 0)
    schedule = RestrictionSchedule(schedule_days=schedule_expression,
                                   hour_start=starts_at,
                                   hour_end=ends_at)
    schedule.save()
Beispiel #5
0
def active_schedule():
    schedule_expression = '1234567'
    start_time = datetime.time(0, 0, 0)
    end_time = datetime.time(23, 59, 59)
    schedule = RestrictionSchedule(schedule_days=schedule_expression,
                                   hour_start=start_time,
                                   hour_end=end_time)
    schedule.save()
    return schedule
Beispiel #6
0
def test_schedule_with_schedule_days_as_list_of_enums_gets_saved_successfully(
        tables):
    schedule_expression = [Weekday.Monday, Weekday.Tuesday]
    starts_at = datetime.time(8, 0, 0)
    ends_at = datetime.time(15, 0, 0)
    schedule = RestrictionSchedule(schedule_days=schedule_expression,
                                   hour_start=starts_at,
                                   hour_end=ends_at)
    schedule.save()
Beispiel #7
0
def inactive_schedule():
    today = str(datetime.datetime.utcnow().weekday() + 1)
    schedule_expression = '1234567'.replace(today, '')
    start_time = datetime.time(8, 0, 0)
    end_time = datetime.time(10, 0, 0)
    schedule = RestrictionSchedule(schedule_days=schedule_expression,
                                   hour_start=start_time,
                                   hour_end=end_time)
    schedule.save()
    return schedule
Beispiel #8
0
def test_create_schedule(tables, client):
    data = {
        'hourStart': '8:00',
        'hourEnd': '16:00',
        'scheduleDays':
        ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
    }
    resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data))
    resp_json = json.loads(resp.data.decode('utf-8'))

    assert resp.status_code == HTTPStatus.CREATED
    assert RestrictionSchedule.get(resp_json['schedule']['id']) is not None
Beispiel #9
0
def get_by_id(id: ScheduleId) -> Tuple[Content, HttpStatusCode]:
    try:
        schedule = RestrictionSchedule.get(id)
    except NoResultFound as e:
        log.warning(e)
        content, status = {'msg': SCHEDULE['not_found']}, HTTPStatus.NOT_FOUND.value
    except Exception as e:
        log.critical(e)
        content, status = {'msg': GENERAL['internal_error']}, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {'msg': SCHEDULE['get']['success'], 'schedule': schedule.as_dict()}, HTTPStatus.OK.value
    finally:
        return content, status
Beispiel #10
0
def test_cannot_create_schedule_with_wrong_schedule_expression(tables):
    starts_at = datetime.time(8, 0, 0)
    ends_at = datetime.time(15, 0, 0)
    wrong_schedule_expression = '1458'
    schedule = RestrictionSchedule(schedule_days=wrong_schedule_expression,
                                   hour_start=starts_at,
                                   hour_end=ends_at)
    with pytest.raises(AssertionError):
        schedule.save()

    schedule.schedule_days = '1123'
    with pytest.raises(AssertionError):
        schedule.save()
Beispiel #11
0
def get_selected(user_id: Optional[UserId], group_id: Optional[GroupId], resource_id: Optional[ResourceId],
                 schedule_id: Optional[ScheduleId], include_user_groups: Optional[bool] = False) \
        -> Tuple[Union[List[Any], Content], HttpStatusCode]:
    try:
        # If a specific group is selected then groups are not included in the restriction information in response
        # The same applies to users and resources
        include_groups = group_id is None
        include_users = user_id is None
        include_resources = schedule_id is None

        restrictions = []  # type: List[Restriction]
        if user_id is not None:
            user = User.get(user_id)
            restrictions.extend(
                user.get_restrictions(include_group=include_user_groups))
        if group_id is not None:
            group = Group.get(group_id)
            restrictions.extend(group.get_restrictions())
        if resource_id is not None:
            resource = Resource.get(resource_id)
            restrictions.extend(resource.get_restrictions())
        if schedule_id is not None:
            schedule = RestrictionSchedule.get(schedule_id)
            restrictions.extend(schedule.restrictions)

        # Take unique restrictions
        result = set(restrictions)
    except NoResultFound as e:
        log.warning(e)
        content, status = {
            'msg': GENERAL['bad_request']
        }, HTTPStatus.BAD_REQUEST.value
    except Exception as e:
        log.critical(e)
        content, status = {
            'msg': GENERAL['internal_error']
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content = [
            restriction.as_dict(
                include_groups=include_groups,
                include_users=include_users,  # type: ignore
                include_resources=include_resources) for restriction in result
        ]
        status = HTTPStatus.OK.value
    finally:
        return content, status
Beispiel #12
0
def add_schedule(restriction_id: RestrictionId,
                 schedule_id: ScheduleId) -> Tuple[Content, HttpStatusCode]:
    restriction = None
    try:
        restriction = Restriction.get(restriction_id)
        schedule = RestrictionSchedule.get(schedule_id)
        restriction.add_schedule(schedule)
        have_users_permissions_increased = len(
            restriction.schedules) > 1  # if added another schedule
        for user in restriction.get_all_affected_users():
            ReservationVerifier.update_user_reservations_statuses(
                user, have_users_permissions_increased)
    except NoResultFound:
        if restriction is None:
            content, status = {
                'msg': RESTRICTION['not_found']
            }, HTTPStatus.NOT_FOUND.value
        else:
            content, status = {
                'msg': SCHEDULE['not_found']
            }, HTTPStatus.NOT_FOUND.value
    except InvalidRequestException:
        content, status = {
            'msg': RESTRICTION['schedules']['add']['failure']['duplicate']
        }, HTTPStatus.CONFLICT.value
    except AssertionError as e:
        content, status = {'msg': RESTRICTION['schedules']['add']['failure']['assertions'].format(reason=e)}, \
            HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        log.critical(e)
        content, status = {
            'msg': GENERAL['internal_error']
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {
            'msg':
            RESTRICTION['schedules']['add']['success'],
            'restriction':
            restriction.as_dict(include_groups=True,
                                include_users=True,
                                include_resources=True)
        }, HTTPStatus.OK.value
    finally:
        return content, status
Beispiel #13
0
def delete(id: ScheduleId) -> Tuple[Content, HttpStatusCode]:
    try:
        schedule_to_destroy = RestrictionSchedule.get(id)
        restrictions = schedule_to_destroy.restrictions
        schedule_to_destroy.destroy()
        for restriction in restrictions:
            have_users_permissions_increased = len(restriction.schedules) == 0  # if deleted last schedule
            for user in restriction.get_all_affected_users():
                ReservationVerifier.update_user_reservations_statuses(user, have_users_permissions_increased)
    except AssertionError as error_message:
        content, status = {'msg': str(error_message)}, HTTPStatus.FORBIDDEN.value
    except NoResultFound:
        content, status = {'msg': SCHEDULE['not_found']}, HTTPStatus.NOT_FOUND.value
    except Exception as e:
        content, status = {'msg': GENERAL['internal_error'] + str(e)}, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {'msg': SCHEDULE['delete']['success']}, HTTPStatus.OK.value
    finally:
        return content, status
Beispiel #14
0
def test_schedule_is_active_method_returns_valid_status(tables, restriction):
    # schedule that runs only on current day of the week
    today_schedule_expression = str(datetime.datetime.utcnow().weekday() + 1)
    hour_start = datetime.time(0, 0, 0)
    hour_end = datetime.time(23, 59, 59)
    active_schedule = RestrictionSchedule(
        schedule_days=today_schedule_expression,
        hour_start=hour_start,
        hour_end=hour_end)
    active_schedule.save()

    # schedule that runs on every day of the week except for today
    not_today_schedule_expression = '1234567'.replace(
        today_schedule_expression, '')
    inactive_schedule = RestrictionSchedule(
        schedule_days=not_today_schedule_expression,
        hour_start=hour_start,
        hour_end=hour_end)
    inactive_schedule.save()

    assert active_schedule.is_active is True
    assert inactive_schedule.is_active is False
Beispiel #15
0
def update(id, newValues: Dict[str, Any]) -> Tuple[Content, HttpStatusCode]:
    new_values = newValues
    allowed_fields = {'scheduleDays', 'hourStart', 'hourEnd'}
    try:
        assert set(new_values.keys()).issubset(allowed_fields), 'invalid field is present'
        schedule = RestrictionSchedule.get(id)

        for field_name, new_value in new_values.items():
            if field_name == 'scheduleDays':
                new_value = [Weekday[day] for day in new_value]
            if field_name in ['hourStart', 'hourEnd']:
                new_value = datetime.strptime(new_value, "%H:%M").time()
            field_name = snakecase(field_name)
            assert (field_name is not None) and hasattr(schedule, field_name), \
                'schedule has no {} field'.format(field_name)
            setattr(schedule, field_name, new_value)
        schedule.save()
        for restriction in schedule.restrictions:
            for user in restriction.get_all_affected_users():
                ReservationVerifier.update_user_reservations_statuses(user, have_users_permissions_increased=True)
                ReservationVerifier.update_user_reservations_statuses(user, have_users_permissions_increased=False)
    except NoResultFound:
        content, status = {'msg': SCHEDULE['not_found']}, HTTPStatus.NOT_FOUND.value
    except KeyError:
        # Invalid day
        content, status = {'msg': GENERAL['bad_request']}, HTTPStatus.UNPROCESSABLE_ENTITY.value
    except AssertionError as e:
        content, status = {'msg': SCHEDULE['update']['failure']['assertions'].format(reason=e)}, \
            HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        log.critical(e)
        content, status = {'msg': GENERAL['internal_error']}, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {'msg': SCHEDULE['update']['success'], 'schedule': schedule.as_dict()}, HTTPStatus.OK.value
    finally:
        return content, status
Beispiel #16
0
def get() -> Tuple[List[Any], HttpStatusCode]:
    return [
        schedule.as_dict() for schedule in RestrictionSchedule.all()
    ], HTTPStatus.OK.value