def test_teacher_available_hours_with_rules( teacher, student, requester, meetup, dropoff ): tomorrow = datetime.utcnow().replace(hour=7, minute=0) + timedelta(days=1) kwargs = { "teacher": teacher, "day": 1, "from_hour": tomorrow.hour, "from_minutes": tomorrow.minute, "to_hour": 23, "to_minutes": 59, "on_date": tomorrow, } WorkDay.create(**kwargs) for i in range(3): Appointment.create( teacher=teacher, student=student, creator=teacher.user, duration=teacher.lesson_duration, date=tomorrow + timedelta(minutes=i), meetup_place=meetup, dropoff_place=dropoff, is_approved=True, ) hours_with_rules = list(teacher.available_hours(tomorrow, student=student)) hours_without_rules = list(teacher.available_hours(tomorrow)) assert hours_with_rules != hours_without_rules
def test_teacher_available_hours(teacher, student, requester, meetup, dropoff): tomorrow = datetime.utcnow().replace(hour=7, minute=0) + timedelta(days=1) kwargs = { "teacher": teacher, "day": 1, "from_hour": tomorrow.hour, "from_minutes": tomorrow.minute, "to_hour": 23, "to_minutes": 59, "on_date": tomorrow, } WorkDay.create(**kwargs) assert next(teacher.available_hours(tomorrow))[0] == tomorrow # we create a non approved lesson - available hours should still contain its date lesson = Appointment.create( teacher=teacher, student=student, creator=teacher.user, duration=teacher.lesson_duration, date=tomorrow, meetup_place=meetup, dropoff_place=dropoff, is_approved=False, ) assert next(teacher.available_hours(tomorrow, only_approved=True))[0] == tomorrow assert next(teacher.available_hours(tomorrow, only_approved=False))[0] != tomorrow
def test_work_days(teacher, auth, requester): auth.login(email=teacher.user.email) date = datetime.utcnow() + timedelta(hours=10) first_kwargs_hour = 13 kwargs = { "teacher": teacher, "day": 1, "from_hour": first_kwargs_hour, "from_minutes": 0, "to_hour": 17, "to_minutes": 0, "on_date": date, } day1 = WorkDay.create(**kwargs) kwargs.pop("on_date") kwargs["from_hour"] = 15 day2 = WorkDay.create(**kwargs) resp = requester.get("/teacher/work_days").json assert resp["data"][0]["from_hour"] == kwargs["from_hour"] day = date.date() resp = requester.get(f"/teacher/work_days?on_date=eq:{day}").json assert resp["data"][0]["from_hour"] == first_kwargs_hour resp = requester.get(f"/teacher/work_days?day=1").json assert resp["data"][0]["from_hour"] == kwargs["from_hour"]
def test_student_blocked_hours_by_test( teacher, student, meetup, dropoff, auth, requester ): date = (datetime.utcnow() + timedelta(days=1)).replace(hour=13, minute=0) data = { "teacher": teacher, "from_hour": 13, "from_minutes": 0, "to_hour": 17, "to_minutes": 0, "on_date": date, } WorkDay.create(**data) Appointment.create( teacher=teacher, student=student, creator=teacher.user, duration=40, date=date, meetup_place=meetup, dropoff_place=dropoff, is_approved=False, type=AppointmentType.TEST.value, ) auth.login(email=student.user.email) resp = requester.post( f"/teacher/{teacher.id}/available_hours", json={"date": date.strftime(WORKDAY_DATE_FORMAT)}, ) hours = [hour[0] for hour in resp.json["data"]] assert all(date.strftime("%H:%M") not in hour for hour in hours)
def test_student_adding_inner_exam(auth, teacher, student, requester): auth.login(email=student.user.email) kwargs = { "teacher": teacher, "day": 1, "from_hour": 7, "from_minutes": 0, "to_hour": 21, "to_minutes": 59, "on_date": tomorrow.date(), } WorkDay.create(**kwargs) date = (tomorrow.replace(hour=21, minute=00)).strftime(DATE_FORMAT) resp = requester.post( "/appointments/", json={ "duration": 40, "date": date, "student_id": student.id, "meetup_place": { "description": "test" }, "dropoff_place": { "description": "test" }, "type": "inner_exam", }, ) assert resp.json["data"]["type"] == AppointmentType.LESSON.name.lower()
def test_student_new_lesson(auth, teacher, student, requester, topic): auth.login(email=student.user.email) date = (tomorrow.replace(hour=16, minute=00)).strftime(DATE_FORMAT) kwargs = { "teacher": teacher, "day": 1, "from_hour": 7, "from_minutes": 0, "to_hour": 21, "to_minutes": 59, "on_date": tomorrow.date(), } WorkDay.create(**kwargs) resp = requester.post( "/appointments/", json={ "date": date, "duration": "60", "meetup_place": { "description": "test" }, "dropoff_place": { "description": "test" }, }, ) assert not resp.json["data"]["is_approved"] assert resp.json["data"]["price"] == student.price * 1.5 assert resp.json["data"]["duration"] == teacher.lesson_duration * 1.5
def test_hour_not_available(auth, teacher, student, requester): auth.login(email=student.user.email) date = (tomorrow.replace(hour=12, minute=00)).strftime(DATE_FORMAT) kwargs = { "teacher": teacher, "day": 1, "from_hour": 13, "from_minutes": 0, "to_hour": 17, "to_minutes": 0, "on_date": tomorrow.date(), } WorkDay.create(**kwargs) logger.debug(f"added work day for {teacher}") resp = requester.post( "/appointments/", json={ "date": date, "duration": 40, "meetup_place": { "description": "test" }, "dropoff_place": { "description": "test" }, }, ) assert "not available" in resp.json["message"]
def test_student_different_car_new_lesson(auth, teacher, student, requester, topic): auth.login(email=student.user.email) date = (tomorrow.replace(hour=16, minute=00)).strftime(DATE_FORMAT) kwargs = { "teacher": teacher, "day": 1, "from_hour": 7, "from_minutes": 0, "to_hour": 21, "to_minutes": 59, "on_date": tomorrow.date(), "car": Car.create(teacher=teacher, number="11111111"), } WorkDay.create(**kwargs) resp = requester.post( "/appointments/", json={ "date": date, "duration": "60", "meetup_place": { "description": "test" }, "dropoff_place": { "description": "test" }, }, ) assert "not available" in resp.json["message"]
def test_available_hours_route_with_places( teacher, student, meetup, dropoff, auth, requester, responses ): auth.login(email=student.user.email) tomorrow = datetime.utcnow() + timedelta(days=1) data = { "teacher": teacher, "from_hour": 7, "from_minutes": 0, "to_hour": 17, "to_minutes": 0, "on_date": tomorrow, } WorkDay.create(**data) date = tomorrow.replace(hour=16, minute=0) Appointment.create( teacher=teacher, student=student, creator=teacher.user, duration=40, date=date, meetup_place=meetup, dropoff_place=dropoff, is_approved=True, # only check places for approved lessons ) ret = { "destination_addresses": ["HaNassi Blvd, Haifa, Israel"], "origin_addresses": ["Gruenbaum St 3, Haifa, Israel"], "rows": [ { "elements": [ { "distance": {"text": "4.8 mi", "value": 7742}, "duration": {"text": "17 mins", "value": 1037}, "status": "OK", } ] } ], "status": "OK", } responses.add( responses.GET, "https://maps.googleapis.com/maps/api/distancematrix/json", body=json.dumps(ret), status=200, content_type="application/json", ) resp = requester.post( f"/teacher/{teacher.id}/available_hours", json={ "date": date.strftime(WORKDAY_DATE_FORMAT), "meetup_place_id": "test1", "dropoff_place_id": "test2", }, ) assert resp.json["data"]
def test_available_hours_route(teacher, student, meetup, dropoff, auth, requester): auth.login(email=teacher.user.email) tomorrow = datetime.utcnow() + timedelta(days=1) date = tomorrow.strftime(WORKDAY_DATE_FORMAT) time_and_date = date + "T13:30:20.123123Z" data = { "teacher": teacher, "from_hour": 13, "from_minutes": 0, "to_hour": 17, "to_minutes": 0, "on_date": tomorrow, } WorkDay.create(**data) # now let's add a lesson lesson_date = datetime.strptime(time_and_date, DATE_FORMAT) lesson = Appointment.create( teacher=teacher, student=student, creator=teacher.user, duration=40, date=lesson_date, meetup_place=meetup, dropoff_place=dropoff, is_approved=False, ) resp = requester.post(f"/teacher/{teacher.id}/available_hours", json={"date": date}) assert len(resp.json["data"]) == 6 lesson.update(is_approved=True) resp = requester.post( f"/teacher/{teacher.id}/available_hours", json={"date": date, "duration": "120"} ) assert len(resp.json["data"]) == 1 auth.logout() # if we login as student, we shouldn't this non approved lesson date auth.login(email=student.user.email) lesson.update(is_approved=False) resp = requester.post(f"/teacher/{teacher.id}/available_hours", json={"date": date}) hours = [hour[0] for hour in resp.json["data"]] assert all(lesson_date.strftime("%H:%M") not in hour for hour in hours)
def filter_work_days(self, args: werkzeug.datastructures.MultiDict): args = args.copy() if "on_date" not in args: args["on_date"] = None def custom_date_func(value): return datetime.strptime(value, WORKDAY_DATE_FORMAT).date() return WorkDay.filter_and_sort(args, query=self.work_days, custom_date=custom_date_func)
def update_work_days(): data = flask.request.get_json() """ example data: 0: [{from_hour: 8, from_minutes: 0, to_hour: 14}], 1: {}.... OR "03-15-2019": [{from_hour: 8}], "03-16-2019": [].... """ logger.debug(f"WORK DAYS - got the following data") logger.debug(data) for day, hours_list in data.items(): # first, let's delete all current data with this date # TODO better algorithm for that try: day = int(day) params = dict(day=day, teacher=current_user.teacher) WorkDay.query.filter_by(**params).delete() except ValueError: # probably a date params = dict( on_date=datetime.strptime(day, WORKDAY_DATE_FORMAT), teacher=current_user.teacher, ) WorkDay.query.filter_by(**params).delete() for hours in hours_list: from_hour = max(min(int(hours.get("from_hour")), 24), 0) to_hour = max(min(int(hours.get("to_hour")), 24), 0) from_minutes = max(min(int(hours.get("from_minutes")), 60), 0) to_minutes = max(min(int(hours.get("to_minutes")), 60), 0) car = current_user.teacher.cars.filter_by( id=hours.get("car_id")).first() if not car: car = current_user.teacher.cars.first() if from_hour >= to_hour: raise RouteError( "There must be a bigger difference between the two times.") current_user.teacher.work_days.append( WorkDay( from_hour=from_hour, from_minutes=from_minutes, to_hour=to_hour, to_minutes=to_minutes, car=car, **params, )) current_user.save() return {"message": "Days updated."}
def test_delete_work_day(teacher, auth, requester): auth.login(email=teacher.user.email) kwargs = { "teacher": teacher, "day": 1, "from_hour": 13, "from_minutes": 0, "to_hour": 17, "to_minutes": 0, } day = WorkDay.create(**kwargs) resp = requester.delete(f"/teacher/work_days/{day.id}") assert "Day deleted" in resp.json["message"] resp = requester.delete("/teacher/work_days/8") assert "not exist" in resp.json["message"]
def setup_db(app): User.create(email="*****@*****.**", password="******", name="test", area="test", phone="044444444") User.create( email="*****@*****.**", password="******", name="admin", area="test", is_admin=True, phone="055555555", ) teacher_user = User.create(email="*****@*****.**", password="******", name="teacher", area="test") teacher = Teacher.create( user=teacher_user, price=100, lesson_duration=40, is_approved=True, crn=999999999, invoice_api_key=DEMO_API_KEY, ) Car.create(teacher=teacher, number=1111111111) student_user = User.create(email="*****@*****.**", password="******", name="student", area="test") student = Student.create(user=student_user, teacher=teacher, creator=teacher.user, is_approved=True) meetup = Place.create( description="test", used_as=PlaceType.meetup.value, student=student, google_id="ID1", ) dropoff = Place.create( description="test", used_as=PlaceType.dropoff.value, student=student, google_id="ID2", ) WorkDay.create( teacher=teacher, day=1, from_hour=0, to_hour=23, to_minutes=59, on_date=(datetime.utcnow() + timedelta(days=2)).date(), ) # 2 days from now Topic.create(title="topic test", min_lesson_number=1, max_lesson_number=5) Appointment.create( teacher=teacher, student=student, # schedule to 5 days from now to it won't bother with no test creator=teacher.user, duration=40, date=(datetime.utcnow() + timedelta(days=5)), meetup_place=meetup, dropoff_place=dropoff, )