from flask import Flask from tinydb import Query from werkzeug.security import generate_password_hash from tests.conftest import TEST_SECRET_KEY, TEST_REFRESH_TOKEN_EXPIRY_DAYS from api.auth_api import auth_api from api.routine_api import routine_api from api.routine_item_api import routine_item_api from api.child_routine_api import child_routine_api from api.routine_schedule_api import routine_schedule_api from db.db import ( users_db, child_db, routine_db, routine_items_db, routine_schedules_db, routine_extensions_db, pending_confirmations_db, ) TEST_USER_ID = 'routine-user-1' TEST_EMAIL = 'routine-user@example.com' TEST_PASSWORD = 'testpass' def add_test_user(): users_db.remove(Query().email == TEST_EMAIL) users_db.insert({ 'id': TEST_USER_ID, 'first_name': 'Routine', 'last_name': 'Tester', 'email': TEST_EMAIL, 'password': generate_password_hash(TEST_PASSWORD), 'verified': True, 'image_id': 'boy01', }) def login_and_set_cookie(client): resp = client.post('/auth/login', json={'email': TEST_EMAIL, 'password': TEST_PASSWORD}) assert resp.status_code == 200 def seed_child(child_id: str): child_db.remove(Query().id == child_id) child_db.insert({ 'id': child_id, 'name': 'Routine Kid', 'age': 9, 'tasks': [], 'routines': [], 'rewards': [], 'points': 0, 'image_id': 'boy01', 'user_id': TEST_USER_ID, }) def _first_routine_id(): routines = routine_db.all() assert routines return routines[0]['id'] def _first_confirmation_id(): confirmations = pending_confirmations_db.all() assert confirmations return confirmations[0]['id'] def _make_client(): app = Flask(__name__) app.register_blueprint(auth_api, url_prefix='/auth') app.register_blueprint(routine_api) app.register_blueprint(routine_item_api) app.register_blueprint(child_routine_api) app.register_blueprint(routine_schedule_api) app.config['TESTING'] = True app.config['SECRET_KEY'] = TEST_SECRET_KEY app.config['REFRESH_TOKEN_EXPIRY_DAYS'] = TEST_REFRESH_TOKEN_EXPIRY_DAYS return app def setup_function(_): routine_db.truncate() routine_items_db.truncate() routine_schedules_db.truncate() routine_extensions_db.truncate() pending_confirmations_db.truncate() child_db.truncate() def test_routine_crud_flow(): app = _make_client() with app.test_client() as client: add_test_user() login_and_set_cookie(client) add_resp = client.put('/routine/add', json={'name': 'Morning Routine', 'points': 8, 'image_id': 'sun'}) assert add_resp.status_code == 201 rid = _first_routine_id() list_resp = client.get('/routine/list') assert list_resp.status_code == 200 routines = list_resp.get_json()['routines'] assert len(routines) == 1 assert routines[0]['name'] == 'Morning Routine' edit_resp = client.put(f'/routine/{rid}/edit', json={'points': 10}) assert edit_resp.status_code == 200 assert edit_resp.get_json()['points'] == 10 delete_resp = client.delete(f'/routine/{rid}') assert delete_resp.status_code == 200 assert routine_db.all() == [] def test_child_routine_assignment_confirmation_and_approval(): app = _make_client() with app.test_client() as client: add_test_user() login_and_set_cookie(client) seed_child('routine-child-1') client.put('/routine/add', json={'name': 'Evening Routine', 'points': 6, 'image_id': 'moon'}) rid = _first_routine_id() add_item_resp = client.put(f'/routine/{rid}/item/add', json={'name': 'Brush Teeth', 'order': 0}) assert add_item_resp.status_code == 201 assign_resp = client.post('/child/routine-child-1/assign-routine', json={'routine_id': rid}) assert assign_resp.status_code == 200 list_resp = client.get('/child/routine-child-1/list-routines') assert list_resp.status_code == 200 routines = list_resp.get_json()['routines'] assert len(routines) == 1 assert routines[0]['id'] == rid assert routines[0]['items'][0]['name'] == 'Brush Teeth' confirm_resp = client.post('/child/routine-child-1/confirm-routine', json={'routine_id': rid}) assert confirm_resp.status_code == 200 confirmation_id = _first_confirmation_id() approve_resp = client.post(f'/child/routine-child-1/approve-routine/{confirmation_id}') assert approve_resp.status_code == 200 child = child_db.get(Query().id == 'routine-child-1') assert child['points'] == 6 def test_routine_schedule_and_extend_flow(): app = _make_client() with app.test_client() as client: add_test_user() login_and_set_cookie(client) seed_child('routine-child-2') client.put('/routine/add', json={'name': 'School Routine', 'points': 5, 'image_id': 'book'}) rid = _first_routine_id() client.post('/child/routine-child-2/assign-routine', json={'routine_id': rid}) set_resp = client.put( f'/child/routine-child-2/routine/{rid}/schedule', json={ 'mode': 'days', 'day_configs': [{'day': 1, 'hour': 8, 'minute': 0}], 'default_hour': 8, 'default_minute': 0, 'default_has_deadline': True, }, ) assert set_resp.status_code == 200 get_resp = client.get(f'/child/routine-child-2/routine/{rid}/schedule') assert get_resp.status_code == 200 assert get_resp.get_json()['mode'] == 'days' extend_resp = client.post( f'/child/routine-child-2/routine/{rid}/extend', json={'date': '2026-05-04'}, ) assert extend_resp.status_code == 200 assert extend_resp.get_json()['routine_id'] == rid