Skip to content

Commit b2e14e9

Browse files
akirkpfefferle
andauthored
Add test for HTML in direct messages (#1093)
Co-authored-by: Matthias Pfefferle <[email protected]>
1 parent ac4d591 commit b2e14e9

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Improved
11+
12+
* Direct Messages: Improve HTML to e-mail text conversion
13+
814
## [4.5.1] - 2024-12-18
915

1016
### Improved

includes/class-mailer.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,17 @@ public static function direct_message( $activity, $user_id ) {
171171
$email = $user->user_email;
172172
}
173173

174+
$content = \html_entity_decode(
175+
\wp_strip_all_tags(
176+
str_replace( '</p>', PHP_EOL . PHP_EOL, $activity['object']['content'] )
177+
),
178+
ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
179+
);
180+
174181
/* translators: 1: Blog name, 2 Actor name */
175182
$subject = \sprintf( \esc_html__( '[%1$s] Direct Message from: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), \esc_html( $actor['name'] ) );
176183
/* translators: 1: Blog name, 2: Actor name */
177-
$message = \sprintf( \esc_html__( 'New Direct Message: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), \wp_strip_all_tags( $activity['object']['content'] ) ) . "\r\n\r\n";
184+
$message = \sprintf( \esc_html__( 'New Direct Message: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), $content ) . "\r\n\r\n";
178185
/* translators: Actor name */
179186
$message .= \sprintf( \esc_html__( 'From: %s', 'activitypub' ), \esc_html( $actor['name'] ) ) . "\r\n";
180187
/* translators: Actor URL */

readme.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ For reasons of data protection, it is not possible to see the followers of other
132132

133133
== Changelog ==
134134

135+
= Unreleased =
136+
137+
* Improved: HTML to e-mail text conversion
138+
135139
= 4.5.1 =
136140

137141
* Improved: Reactions block: Remove the `wp-block-editor` dependency for frontend views

tests/includes/class-test-mailer.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,70 @@ function ( $args ) {
307307
remove_all_filters( 'wp_mail' );
308308
wp_delete_user( $user_id );
309309
}
310+
311+
/**
312+
* Data provider for direct message notification text.
313+
*
314+
* @return array
315+
*/
316+
public function direct_message_text_provider() {
317+
return array(
318+
'HTML entities' => array(
319+
json_decode( '"<p>Interesting story from <span class=\"h-card\" translate=\"no\"><a href=\"https:\/\/example.com\/@test\" class=\"u-url mention\">@<span>test<\/span><\/a><\/span> about people who don&#39;t own their own domain.<\/p><p>&quot;This is not a new issue, of course, but Service\u2019s implementation shows limitations.&quot;<\/p>"' ),
320+
'Interesting story from @test about people who don\'t own their own domain.' . PHP_EOL . PHP_EOL . '"This is not a new issue, of course, but Service’s implementation shows limitations."',
321+
),
322+
'invalid HTML' => array(
323+
json_decode( '"<ptest"' ),
324+
'',
325+
),
326+
);
327+
}
328+
329+
/**
330+
* Test direct message notification text.
331+
*
332+
* @param string $text Text to test.
333+
* @param string $expected Expected result.
334+
*
335+
* @covers ::direct_message
336+
* @dataProvider direct_message_text_provider
337+
*/
338+
public function test_direct_message_text( $text, $expected ) {
339+
$user_id = self::$user_id;
340+
341+
$activity = array(
342+
'actor' => 'https://example.com/author',
343+
'object' => array(
344+
'content' => $text,
345+
),
346+
);
347+
348+
// Mock remote metadata.
349+
add_filter(
350+
'pre_get_remote_metadata_by_actor',
351+
function () {
352+
return array(
353+
'name' => 'Test Sender',
354+
'url' => 'https://example.com/author',
355+
);
356+
}
357+
);
358+
359+
// Capture email.
360+
add_filter(
361+
'wp_mail',
362+
function ( $args ) use ( $expected, $user_id ) {
363+
$this->assertStringContainsString( $expected, $args['message'] );
364+
$this->assertEquals( get_user_by( 'id', $user_id )->user_email, $args['to'] );
365+
return $args;
366+
}
367+
);
368+
369+
Mailer::direct_message( $activity, $user_id );
370+
371+
// Clean up.
372+
remove_all_filters( 'pre_get_remote_metadata_by_actor' );
373+
remove_all_filters( 'wp_mail' );
374+
wp_delete_user( $user_id );
375+
}
310376
}

0 commit comments

Comments
 (0)