@@ -949,3 +949,52 @@ def test_api2_source_conversation_deleted_resubmission(
949949 )
950950 assert res3 .status_code == 200
951951 assert res3 .json ["events" ][event .id ][0 ] == 208
952+
953+
954+ def test_api2_reply_sent_then_requested_item_is_deduped (
955+ journalist_app ,
956+ journalist_api_token ,
957+ test_files ,
958+ ):
959+ """
960+ When a reply is created by a `REPLY_SENT` event and the same UUID is also
961+ requested in the same `BatchRequest`, the request should succeed (200) and
962+ return the reply once.
963+ """
964+ with journalist_app .test_client () as app :
965+ # Fetch an existing reply so that we can resubmit it.
966+ source = test_files ["source" ]
967+ reply = test_files ["replies" ][0 ]
968+ reply_res = app .get (
969+ url_for ("api.download_reply" , source_uuid = source .uuid , reply_uuid = reply .uuid ),
970+ headers = get_api_headers (journalist_api_token ),
971+ )
972+ reply_ct = reply_res .data
973+ armored_ct = ascii_armor (reply_ct )
974+
975+ # Get current source version to build a valid "reply_sent" event.
976+ index = app .get (
977+ url_for ("api2.index" ),
978+ headers = get_api_headers (journalist_api_token ),
979+ )
980+ assert index .status_code == 200
981+ source_version = index .json ["sources" ][source .uuid ]
982+
983+ new_reply_uuid = str (uuid .uuid4 ())
984+ event = Event (
985+ id = "987654321" ,
986+ target = SourceTarget (source_uuid = source .uuid , version = source_version ),
987+ type = EventType .REPLY_SENT ,
988+ data = {"uuid" : new_reply_uuid , "reply" : armored_ct },
989+ )
990+
991+ # The same batch both creates the reply (`events`) and requests it (`items`).
992+ response = app .post (
993+ url_for ("api2.data" ),
994+ json = {"events" : [asdict (event )], "items" : [new_reply_uuid ]},
995+ headers = get_api_headers (journalist_api_token ),
996+ )
997+ assert response .status_code == 200
998+ assert response .json ["events" ][event .id ] == [200 , None ]
999+ assert new_reply_uuid in response .json ["items" ]
1000+ assert response .json ["items" ][new_reply_uuid ] is not None
0 commit comments