|
19 | 19 | require_once __DIR__ . '/../../../../../../tests/notification/base.php'; |
20 | 20 | require_once __DIR__ . '/../../vendor/autoload.php'; // load the composer dependencies for this extension |
21 | 21 |
|
22 | | -/** |
23 | | - * @group slow |
24 | | - */ |
25 | 22 | class notification_method_webpush_test extends \phpbb_tests_notification_base |
26 | 23 | { |
27 | 24 | /** @var string[] VAPID keys for testing purposes */ |
@@ -648,6 +645,58 @@ public function test_get_type(): void |
648 | 645 | $this->assertEquals('notification.method.phpbb.wpn.webpush', $this->notification_method_webpush->get_type()); |
649 | 646 | } |
650 | 647 |
|
| 648 | + public function test_push_token_map_is_per_user(): void |
| 649 | + { |
| 650 | + // Verifies that when multiple users are notified about the same item, |
| 651 | + // each user's push token is stored and used independently. |
| 652 | + // Previously the map was keyed [type_id][item_id], so the last user's |
| 653 | + // token overwrote all others, making every other user's token invalid. |
| 654 | + $subscription_info = []; |
| 655 | + $expected_users = [2 => ['user_id' => '2'], 3 => ['user_id' => '3'], 4 => ['user_id' => '4']]; |
| 656 | + foreach ($expected_users as $user_id => $user_data) |
| 657 | + { |
| 658 | + $subscription_info[$user_id] = $this->create_subscription_for_user($user_id); |
| 659 | + } |
| 660 | + |
| 661 | + $post_data = [ |
| 662 | + 'post_time' => 1349413322, |
| 663 | + 'poster_id' => 1, |
| 664 | + 'topic_title' => '', |
| 665 | + 'post_subject' => '', |
| 666 | + 'post_username' => '', |
| 667 | + 'forum_name' => '', |
| 668 | + 'forum_id' => '1', |
| 669 | + 'post_id' => '2', |
| 670 | + 'topic_id' => '1', |
| 671 | + ]; |
| 672 | + |
| 673 | + $this->notifications->add_notifications('notification.type.post', $post_data); |
| 674 | + |
| 675 | + // Fetch the stored rows only for users we created subscriptions for |
| 676 | + $webpush_table = $this->container->getParameter('tables.phpbb.wpn.notification_push'); |
| 677 | + $sql = 'SELECT user_id, push_token FROM ' . $webpush_table . ' WHERE ' . $this->db->sql_in_set('user_id', array_keys($expected_users)) . ' ORDER BY user_id ASC'; |
| 678 | + $result = $this->db->sql_query($sql); |
| 679 | + $rows = $this->db->sql_fetchrowset($result); |
| 680 | + $this->db->sql_freeresult($result); |
| 681 | + |
| 682 | + $this->assertCount(count($expected_users), $rows, 'Each expected user must have a notification row'); |
| 683 | + $tokens = array_column($rows, 'push_token'); |
| 684 | + $this->assertEquals(count($tokens), count(array_unique($tokens)), 'Each user must have a unique push_token'); |
| 685 | + |
| 686 | + // Verify each message payload contains the token hashed with that specific user's salt |
| 687 | + foreach ($rows as $row) |
| 688 | + { |
| 689 | + $user_id = (int) $row['user_id']; |
| 690 | + $client_hash = basename($subscription_info[$user_id]['endpoint']); |
| 691 | + $messages = $this->get_messages_for_subscription($client_hash); |
| 692 | + $this->assertNotEmpty($messages); |
| 693 | + $payload = json_decode($messages[0], true); |
| 694 | + $user = $this->user_loader->get_user($user_id); |
| 695 | + $expected_token = hash('sha256', $user['user_form_salt'] . $row['push_token']); |
| 696 | + $this->assertEquals($expected_token, $payload['token'], 'Token in push payload must match hash of that user\'s salt + their own push_token'); |
| 697 | + } |
| 698 | + } |
| 699 | + |
651 | 700 | public function test_get_ucp_template_data_uses_millisecond_expiration_time(): void |
652 | 701 | { |
653 | 702 | $this->user->data['user_id'] = 2; |
|
0 commit comments