1
0
Fork 0
mirror of https://github.com/buddypress/buddypress.git synced 2026-07-21 20:54:17 +08:00
buddypress/tests/phpunit/testcases/notifications/functions.php
Boone B Gorges bcd37e29d3 Move notification-grouping logic to MySQL.
The notification-grouping logic required to show the collapsed Notifications
toolbar - "You have 3 pending friend requests", etc - is currently done in
PHP, in a manner that requires all notifications to be loaded into memory
and processed. On sites where users have large numbers of notifications, this
operation requires extensive resources. By leaving the grouping to MySQL,
we can speed up processing in almost all situations.

This changeset also adds specific caching for grouped notifications.

Props m_uysl.
See #7130.

git-svn-id: https://buddypress.svn.wordpress.org/trunk@11888 cdf35c40-ae34-48e0-9cc9-0c9da1808c22
2018-03-05 12:57:24 +00:00

435 lines
12 KiB
PHP

<?php
/**
* @group notifications
*/
class BP_Tests_Notifications_Functions extends BP_UnitTestCase {
/**
* @group cache
*/
public function test_cache_invalidation_all_for_user_on_save() {
$u = self::factory()->user->create();
self::factory()->notification->create( array(
'component_name' => 'groups',
'user_id' => $u
) );
self::factory()->notification->create( array(
'component_name' => 'messages',
'user_id' => $u,
'item_id' => 1
) );
// prime cache
$count = bp_notifications_get_unread_notification_count( $u );
// just to be sure...
$this->assertEquals( 2, $count, 'Cache count should be 2 before invalidation.' );
// Trigger invalidation via save
self::factory()->notification->create( array(
'component_name' => 'messages',
'user_id' => $u,
'item_id' => 2
) );
$this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) );
$this->assertFalse( wp_cache_get( $u, 'bp_notifications_unread_count' ) );
}
/**
* @group cache
*/
public function test_cache_invalidation_all_for_user_on_delete() {
$u = self::factory()->user->create();
$n1 = self::factory()->notification->create( array(
'component_name' => 'groups',
'user_id' => $u
) );
self::factory()->notification->create( array(
'component_name' => 'messages',
'user_id' => $u
) );
// prime cache
$count = bp_notifications_get_unread_notification_count( $u );
// just to be sure...
$this->assertEquals( 2, $count, 'Cache count should be 2 before invalidation.' );
// delete
BP_Notifications_Notification::delete( array( 'id' => $n1, ) );
$this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) );
$this->assertFalse( wp_cache_get( $u, 'bp_notifications_unread_count' ) );
}
/**
* @group cache
*/
public function test_cache_invalidation_all_for_user_on_update_user_id() {
$u = self::factory()->user->create();
self::factory()->notification->create( array(
'component_name' => 'groups',
'user_id' => $u
) );
self::factory()->notification->create( array(
'component_name' => 'messages',
'user_id' => $u
) );
// prime cache
$count = bp_notifications_get_unread_notification_count( $u );
// just to be sure...
$this->assertEquals( 2, $count, 'Cache count should be 2 before invalidation.' );
// mark all notifications by user as read
BP_Notifications_Notification::update(
array( 'is_new' => false ),
array( 'user_id' => $u )
);
$this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) );
$this->assertFalse( wp_cache_get( $u, 'bp_notifications_unread_count' ) );
}
/**
* @group cache
*/
public function test_cache_invalidation_all_for_user_on_update_id() {
$u = self::factory()->user->create();
$n1 = self::factory()->notification->create( array(
'component_name' => 'groups',
'user_id' => $u
) );
self::factory()->notification->create( array(
'component_name' => 'messages',
'user_id' => $u
) );
// prime cache
$count = bp_notifications_get_unread_notification_count( $u );
// just to be sure...
$this->assertEquals( 2, $count, 'Cache count should be 2 before invalidation.' );
// mark one notification as read
BP_Notifications_Notification::update(
array( 'is_new' => false ),
array( 'id' => $n1 )
);
$this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) );
$this->assertFalse( wp_cache_get( $u, 'bp_notifications_unread_count' ) );
}
/**
* @group bp_notifications_update_meta_cache
*/
public function test_bp_notifications_update_meta_cache() {
$u = self::factory()->user->create();
$n1 = self::factory()->notification->create( array(
'component_name' => 'messages',
'user_id' => $u
) );
$n2 = self::factory()->notification->create( array(
'component_name' => 'groups',
'user_id' => $u
) );
// Add cache for each notification.
bp_notifications_update_meta( $n1, 'meta', 'data' );
bp_notifications_update_meta( $n1, 'data', 'meta' );
bp_notifications_update_meta( $n2, 'meta', 'human' );
// Prime cache.
bp_notifications_get_meta( $n1, 'meta' );
// Ensure an empty cache for second notification.
wp_cache_delete( $n2, 'notification_meta' );
// Update notification meta cache.
bp_notifications_update_meta_cache( array( $n1, $n2 ) );
$expected = array(
$n1 => array(
'meta' => array(
'data',
),
'data' => array(
'meta',
),
),
$n2 => array(
'meta' => array(
'human',
),
),
);
$found = array(
$n1 => wp_cache_get( $n1, 'notification_meta' ),
$n2 => wp_cache_get( $n2, 'notification_meta' ),
);
$this->assertEquals( $expected, $found );
}
/**
* @group bp_notifications_add_notification
*/
public function test_bp_notifications_add_notification_no_dupes() {
$args = array(
'user_id' => 5,
'item_id' => 10,
'secondary_item_id' => 25,
'component_name' => 'messages',
'component_action' => 'new_message'
);
self::factory()->notification->create( $args );
$this->assertFalse( bp_notifications_add_notification( $args ) );
}
/**
* @group bp_notifications_add_notification
*/
public function test_bp_notifications_add_notification_allow_duplicate() {
$args = array(
'user_id' => 5,
'item_id' => 10,
'secondary_item_id' => 25,
'component_name' => 'messages',
'component_action' => 'new_message'
);
self::factory()->notification->create( $args );
$args['allow_duplicate'] = true;
$this->assertNotEmpty( bp_notifications_add_notification( $args ) );
}
/**
* @group bp_notifications_get_unread_notification_count
* @group cache
*/
public function test_bp_notifications_get_unread_notification_count_cache() {
$u1 = self::factory()->user->create();
$u2 = self::factory()->user->create();
self::factory()->notification->create( array(
'component_name' => 'messages',
'component_action' => 'new_message',
'item_id' => 99,
'user_id' => $u2,
'secondary_item_id' => $u1,
'is_new' => true
) );
// prime cache
bp_notifications_get_unread_notification_count( $u2 );
// mark the created notification as read
bp_notifications_mark_notifications_by_item_id( $u2, 99, 'messages', 'new_message', $u1 );
// now grab the updated notification count
$n = bp_notifications_get_unread_notification_count( $u2 );
// assert
$this->assertEquals( 0, $n );
}
/**
* @group bp_has_notifications
*/
public function test_bp_has_notifications_filtering() {
$u1 = self::factory()->user->create();
$u2 = self::factory()->user->create();
// create a mixture of different notifications
self::factory()->notification->create( array(
'component_name' => 'messages',
'component_action' => 'new_message',
'item_id' => 99,
'user_id' => $u2,
'secondary_item_id' => $u1,
'is_new' => true
) );
self::factory()->notification->create( array(
'component_name' => 'activity',
'component_action' => 'new_at_mention',
'item_id' => 99,
'user_id' => $u2,
'secondary_item_id' => $u1,
'is_new' => true
) );
self::factory()->notification->create( array(
'component_name' => 'activity',
'component_action' => 'new_at_mention',
'item_id' => 100,
'user_id' => $u2,
'secondary_item_id' => $u1,
'is_new' => true
) );
// now fetch only activity notifications
bp_has_notifications( array(
'component_name' => 'activity',
'user_id' => $u2
) );
// assert
$this->assertEquals( 2, buddypress()->notifications->query_loop->total_notification_count );
}
/**
* @group bp_notifications_delete_notifications_on_user_delete
* @ticket BP6681
*/
public function test_bp_notifications_delete_notifications_on_user_delete_should_delete_all_notifications() {
$u = self::factory()->user->create();
// Create notifications
$n1 = self::factory()->notification->create( array(
'component_name' => 'messages',
'component_action' => 'new_message',
'item_id' => 99,
'user_id' => $u,
) );
$n2 = self::factory()->notification->create( array(
'component_name' => 'activity',
'component_action' => 'new_at_mention',
'item_id' => 99,
'user_id' => $u,
) );
$n3 = self::factory()->notification->create( array(
'component_name' => 'groups',
'user_id' => $u,
) );
$n4 = self::factory()->notification->create( array(
'component_name' => 'friends',
'component_action' => 'friendship_request',
'user_id' => $u,
) );
// Create notification for non-core component
$n5 = self::factory()->notification->create( array(
'component_name' => 'foo',
'component_action' => 'bar',
'item_id' => 99,
'user_id' => $u,
) );
global $wpdb, $bp;
/**
* Can't use BP_Notifications_Notification::get(), because class::parse_args,
* checks against bp_notifications_get_registered_components()
* and if component is disabled it will be ignored.
*/
$query = $wpdb->prepare( "SELECT id FROM {$bp->notifications->table_name} WHERE user_id = %d and is_new = 1", $u );
// Make sure notifications have been added.
$found1 = $wpdb->get_col( $query );
$this->assertEqualSets( array( $n1, $n2, $n3, $n4, $n5 ), $found1 );
wp_delete_user( $u );
// Check if notifications are deleted.
$found2 = $wpdb->get_col( $query );
$this->assertEmpty( $found2 );
}
/**
* @group notification_callback
* @ticket BP7141
*/
public function test_notification_callback_parameter_integrity() {
$u = self::factory()->user->create();
$n = self::factory()->notification->create( array(
'component_name' => 'activity',
'component_action' => 'new_at_mention',
'item_id' => 99,
'user_id' => $u,
) );
// Override activity notification callback so we can test integrity.
buddypress()->activity->notification_callback = array( $this, 'dummy_notification_callback' );
// Fetch notifications with string format.
bp_notifications_get_notifications_for_user( $u, 'string' );
// Assert!
// @todo When we cast all numeric strings as integers, this needs to be changed.
$expected = array(
'action' => 'new_at_mention',
'item_id' => '99',
'secondary_item_id' => '0',
'total_items' => 1,
'id' => (string) $n,
'format' => 'string'
);
$this->assertEquals( $expected, $this->n_args );
// Fetch notifications with object format this time.
bp_notifications_get_notifications_for_user( $u, 'object' );
// Assert!
$expected['format'] = 'array';
$this->assertEquals( $expected, $this->n_args );
// Reset!
buddypress()->activity->notification_callback = 'bp_activity_format_notifications';
unset( $this->n_args );
}
/**
* Used in test_notification_callback_parameter_integrity() test.
*/
public function dummy_notification_callback( $action, $item_id, $secondary_item_id, $total_items, $format = 'string', $id = 0 ) {
$this->n_args = compact( 'action', 'item_id', 'secondary_item_id', 'total_items', 'id', 'format' );
}
/**
* @group cache
* @ticket BP7130
*/
public function test_get_grouped_notifications_for_user_cache_invalidation() {
$u = self::factory()->user->create();
$n1 = self::factory()->notification->create( array(
'component_name' => 'activity',
'component_action' => 'new_at_mention',
'item_id' => 99,
'user_id' => $u,
) );
// Prime cache.
$found = bp_notifications_get_grouped_notifications_for_user( $u );
$this->assertEquals( 1, $found[0]->total_count );
$n2 = self::factory()->notification->create( array(
'component_name' => 'activity',
'component_action' => 'new_at_mention',
'item_id' => 100,
'user_id' => $u,
) );
$found = bp_notifications_get_grouped_notifications_for_user( $u );
$this->assertEquals( 2, $found[0]->total_count );
}
}