22from contextlib import contextmanager
33from copy import deepcopy
44from dataclasses import asdict
5+ from datetime import UTC , datetime
56
67import pytest
78from flask import url_for
89from flask_sqlalchemy import get_debug_queries
910from journalist_app import api2
1011from journalist_app .api2 import json_version
1112from journalist_app .api2 .types import Event , EventType , ItemTarget , SourceTarget
12- from models import Reply , Submission
13+ from models import Reply , Submission , db
1314from sqlalchemy .orm .exc import MultipleResultsFound
1415from tests .utils import ascii_armor , decrypt_as_journalist
1516from tests .utils .api_helper import get_api_headers
17+ from tests .utils .db_helper import init_source , submit
1618
1719
1820def filtered_queries ():
@@ -73,10 +75,26 @@ def test_auth_required(journalist_app, endpoint, kwargs):
7375 assert response .status_code == 403
7476
7577
76- def test_index (journalist_app , test_files , journalist_api_token ):
78+ def test_index (journalist_app , test_files , journalist_api_token , app_storage ):
7779 """
78- Verify GET /index response and HTTP 304 behavior
80+ Verify GET /index response and HTTP 304 behavior.
7981 """
82+ # Create a pending source and a deleted source to verify they're excluded
83+ with journalist_app .app_context ():
84+ # Create a pending source (no submissions)
85+ pending_source , _ = init_source (app_storage )
86+ pending_uuid = pending_source .uuid
87+ assert pending_source .pending is True
88+
89+ # Create source that is queued for deletion but not yet deleted
90+ deleted_source , _ = init_source (app_storage )
91+ submit (app_storage , deleted_source , 1 )
92+ deleted_uuid = deleted_source .uuid
93+ assert deleted_source .pending is False
94+ # Mark it as deleted
95+ deleted_source .deleted_at = datetime .now (UTC )
96+ db .session .commit ()
97+
8098 with journalist_app .test_client () as app :
8199 uuid = test_files ["source" ].uuid
82100 with assert_query_count (2 ):
@@ -85,11 +103,14 @@ def test_index(journalist_app, test_files, journalist_api_token):
85103 headers = get_api_headers (journalist_api_token ),
86104 )
87105
88- # Verify the source is in the response
106+ # Verify the active source is in the response
89107 assert response .status_code == 200
90108 assert uuid in response .json ["sources" ]
91109 # test_files generates 2 submissions and 1 reply, so 3 items total
92110 assert len (response .json ["items" ]) == 3
111+ # Verify pending and deleted sources are NOT in the response
112+ assert pending_uuid not in response .json ["sources" ]
113+ assert deleted_uuid not in response .json ["sources" ]
93114
94115 with assert_query_count (2 ):
95116 response2 = app .get (
0 commit comments