@@ -1034,43 +1034,47 @@ public function test_get_interaction_policy_invalid_value_returns_null() {
10341034 }
10351035
10361036 /**
1037- * Test that get_post_content_template falls back to constant when option is empty .
1037+ * Test get_post_content_template with various post types and reply scenarios .
10381038 *
1039- * @covers ::get_post_content_template
1040- */
1041- public function test_get_post_content_template_fallback_with_empty_option () {
1042- $ post = $ this ->create_test_post ();
1043-
1044- // Set object type to something other than wordpress-post-format.
1045- \update_option ( 'activitypub_object_type ' , 'Article ' );
1046-
1047- // Test with empty string option - should fall back to constant.
1048- \update_option ( 'activitypub_custom_post_content ' , '' );
1049-
1050- $ transformer = new Post ( $ post );
1051- $ reflection = new \ReflectionClass ( Post::class );
1052- $ method = $ reflection ->getMethod ( 'get_post_content_template ' );
1053- $ method ->setAccessible ( true );
1054-
1055- $ template = $ method ->invoke ( $ transformer );
1056-
1057- $ this ->assertSame ( ACTIVITYPUB_CUSTOM_POST_CONTENT , $ template , 'Empty option should fall back to ACTIVITYPUB_CUSTOM_POST_CONTENT constant. ' );
1058- }
1059-
1060- /**
1061- * Test that get_post_content_template uses option value when set.
1039+ * Tests how the template is generated for different post types (Article, Note)
1040+ * and reply configurations, as well as option fallback scenarios.
10621041 *
1042+ * @dataProvider wordpress_post_format_template_provider
10631043 * @covers ::get_post_content_template
1044+ *
1045+ * @param array $post_data The post data to create.
1046+ * @param string $expected_template The expected template string.
1047+ * @param string $object_type The activitypub_object_type option value.
1048+ * @param string|null $custom_post_content The activitypub_custom_post_content option value (null to delete).
1049+ * @param string $description Description of the test case.
10641050 */
1065- public function test_get_post_content_template_uses_option_when_set () {
1066- $ post = $ this ->create_test_post ();
1051+ public function test_get_post_content_template_with_scenarios ( $ post_data , $ expected_template , $ object_type , $ custom_post_content , $ description ) {
1052+ // Set object type.
1053+ \update_option ( 'activitypub_object_type ' , $ object_type );
10671054
1068- // Set object type to something other than wordpress-post-format.
1069- \update_option ( 'activitypub_object_type ' , 'Article ' );
1055+ // Set or delete custom post content option.
1056+ if ( null === $ custom_post_content ) {
1057+ \delete_option ( 'activitypub_custom_post_content ' );
1058+ } else {
1059+ \update_option ( 'activitypub_custom_post_content ' , $ custom_post_content );
1060+ }
1061+
1062+ // Mock mentions extraction if the post content contains mention patterns.
1063+ $ content = $ post_data ['post_content ' ] ?? '' ;
1064+ $ mentions_filter = null ;
1065+ if ( \preg_match ( '/@ ' . ACTIVITYPUB_USERNAME_REGEXP . '/i ' , $ content ) ) {
1066+ $ mentions_filter = function ( $ mentions , $ post_content ) {
1067+ // Extract all mention patterns from content.
1068+ \preg_match_all ( '/@ ' . ACTIVITYPUB_USERNAME_REGEXP . '/i ' , $ post_content , $ all_matches );
1069+ foreach ( $ all_matches [0 ] as $ match ) {
1070+ $ mentions [ $ match ] = 'https://example.com/ ' . \ltrim ( $ match , '@ ' );
1071+ }
1072+ return $ mentions ;
1073+ };
1074+ \add_filter ( 'activitypub_extract_mentions ' , $ mentions_filter , 10 , 2 );
1075+ }
10701076
1071- // Test with custom template option.
1072- $ custom_template = '[ap_title]\n\n[ap_content]\n\n[ap_hashtags] ' ;
1073- \update_option ( 'activitypub_custom_post_content ' , $ custom_template );
1077+ $ post = self ::factory ()->post ->create_and_get ( $ post_data );
10741078
10751079 $ transformer = new Post ( $ post );
10761080 $ reflection = new \ReflectionClass ( Post::class );
@@ -1079,79 +1083,109 @@ public function test_get_post_content_template_uses_option_when_set() {
10791083
10801084 $ template = $ method ->invoke ( $ transformer );
10811085
1082- $ this ->assertSame ( $ custom_template , $ template , 'Should use custom template option when set. ' );
1083- }
1084-
1085- /**
1086- * Test that get_post_content_template falls back with null option.
1087- *
1088- * @covers ::get_post_content_template
1089- */
1090- public function test_get_post_content_template_fallback_with_false_option () {
1091- $ post = $ this ->create_test_post ();
1092-
1093- // Set object type to something other than wordpress-post-format.
1094- \update_option ( 'activitypub_object_type ' , 'Article ' );
1095-
1096- // Test with false option (not set) - should fall back to constant.
1097- \delete_option ( 'activitypub_custom_post_content ' );
1098-
1099- $ transformer = new Post ( $ post );
1100- $ reflection = new \ReflectionClass ( Post::class );
1101- $ method = $ reflection ->getMethod ( 'get_post_content_template ' );
1102- $ method ->setAccessible ( true );
1086+ // Clean up mentions filter if it was added.
1087+ if ( $ mentions_filter ) {
1088+ \remove_filter ( 'activitypub_extract_mentions ' , $ mentions_filter , 10 );
1089+ }
11031090
1104- $ template = $ method ->invoke ( $ transformer );
1091+ // All wordpress-post-format templates should contain [ap_content].
1092+ if ( 'wordpress-post-format ' === $ object_type ) {
1093+ $ this ->assertStringContainsString ( '[ap_content] ' , $ template , $ description . ' - should contain [ap_content] ' );
1094+ }
11051095
1106- $ this ->assertSame ( ACTIVITYPUB_CUSTOM_POST_CONTENT , $ template , ' False option should fall back to ACTIVITYPUB_CUSTOM_POST_CONTENT constant. ' );
1096+ $ this ->assertSame ( $ expected_template , $ template , $ description );
11071097 }
11081098
11091099 /**
1110- * Test that get_post_content_template respects wordpress-post-format setting .
1100+ * Data provider for get_post_content_template tests with various scenarios .
11111101 *
1112- * @covers ::get_post_content_template
1102+ * @return array Each test case contains:
1103+ * - post_data: The post data to create
1104+ * - expected_template: The expected template string
1105+ * - object_type: The activitypub_object_type option value
1106+ * - custom_post_content: The activitypub_custom_post_content option value (null to delete)
1107+ * - description: Description of the test case
11131108 */
1114- public function test_get_post_content_template_wordpress_post_format () {
1115- // Create a post with long content and title (will be Article type).
1116- $ article_post = self ::factory ()->post ->create_and_get (
1117- array (
1118- 'post_title ' => 'Test Article ' ,
1119- 'post_content ' => str_repeat ( 'Long content. ' , 100 ),
1120- 'post_status ' => 'publish ' ,
1121- )
1122- );
1123-
1124- // Set custom content template.
1125- \update_option ( 'activitypub_custom_post_content ' , '[ap_title]\n\n[ap_content] ' );
1126-
1127- // Set post format setting to wordpress-post-format.
1128- \update_option ( 'activitypub_object_type ' , 'wordpress-post-format ' );
1129-
1130- $ transformer = new Post ( $ article_post );
1131- $ reflection = new \ReflectionClass ( Post::class );
1132- $ method = $ reflection ->getMethod ( 'get_post_content_template ' );
1133- $ method ->setAccessible ( true );
1134-
1135- $ template = $ method ->invoke ( $ transformer );
1136-
1137- // When wordpress-post-format is set, template should be generated based on post type.
1138- // For an Article (long content with title), it should just be [ap_content].
1139- $ this ->assertSame ( '[ap_content] ' , $ template , 'wordpress-post-format should override custom template for Article type. ' );
1140-
1141- // Test with a Note type (no title or short content).
1142- $ note_post = self ::factory ()->post ->create_and_get (
1143- array (
1144- 'post_title ' => '' ,
1145- 'post_content ' => 'Short note ' ,
1146- 'post_status ' => 'publish ' ,
1147- )
1109+ public function wordpress_post_format_template_provider () {
1110+ return array (
1111+ 'Article type ' => array (
1112+ array (
1113+ 'post_title ' => 'Test Article ' ,
1114+ 'post_content ' => str_repeat ( 'Long content. ' , 100 ),
1115+ 'post_status ' => 'publish ' ,
1116+ ),
1117+ '[ap_content] ' ,
1118+ 'wordpress-post-format ' ,
1119+ '[ap_title]\n\n[ap_content] ' ,
1120+ 'wordpress-post-format should override custom template for Article type. ' ,
1121+ ),
1122+ 'Note type without reply ' => array (
1123+ array (
1124+ 'post_title ' => '' ,
1125+ 'post_content ' => 'Short note ' ,
1126+ 'post_status ' => 'publish ' ,
1127+ ),
1128+ "[ap_title type= \"html \"] \n\n[ap_content] " ,
1129+ 'wordpress-post-format ' ,
1130+ '[ap_title]\n\n[ap_content] ' ,
1131+ 'wordpress-post-format should add title for Note type without reply. ' ,
1132+ ),
1133+ 'Note type with reply block ' => array (
1134+ array (
1135+ 'post_title ' => '' ,
1136+ 'post_content ' => '<!-- wp:activitypub/reply {"url":"https://example.com/posts/123"} /--> ' . PHP_EOL .
1137+ '<!-- wp:paragraph --><p>This is a reply note.</p><!-- /wp:paragraph --> ' ,
1138+ 'post_status ' => 'publish ' ,
1139+ ),
1140+ '[ap_content] ' ,
1141+ 'wordpress-post-format ' ,
1142+ '[ap_title]\n\n[ap_content] ' ,
1143+ 'wordpress-post-format should not add title for Note type when it is a reply. ' ,
1144+ ),
1145+ 'Note type with mentions ' => array (
1146+ array (
1147+ 'post_title ' => '' ,
1148+ 'post_content ' =>
'Short note mentioning @[email protected] ' ,
1149+ 'post_status ' => 'publish ' ,
1150+ ),
1151+ '[ap_content] ' ,
1152+ 'wordpress-post-format ' ,
1153+ null ,
1154+ 'wordpress-post-format should not add title for Note type when it has mentions. ' ,
1155+ ),
1156+ 'fallback_with_false_option ' => array (
1157+ array (
1158+ 'post_title ' => 'Interaction Policy Test ' ,
1159+ 'post_content ' => 'Content ' ,
1160+ 'post_status ' => 'publish ' ,
1161+ ),
1162+ ACTIVITYPUB_CUSTOM_POST_CONTENT ,
1163+ 'Article ' ,
1164+ null ,
1165+ 'False option should fall back to ACTIVITYPUB_CUSTOM_POST_CONTENT constant. ' ,
1166+ ),
1167+ 'uses_custom_option_when_set ' => array (
1168+ array (
1169+ 'post_title ' => 'Interaction Policy Test ' ,
1170+ 'post_content ' => 'Content ' ,
1171+ 'post_status ' => 'publish ' ,
1172+ ),
1173+ '[ap_title]\n\n[ap_content]\n\n[ap_hashtags] ' ,
1174+ 'Article ' ,
1175+ '[ap_title]\n\n[ap_content]\n\n[ap_hashtags] ' ,
1176+ 'Should use custom template option when set. ' ,
1177+ ),
1178+ 'fallback_with_empty_option ' => array (
1179+ array (
1180+ 'post_title ' => 'Interaction Policy Test ' ,
1181+ 'post_content ' => 'Content ' ,
1182+ 'post_status ' => 'publish ' ,
1183+ ),
1184+ ACTIVITYPUB_CUSTOM_POST_CONTENT ,
1185+ 'Article ' ,
1186+ '' ,
1187+ 'Empty activitypub_custom_post_content option should fall back to ACTIVITYPUB_CUSTOM_POST_CONTENT constant. ' ,
1188+ ),
11481189 );
1149-
1150- $ note_transformer = new Post ( $ note_post );
1151- $ note_template = $ method ->invoke ( $ note_transformer );
1152-
1153- // For a Note, the template should include the title.
1154- $ this ->assertStringContainsString ( '[ap_title type="html"] ' , $ note_template , 'wordpress-post-format should add title for Note type. ' );
1155- $ this ->assertStringContainsString ( '[ap_content] ' , $ note_template , 'wordpress-post-format should include content for Note type. ' );
11561190 }
11571191}
0 commit comments