Add API module for sending notifications

Allows users to send notifications to themselves (T306211). For sending
notifications to others, a new permission is created (echo-create),
assigned only to bots by default. For now, only one user can be notified
in one API request.

If the email flag is set in the API params, the notification is also
sent as an email, provided the user hasn't disabled email notifications
for the "api-triggered" category.

This feature is behind a feature flag. Set $wgEchoEnableApiEvents = true
to use.

Adapted from If0267a38be7d454e3d284d30f93c93a828288dd7.
Co-authored-by: TheresNoTime <starling-ctr@wikimedia.org>

Bug: T58362
Bug: T306211
Change-Id: I94642bff5dcb075cb9db862206d59c19edad9fd1
This commit is contained in:
Siddharth VP 2023-06-08 01:48:51 +05:30
parent 33d24a2240
commit e27f4937ff
11 changed files with 393 additions and 2 deletions

View file

@ -35,6 +35,12 @@
"APIModules": {
"echomarkread": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoMarkRead",
"echomarkseen": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoMarkSeen",
"echocreateevent": {
"class": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoCreateEvent",
"services": [
"UserNameUtils"
]
},
"echoarticlereminder": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoArticleReminder",
"echomute": {
"class": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoMute",
@ -100,11 +106,15 @@
"NotificationsMarkRead": "MediaWiki\\Extension\\Notifications\\Special\\SpecialNotificationsMarkRead"
},
"AvailableRights": [
"manage-all-push-subscriptions"
"manage-all-push-subscriptions",
"echo-create"
],
"GroupPermissions": {
"push-subscription-manager": {
"manage-all-push-subscriptions": true
},
"bot": {
"echo-create": true
}
},
"MessagesDirs": {
@ -689,6 +699,10 @@
"minor-watchlist": {
"priority": 6,
"tooltip": "echo-pref-tooltip-minor-watchlist"
},
"api-triggered": {
"priority": 9,
"tooltip": "echo-pref-tooltip-api-triggered"
}
},
"merge_strategy": "array_plus_2d"
@ -760,6 +774,9 @@
},
"article-reminder": {
"path": "Echo/modules/icons/global-progressive.svg"
},
"robot": {
"path": "Echo/modules/icons/robot.svg"
}
},
"merge_strategy": "array_plus_2d"
@ -1013,6 +1030,36 @@
"group": "positive",
"presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoArticleReminderPresentationModel",
"section": "message"
},
"api-alert": {
"user-locators": [
[
"EchoUserLocator::locateFromEventExtra",
[
"recipients"
]
]
],
"canNotifyAgent": true,
"category": "api-triggered",
"group": "neutral",
"section": "alert",
"presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoManualPresentationModel"
},
"api-notice": {
"user-locators": [
[
"EchoUserLocator::locateFromEventExtra",
[
"recipients"
]
]
],
"canNotifyAgent": true,
"category": "api-triggered",
"group": "neutral",
"section": "message",
"presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoManualPresentationModel"
}
},
"merge_strategy": "array_plus_2d"
@ -1040,6 +1087,10 @@
"value": true,
"description": "Whether to send email notifications each time a watched page is edited (if false) or only the first time the page is changed before being visited again by the user (if true)"
},
"EchoEnableApiEvents": {
"value": false,
"description": "Whether to enable the API for creating custom Echo events"
},
"EchoEnablePush": {
"value": false,
"description": "Whether to enable push notifications"

View file

@ -9,6 +9,15 @@
"Stephane Bisson"
]
},
"apihelp-echocreateevent-description": "Manually trigger a notification to a user",
"apihelp-echocreateevent-summary": "Manually trigger a notification to a user",
"apihelp-echocreateevent-example": "Send a notification",
"apihelp-echocreateevent-param-user": "User to send the notification to",
"apihelp-echocreateevent-param-header": "Header content of the notification",
"apihelp-echocreateevent-param-content": "Body content of the notification",
"apihelp-echocreateevent-param-page": "Page to link to in the notification",
"apihelp-echocreateevent-param-section": "Section where notification would be delivered",
"apihelp-echocreateevent-param-email": "Whether to send an email as well",
"apihelp-echomarkread-summary": "Mark notifications as read for the current user.",
"apihelp-echomarkread-param-list": "A list of notification IDs to mark as read.",
"apihelp-echomarkread-param-unreadlist": "A list of notification IDs to mark as unread.",

View file

@ -11,6 +11,15 @@
"Umherirrender"
]
},
"apihelp-echocreateevent-description": "{{doc-apihelp-description|echocreateevent}}",
"apihelp-echocreateevent-summary": "{{doc-apihelp-summary|echocreateevent}}",
"apihelp-echocreateevent-example": "{{doc-apihelp-example|echocreateevent}}",
"apihelp-echocreateevent-param-user": "{{doc-apihelp-param|echocreateevent}}",
"apihelp-echocreateevent-param-header": "{{doc-apihelp-param|echocreateevent}}",
"apihelp-echocreateevent-param-content": "{{doc-apihelp-param|echocreateevent}}",
"apihelp-echocreateevent-param-page": "{{doc-apihelp-param|echocreateevent}}",
"apihelp-echocreateevent-param-section": "{{doc-apihelp-param|echocreateevent}}",
"apihelp-echocreateevent-param-email": "{{doc-apihelp-param|echocreateevent}}",
"apihelp-echomarkread-summary": "{{doc-apihelp-summary|echomarkread}}",
"apihelp-echomarkread-param-list": "{{doc-apihelp-param|echomarkread|list}}",
"apihelp-echomarkread-param-unreadlist": "{{doc-apihelp-param|echomarkread|unreadlist}}",

View file

@ -83,6 +83,7 @@
"echo-category-title-thank-you-edit": "Edit {{PLURAL:$1|milestone|milestones}}",
"echo-category-title-watchlist": "Edit to watched page",
"echo-category-title-minor-watchlist": "Minor edit to watched page",
"echo-category-title-api-triggered": "API triggered notifications",
"echo-pref-tooltip-edit-user-talk": "Notify me when someone edits my user talk page.",
"echo-pref-tooltip-edit-user-page": "Notify me when someone edits my user page.",
"echo-pref-tooltip-article-linked": "Notify me when someone links to a page I created from another page.",
@ -96,6 +97,7 @@
"echo-pref-tooltip-thank-you-edit": "Notify me when I reach my 1st, 10th, 100th... edit.",
"echo-pref-tooltip-watchlist": "Notify me when someone makes a (non-minor) edit to a page on my watchlist.",
"echo-pref-tooltip-minor-watchlist": "Notify me when someone makes a minor edit to a page on my watchlist.",
"echo-pref-tooltip-api-triggered": "Send me notifications triggered by bots or gadgets via the API.",
"notifications": "Notifications",
"tooltip-pt-notifications-alert": "{{GENDER:|Your}} alerts",
"tooltip-pt-notifications-notice": "{{GENDER:|Your}} notices",
@ -202,6 +204,8 @@
"notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, a page on {{GENDER:$2|your}} watchlist, was deleted $3 {{PLURAL:$3|time|times}}.",
"notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, a page on {{GENDER:$2|your}} watchlist, was moved $3 {{PLURAL:$3|time|times}}.",
"notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, a page on {{GENDER:$2|your}} watchlist, was restored $3 {{PLURAL:$3|time|times}}.",
"notification-header-api-triggered": "$1",
"notification-tooltip-api-triggered": "This notification was sent to you by $1",
"notification-body-watchlist-once": "There will be no other email notifications in case of further activity unless {{GENDER:$1|you visit}} this page while logged in.",
"notification-welcome-link": "",
"notification-welcome-linktext": "Welcome",
@ -216,10 +220,12 @@
"notification-link-thank-you-edit": "{{GENDER:$1|Your}} edit",
"notification-link-text-view-edit": "View edit",
"notification-link-article-reminder": "View page",
"notification-link-api-triggered": "View page",
"notification-header-reverted": "Your {{PLURAL:$4|edit on <strong>$3</strong> was|edits on <strong>$3</strong> were}} {{GENDER:$2|reverted}}.",
"notification-body-reverted": "$1",
"notification-header-emailuser": "$1 {{GENDER:$2|sent}} you an email.",
"notification-body-emailuser": "$1",
"notification-body-api-triggered": "$1",
"notification-edit-user-page-email-subject": "$1 {{GENDER:$2|edited}} {{GENDER:$3|your}} user page on {{SITENAME}}",
"notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|left}} {{GENDER:$3|you}} a message on {{SITENAME}}",
"notification-page-linked-email-subject": "A page {{GENDER:$3|you}} created was linked on {{SITENAME}}",
@ -268,6 +274,8 @@
"echo-foreign-wiki-lang": "$1 - $2",
"echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}",
"echo-blacklist": "",
"right-echo-create": "Send notifications to others",
"action-echo-create": "send notifications to others",
"right-manage-all-push-subscriptions": "Manage all push subscriptions",
"action-manage-all-push-subscriptions": "manage all push subscriptions",
"group-push-subscription-manager": "Push subscription managers",

View file

@ -87,6 +87,7 @@
"echo-category-title-thank-you-edit": "'''Note that this doesn't mean \"to edit milestones\", but \"milestones of editing\".'''\n\n{{doc-echo-category-title|tooltip=Echo-pref-tooltip-thank-you-edit}}",
"echo-category-title-watchlist": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-watchlist}}",
"echo-category-title-minor-watchlist": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-minor-watchlist}}",
"echo-category-title-api-triggered": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-api-triggered}}",
"echo-pref-tooltip-edit-user-talk": "{{doc-echo-pref-tooltip|title=Echo-category-title-edit-user-talk}}",
"echo-pref-tooltip-edit-user-page": "{{doc-echo-pref-tooltip|title=Echo-category-title-edit-user-page}}",
"echo-pref-tooltip-article-linked": "{{doc-echo-pref-tooltip|title=Echo-category-title-article-linked}}",
@ -100,6 +101,7 @@
"echo-pref-tooltip-thank-you-edit": "{{doc-echo-pref-tooltip|title=Echo-category-title-thank-you-edit}}",
"echo-pref-tooltip-watchlist": "{{doc-echo-pref-tooltip|title=Echo-category-title-watchlist}}",
"echo-pref-tooltip-minor-watchlist": "{{doc-echo-pref-tooltip|title=Echo-category-title-minor-watchlist}}",
"echo-pref-tooltip-api-triggered": "{{doc-echo-pref-tooltip|title=Echo-category-title-api-triggered}}",
"notifications": "{{doc-special|Notifications}}\n{{Identical|Notification}}",
"tooltip-pt-notifications-alert": "This is used for the title (mouseover text) of the alert notifications user tool.",
"tooltip-pt-notifications-notice": "This is used for the title (mouseover text) of the notice notifications user tool.",
@ -206,6 +208,8 @@
"notification-header-watchlist-multiuser-deleted": "Text of a notification when multiple different users delete pages on your watchlist.\n* $1 - name of the page that was deleted (with namespace) \n* $2 - name of the user viewing the notification, can be used for GENDER \n* $3 - Number of times the page has been deleted. (Always greater than one)",
"notification-header-watchlist-multiuser-moved": "Text of a notification when multiple different users move pages on your watchlist.\n* $1 - name of the page that was moved (with namespace) \n* $2 - name of the user viewing the notification, can be used for GENDER \n* $3 - Number of times the page has been moved. (Always greater than one)",
"notification-header-watchlist-multiuser-restored": "Text of a notification when multiple different users restore pages on your watchlist.\n* $1 - name of the page that was restored (with namespace) \n* $2 - name of the user viewing the notification, can be used for GENDER \n* $3 - Number of times the page has been restored. (Always greater than one)",
"notification-header-api-triggered": "Header text for a notification triggered via API.\n* $1 - header specified in API request\n* $2 - triggering user or bot",
"notification-tooltip-api-triggered": "Tooltip text for a notification triggered via API.\n* $1 - triggering user or bot",
"notification-body-watchlist-once": "Text added to email notifications of watchlist changes to specify that no further emails will be sent for that page until it is visited. \n* $1 - user's name for use in GENDER",
"notification-welcome-link": "{{notranslate}}",
"notification-welcome-linktext": "Link text for link to the wiki's welcome or introduction page.\n{{Identical|Welcome}}",
@ -220,10 +224,12 @@
"notification-link-thank-you-edit": "Label for the link to the user's edit which triggered a threshold congratulations message.\nParameters:\n* $1 - the username for gender purposes",
"notification-link-text-view-edit": "Label for button that links to a \"diff\" view showing an edit made to a page. This is an alternative to the wording in {{msg-mw|notification-link-text-view-changes}}, which serves essentially the same function.",
"notification-link-article-reminder": "Label for the link to the article the user requested to be reminded about",
"notification-link-api-triggered": "Label for the link to the article included in the API notification",
"notification-header-reverted": "Notification header of a user's edit has being reverted by other user.\nParameters:\n* $1 - the formatted username of the person who reverted the edit, using the undo or rollback features (not suitable for GENDER).\n* $2 - the username for GENDER\n* $3 - the page that was reverted, formatted\n* $4 - the number of edits that were reverted\n\nWhen the notified user clicks on the notification message, this appoint to a diff page.\n{{Related|Notification-reverted}}",
"notification-body-reverted": "{{notranslate}}",
"notification-header-emailuser": "Flyout-specific format for displaying notifications of user has sent an email to another user.\n\nParameters:\n* $1 - the formatted username of the person who sent the email.\n* $2 - the username for GENDER.",
"notification-body-emailuser": "{{notranslate}}",
"notification-body-api-triggered": "{{notranslate}}",
"notification-edit-user-page-email-subject": "Email subject. Parameters:\n* $1 - the formatted username of the person who edited (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.",
"notification-edit-talk-page-email-subject2": "Email subject. Parameters:\n* $1 - the formatted username of the person who edited (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.",
"notification-page-linked-email-subject": "E-mail subject Parameters:\n* $1 - the formatted username of the person who edited (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.",
@ -272,6 +278,8 @@
"echo-foreign-wiki-lang": "{{optional}}\nTitle of the wiki for which you're seeing foreign notifications:\n\nParameters:\n* $1 - the name of the site (e.g. 'Wikipedia', 'Wikiversity', ...)\n* $2 - the language of the website (e.g. 'English', 'Deutsch', ...)",
"echo-badge-count": "{{optional}}\nUsed only for the two Echo badges shown on the personal toolbar.\nParameters:\n* $1 - Formatted notification count. However, for 100 or greater, 100 will be passed.",
"echo-blacklist": "{{ignored}} Site-wide list of accounts that cannot trigger notifications. Can be overridden by users at [[Special:MyPage/Echo-whitelist]].",
"right-echo-create": "{{doc-right|echo-create}}",
"action-echo-create": "{{doc-action|echo-create}}",
"right-manage-all-push-subscriptions": "{{doc-right|manage-all-push-subscriptions}}",
"action-manage-all-push-subscriptions": "{{doc-action|manage-all-push-subscriptions}}",
"group-push-subscription-manager": "{{doc-group|push-subscription-manager}}",

View file

@ -0,0 +1,152 @@
<?php
namespace MediaWiki\Extension\Notifications\Api;
use ApiBase;
use ApiMain;
use MediaWiki\Extension\Notifications\Model\Event;
use MediaWiki\ParamValidator\TypeDef\TitleDef;
use MediaWiki\ParamValidator\TypeDef\UserDef;
use MediaWiki\Title\Title;
use MediaWiki\User\UserIdentity;
use MediaWiki\User\UserNameUtils;
use Wikimedia\ParamValidator\ParamValidator;
use Wikimedia\ParamValidator\TypeDef\StringDef;
class ApiEchoCreateEvent extends ApiBase {
private UserNameUtils $userNameUtils;
public function __construct(
ApiMain $mainModule,
$moduleName,
UserNameUtils $userNameUtils
) {
parent::__construct( $mainModule, $moduleName );
$this->userNameUtils = $userNameUtils;
}
/**
* @see ApiBase::execute()
* @return void
*/
public function execute() {
if ( !$this->getConfig()->get( 'EchoEnableApiEvents' ) ) {
$this->dieWithError( [ 'apierror-moduledisabled', $this->getModuleName() ] );
}
// Only for logged in users
$user = $this->getUser();
if ( !$user->isNamed() ) {
$this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' );
}
$params = $this->extractRequestParams();
// Default to self if unspecified
/** @var UserIdentity $userToNotify */
$userToNotify = $params['user'] ?? $user;
if ( $userToNotify->getName() !== $user->getName() ) {
$this->checkUserRightsAny( 'echo-create' );
}
if ( !$userToNotify->isRegistered() || $this->userNameUtils->isTemp( $userToNotify->getName() ) ) {
$this->dieWithError( [ 'nosuchusershort', $userToNotify->getName() ] );
}
$event = Event::create( [
// type is one of api-notice, api-alert
'type' => 'api-' . $params['section'],
'agent' => $user,
'title' => $params['page'] ? Title::newFromLinkTarget( $params['page'] ) : null,
'extra' => [
'recipients' => [ $userToNotify->getId() ],
'header' => $params['header'],
'content' => $params['content'],
// Send email only if specified
'noemail' => !$params['email'],
]
] );
// Return a success message
$this->getResult()->addValue(
null,
$this->getModuleName(),
[
'result' => 'success'
]
);
}
/**
* @see ApiBase::needsToken()
* @return bool
*/
public function mustBePosted() {
return true;
}
public function isWriteMode() {
return true;
}
public function needsToken() {
return 'csrf';
}
/**
* @see ApiBase::getAllowedParams()
* @return array
*/
public function getAllowedParams() {
return [
'user' => [
ParamValidator::PARAM_TYPE => 'user',
UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'id' ],
UserDef::PARAM_RETURN_OBJECT => true,
],
'header' => [
ParamValidator::PARAM_REQUIRED => true,
ParamValidator::PARAM_TYPE => 'string',
StringDef::PARAM_MAX_BYTES => 160,
],
'content' => [
ParamValidator::PARAM_REQUIRED => true,
ParamValidator::PARAM_TYPE => 'string',
StringDef::PARAM_MAX_BYTES => 5000,
],
'page' => [
ParamValidator::PARAM_TYPE => 'title',
TitleDef::PARAM_RETURN_OBJECT => true,
],
'section' => [
ParamValidator::PARAM_REQUIRED => true,
ParamValidator::PARAM_TYPE => [ 'alert', 'notice' ],
ParamValidator::PARAM_DEFAULT => 'notice',
],
'email' => [
ParamValidator::PARAM_TYPE => 'boolean',
ParamValidator::PARAM_DEFAULT => false,
],
];
}
/**
* @see ApiBase::getExamplesMessages()
* @return string[]
*/
protected function getExamplesMessages() {
return [
'action=echocreateevent&header=Hi&content=From_API' => 'apihelp-echocreateevent-example',
];
}
/**
* @see ApiBase::getHelpUrls()
* @return string
*/
public function getHelpUrls() {
return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Echo_(Notifications)/API';
}
}

View file

@ -0,0 +1,51 @@
<?php
namespace MediaWiki\Extension\Notifications\Formatters;
class EchoManualPresentationModel extends EchoEventPresentationModel {
/** @inheritDoc */
public function getIconType() {
return 'robot';
}
/** @inheritDoc */
public function getHeaderMessage() {
return $this->msg( 'notification-header-api-triggered' )
->plaintextParams( $this->event->getExtraParam( 'header' ), $this->event->getAgent()->getName() );
}
/** @inheritDoc */
public function getSubjectMessage() {
return $this->getHeaderMessage();
}
/** @inheritDoc */
public function getPrimaryLink() {
if ( !$this->event->getTitle() ) {
return false;
}
return [
'url' => $this->event->getTitle()->getLocalURL(),
'label' => $this->msg( 'notification-link-api-triggered' )->text(),
];
}
/** @inheritDoc */
public function getBodyMessage() {
$content = $this->event->getExtraParam( 'content' );
// Content here passed through plaintextParams for sanitization
return $content ? $this->msg( 'notification-body-api-triggered' )->plaintextParams( $content ) : false;
}
/** @inheritDoc */
public function getSecondaryLinks() {
$agentLink = $this->getAgentLink();
$agentLink['tooltip'] = $this->msg( 'notification-tooltip-api-triggered',
$this->event->getAgent()->getName() );
return [
$agentLink
];
}
}

View file

@ -204,6 +204,10 @@ class Hooks implements
'minor-watchlist' => [
'web' => false,
],
'api-triggered' => [
// emails are sent only if sender also sets the API option, which is disabled by default
'email' => true,
],
];
$echoPushEnabled = $this->config->get( ConfigNames::EnablePush );
@ -241,7 +245,7 @@ class Hooks implements
global $wgEchoNotifications, $wgEchoNotificationCategories, $wgEchoNotificationIcons,
$wgEchoMentionStatusNotifications, $wgAllowArticleReminderNotification, $wgAPIModules,
$wgEchoWatchlistNotifications, $wgEchoSeenTimeCacheType, $wgMainStash, $wgEnableEmail,
$wgEnableUserEmail;
$wgEnableUserEmail, $wgEchoEnableApiEvents;
// allow extensions to define their own event
( new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ) )->onBeforeCreateEchoEvent(
@ -270,6 +274,11 @@ class Hooks implements
unset( $wgEchoNotificationCategories['emailuser'] );
}
// Only allow API-triggered notifications when enabled
if ( !$wgEchoEnableApiEvents ) {
unset( $wgEchoNotificationCategories['api-triggered'] );
}
// Default $wgEchoSeenTimeCacheType to $wgMainStash
if ( $wgEchoSeenTimeCacheType === null ) {
$wgEchoSeenTimeCacheType = $wgMainStash;

View file

@ -80,6 +80,10 @@ class Notifier {
return false;
}
}
} elseif ( $event->getExtraParam( 'noemail' ) ) {
// Could be set for API triggered notifications were email is not
// requested in API request params
return false;
}
$hookRunner = new HookRunner( $services->getHookContainer() );

7
modules/icons/robot.svg Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<title>
robot
</title>
<path d="M10.5 5h6.505C18.107 5 19 5.896 19 6.997V14h-7v2h5.005c1.102 0 1.995.888 1.995 2v2H1v-2c0-1.105.893-2 1.995-2H8v-2H1V6.997C1 5.894 1.893 5 2.995 5H9.5V2.915a1.5 1.5 0 1 1 1 0zm-4 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3m7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3"/>
</svg>

After

Width:  |  Height:  |  Size: 427 B

View file

@ -0,0 +1,83 @@
<?php
use MediaWiki\Extension\Notifications\Mapper\NotificationMapper;
use MediaWiki\Extension\Notifications\NotifUser;
/**
* @group API
* @group Database
* @covers \MediaWiki\Extension\Notifications\Api\ApiEchoCreateEvent
*/
class ApiEchoCreateEventTest extends ApiTestCase {
protected function setUp(): void {
parent::setUp();
$this->overrideConfigValue( 'EchoEnableApiEvents', true );
}
public function testNotifySelf() {
$result = $this->doApiRequestWithToken( [
'action' => 'echocreateevent',
'user' => $this->getTestUser()->getUser()->getName(),
'header' => 'notification header',
'content' => 'notification content',
], null, $this->getTestUser()->getUser() );
$this->assertEquals( 'success', $result[0]['echocreateevent']['result'] );
$user = NotifUser::newFromUser( $this->getTestUser()->getUser() );
$this->assertSame( 1, $user->getNotificationCount() );
$mapper = new NotificationMapper();
$notifs = $mapper->fetchByUser( $this->getTestUser()->getUser(), 5, null, [ 'api-notice' ] );
$this->assertCount( 1, $notifs );
$notif = array_values( $notifs )[0];
$this->assertSame( 'notification header', $notif->getEvent()->getExtraParam( 'header' ) );
$this->assertSame( 'notification content', $notif->getEvent()->getExtraParam( 'content' ) );
$this->assertTrue( $notif->getEvent()->getExtraParam( 'noemail' ) );
}
public function testAlertWithEmail() {
$result = $this->doApiRequestWithToken( [
'action' => 'echocreateevent',
'user' => $this->getTestUser()->getUser()->getName(),
'header' => 'notification header',
'content' => 'notification content',
'email' => true,
'section' => 'alert'
], null, $this->getTestUser()->getUser() );
$this->assertEquals( 'success', $result[0]['echocreateevent']['result'] );
$mapper = new NotificationMapper();
$notifs = $mapper->fetchByUser( $this->getTestUser()->getUser(), 5, null, [ 'api-alert' ] );
$this->assertFalse( array_values( $notifs )[0]->getEvent()->getExtraParam( 'noemail' ) );
}
public function testNotifyOthers() {
$this->setGroupPermissions( 'sysop', 'echo-create', true );
$result = $this->doApiRequestWithToken( [
'action' => 'echocreateevent',
'user' => $this->getTestUser()->getUser()->getName(),
'header' => 'notification header',
'content' => 'notification content',
], null, $this->getTestSysop()->getUser() );
$this->assertEquals( 'success', $result[0]['echocreateevent']['result'] );
$user = NotifUser::newFromUser( $this->getTestUser()->getUser() );
$this->assertSame( 1, $user->getNotificationCount() );
}
public function testNotifyOthersWithoutPermission() {
try {
$this->doApiRequestWithToken( [
'action' => 'echocreateevent',
'user' => $this->getTestUser()->getUser()->getName(),
'header' => 'notification header',
'content' => 'notification content',
], null, $this->getTestSysop()->getUser() );
} catch ( ApiUsageException $ex ) {
$this->assertApiErrorCode( 'permissiondenied', $ex );
}
}
}