Commit b7467fe43e6 for woocommerce

commit b7467fe43e6dc0ea2fcda5f748ce62a42ecf9d0f
Author: Hannah Tinkler <hannah.tinkler@gmail.com>
Date:   Fri Apr 24 15:24:04 2026 +0100

    Restructure review notification payload into title and message. (#64144)

    * Restructure review notification payload into title and message.

    - Move reviewer name and product name into the title format args.
    - Use the stripped review content as the message format.

diff --git a/plugins/woocommerce/src/Internal/PushNotifications/Notifications/NewReviewNotification.php b/plugins/woocommerce/src/Internal/PushNotifications/Notifications/NewReviewNotification.php
index 965e5a321d6..6c78fa56cc8 100644
--- a/plugins/woocommerce/src/Internal/PushNotifications/Notifications/NewReviewNotification.php
+++ b/plugins/woocommerce/src/Internal/PushNotifications/Notifications/NewReviewNotification.php
@@ -48,17 +48,19 @@ class NewReviewNotification extends Notification {
 			'timestamp'   => gmdate( 'c' ),
 			'resource_id' => $this->get_resource_id(),
 			'title'       => array(
-				'format' => 'You have a new review! ⭐️',
-			),
-			'message'     => array(
 				/**
 				 * This will be translated in WordPress.com, format:
-				 * 1: reviewer name, 2: product name, 3: comment content
+				 * 1: reviewer name, 2: product name
 				 */
-				'format' => '%1$s left a review on %2$s: %3$s',
+				'format' => '%1$s left a review on %2$s',
 				'args'   => array(
 					wp_strip_all_tags( $comment->comment_author ),
 					wp_strip_all_tags( get_the_title( (int) $comment->comment_post_ID ) ),
+				),
+			),
+			'message'     => array(
+				'format' => '%1$s',
+				'args'   => array(
 					wp_strip_all_tags( $comment->comment_content ),
 				),
 			),
diff --git a/plugins/woocommerce/tests/php/src/Internal/PushNotifications/Notifications/NewReviewNotificationTest.php b/plugins/woocommerce/tests/php/src/Internal/PushNotifications/Notifications/NewReviewNotificationTest.php
index 16d9e6f31b7..f920a60ce39 100644
--- a/plugins/woocommerce/tests/php/src/Internal/PushNotifications/Notifications/NewReviewNotificationTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/PushNotifications/Notifications/NewReviewNotificationTest.php
@@ -27,6 +27,7 @@ class NewReviewNotificationTest extends WC_Unit_Test_Case {
 		$this->assertArrayHasKey( 'resource_id', $payload );
 		$this->assertArrayHasKey( 'title', $payload );
 		$this->assertArrayHasKey( 'format', $payload['title'] );
+		$this->assertArrayHasKey( 'args', $payload['title'] );
 		$this->assertArrayHasKey( 'message', $payload );
 		$this->assertArrayHasKey( 'format', $payload['message'] );
 		$this->assertArrayHasKey( 'args', $payload['message'] );
@@ -54,10 +55,10 @@ class NewReviewNotificationTest extends WC_Unit_Test_Case {
 	}

 	/**
-	 * @testdox Should include the reviewer name, product name, and review
-	 * content in the message args.
+	 * @testdox Should include the reviewer name and product name in the title args,
+	 * and the review content in the message args.
 	 */
-	public function test_to_payload_message_args_contains_expected_values(): void {
+	public function test_to_payload_splits_review_details_between_title_and_message(): void {
 		$product    = WC_Helper_Product::create_simple_product();
 		$comment_id = WC_Helper_Product::create_product_review( $product->get_id() );
 		$comment    = get_comment( $comment_id );
@@ -65,14 +66,14 @@ class NewReviewNotificationTest extends WC_Unit_Test_Case {
 		$notification = new NewReviewNotification( $comment_id );
 		$payload      = $notification->to_payload();

-		$this->assertSame( $comment->comment_author, $payload['message']['args'][0] );
-		$this->assertSame( $product->get_name(), $payload['message']['args'][1] );
-		$this->assertSame( $comment->comment_content, $payload['message']['args'][2] );
+		$this->assertSame( $comment->comment_author, $payload['title']['args'][0] );
+		$this->assertSame( $product->get_name(), $payload['title']['args'][1] );
+		$this->assertSame( $comment->comment_content, $payload['message']['args'][0] );
 	}

 	/**
 	 * @testdox Should strip HTML tags, and script tags including content, from
-	 * reviewer name in message args.
+	 * reviewer name in title args.
 	 */
 	public function test_to_payload_strips_html_and_script_content_from_comment_author(): void {
 		$product    = WC_Helper_Product::create_simple_product();
@@ -90,12 +91,12 @@ class NewReviewNotificationTest extends WC_Unit_Test_Case {
 		$notification = new NewReviewNotification( $comment_id );
 		$payload      = $notification->to_payload();

-		$this->assertSame( 'Evil Author', $payload['message']['args'][0] );
+		$this->assertSame( 'Evil Author', $payload['title']['args'][0] );
 	}

 	/**
 	 * @testdox Should strip HTML tags, and script tags including content, from
-	 * review content in message args.
+	 * review content in the message args.
 	 */
 	public function test_to_payload_strips_html_and_script_content_from_comment_content(): void {
 		$product    = WC_Helper_Product::create_simple_product();
@@ -113,7 +114,37 @@ class NewReviewNotificationTest extends WC_Unit_Test_Case {
 		$notification = new NewReviewNotification( $comment_id );
 		$payload      = $notification->to_payload();

-		$this->assertSame( 'Great product!', $payload['message']['args'][2] );
+		$this->assertSame( 'Great product!', $payload['message']['args'][0] );
+	}
+
+	/**
+	 * @testdox Should preserve percent signs in review content so downstream
+	 * sprintf-style formatting doesn't break.
+	 */
+	public function test_to_payload_preserves_percent_signs_in_review_content(): void {
+		$product    = WC_Helper_Product::create_simple_product();
+		$content    = 'Works 100% great %1$s';
+		$comment_id = wp_insert_comment(
+			array(
+				'comment_post_ID'      => $product->get_id(),
+				'comment_author'       => 'Reviewer',
+				'comment_author_email' => 'test@test.local',
+				'comment_content'      => $content,
+				'comment_approved'     => 1,
+				'comment_type'         => 'review',
+			)
+		);
+
+		$notification = new NewReviewNotification( $comment_id );
+		$payload      = $notification->to_payload();
+
+		$this->assertSame( $content, $payload['message']['args'][0] );
+		$this->assertSame(
+			$content,
+			vsprintf( $payload['message']['format'], $payload['message']['args'] )
+		);
+		$this->assertSame( 'Reviewer', $payload['title']['args'][0] );
+		$this->assertSame( $product->get_name(), $payload['title']['args'][1] );
 	}

 	/**