@@ -894,6 +894,101 @@ describe("quote request lifecycle", () => {
894894 expect ( sendActivity ) . toHaveBeenCalledTimes ( 2 ) ;
895895 } ) ;
896896
897+ it ( "recomputes quote counts when accepted quotes are retargeted" , async ( ) => {
898+ expect . assertions ( 6 ) ;
899+
900+ const author = await createAccount ( { username : "quote-author" } ) ;
901+ const oldPostId = crypto . randomUUID ( ) as Uuid ;
902+ const newPostId = crypto . randomUUID ( ) as Uuid ;
903+ const oldPostIri = `https://hollo.test/@quote-author/${ oldPostId } ` ;
904+ const newPostIri = `https://hollo.test/@quote-author/${ newPostId } ` ;
905+ const quotePostIri = "https://remote.test/@quoter/quote-retargeted" ;
906+ const sendActivity = vi . fn ( async ( ) => undefined ) ;
907+ const requestCtx = {
908+ ...ctx ,
909+ sendActivity,
910+ } as unknown as InboxContext < void > ;
911+
912+ await db . insert ( posts ) . values ( [
913+ {
914+ id : oldPostId ,
915+ iri : oldPostIri ,
916+ type : "Note" ,
917+ accountId : author . id as Uuid ,
918+ visibility : "public" ,
919+ quoteApprovalPolicy : "public" ,
920+ contentHtml : "<p>Old quoted post</p>" ,
921+ content : "Old quoted post" ,
922+ published : new Date ( ) ,
923+ } ,
924+ {
925+ id : newPostId ,
926+ iri : newPostIri ,
927+ type : "Note" ,
928+ accountId : author . id as Uuid ,
929+ visibility : "public" ,
930+ quoteApprovalPolicy : "public" ,
931+ contentHtml : "<p>New quoted post</p>" ,
932+ content : "New quoted post" ,
933+ published : new Date ( ) ,
934+ } ,
935+ ] ) ;
936+
937+ const oldRequest = new QuoteRequest ( {
938+ actor : new URL ( "https://remote.test/@quoter" ) ,
939+ object : new URL ( oldPostIri ) ,
940+ instrument : new Note ( {
941+ id : new URL ( quotePostIri ) ,
942+ attribution : new Person ( {
943+ id : new URL ( "https://remote.test/@quoter" ) ,
944+ name : "quoter" ,
945+ preferredUsername : "quoter" ,
946+ inbox : new URL ( "https://remote.test/@quoter/inbox" ) ,
947+ } ) ,
948+ quote : new URL ( oldPostIri ) ,
949+ to : new URL ( "https://www.w3.org/ns/activitystreams#Public" ) ,
950+ content : "<p>Remote quote</p>" ,
951+ } ) ,
952+ } ) ;
953+ const newRequest = new QuoteRequest ( {
954+ actor : new URL ( "https://remote.test/@quoter" ) ,
955+ object : new URL ( newPostIri ) ,
956+ instrument : new Note ( {
957+ id : new URL ( quotePostIri ) ,
958+ attribution : new Person ( {
959+ id : new URL ( "https://remote.test/@quoter" ) ,
960+ name : "quoter" ,
961+ preferredUsername : "quoter" ,
962+ inbox : new URL ( "https://remote.test/@quoter/inbox" ) ,
963+ } ) ,
964+ quote : new URL ( newPostIri ) ,
965+ to : new URL ( "https://www.w3.org/ns/activitystreams#Public" ) ,
966+ content : "<p>Remote quote retargeted</p>" ,
967+ } ) ,
968+ } ) ;
969+
970+ await onQuoteRequested ( requestCtx , oldRequest ) ;
971+ await onQuoteRequested ( requestCtx , newRequest ) ;
972+
973+ const quote = await db . query . posts . findFirst ( {
974+ where : eq ( posts . iri , quotePostIri ) ,
975+ } ) ;
976+ const oldPost = await db . query . posts . findFirst ( {
977+ where : eq ( posts . id , oldPostId ) ,
978+ } ) ;
979+ const newPost = await db . query . posts . findFirst ( {
980+ where : eq ( posts . id , newPostId ) ,
981+ } ) ;
982+ expect ( quote ?. quoteTargetId ) . toBe ( newPostId ) ;
983+ expect ( quote ?. quoteState ) . toBe ( "accepted" ) ;
984+ expect ( quote ?. quoteAuthorizationIri ) . toBe (
985+ `${ newPostIri } /quote_authorizations/${ quote ?. id } ` ,
986+ ) ;
987+ expect ( oldPost ?. quotesCount ) . toBe ( 0 ) ;
988+ expect ( newPost ?. quotesCount ) . toBe ( 1 ) ;
989+ expect ( sendActivity ) . toHaveBeenCalledTimes ( 2 ) ;
990+ } ) ;
991+
897992 it ( "rejects a private QuoteRequest from an approved follower" , async ( ) => {
898993 expect . assertions ( 4 ) ;
899994
0 commit comments