From f190be9e2d4d285fb71d84e5d3884206067cf7af Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 19 Apr 2015 19:23:42 -0400 Subject: [PATCH] Add Sendgrid integration (incoming email handling) --- README.markdown | 2 + app/Controller/Webhook.php | 14 ++++ app/Core/Tool.php | 20 +++++ app/Integration/MailgunWebhook.php | 29 +++---- app/Integration/PostmarkWebhook.php | 11 ++- app/Integration/SendgridWebhook.php | 74 +++++++++++++++++ app/Locale/da_DK/translations.php | 2 + app/Locale/de_DE/translations.php | 2 + app/Locale/es_ES/translations.php | 2 + app/Locale/fi_FI/translations.php | 2 + app/Locale/fr_FR/translations.php | 2 + app/Locale/hu_HU/translations.php | 2 + app/Locale/it_IT/translations.php | 2 + app/Locale/ja_JP/translations.php | 2 + app/Locale/nl_NL/translations.php | 2 + app/Locale/pl_PL/translations.php | 2 + app/Locale/pt_BR/translations.php | 2 + app/Locale/ru_RU/translations.php | 2 + app/Locale/sr_Latn_RS/translations.php | 2 + app/Locale/sv_SE/translations.php | 2 + app/Locale/th_TH/translations.php | 2 + app/Locale/tr_TR/translations.php | 2 + app/Locale/zh_CN/translations.php | 2 + app/Model/User.php | 4 + app/ServiceProvider/ClassProvider.php | 1 + app/Template/config/integrations.php | 6 ++ assets/img/chosen-sprite.png | Bin assets/img/chosen-sprite@2x.png | Bin assets/img/sendgrid-icon.png | Bin 0 -> 600 bytes docs/create-tasks-by-email.markdown | 44 ++++++++++ docs/mailgun.markdown | 35 +------- docs/postmark.markdown | 36 ++------- docs/sendgrid.markdown | 24 ++++++ tests/units/ProjectTest.php | 3 + tests/units/SendgridWebhookTest.php | 107 +++++++++++++++++++++++++ tests/units/ToolTest.php | 15 ++++ tests/units/UserTest.php | 10 +++ 37 files changed, 380 insertions(+), 89 deletions(-) create mode 100644 app/Integration/SendgridWebhook.php mode change 100755 => 100644 assets/img/chosen-sprite.png mode change 100755 => 100644 assets/img/chosen-sprite@2x.png create mode 100644 assets/img/sendgrid-icon.png create mode 100644 docs/create-tasks-by-email.markdown create mode 100644 docs/sendgrid.markdown create mode 100644 tests/units/SendgridWebhookTest.php create mode 100644 tests/units/ToolTest.php diff --git a/README.markdown b/README.markdown index e2f137ca2..6a3136d09 100644 --- a/README.markdown +++ b/README.markdown @@ -84,6 +84,7 @@ Documentation - [Task links](docs/task-links.markdown) - [Transitions](docs/transitions.markdown) - [Time tracking](docs/time-tracking.markdown) +- [Create tasks by email](docs/create-tasks-by-email.markdown) #### Working with users @@ -108,6 +109,7 @@ Documentation - [Gitlab webhooks](docs/gitlab-webhooks.markdown) - [Hipchat](docs/hipchat.markdown) - [Mailgun](docs/mailgun.markdown) +- [Sendgrid](docs/sendgrid.markdown) - [Slack](docs/slack.markdown) - [Postmark](docs/postmark.markdown) diff --git a/app/Controller/Webhook.php b/app/Controller/Webhook.php index 06bfcd4ef..667c50879 100644 --- a/app/Controller/Webhook.php +++ b/app/Controller/Webhook.php @@ -128,4 +128,18 @@ class Webhook extends Base echo $this->mailgunWebhook->parsePayload($_POST) ? 'PARSED' : 'IGNORED'; } + + /** + * Handle Sendgrid webhooks + * + * @access public + */ + public function sendgrid() + { + if ($this->config->get('webhook_token') !== $this->request->getStringParam('token')) { + $this->response->text('Not Authorized', 401); + } + + echo $this->sendgridWebhook->parsePayload($_POST) ? 'PARSED' : 'IGNORED'; + } } diff --git a/app/Core/Tool.php b/app/Core/Tool.php index ade99cad1..84e42ba84 100644 --- a/app/Core/Tool.php +++ b/app/Core/Tool.php @@ -31,4 +31,24 @@ class Tool fclose($fp); } } + + /** + * Get the mailbox hash from an email address + * + * @static + * @access public + * @param string $email + * @return string + */ + public static function getMailboxHash($email) + { + if (! strpos($email, '@') || ! strpos($email, '+')) { + return ''; + } + + list($local_part,) = explode('@', $email); + list(,$identifier) = explode('+', $local_part); + + return $identifier; + } } diff --git a/app/Integration/MailgunWebhook.php b/app/Integration/MailgunWebhook.php index 17338faa5..8e5425134 100644 --- a/app/Integration/MailgunWebhook.php +++ b/app/Integration/MailgunWebhook.php @@ -3,6 +3,7 @@ namespace Integration; use HTML_To_Markdown; +use Core\Tool; /** * Mailgun Webhook @@ -21,7 +22,7 @@ class MailgunWebhook extends Base */ public function parsePayload(array $payload) { - if (empty($payload['sender']) || empty($payload['subject']) || empty($payload['recipient']) || empty($payload['stripped-text'])) { + if (empty($payload['sender']) || empty($payload['subject']) || empty($payload['recipient'])) { return false; } @@ -34,7 +35,7 @@ class MailgunWebhook extends Base } // The project must have a short name - $project = $this->project->getByIdentifier($this->getMailboxHash($payload['recipient'])); + $project = $this->project->getByIdentifier(Tool::getMailboxHash($payload['recipient'])); if (empty($project)) { $this->container['logger']->debug('MailgunWebhook: ignored => project not found'); @@ -48,12 +49,15 @@ class MailgunWebhook extends Base } // Get the Markdown contents - if (empty($payload['stripped-html'])) { + if (! empty($payload['stripped-html'])) { + $markdown = new HTML_To_Markdown($payload['stripped-html'], array('strip_tags' => true)); + $description = $markdown->output(); + } + else if (! empty($payload['stripped-text'])) { $description = $payload['stripped-text']; } else { - $markdown = new HTML_To_Markdown($payload['stripped-html'], array('strip_tags' => true)); - $description = $markdown->output(); + $description = ''; } // Finally, we create the task @@ -64,19 +68,4 @@ class MailgunWebhook extends Base 'creator_id' => $user['id'], )); } - - /** - * Get the project identifier - * - * @access public - * @param string $email - * @return string - */ - public function getMailboxHash($email) - { - list($local_part,) = explode('@', $email); - list(,$identifier) = explode('+', $local_part); - - return $identifier; - } } diff --git a/app/Integration/PostmarkWebhook.php b/app/Integration/PostmarkWebhook.php index 6387ba20d..642955df7 100644 --- a/app/Integration/PostmarkWebhook.php +++ b/app/Integration/PostmarkWebhook.php @@ -21,7 +21,7 @@ class PostmarkWebhook extends Base */ public function parsePayload(array $payload) { - if (empty($payload['From']) || empty($payload['Subject']) || empty($payload['MailboxHash']) || empty($payload['TextBody'])) { + if (empty($payload['From']) || empty($payload['Subject']) || empty($payload['MailboxHash'])) { return false; } @@ -48,12 +48,15 @@ class PostmarkWebhook extends Base } // Get the Markdown contents - if (empty($payload['HtmlBody'])) { + if (! empty($payload['HtmlBody'])) { + $markdown = new HTML_To_Markdown($payload['HtmlBody'], array('strip_tags' => true)); + $description = $markdown->output(); + } + else if (! empty($payload['TextBody'])) { $description = $payload['TextBody']; } else { - $markdown = new HTML_To_Markdown($payload['HtmlBody'], array('strip_tags' => true)); - $description = $markdown->output(); + $description = ''; } // Finally, we create the task diff --git a/app/Integration/SendgridWebhook.php b/app/Integration/SendgridWebhook.php new file mode 100644 index 000000000..142ed49f1 --- /dev/null +++ b/app/Integration/SendgridWebhook.php @@ -0,0 +1,74 @@ +user->getByEmail($envelope['from']); + + if (empty($user)) { + $this->container['logger']->debug('SendgridWebhook: ignored => user not found'); + return false; + } + + // The project must have a short name + $project = $this->project->getByIdentifier(Tool::getMailboxHash($sender)); + + if (empty($project)) { + $this->container['logger']->debug('SendgridWebhook: ignored => project not found'); + return false; + } + + // The user must be member of the project + if (! $this->projectPermission->isMember($project['id'], $user['id'])) { + $this->container['logger']->debug('SendgridWebhook: ignored => user is not member of the project'); + return false; + } + + // Get the Markdown contents + if (! empty($payload['html'])) { + $markdown = new HTML_To_Markdown($payload['html'], array('strip_tags' => true)); + $description = $markdown->output(); + } + else if (! empty($payload['text'])) { + $description = $payload['text']; + } + else { + $description = ''; + } + + // Finally, we create the task + return (bool) $this->taskCreation->create(array( + 'project_id' => $project['id'], + 'title' => $payload['subject'], + 'description' => $description, + 'creator_id' => $user['id'], + )); + } +} diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php index cc3809298..f1352b8d6 100644 --- a/app/Locale/da_DK/translations.php +++ b/app/Locale/da_DK/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php index 20d459775..2fc01f3e6 100644 --- a/app/Locale/de_DE/translations.php +++ b/app/Locale/de_DE/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php index f1d344be5..c150bfe50 100644 --- a/app/Locale/es_ES/translations.php +++ b/app/Locale/es_ES/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php index 728a57467..99ead93c6 100644 --- a/app/Locale/fi_FI/translations.php +++ b/app/Locale/fi_FI/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php index 54370f3af..709131a6c 100644 --- a/app/Locale/fr_FR/translations.php +++ b/app/Locale/fr_FR/translations.php @@ -866,4 +866,6 @@ return array( 'Help on Postmark integration' => 'Aide sur l\'intégration avec Postmark', 'Mailgun (incoming emails)' => 'Mailgun (emails entrants)', 'Help on Mailgun integration' => 'Aide sur l\'intégration avec Mailgun', + 'Sendgrid (incoming emails)' => 'Sendgrid (emails entrants)', + 'Help on Sendgrid integration' => 'Aide sur l\'intégration avec Sendgrid', ); diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php index feca5d32f..d2d0d6e9c 100644 --- a/app/Locale/hu_HU/translations.php +++ b/app/Locale/hu_HU/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php index 8601af4fa..c2882ffc8 100644 --- a/app/Locale/it_IT/translations.php +++ b/app/Locale/it_IT/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php index 3a08da17e..a35ff2e91 100644 --- a/app/Locale/ja_JP/translations.php +++ b/app/Locale/ja_JP/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php index 4a53bf484..06a7026af 100644 --- a/app/Locale/nl_NL/translations.php +++ b/app/Locale/nl_NL/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php index 519fb32bd..c91d4ba12 100644 --- a/app/Locale/pl_PL/translations.php +++ b/app/Locale/pl_PL/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php index 953f3a594..1e5dae59d 100644 --- a/app/Locale/pt_BR/translations.php +++ b/app/Locale/pt_BR/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php index dee35d70f..53616d9a4 100644 --- a/app/Locale/ru_RU/translations.php +++ b/app/Locale/ru_RU/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php index c4bab8cbc..fd5c4f5d0 100644 --- a/app/Locale/sr_Latn_RS/translations.php +++ b/app/Locale/sr_Latn_RS/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php index 22286c369..7f765815b 100644 --- a/app/Locale/sv_SE/translations.php +++ b/app/Locale/sv_SE/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php index c8e253b67..f282beee7 100644 --- a/app/Locale/th_TH/translations.php +++ b/app/Locale/th_TH/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php index 5fb403e89..11cba8334 100644 --- a/app/Locale/tr_TR/translations.php +++ b/app/Locale/tr_TR/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php index 7470bae1c..09df6d454 100644 --- a/app/Locale/zh_CN/translations.php +++ b/app/Locale/zh_CN/translations.php @@ -864,4 +864,6 @@ return array( // 'Help on Postmark integration' => '', // 'Mailgun (incoming emails)' => '', // 'Help on Mailgun integration' => '', + // 'Sendgrid (incoming emails)' => '', + // 'Help on Sendgrid integration' => '', ); diff --git a/app/Model/User.php b/app/Model/User.php index d9f174bd4..be2b034bd 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -150,6 +150,10 @@ class User extends Base */ public function getByEmail($email) { + if (empty($email)) { + return false; + } + return $this->db->table(self::TABLE)->eq('email', $email)->findOne(); } diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index de9de546e..a64ac061e 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -78,6 +78,7 @@ class ClassProvider implements ServiceProviderInterface 'BitbucketWebhook', 'Hipchat', 'MailgunWebhook', + 'SendgridWebhook', 'SlackWebhook', 'PostmarkWebhook', ) diff --git a/app/Template/config/integrations.php b/app/Template/config/integrations.php index a012b566b..bf051cfcb 100644 --- a/app/Template/config/integrations.php +++ b/app/Template/config/integrations.php @@ -12,6 +12,12 @@

+

 

+
+
+

+
+

 


diff --git a/assets/img/chosen-sprite.png b/assets/img/chosen-sprite.png old mode 100755 new mode 100644 diff --git a/assets/img/chosen-sprite@2x.png b/assets/img/chosen-sprite@2x.png old mode 100755 new mode 100644 diff --git a/assets/img/sendgrid-icon.png b/assets/img/sendgrid-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4247e27b8d8904c97971afde57a9a484cbdcf4fe GIT binary patch literal 600 zcmV-e0;m0nP)}~=|vYTv*LyU!mMGD2{ zwD1E?u+bAyL_raRYeX@Kf=F(g3p+DUChSTIFDaaEX8!N@{`2NNg#TPPExuGL<%-4P zbpSX800{upgCMw;#Z3g1%Vj5@&p#DH?8yR{xsfEvN)$ye&Dlgiy5>-|F>x8=C?=&pU^RSG3j_Ez7!>0hCfl<2YV*9Oq0B1UE*2N~N;RvaHiY zGzS1XnfWUb?PuooAP8oB-(Ml3BN;?%ZGbP5Bw0q!^X3t8nTWO+fl?|4fOkTO1I+xp z*=%lgU3Zpt@VadYG1qEe(Sn!WLef_ zrPOUiJVr!0b8i5#*`%2tr#8O}Ar{9he_`eah?oO_vj(0z`GK`st*n&Vi-^0-cS$Kb zgTbItC=@;kA-0bd?-?TQHpx=ALuNjK)oOJ{2(gyEkC`tto6WB8`^SmsewyhQB0e_- z27u4Z{8~zRr_~_2BQvpWcy6z<+YNX=3 mQp&|BiUyMgZt65no7O*1=k(a)dta~s0000 Edit** 3. Try to send an email to your project - -Troubleshootings ----------------- - -- Test if your route match in the console -- Double-check requirements mentioned above diff --git a/docs/postmark.markdown b/docs/postmark.markdown index 681ec5a22..a859961ce 100644 --- a/docs/postmark.markdown +++ b/docs/postmark.markdown @@ -6,40 +6,15 @@ You can use the service [Postmark](https://postmarkapp.com/) to create tasks dir This integration works with the inbound email service of Postmark. Kanboard use a webhook to handle incoming emails. -Incoming emails workflow ------------------------- - -1. You send an email to a specific address, by example **something+myproject@inbound.mydomain.tld** -2. Your email is forwarded to Postmark SMTP servers -3. Postmark call the Kanboard webhook with the email in JSON format -4. Kanboard parse the received email and create the task to the right project - -Note: New tasks are automatically created in the first column. - -Email format ------------- - -- The local part of the email address must use the plus separator, by example **kanboard+project123** -- The string defined after the plus sign must match a project identifier, by example **project123** is the identifier of the project **Project 123** -- The email subject becomes the task title -- The email body becomes the task description (Markdown format) - -Incoming emails can be written in text or HTML formats. -**Kanboard is able to convert simple HTML emails to Markdown**. - -Security and requirements -------------------------- - -- The Kanboard webhook is protected by a random token -- The sender email address (From header) must match a Kanboard user -- The Kanboard project must have a unique identifier, by example **MYPROJECT** -- The Kanboard user must be member of the project +The [incoming email workflow is described here](http://kanboard.net/documentation/email-tasks). Postmark configuration ---------------------- -- Follow the [official documentation about inbound email processing](http://developer.postmarkapp.com/developer-process-configure.html) -- The Kanboard webhook url is displayed in **Settings > Integrations > Postmark** +Just follow the [official documentation about inbound email processing](http://developer.postmarkapp.com/developer-process-configure.html). +Basically, you have to forward your own domain or subdomain to a specific Postmark email address. + +The Kanboard webhook url is displayed in **Settings > Integrations > Postmark** Kanboard configuration ---------------------- @@ -52,4 +27,3 @@ Troubleshootings ---------------- - Test the webhook url from the Postmark console, you should have a status code `200 OK` -- Double-check requirements mentioned above diff --git a/docs/sendgrid.markdown b/docs/sendgrid.markdown new file mode 100644 index 000000000..5c7bb835d --- /dev/null +++ b/docs/sendgrid.markdown @@ -0,0 +1,24 @@ +Sendgrid +======== + +You can use the service [Sendgrid](https://sendgrid.com/) to create tasks directly by email. + +This integration works with the [Parse API of Sendgrid](https://sendgrid.com/docs/API_Reference/Webhooks/parse.html). +Kanboard use a webhook to handle incoming emails. + +The [incoming email workflow is described here](http://kanboard.net/documentation/email-tasks). + +Sendgrid configuration +---------------------- + +1. Create a new domain or subdomain (by example **inbound.mydomain.tld**) with a MX record that point to **mx.sendgrid.net** +2. Add your domain and the Kanboard webhook url to [the configuration page in Sendgrid](https://sendgrid.com/developer/reply) + +The Kanboard webhook url is displayed in **Settings > Integrations > Sendgrid** + +Kanboard configuration +---------------------- + +1. Be sure that your users have an email address in their profiles +2. Assign a project identifier to the desired projects: **Project settings > Edit** +3. Try to send an email to your project diff --git a/tests/units/ProjectTest.php b/tests/units/ProjectTest.php index 231d403f9..9f49af8ab 100644 --- a/tests/units/ProjectTest.php +++ b/tests/units/ProjectTest.php @@ -231,6 +231,9 @@ class ProjectTest extends Base $this->assertNotEmpty($project); $this->assertEquals('TEST1', $project['identifier']); + $project = $p->getByIdentifier(''); + $this->assertFalse($project); + // Validation rules $r = $p->validateCreation(array('name' => 'test', 'identifier' => 'TEST1')); $this->assertFalse($r[0]); diff --git a/tests/units/SendgridWebhookTest.php b/tests/units/SendgridWebhookTest.php new file mode 100644 index 000000000..3b30d2127 --- /dev/null +++ b/tests/units/SendgridWebhookTest.php @@ -0,0 +1,107 @@ +container); + $p = new Project($this->container); + $pp = new ProjectPermission($this->container); + $u = new User($this->container); + $tc = new TaskCreation($this->container); + $tf = new TaskFinder($this->container); + + $this->assertEquals(2, $u->create(array('name' => 'me', 'email' => 'me@localhost'))); + + $this->assertEquals(1, $p->create(array('name' => 'test1'))); + $this->assertEquals(2, $p->create(array('name' => 'test2', 'identifier' => 'TEST1'))); + + // Empty payload + $this->assertFalse($w->parsePayload(array())); + + // Unknown user + $this->assertFalse($w->parsePayload(array( + 'envelope' => '{"to":["a@b.c"],"from":"a.b.c"}', + 'subject' => 'Email task' + ))); + + // Project not found + $this->assertFalse($w->parsePayload(array( + 'envelope' => '{"to":["a@b.c"],"from":"me@localhost"}', + 'subject' => 'Email task' + ))); + + // User is not member + $this->assertFalse($w->parsePayload(array( + 'envelope' => '{"to":["something+test1@localhost"],"from":"me@localhost"}', + 'subject' => 'Email task' + ))); + + $this->assertTrue($pp->addMember(2, 2)); + + // The task must be created + $this->assertTrue($w->parsePayload(array( + 'envelope' => '{"to":["something+test1@localhost"],"from":"me@localhost"}', + 'subject' => 'Email task' + ))); + + $task = $tf->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(2, $task['project_id']); + $this->assertEquals('Email task', $task['title']); + $this->assertEquals('', $task['description']); + $this->assertEquals(2, $task['creator_id']); + + // Html content + $this->assertTrue($w->parsePayload(array( + 'envelope' => '{"to":["something+test1@localhost"],"from":"me@localhost"}', + 'subject' => 'Email task', + 'html' => 'bold text', + ))); + + $task = $tf->getById(2); + $this->assertNotEmpty($task); + $this->assertEquals(2, $task['project_id']); + $this->assertEquals('Email task', $task['title']); + $this->assertEquals('**bold** text', $task['description']); + $this->assertEquals(2, $task['creator_id']); + + // Text content + $this->assertTrue($w->parsePayload(array( + 'envelope' => '{"to":["something+test1@localhost"],"from":"me@localhost"}', + 'subject' => 'Email task', + 'text' => '**bold** text', + ))); + + $task = $tf->getById(3); + $this->assertNotEmpty($task); + $this->assertEquals(2, $task['project_id']); + $this->assertEquals('Email task', $task['title']); + $this->assertEquals('**bold** text', $task['description']); + $this->assertEquals(2, $task['creator_id']); + + // Text + html content + $this->assertTrue($w->parsePayload(array( + 'envelope' => '{"to":["something+test1@localhost"],"from":"me@localhost"}', + 'subject' => 'Email task', + 'html' => 'bold html', + 'text' => '**bold** text', + ))); + + $task = $tf->getById(4); + $this->assertNotEmpty($task); + $this->assertEquals(2, $task['project_id']); + $this->assertEquals('Email task', $task['title']); + $this->assertEquals('**bold** html', $task['description']); + $this->assertEquals(2, $task['creator_id']); + } +} diff --git a/tests/units/ToolTest.php b/tests/units/ToolTest.php new file mode 100644 index 000000000..4a62fe3bb --- /dev/null +++ b/tests/units/ToolTest.php @@ -0,0 +1,15 @@ +assertEquals('test1', Tool::getMailboxHash('a+test1@localhost')); + $this->assertEquals('', Tool::getMailboxHash('test1@localhost')); + $this->assertEquals('', Tool::getMailboxHash('test1')); + } +} diff --git a/tests/units/UserTest.php b/tests/units/UserTest.php index c4094ea21..a946621c4 100644 --- a/tests/units/UserTest.php +++ b/tests/units/UserTest.php @@ -10,6 +10,16 @@ use Model\Project; class UserTest extends Base { + public function testGetByEmail() + { + $u = new User($this->container); + $this->assertNotFalse($u->create(array('username' => 'user1', 'password' => '123456', 'email' => 'user1@localhost'))); + $this->assertNotFalse($u->create(array('username' => 'user2', 'password' => '123456', 'email' => ''))); + + $this->assertNotEmpty($u->getByEmail('user1@localhost')); + $this->assertEmpty($u->getByEmail('')); + } + public function testPassword() { $password = 'test123';