@@ -243,7 +243,7 @@ async def test_record_video_view_success():
243243 # but we already pass mock_stats_table, so get_table will be used only once
244244 mock_get_table .return_value = mock_activity_table
245245
246- await video_service .record_video_view (vid , mock_stats_table )
246+ await video_service .record_video_view (vid , db_table = mock_stats_table )
247247
248248 # Validate stats table increment
249249 mock_stats_table .update_one .assert_called_once_with (
@@ -254,6 +254,95 @@ async def test_record_video_view_success():
254254 mock_activity_table .insert_one .assert_called_once ()
255255
256256
257+ @pytest .mark .asyncio
258+ async def test_record_video_view_authenticated_user_activity ():
259+ """Authenticated view calls record_user_activity with real user ID."""
260+ vid = uuid4 ()
261+ viewer_id = uuid4 ()
262+ mock_stats_table = AsyncMock ()
263+ mock_activity_table = AsyncMock ()
264+
265+ with (
266+ patch (
267+ "app.services.video_service.get_table" , new_callable = AsyncMock
268+ ) as mock_get_table ,
269+ patch (
270+ "app.services.user_activity_service.record_user_activity" ,
271+ new_callable = AsyncMock ,
272+ ) as mock_record_user_activity ,
273+ ):
274+ mock_get_table .return_value = mock_activity_table
275+
276+ await video_service .record_video_view (
277+ vid , viewer_user_id = viewer_id , db_table = mock_stats_table
278+ )
279+
280+ # record_user_activity should be called with the real user ID
281+ mock_record_user_activity .assert_awaited_once_with (
282+ userid = viewer_id ,
283+ activity_type = "view" ,
284+ )
285+
286+
287+ @pytest .mark .asyncio
288+ async def test_record_video_view_anonymous_user_activity ():
289+ """Anonymous view calls record_user_activity with nil UUID sentinel."""
290+ from app .services .user_activity_service import ANONYMOUS_USER_ID
291+
292+ vid = uuid4 ()
293+ mock_stats_table = AsyncMock ()
294+ mock_activity_table = AsyncMock ()
295+
296+ with (
297+ patch (
298+ "app.services.video_service.get_table" , new_callable = AsyncMock
299+ ) as mock_get_table ,
300+ patch (
301+ "app.services.user_activity_service.record_user_activity" ,
302+ new_callable = AsyncMock ,
303+ ) as mock_record_user_activity ,
304+ ):
305+ mock_get_table .return_value = mock_activity_table
306+
307+ await video_service .record_video_view (
308+ vid , viewer_user_id = None , db_table = mock_stats_table
309+ )
310+
311+ # record_user_activity should be called with the anonymous sentinel UUID
312+ mock_record_user_activity .assert_awaited_once_with (
313+ userid = ANONYMOUS_USER_ID ,
314+ activity_type = "view" ,
315+ )
316+
317+
318+ @pytest .mark .asyncio
319+ async def test_record_video_view_user_activity_failure_does_not_break ():
320+ """If record_user_activity raises, the video view still succeeds."""
321+ vid = uuid4 ()
322+ mock_stats_table = AsyncMock ()
323+ mock_activity_table = AsyncMock ()
324+
325+ with (
326+ patch (
327+ "app.services.video_service.get_table" , new_callable = AsyncMock
328+ ) as mock_get_table ,
329+ patch (
330+ "app.services.user_activity_service.record_user_activity" ,
331+ new_callable = AsyncMock ,
332+ ) as mock_record_user_activity ,
333+ ):
334+ mock_get_table .return_value = mock_activity_table
335+ mock_record_user_activity .side_effect = Exception ("DB error" )
336+
337+ # Should NOT raise despite user_activity failure
338+ await video_service .record_video_view (
339+ vid , viewer_user_id = uuid4 (), db_table = mock_stats_table
340+ )
341+
342+ # video_activity insert still happened
343+ mock_activity_table .insert_one .assert_called_once ()
344+
345+
257346# ------------------------------------------------------------
258347# list_latest_videos (delegate to generic) – just verify query call
259348# ------------------------------------------------------------
@@ -276,7 +365,7 @@ async def test_list_latest_videos():
276365 mock_list_with_query .assert_called_once_with (
277366 {},
278367 1 ,
279- 3 ,
368+ 10 ,
280369 sort_options = {"added_date" : - 1 },
281370 db_table = mock_db ,
282371 source_table_name = video_service .VIDEOS_TABLE_NAME ,
@@ -293,20 +382,18 @@ async def test_list_latest_videos():
293382@pytest .mark .asyncio
294383async def test_search_videos_by_keyword ():
295384 mock_db = AsyncMock ()
296- mock_db .find .return_value = []
297- mock_db .count_documents .return_value = 0
298385
299386 with patch (
300- "app.services.video_service.list_videos_with_query " ,
387+ "app.services.video_service.search_videos_by_semantic " ,
301388 new_callable = AsyncMock ,
302- ) as mock_list_with_query :
303- mock_list_with_query .return_value = ([], 0 )
389+ ) as mock_semantic :
390+ mock_semantic .return_value = ([], 0 )
304391
305392 summaries , total = await video_service .search_videos_by_keyword (
306393 query = "test" , page = 1 , page_size = 10 , db_table = mock_db
307394 )
308395
309- mock_list_with_query .assert_called_once ()
396+ mock_semantic .assert_called_once ()
310397 assert summaries == []
311398 assert total == 0
312399
0 commit comments