BREAKING CHANGE: Change $wgEchoDefaultNotificationTypes to be logical

Merge and deploy at the *same time* as:
* BounceHandler - I3c669945080d8e1f67880bd8a31af7f88a70904d
* mediawiki-config - I13817c139967ed9e230cfb0c87c5de66da793c96

Despite claiming to be about categories, $wgEchoDefaultNotificationTypes
was actually configuring both categories and types (which go inside
categories).

For example, 'thank-you-edit' is a type, but 'emailuser' is both
a category and a type (when used as a category, this has special
effects at Special:Preferences).

Since types and categories can and sometimes do have the same names,
this leaves no way to properly and clearly configure them.  It also
makes it difficult to document what is going on (as required by
T132127).

Split into three variables:

$wgDefaultNotifyTypeAvailability - Applies unless overriden

$wgNotifyTypeAvailabilityByCategory - By category; this can be and is
displayed at Special:Preferences

$wgNotifyTypeAvailabilityByNotificationType - By type; this cannot
be displayed at Special:Preferences. To avoid confusing the user,
we introduce a restriction (which was previously followed in practice,
AFAICT) that types can only be overridden if the category is not
displayed in preferences.

Otherwise, it can look to the user like a category is on/off, but the
types within might have the opposite state.

Due to this configuration change, this is a breaking change, and needs
coordinated deployments.

This also lays the groundwork for T132127

Also change terminology to consistently use "notify type" for web/email.

It was mixing between that and output format (which unfortunately
sounds like the API format, e.g. 'model').

Bug: T132820
Bug: T132127
Change-Id: I09f39f5fc5f13f3253af9f7819bca81f1601da93
This commit is contained in:
Matthew Flaschen 2016-04-18 22:54:15 -04:00 committed by Roan Kattouw
parent b50f1dfa0e
commit 5ecc6aa7c8
7 changed files with 425 additions and 79 deletions

View file

@ -171,21 +171,19 @@ $wgEchoShowFooterNotice = false;
// notification popup
$wgEchoFooterNoticeURL = '';
// Define which output formats are available for each notification category
$wgEchoDefaultNotificationTypes = array(
'all' => array(
'web' => true,
'email' => true,
),
// Only send web notification for welcome event
'welcome' => array(
'email' => false,
),
// … and for edit threshold events
'thank-you-edit' => array(
'email' => false,
),
// No need to get a email when another user sends to me
// Allowed notify types for all notifications and categories, unless overriden
// on a per-category or per-type basis.
// All of the keys from $wgEchoNotifiers must also be keys here.
$wgDefaultNotifyTypeAvailability = array(
'web' => true,
'email' => true,
);
// Define which notify types are available for each notification category
// If any notify types are omitted, it defaults to $wgDefaultNotifyTypeAvailability.
$wgNotifyTypeAvailabilityByCategory = array(
// Otherwise, a user->user email could trigger an additional redundant
// notification email.
'emailuser' => array(
'web' => true,
'email' => false,
@ -219,20 +217,26 @@ $wgEchoPerUserWhitelistFormat = '%s/Echo-whitelist';
$wgEchoUseCrossWikiBetaFeature = false;
// Define the categories that notifications can belong to. Categories can be
// assigned the following parameters: priority, nodismiss, tooltip, and usergroups.
// assigned the following parameters: priority, no-dismiss, tooltip, and usergroups.
// All parameters are optional.
// If a notifications type doesn't have a category parameter, it is
// automatically assigned to the 'other' category which is lowest priority and
// has no preferences or dismissibility.
// The priority parameter controls the order in which notifications are
// displayed in preferences and batch emails. Priority ranges from 1 to 10. If
// the priority is not specified, it defaults to 10, which is the lowest.
// The usergroups param specifies an array of usergroups eligible to recieve the
// notifications in the category. If no usergroups parameter is specified, all
// groups are eligible.
// The nodismiss parameter disables the dismissability of notifications in the
// category. It can either be set to an array of output formats (see
// $wgEchoNotifiers) or an array containing 'all'.
// The no-dismiss parameter disables the dismissability of notifications in the
// category. It can either be set to an array of notify types (see
// $wgEchoNotifiers) or an array containing 'all'. If no-dismiss is 'all',
// it will not appear in preferences.
$wgEchoNotificationCategories = array(
'system' => array(
'priority' => 9,
@ -326,6 +330,19 @@ $wgEchoNotificationIcons = array(
// Definitions of the notification event types built into Echo.
// If formatter-class isn't specified, defaults to EchoBasicFormatter.
// 'notify-type-availabilty' - Defines which notifier (e.g. web/email) types are available
// for each notification type (e.g. welcome). Notification types are the keys of
// $wgEchoNotificationCategories.
// This is *ONLY* considered if the category is 'no-dismiss'. Otherwise,
// use $wgNotifyTypeAvailabilityByCategory
// Without this constraint, we would have no way to display this information
// on Special:Preferences in a non-misleading way.
// If any notify types are omitted, it defaults to $wgNotifyTypeAvailabilityByCategory
// which itself defaults to $wgDefaultNotifyTypeAvailability.
$wgEchoNotifications = array(
'welcome' => array(
EchoAttributeManager::ATTR_LOCATORS => array(
@ -334,6 +351,10 @@ $wgEchoNotifications = array(
'category' => 'system',
'group' => 'positive',
'section' => 'alert',
// Only send web notification for welcome event
'notify-type-availability' => array(
'email' => false,
),
'presentation-model' => 'EchoWelcomePresentationModel',
'title-message' => 'notification-new-user',
'title-params' => array( 'agent' ),
@ -468,6 +489,10 @@ $wgEchoNotifications = array(
'EchoUserLocator::locateEventAgent'
),
'category' => 'system',
// Only send 'web' notification
'notify-type-availability' => array(
'email' => false,
),
'group' => 'positive',
'presentation-model' => 'EchoEditThresholdPresentationModel',
'section' => 'alert',

View file

@ -247,11 +247,13 @@ class EchoHooks {
* @return bool true in all cases
*/
public static function getPreferences( $user, &$preferences ) {
global $wgEchoDefaultNotificationTypes, $wgAuth, $wgEchoEnableEmailBatch,
global $wgAuth, $wgEchoEnableEmailBatch,
$wgEchoNotifiers, $wgEchoNotificationCategories, $wgEchoNotifications,
$wgEchoNewMsgAlert, $wgAllowHTMLEmail, $wgEchoUseCrossWikiBetaFeature,
$wgEchoShowFooterNotice;
$attributeManager = EchoAttributeManager::newFromGlobalVars();
// Show email frequency options
$never = wfMessage( 'echo-pref-email-frequency-never' )->plain();
$immediately = wfMessage( 'echo-pref-email-frequency-immediately' )->plain();
@ -316,13 +318,12 @@ class EchoHooks {
// Sort notification categories by priority
$categoriesAndPriorities = array();
foreach ( $wgEchoNotificationCategories as $category => $categoryData ) {
// See if the category is not dismissable at all. Must do strict
// comparison to true since no-dismiss can also be an array
if ( isset( $categoryData['no-dismiss'] ) && in_array( 'all', $categoryData['no-dismiss'] ) ) {
foreach ( $attributeManager->getInternalCategoryNames() as $category ) {
// See if the category should be hidden from preferences.
if ( !$attributeManager->isCategoryDisplayedInPreferences( $category ) ) {
continue;
}
$attributeManager = EchoAttributeManager::newFromGlobalVars();
// See if user is eligible to recieve this notification (per user group restrictions)
if ( $attributeManager->getCategoryEligibility( $user, $category ) ) {
$categoriesAndPriorities[$category] = $attributeManager->getCategoryPriority( $category );
@ -339,7 +340,7 @@ class EchoHooks {
// new wikis or Echo is disabled and re-enabled for some reason. We can update the name
// if Echo is ever merged to core
// Build the columns (output formats)
// Build the columns (notify types)
$columns = array();
foreach ( $wgEchoNotifiers as $notifierType => $notifierData ) {
$formatMessage = wfMessage( 'echo-pref-' . $notifierType )->escaped();
@ -361,19 +362,12 @@ class EchoHooks {
$forceOptionsOff = $forceOptionsOn = array();
foreach ( $wgEchoNotifiers as $notifierType => $notifierData ) {
foreach ( $validSortedCategories as $category ) {
// See if this output format is non-dismissable
if ( isset( $wgEchoNotificationCategories[$category]['no-dismiss'] )
&& in_array( $notifierType, $wgEchoNotificationCategories[$category]['no-dismiss'] )
) {
// See if this notify type is non-dismissable
if ( !$attributeManager->isNotifyTypeDismissableForCategory( $category, $notifierType ) ) {
$forceOptionsOn[] = "$notifierType-$category";
}
// Make sure this output format is possible for this notification category
if ( isset( $wgEchoDefaultNotificationTypes[$category] ) ) {
if ( !$wgEchoDefaultNotificationTypes[$category][$notifierType] ) {
$forceOptionsOff[] = "$notifierType-$category";
}
} elseif ( !$wgEchoDefaultNotificationTypes['all'][$notifierType] ) {
if ( !$attributeManager->isNotifyTypeAvailableForCategory( $category, $notifierType ) ) {
$forceOptionsOff[] = "$notifierType-$category";
}
}
@ -569,6 +563,22 @@ class EchoHooks {
return true;
}
/**
* Get overrides for new users. This allows changes that only apply going forward,
* without affecting existing users.
*
* @return Associative array mapping key to boolean for whether it should be enabled
*/
public static function getNewUserPreferenceOverrides() {
return array(
'echo-subscriptions-web-reverted' => false,
'echo-subscriptions-email-reverted' => false,
'echo-subscriptions-web-article-linked' => true,
'echo-subscriptions-email-mention' => true,
'echo-subscriptions-email-article-linked' => true,
);
}
/**
* Handler for AddNewAccount hook.
* @see http://www.mediawiki.org/wiki/Manual:Hooks/AddNewAccount
@ -577,13 +587,11 @@ class EchoHooks {
* @return bool
*/
public static function onAccountCreated( $user, $byEmail ) {
$overrides = self::getNewUserPreferenceOverrides();
foreach ( $overrides as $prefKey => $value ) {
$user->setOption( $prefKey, $value );
}
// new users get echo preferences set that are not the default settings for existing users
$user->setOption( 'echo-subscriptions-web-reverted', false );
$user->setOption( 'echo-subscriptions-email-reverted', false );
$user->setOption( 'echo-subscriptions-web-article-linked', true );
$user->setOption( 'echo-subscriptions-email-mention', true );
$user->setOption( 'echo-subscriptions-email-article-linked', true );
$user->saveSettings();
EchoEvent::create( array(

View file

@ -1,3 +1,11 @@
April, 2016
-----------
* BREAKING CHANGE: $wgEchoDefaultNotificationTypes has been split into
three variables. See Echo.php for documentation:
** $wgDefaultNotifyTypeAvailability
** $wgNotifyTypeAvailabilityByCategory
** $wgEchoNotifications[$notificationType]['notify-type-availability']
March, 2015
-----------

View file

@ -16,6 +16,26 @@ class EchoAttributeManager {
*/
protected $categories;
/**
* @var array
*/
protected $defaultNotifyTypeAvailability;
/**
* @var array
*/
protected $notifyTypeAvailabilityByCategory;
/**
* @var array
*/
protected $dismissabilityByCategory;
/**
* @var array
*/
protected $notifiers;
/**
* Notification section constant
*/
@ -45,13 +65,27 @@ class EchoAttributeManager {
protected static $globalVarInstance = null;
/**
* @param array $notifications notification attributes
* @param array $categories notification categories
* @param array $notifications Notification attributes
* @param array $categories Notification categories
* @param array $defaultNotifyTypeAvailability Associative array with output
* formats as keys and whether they are available as boolean values.
* @param array $notifyTypeAvailabilityByCategory Associative array with
* categories as keys and value an associative array as with
* $defaultNotifyTypeAvailability.
* @param array $notifiers Associative array mapping notify types to notifier
* that handles them
*/
public function __construct( array $notifications, array $categories ) {
public function __construct( array $notifications, array $categories, array $defaultNotifyTypeAvailability, array $notifyTypeAvailabilityByCategory, array $notifiers ) {
// Extensions can define their own notifications and categories
$this->notifications = $notifications;
$this->categories = $categories;
$this->defaultNotifyTypeAvailability = $defaultNotifyTypeAvailability;
$this->notifyTypeAvailabilityByCategory = $notifyTypeAvailabilityByCategory;
$this->dismissabilityByCategory = null;
$this->notifiers = $notifiers;
}
/**
@ -59,17 +93,20 @@ class EchoAttributeManager {
* @return EchoAttributeManager
*/
public static function newFromGlobalVars() {
global $wgEchoNotifications, $wgEchoNotificationCategories;
global $wgEchoNotifications, $wgEchoNotificationCategories, $wgDefaultNotifyTypeAvailability, $wgNotifyTypeAvailabilityByCategory, $wgEchoNotifiers;
// Unit test may alter the global data for test purpose
if ( defined( 'MW_PHPUNIT_TEST' ) ) {
return new self( $wgEchoNotifications, $wgEchoNotificationCategories );
return new self( $wgEchoNotifications, $wgEchoNotificationCategories, $wgDefaultNotifyTypeAvailability, $wgNotifyTypeAvailabilityByCategory, $wgEchoNotifiers );
}
if ( self::$globalVarInstance === null ) {
self::$globalVarInstance = new self(
$wgEchoNotifications,
$wgEchoNotificationCategories
$wgEchoNotificationCategories,
$wgDefaultNotifyTypeAvailability,
$wgNotifyTypeAvailabilityByCategory,
$wgEchoNotifiers
);
}
@ -98,7 +135,7 @@ class EchoAttributeManager {
* @param string web/email
* @return string[]
*/
public function getUserEnabledEvents( User $user, $outputFormat ) {
public function getUserEnabledEvents( User $user, $notifyType ) {
$eventTypesToLoad = $this->notifications;
foreach ( $eventTypesToLoad as $eventType => $eventData ) {
$category = $this->getNotificationCategory( $eventType );
@ -106,7 +143,7 @@ class EchoAttributeManager {
if ( !$this->getCategoryEligibility( $user, $category ) ) {
unset( $eventTypesToLoad[$eventType] );
}
if ( !$user->getOption( 'echo-subscriptions-' . $outputFormat . '-' . $category ) ) {
if ( !$user->getOption( 'echo-subscriptions-' . $notifyType . '-' . $category ) ) {
unset( $eventTypesToLoad[$eventType] );
}
}
@ -122,7 +159,7 @@ class EchoAttributeManager {
* @param string[]
* @return string[]
*/
public function getUserEnabledEventsbySections( User $user, $outputFormat, array $sections ) {
public function getUserEnabledEventsbySections( User $user, $notifyType, array $sections ) {
$events = array();
foreach ( $sections as $section ) {
$events = array_merge(
@ -134,7 +171,7 @@ class EchoAttributeManager {
}
return array_intersect(
$this->getUserEnabledEvents( $user, $outputFormat ),
$this->getUserEnabledEvents( $user, $notifyType ),
$events
);
}
@ -177,6 +214,15 @@ class EchoAttributeManager {
return $events;
}
/**
* Gets array of internal category names
*
* @return All internal names
*/
public function getInternalCategoryNames() {
return array_keys( $this->categories );
}
/**
* See if a user is eligible to recieve a certain type of notification
* (based on user groups, not user preferences)
@ -244,6 +290,81 @@ class EchoAttributeManager {
return 'other';
}
/**
* Gets an associative array mapping categories to the notification types in
* the category
*
* @return array Associative array with category as key
*/
public function getEventsByCategory() {
$eventsByCategory = array();
foreach ( $this->categories as $category => $categoryDetails ) {
$eventsByCategory[$category] = array();
}
foreach ( $this->notifications as $notificationType => $notificationDetails ) {
$category = $notificationDetails['category'];
if ( isset( $eventsByCategory[$category] ) ) {
// Only real categories. Currently, this excludes the 'foreign'
// psuedo-category.
$eventsByCategory[$category][] = $notificationType;
}
}
return $eventsByCategory;
}
/**
* Checks whether the specified notify type is available for the specified
* category.
*
* This means whether users *can* turn notifications for this category and format
* on, regardless of the default or a particular user's preferences.
*
* @param string $category Category name
* @param string $notifyType notify type, e.g. email/web.
*/
public function isNotifyTypeAvailableForCategory( $category, $notifyType ) {
if ( isset( $this->notifyTypeAvailabilityByCategory[$category][$notifyType] ) ) {
return $this->notifyTypeAvailabilityByCategory[$category][$notifyType];
} else {
return $this->defaultNotifyTypeAvailability[$notifyType];
}
}
/**
* Checks whether category is displayed in preferences
*
* @param string $category Category name
*/
public function isCategoryDisplayedInPreferences( $category ) {
return !(
isset( $this->categories[$category]['no-dismiss'] ) &&
in_array( 'all', $this->categories[$category]['no-dismiss'] )
);
}
/**
* Checks whether the specified notify type is dismissable for the specified
* category.
*
* This means whether the user is allowed to opt out of receiving notifications
* for this category and format.
*
* @param string $category Name of category
* @param string $notifyType notify type, e.g. email/web.
*/
public function isNotifyTypeDismissableForCategory( $category, $notifyType ) {
return !(
isset( $this->categories[$category]['no-dismiss'] ) &&
(
in_array( 'all', $this->categories[$category]['no-dismiss'] ) ||
in_array( $notifyType, $this->categories[$category]['no-dismiss'] )
)
);
}
/**
* Get notification section for a notification type
* @todo add a unit test case

View file

@ -141,22 +141,38 @@ class EchoNotificationController {
}
/**
* @param string $type Event type
* @return string[] List of notification types to send for
* Get the notify types for this event, eg, web/email
*
* @param string $eventType Event type
* @return string[] List of notify types that apply for
* this event type
*/
public static function getEventNotifyTypes( $type ) {
// Get the notification types for this event, eg, web/email
global $wgEchoDefaultNotificationTypes;
public static function getEventNotifyTypes( $eventType ) {
global $wgDefaultNotifyTypeAvailability,
$wgEchoNotifications;
$notifyTypes = $wgEchoDefaultNotificationTypes['all'];
if ( isset( $wgEchoDefaultNotificationTypes[$type] ) ) {
$notifyTypes = array();
$attributeManager = EchoAttributeManager::newFromGlobalVars();
$category = $attributeManager->getNotificationCategory( $eventType );
// If the category is displayed in preferences, we should go by that, rather
// than overrides that are inconsistent with what the user saw in preferences.
$isTypeSpecificConsidered = !$attributeManager->isCategoryDisplayedInPreferences(
$category
);
$notifyTypes = $wgDefaultNotifyTypeAvailability;
if ( $isTypeSpecificConsidered && isset( $wgEchoNotifications[$eventType]['notify-type-availability'] ) ) {
$notifyTypes = array_merge(
$notifyTypes,
$wgEchoDefaultNotificationTypes[$type]
$wgEchoNotifications[$eventType]['notify-type-availability']
);
}
// Category settings for availability are considered in EchoNotifier
return array_keys( array_filter( $notifyTypes ) );
}

View file

@ -55,7 +55,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
* @dataProvider getUserLocatorsProvider
*/
public function testGetUserLocators( $message, $expect, $type, $notifications ) {
$manager = new EchoAttributeManager( $notifications, array() );
$manager = new EchoAttributeManager( $notifications, array(), array(), array(), array() );
$result = $manager->getUserCallable( $type, EchoAttributeManager::ATTR_LOCATORS );
$this->assertEquals( $expect, $result, $message );
@ -72,7 +72,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
'priority' => 10
)
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertTrue( $manager->getCategoryEligibility( $this->mockUser(), 'category_one' ) );
$category = array(
'category_one' => array(
@ -82,7 +82,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
)
)
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertFalse( $manager->getCategoryEligibility( $this->mockUser(), 'category_one' ) );
}
@ -97,10 +97,10 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
'priority' => 10
)
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertEquals( $manager->getNotificationCategory( 'event_one' ), 'category_one' );
$manager = new EchoAttributeManager( $notif, array() );
$manager = new EchoAttributeManager( $notif, array(), array(), array(), array() );
$this->assertEquals( $manager->getNotificationCategory( 'event_one' ), 'other' );
$notif = array(
@ -113,7 +113,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
'priority' => 10
)
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertEquals( $manager->getNotificationCategory( 'event_one' ), 'other' );
}
@ -135,7 +135,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
),
'category_four' => array()
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertEquals( 6, $manager->getCategoryPriority( 'category_one' ) );
$this->assertEquals( 10, $manager->getCategoryPriority( 'category_two' ) );
$this->assertEquals( 10, $manager->getCategoryPriority( 'category_three' ) );
@ -169,7 +169,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
),
'category_four' => array()
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertEquals( 6, $manager->getNotificationPriority( 'event_one' ) );
$this->assertEquals( 10, $manager->getNotificationPriority( 'event_two' ) );
$this->assertEquals( 10, $manager->getNotificationPriority( 'event_three' ) );
@ -198,7 +198,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
'priority' => 6
)
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertEquals( $manager->getMessageEvents(), array( 'event_one', 'event_three' ) );
}
@ -224,7 +224,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
'priority' => 6
)
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertEquals( $manager->getAlertEvents(), array( 'event_two', 'event_three', 'event_four' ) );
}
@ -257,7 +257,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
'priority' => 10,
),
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$this->assertEquals( $manager->getUserEnabledEvents( $this->mockUser(), 'web' ), array( 'event_two', 'event_three' ) );
}
@ -289,7 +289,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
'priority' => 10
),
);
$manager = new EchoAttributeManager( $notif, $category );
$manager = new EchoAttributeManager( $notif, $category, array(), array(), array() );
$expected = array( 'event_one', 'event_three', 'event_four' );
$actual = $manager->getUserEnabledEventsBySections( $this->mockUser(), 'web', array( 'alert' ) );
sort( $expected );
@ -309,6 +309,151 @@ class EchoAttributeManagerTest extends MediaWikiTestCase {
$this->assertEquals( $actual, $expected );
}
public static function getEventsByCategoryProvider() {
return array(
array(
'Mix of populated and empty categories handled appropriately',
array(
'category_one' => array(
'event_two',
'event_five',
),
'category_two' => array(
'event_one',
'event_three',
'event_four',
),
'category_three' => array(),
),
array(
'category_one' => array(),
'category_two' => array(),
'category_three' => array(),
),
array(
'event_one' => array(
'category' => 'category_two',
),
'event_two' => array(
'category' => 'category_one',
),
'event_three' => array(
'category' => 'category_two',
),
'event_four' => array(
'category' => 'category_two',
),
'event_five' => array(
'category' => 'category_one',
),
)
)
);
}
/**
* @dataProvider getEventsByCategoryProvider
*/
public function testGetEventsByCategory( $message, $expectedMapping, $categories, $notifications ) {
$am = new EchoAttributeManager( $notifications, $categories, array(), array(), array() );
$actualMapping = $am->getEventsByCategory();
$this->assertEquals( $expectedMapping, $actualMapping, $message );
}
public static function isNotifyTypeAvailableForCategoryProvider() {
return array(
array(
'Fallback to default entirely',
true,
'category_one',
'web',
array( 'web' => true, 'email' => true ),
array()
),
array(
'Fallback to default for single type',
false,
'category_two',
'email',
array( 'web' => true, 'email' => false ),
array(
'category_two' => array(
'web' => true,
),
)
),
array(
'Use override',
false,
'category_three',
'web',
array( 'web' => true, 'email' => true ),
array(
'category_three' => array(
'web' => false,
),
),
),
);
}
/**
@dataProvider isNotifyTypeAvailableForCategoryProvider
*/
public function testIsNotifyTypeAvailableForCategory( $message, $expected, $categoryName, $notifyType, $defaultNotifyTypeAvailability, $notifyTypeAvailabilityByCategory ) {
$am = new EchoAttributeManager( array(), array(), $defaultNotifyTypeAvailability, $notifyTypeAvailabilityByCategory, array() );
$actual = $am->isNotifyTypeAvailableForCategory( $categoryName, $notifyType );
$this->assertEquals( $expected, $actual, $message );
}
public static function isNotifyTypeDismissableForCategoryProvider() {
return array(
array(
'Not dismissable because of all',
false,
array(
'category_one' => array(
'no-dismiss' => array( 'all' ),
)
),
'category_one',
'web',
),
array(
'Not dismissable because of specific notify type',
false,
array(
'category_two' => array(
'no-dismiss' => array( 'email' ),
)
),
'category_two',
'email',
),
array(
'Dismissable because of different affected notify type',
true,
array(
'category_three' => array(
'no-dismiss' => array( 'web' ),
)
),
'category_three',
'email',
),
);
}
/**
* @dataProvider isNotifyTypeDismissableForCategoryProvider
*/
public function testIsNotifyTypeDismissableForCategory( $message, $expected, $categories, $categoryName, $notifyType ) {
$am = new EchoAttributeManager( array(), $categories, array(), array(), array() );
$actual = $am->isNotifyTypeDismissableForCategory( $categoryName, $notifyType );
$this->assertEquals( $expected, $actual, $message );
}
/**
* Mock object of User
*/

View file

@ -193,9 +193,12 @@ class NotificationControllerTest extends MediaWikiTestCase {
// event type
'bar',
// default notification types configuration
array( 'web' => true ),
// type-specific
array(
'all' => array( 'web' => true ),
'foo' => array( 'email' => true ),
'foo' => array(
'notify-type-availability' => array( 'email' => true ),
),
),
),
@ -206,21 +209,41 @@ class NotificationControllerTest extends MediaWikiTestCase {
// event type
'foo',
// default notification types configuration
array( 'web' => true, 'email' => true ),
// type-specific
array(
'all' => array( 'web' => true, 'email' => true ),
'foo' => array( 'email' => false ),
'bar' => array( 'sms' => true ),
'foo' => array(
'notify-type-availability' => array( 'email' => false ),
),
'bar' => array(
'notify-type-availability' => array( 'sms' => true ),
),
),
),
array(
'Uses all configuration when notify-type-availability not set at all',
// expected result
array( 'web', 'email' ),
// event type
'baz',
// default notification types configuration
array( 'web' => true, 'email' => true ),
// type-specific
array(
'baz' => array(),
),
)
);
}
/**
* @dataProvider getEventNotifyTypesProvider
*/
public function testGetEventNotifyTypes( $message, $expect, $type, array $notificationTypes ) {
public function testGetEventNotifyTypes( $message, $expect, $type, array $defaultNotifyTypeAvailability, array $notifications ) {
$this->setMwGlobals( array(
'wgEchoDefaultNotificationTypes' => $notificationTypes,
'wgDefaultNotifyTypeAvailability' => $defaultNotifyTypeAvailability,
'wgEchoNotifications' => $notifications,
) );
$result = EchoNotificationController::getEventNotifyTypes( $type );
$this->assertEquals( $expect, $result, $message );