Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -1697,6 +1697,7 @@
     'PhabricatorNamedQuery' => 'applications/search/storage/PhabricatorNamedQuery.php',
     'PhabricatorNamedQueryQuery' => 'applications/search/query/PhabricatorNamedQueryQuery.php',
     'PhabricatorNoteExample' => 'applications/uiexample/examples/PhabricatorNoteExample.php',
+    'PhabricatorNotificationAdHocFeedStory' => 'applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php',
     'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php',
     'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.php',
     'PhabricatorNotificationClient' => 'applications/notification/client/PhabricatorNotificationClient.php',
@@ -1707,6 +1708,7 @@
     'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php',
     'PhabricatorNotificationQuery' => 'applications/notification/PhabricatorNotificationQuery.php',
     'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php',
+    'PhabricatorNotificationTestController' => 'applications/notification/controller/PhabricatorNotificationTestController.php',
     'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
     'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationBaseController.php',
     'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationDeleteController.php',
@@ -4430,6 +4432,7 @@
     ),
     'PhabricatorNamedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorNoteExample' => 'PhabricatorUIExample',
+    'PhabricatorNotificationAdHocFeedStory' => 'PhabricatorFeedStory',
     'PhabricatorNotificationClearController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorNotificationController' => 'PhabricatorController',
@@ -4438,6 +4441,7 @@
     'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController',
+    'PhabricatorNotificationTestController' => 'PhabricatorNotificationController',
     'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO',
     'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController',
     'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController',
Index: src/applications/feed/PhabricatorFeedStoryPublisher.php
===================================================================
--- src/applications/feed/PhabricatorFeedStoryPublisher.php
+++ src/applications/feed/PhabricatorFeedStoryPublisher.php
@@ -10,6 +10,17 @@
   private $primaryObjectPHID;
   private $subscribedPHIDs = array();
   private $mailRecipientPHIDs = array();
+  private $notifyAuthor;
+
+
+  public function setNotifyAuthor($notify_author) {
+    $this->notifyAuthor = $notify_author;
+    return $this;
+  }
+
+  public function getNotifyAuthor() {
+    return $this->notifyAuthor;
+  }
 
   public function setRelatedPHIDs(array $phids) {
     $this->relatedPHIDs = $phids;
@@ -116,9 +127,12 @@
 
   private function insertNotifications($chrono_key) {
     $subscribed_phids = $this->subscribedPHIDs;
-    $subscribed_phids = array_diff(
-      $subscribed_phids,
-      array($this->storyAuthorPHID));
+
+    if (!$this->notifyAuthor) {
+      $subscribed_phids = array_diff(
+        $subscribed_phids,
+        array($this->storyAuthorPHID));
+    }
 
     if (!$subscribed_phids) {
       return;
Index: src/applications/notification/application/PhabricatorApplicationNotifications.php
===================================================================
--- src/applications/notification/application/PhabricatorApplicationNotifications.php
+++ src/applications/notification/application/PhabricatorApplicationNotifications.php
@@ -19,6 +19,7 @@
         'individual/' => 'PhabricatorNotificationIndividualController',
         'status/' => 'PhabricatorNotificationStatusController',
         'clear/' => 'PhabricatorNotificationClearController',
+        'test/' => 'PhabricatorNotificationTestController',
       ),
     );
   }
Index: src/applications/notification/controller/PhabricatorNotificationIndividualController.php
===================================================================
--- src/applications/notification/controller/PhabricatorNotificationIndividualController.php
+++ src/applications/notification/controller/PhabricatorNotificationIndividualController.php
@@ -26,7 +26,7 @@
     $response = array(
       'pertinent'         => true,
       'primaryObjectPHID' => head($stories)->getPrimaryObjectPHID(),
-      'content'           => $content,
+      'content'           => hsprintf('%s', $content),
     );
 
     return id(new AphrontAjaxResponse())->setContent($response);
Index: src/applications/notification/controller/PhabricatorNotificationStatusController.php
===================================================================
--- src/applications/notification/controller/PhabricatorNotificationStatusController.php
+++ src/applications/notification/controller/PhabricatorNotificationStatusController.php
@@ -59,8 +59,23 @@
         'wide',
       ));
 
+    $test_icon = id(new PHUIIconView())
+      ->setSpriteSheet(PHUIIconView::SPRITE_ICONS)
+      ->setSpriteIcon('warning');
+
+    $test_button = id(new PHUIButtonView())
+        ->setTag('a')
+        ->setWorkflow(true)
+        ->setText(pht('Send Test Notification'))
+        ->setHref($this->getApplicationURI("test/"))
+        ->setIcon($test_icon);
+
+    $header = id(new PHUIHeaderView())
+      ->setHeader(pht('Notification Server Status'))
+      ->addActionLink($test_button);
+
     $box = id(new PHUIObjectBoxView())
-      ->setHeaderText(pht('Server Status'))
+      ->setHeader($header)
       ->appendChild($table);
 
     return $box;
Index: src/applications/notification/controller/PhabricatorNotificationTestController.php
===================================================================
--- /dev/null
+++ src/applications/notification/controller/PhabricatorNotificationTestController.php
@@ -0,0 +1,38 @@
+<?php
+
+final class PhabricatorNotificationTestController
+  extends PhabricatorNotificationController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+    $viewer = $request->getUser();
+
+    $story_type = 'PhabricatorNotificationAdHocFeedStory';
+    $story_data = array(
+      'title' => pht(
+        'This is a test notification, sent at %s.',
+        phabricator_datetime(time(), $viewer)),
+    );
+
+    $viewer_phid = $viewer->getPHID();
+
+    // TODO: When it's easier to get these buttons to render as forms, this
+    // would be slightly nicer as a more standard isFormPost() check.
+
+    if ($request->validateCSRF()) {
+      id(new PhabricatorFeedStoryPublisher())
+        ->setStoryType($story_type)
+        ->setStoryData($story_data)
+        ->setStoryTime(time())
+        ->setStoryAuthorPHID($viewer_phid)
+        ->setRelatedPHIDs(array($viewer_phid))
+        ->setPrimaryObjectPHID($viewer_phid)
+        ->setSubscribedPHIDs(array($viewer_phid))
+        ->setNotifyAuthor(true)
+        ->publish();
+    }
+
+    return id(new AphrontAjaxResponse());
+  }
+
+}
Index: src/applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php
===================================================================
--- /dev/null
+++ src/applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php
@@ -0,0 +1,27 @@
+<?php
+
+final class PhabricatorNotificationAdHocFeedStory extends PhabricatorFeedStory {
+
+  public function getPrimaryObjectPHID() {
+    return $this->getAuthorPHID();
+  }
+
+  public function renderView() {
+    $data = $this->getStoryData();
+
+    $author_phid = $data->getAuthorPHID();
+
+    $view = $this->newStoryView();
+
+    $view->setTitle($data->getValue('title'));
+    $view->setImage($this->getHandle($author_phid)->getImageURI());
+
+    return $view;
+  }
+
+  public function renderText() {
+    $data = $this->getStoryData();
+    return $data->getValue('title');
+  }
+
+}