@@ -678,6 +678,36 @@ def fake_presigned(object_name: str, *, expires):
678678 await session .commit ()
679679
680680
681+ @pytest .mark .asyncio
682+ async def test_get_archive_preview_url_not_found (
683+ client : AsyncClient ,
684+ make_user ,
685+ ):
686+ user = await make_user ()
687+
688+ app .dependency_overrides [get_current_user ] = _override_user (user )
689+ try :
690+ response = await client .get ("/courses/999/archives/1/preview" )
691+ assert response .status_code == 404
692+ finally :
693+ app .dependency_overrides .pop (get_current_user , None )
694+
695+
696+ @pytest .mark .asyncio
697+ async def test_get_archive_download_url_not_found (
698+ client : AsyncClient ,
699+ make_user ,
700+ ):
701+ user = await make_user ()
702+
703+ app .dependency_overrides [get_current_user ] = _override_user (user )
704+ try :
705+ response = await client .get ("/courses/123/archives/456/download" )
706+ assert response .status_code == 404
707+ finally :
708+ app .dependency_overrides .pop (get_current_user , None )
709+
710+
681711@pytest .mark .asyncio
682712async def test_update_archive_direct_sets_fields (
683713 session_maker ,
@@ -990,6 +1020,46 @@ async def test_delete_course_not_found_direct(session_maker, make_user):
9901020 assert exc .value .status_code == 404
9911021
9921022
1023+ @pytest .mark .asyncio
1024+ async def test_admin_delete_course_soft_deletes_archives (
1025+ client : AsyncClient ,
1026+ session_maker ,
1027+ make_user ,
1028+ ):
1029+ admin = await make_user (is_admin = True )
1030+ course = await _create_course (session_maker )
1031+ archive = await _create_archive (
1032+ session_maker ,
1033+ course_id = course .id ,
1034+ uploader_id = admin .id ,
1035+ )
1036+
1037+ app .dependency_overrides [get_current_user ] = _override_user (admin )
1038+ try :
1039+ response = await client .delete (
1040+ f"/courses/admin/courses/{ course .id } "
1041+ )
1042+ assert response .status_code == 200
1043+ body = response .json ()
1044+ assert "1 associated archives" in body ["message" ]
1045+
1046+ async with session_maker () as session :
1047+ refreshed_course = await session .get (Course , course .id )
1048+ refreshed_archive = await session .get (Archive , archive .id )
1049+ assert refreshed_course .deleted_at is not None
1050+ assert refreshed_archive .deleted_at is not None
1051+ finally :
1052+ app .dependency_overrides .pop (get_current_user , None )
1053+ async with session_maker () as session :
1054+ await session .execute (
1055+ delete (Archive ).where (Archive .id == archive .id )
1056+ )
1057+ await session .execute (
1058+ delete (Course ).where (Course .id == course .id )
1059+ )
1060+ await session .commit ()
1061+
1062+
9931063@pytest .mark .asyncio
9941064async def test_list_all_courses_direct_returns_courses (
9951065 session_maker ,
@@ -1009,3 +1079,129 @@ async def test_list_all_courses_direct_returns_courses(
10091079 async with session_maker () as session :
10101080 await session .execute (delete (Course ).where (Course .id == course .id ))
10111081 await session .commit ()
1082+
1083+
1084+ @pytest .mark .asyncio
1085+ async def test_get_course_archives_not_found_direct (session_maker , make_user ):
1086+ user = await make_user ()
1087+ async with session_maker () as session :
1088+ with pytest .raises (HTTPException ) as exc :
1089+ await get_course_archives (
1090+ course_id = 999999 ,
1091+ current_user = UserRoles (user_id = user .id , is_admin = False ),
1092+ db = session ,
1093+ )
1094+ assert exc .value .status_code == 404
1095+
1096+
1097+ @pytest .mark .asyncio
1098+ async def test_get_archive_preview_url_not_found_direct (session_maker , make_user ):
1099+ user = await make_user ()
1100+ async with session_maker () as session :
1101+ with pytest .raises (HTTPException ) as exc :
1102+ await get_archive_preview_url (
1103+ course_id = 1 ,
1104+ archive_id = 2 ,
1105+ current_user = UserRoles (user_id = user .id , is_admin = False ),
1106+ db = session ,
1107+ )
1108+ assert exc .value .status_code == 404
1109+
1110+
1111+ @pytest .mark .asyncio
1112+ async def test_get_archive_download_url_not_found_direct (session_maker , make_user ):
1113+ user = await make_user ()
1114+ async with session_maker () as session :
1115+ with pytest .raises (HTTPException ) as exc :
1116+ await get_archive_download_url (
1117+ course_id = 1 ,
1118+ archive_id = 2 ,
1119+ current_user = UserRoles (user_id = user .id , is_admin = False ),
1120+ db = session ,
1121+ )
1122+ assert exc .value .status_code == 404
1123+
1124+
1125+ @pytest .mark .asyncio
1126+ async def test_update_archive_course_creates_new_course_direct (session_maker , make_user ):
1127+ admin = await make_user (is_admin = True )
1128+ course = await _create_course (session_maker , name = "Direct Course" )
1129+ archive = await _create_archive (
1130+ session_maker ,
1131+ course_id = course .id ,
1132+ uploader_id = admin .id ,
1133+ )
1134+
1135+ async with session_maker () as session :
1136+ response = await update_archive_course (
1137+ course_id = course .id ,
1138+ archive_id = archive .id ,
1139+ course_update = ArchiveUpdateCourse (
1140+ course_name = "Brand New Course" ,
1141+ course_category = CourseCategory .GRADUATE ,
1142+ ),
1143+ current_user = UserRoles (user_id = admin .id , is_admin = True ),
1144+ db = session ,
1145+ )
1146+ new_course_id = response ["new_course_id" ]
1147+ new_course = await session .get (Course , new_course_id )
1148+ assert new_course .name == "Brand New Course"
1149+
1150+ await session .execute (delete (Archive ).where (Archive .id == archive .id ))
1151+ await session .execute (delete (Course ).where (Course .id == course .id ))
1152+ await session .execute (delete (Course ).where (Course .id == new_course_id ))
1153+ await session .commit ()
1154+
1155+
1156+ @pytest .mark .asyncio
1157+ async def test_create_course_duplicate_direct (session_maker , make_user ):
1158+ admin = await make_user (is_admin = True )
1159+ course = await _create_course (
1160+ session_maker ,
1161+ name = "Duplicate Direct" ,
1162+ category = CourseCategory .GENERAL ,
1163+ )
1164+
1165+ async with session_maker () as session :
1166+ with pytest .raises (HTTPException ) as exc :
1167+ await create_course (
1168+ course_data = CourseCreate (
1169+ name = "Duplicate Direct" ,
1170+ category = CourseCategory .GENERAL ,
1171+ ),
1172+ current_user = UserRoles (user_id = admin .id , is_admin = True ),
1173+ db = session ,
1174+ )
1175+ assert exc .value .status_code == 400
1176+
1177+ async with session_maker () as session :
1178+ await session .execute (delete (Course ).where (Course .id == course .id ))
1179+ await session .commit ()
1180+
1181+
1182+ @pytest .mark .asyncio
1183+ async def test_delete_course_soft_deletes_direct (session_maker , make_user ):
1184+ admin = await make_user (is_admin = True )
1185+ course = await _create_course (session_maker , name = "Delete Direct" )
1186+ archive = await _create_archive (
1187+ session_maker ,
1188+ course_id = course .id ,
1189+ uploader_id = admin .id ,
1190+ )
1191+
1192+ async with session_maker () as session :
1193+ result = await delete_course (
1194+ course_id = course .id ,
1195+ current_user = UserRoles (user_id = admin .id , is_admin = True ),
1196+ db = session ,
1197+ )
1198+ assert "associated archives" in result ["message" ]
1199+
1200+ refreshed_course = await session .get (Course , course .id )
1201+ refreshed_archive = await session .get (Archive , archive .id )
1202+ assert refreshed_course .deleted_at is not None
1203+ assert refreshed_archive .deleted_at is not None
1204+
1205+ await session .execute (delete (Archive ).where (Archive .id == archive .id ))
1206+ await session .execute (delete (Course ).where (Course .id == course .id ))
1207+ await session .commit ()
0 commit comments