Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replacing Ushahidi_Mailer with a Lumen implementation
Browse files Browse the repository at this point in the history
- Add new implementation
- Add illuminate/mail
- Add mockery for tests
- Add tests
rjmackay committed Jul 4, 2017
1 parent 82454c1 commit c83293d
Showing 11 changed files with 719 additions and 135 deletions.
7 changes: 7 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ public function register()
$this->app->configure('cdn');
$this->app->configure('ratelimiter');
$this->app->configure('multisite');
$this->app->configure('mail');

$this->configureAuraDI();
}
@@ -126,6 +127,12 @@ protected function configureAuraDI()
return '';
});

// Configure mailer
$di->set('tool.mailer', $di->lazyNew('Ushahidi\App\Tools\LumenMailer', [
'mailer' => app('mailer'),
'siteConfig' => $di->lazyGet('site.config'),
'clientUrl' => $di->lazyGet('clienturl')
]));

// @todo move to auth provider?
$di->set('session.user', function () use ($di) {
77 changes: 77 additions & 0 deletions app/Tools/LumenMailer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

/**
* Ushahidi Mailer
*
* @author Ushahidi Team <team@ushahidi.com>
* @package Ushahidi\Application
* @copyright 2014 Ushahidi
* @license https://www.gnu.org/licenses/agpl-3.0.html GNU Affero General Public License Version 3 (AGPL3)
*/

namespace Ushahidi\App\Tools;

use Ushahidi\Core\Tool\Mailer as MailerContract;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Support\Str;

class LumenMailer implements MailerContract
{
public function __construct(Mailer $mailer, $siteConfig, $clientUrl)
{
$this->mailer = $mailer;
$this->siteConfig = $siteConfig;
$this->clientUrl = $clientUrl;
}

public function send($to, $type, Array $params = null)
{
// Only available type right now is 'resetpassword'
$method = "send" . Str::ucfirst($type);
if (method_exists($this, $method)) {
$this->$method($to, $params);
} else {
// Exception
throw new Exception('Unsupported mail type: ' + $type);
}
}

protected function sendResetpassword($to, $params)
{
$site_name = $this->siteConfig['name'];
$site_email = $this->siteConfig['email'];
$multisite_email = config('multisite.email');

// @todo make this more robust
if ($multisite_email) {
$from_email = $multisite_email;
} elseif ($site_email) {
$from_email = $site_email;
} else {
$from_email = false;
// Get host from lumen
// $host = app()->make('request')->getHost();
// $from_email = 'noreply@' . $host;
}

$data = [
'site_name' => $site_name,
'token' => $params['token'],
'client_url' => $this->clientUrl
];

$subject = $site_name . ': Password reset';

$this->mailer->send(
'emails/forgot-password',
$data,
function ($message) use ($to, $subject, $from_email, $site_name) {
$message->to($to);
$message->subject($subject);
if ($from_email) {
$message->from($from_email, $site_name);
}
}
);
}
}
8 changes: 2 additions & 6 deletions application/classes/Ushahidi/Core.php
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ public static function init()
* 0. Register depenendencies for injection.
*/
$di = service();

/*
// Kohana injection
// DB config
$di->set('db.config', function() use ($di) {
@@ -50,11 +50,7 @@ public static function init()
return getenv('INTERCOM_APP_TOKEN');
});
$di->set('tool.mailer', $di->lazyNew('Ushahidi_Mailer', [
'siteConfig' => $di->lazyGet('site.config'),
'clientUrl' => $di->lazyGet('clienturl')
]));

*/
/**
* 1. Load the plugins
*/
1 change: 1 addition & 0 deletions bootstrap/lumen.php
Original file line number Diff line number Diff line change
@@ -76,6 +76,7 @@
|
*/

$app->register(Illuminate\Mail\MailServiceProvider::class);
$app->register(Ushahidi\App\Providers\AppServiceProvider::class);
$app->register(Ushahidi\App\Providers\AuthServiceProvider::class);
// $app->register(Ushahidi\App\Providers\EventServiceProvider::class);
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@
"kohana/minion" : "3.3.*@dev",
"ohanzee/database": "dev-namespaces",
"robmorgan/phinx": "~0.8.0",
"ushahidi/shadowhand-email": "dev-master",
"symm/gisconverter": "~1.0.5",
"twilio/sdk": "3.12.*",
"vlucas/phpdotenv": "~2.2",
@@ -53,7 +52,9 @@
"sentry/sentry": "~1.5",
"dusterio/lumen-passport": "^0.1.9",
"barryvdh/laravel-cors": "^0.9.2",
"ushahidi/kohana-validation": "dev-master"
"ushahidi/kohana-validation": "dev-master",
"illuminate/mail": "5.4.*",
"mockery/mockery": "^0.9.9"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
449 changes: 323 additions & 126 deletions composer.lock

Large diffs are not rendered by default.

124 changes: 124 additions & 0 deletions config/mail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

return [

/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill", "ses", "log"
|
*/

'driver' => env('MAIL_DRIVER', 'mail'),

/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/

'host' => env('MAIL_HOST', 'smtp.mailgun.org'),

/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/

'port' => env('MAIL_PORT', 587),

/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/

'from' => ['address' => env('MAIL_ADDRESS'), 'name' => env('MAIL_NAME')],

/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/

'encryption' => env('MAIL_ENCRYPTION', 'tls'),

/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/

'username' => env('MAIL_USERNAME'),

/*
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/

'password' => env('MAIL_PASSWORD'),

/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/

'sendmail' => '/usr/sbin/sendmail -bs',

/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/

'pretend' => env('MAIL_PRETEND', false),

];
2 changes: 2 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -30,5 +30,7 @@
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="MAIL_DRIVER" value="log"/>
<env name="MAIL_PRETEND" value="true"/>
</php>
</phpunit>
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/TestCase.php
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

namespace Tests;

abstract class TestCase extends Laravel\Lumen\Testing\TestCase
abstract class TestCase extends \Laravel\Lumen\Testing\TestCase
{
/**
* Creates the application.
179 changes: 179 additions & 0 deletions tests/unit/App/Tools/LumenMailerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<?php

/**
* Unit tests for Lumen implementation of Ushahidi\Core\Tool\Mailer
*
* @author Ushahidi Team <team@ushahidi.com>
* @package Ushahidi\Application\Tests
* @copyright 2013 Ushahidi
* @license https://www.gnu.org/licenses/agpl-3.0.html GNU Affero General Public License Version 3 (AGPL3)
*/

namespace Tests\Unit\App\Tools;

use Ushahidi\App\Tools\LumenMailer;
// use Illuminate\Support\Facades\Mail;
use Tests\TestCase;
use Mockery as M;

/**
* @backupGlobals disabled
* @preserveGlobalState disabled
*/
class LumenMailerTest extends TestCase
{

protected function buildMailer() {

}

public function testSendWithMultisite() {
config([
'mail.pretend' => true
]);

config([
'multisite.email' => 'deploy@multisite.ushahidi.app'
]);

$illuminateMailer = M::spy(app('mailer'));

$mailer = new LumenMailer(
$illuminateMailer,
[
'name' => 'TestDeploy',
'email' => 'test@ushahidi.app'
],
'https://ushahidi.app/'
);

$mailer->send('noone@ushahidi.com', 'Resetpassword', [
'token' => 'abc123'
]);

$illuminateMailer->shouldHaveReceived('send')
->once()
->with(
'emails/forgot-password',
M::on(function($data) {
$this->assertArrayHasKey( 'site_name', $data );
$this->assertArrayHasKey( 'token', $data );
$this->assertArrayHasKey( 'client_url', $data );

return true;
}),
M::on(function(\Closure $closure) {
$mock = M::mock('Illuminate\Mailer\Message');
$mock->shouldReceive('to')->once()->with('noone@ushahidi.com')
->andReturn($mock); // simulate the chaining
$mock->shouldReceive('from')->once()->with('deploy@multisite.ushahidi.app', 'TestDeploy')
->andReturn($mock); // simulate the chaining
$mock->shouldReceive('subject')->once()->with('TestDeploy: Password reset')
->andReturn($mock); // simulate the chaining

$closure($mock);
return true;
})
);
}

public function testSendWithSiteEmail() {
config([
'mail.pretend' => true
]);

config([
'multisite.email' => false
]);

$illuminateMailer = M::spy(app('mailer'));

$mailer = new LumenMailer(
$illuminateMailer,
[
'name' => 'TestDeploy',
'email' => 'test@ushahidi.app'
],
'https://ushahidi.app/'
);

$mailer->send('noone@ushahidi.com', 'Resetpassword', [
'token' => 'abc123'
]);

$illuminateMailer->shouldHaveReceived('send')
->once()
->with(
'emails/forgot-password',
M::on(function($data) {
$this->assertArrayHasKey( 'site_name', $data );
$this->assertArrayHasKey( 'token', $data );
$this->assertArrayHasKey( 'client_url', $data );

return true;
}),
M::on(function(\Closure $closure) {
$mock = M::mock('Illuminate\Mailer\Message');
$mock->shouldReceive('to')->once()->with('noone@ushahidi.com')
->andReturn($mock); // simulate the chaining
$mock->shouldReceive('from')->once()->with('test@ushahidi.app', 'TestDeploy')
->andReturn($mock); // simulate the chaining
$mock->shouldReceive('subject')->once()->with('TestDeploy: Password reset')
->andReturn($mock); // simulate the chaining

$closure($mock);
return true;
})
);
}

public function testSendWithFallbackEmail() {

config([
'mail.pretend' => true
]);

config([
'multisite.email' => false
]);

$illuminateMailer = M::spy(app('mailer'));

$mailer = new LumenMailer(
$illuminateMailer,
[
'name' => 'TestDeploy',
'email' => false
],
'https://ushahidi.app/'
);

$mailer->send('noone@ushahidi.com', 'Resetpassword', [
'token' => 'abc123'
]);

$illuminateMailer->shouldHaveReceived('send')
->once()
->with(
'emails/forgot-password',
M::on(function($data) {
$this->assertArrayHasKey( 'site_name', $data );
$this->assertArrayHasKey( 'token', $data );
$this->assertArrayHasKey( 'client_url', $data );

return true;
}),
M::on(function(\Closure $closure) {
$mock = M::mock('Illuminate\Mailer\Message');
$mock->shouldReceive('to')->once()->with('noone@ushahidi.com')
->andReturn($mock); // simulate the chaining
$mock->shouldNotReceive('from');
$mock->shouldReceive('subject')->once()->with('TestDeploy: Password reset')
->andReturn($mock); // simulate the chaining

$closure($mock);
return true;
})
);
}
}

0 comments on commit c83293d

Please sign in to comment.