Ярлыки

.htaccess (4) тестирование (8) шаблоны проектирования (3) css (5) Debian (6) docker (2) Doctrine2 (6) Git (6) html (4) java (6) javascript (13) jquery (11) LFS (3) linux (23) mac os (4) mod_rewrite (2) MSSQL (4) MySQL (18) ORM Doctrine (17) patterns (3) PDO (3) perl (7) PHP (64) PHPUnit (8) Python (15) SEO (2) Silex (1) SimpleXML (1) SQL (14) ssh (4) Ubuntu (24) Yii1 (1) Zend Framework (19) ZendFramework2 (8)

пятница, 19 декабря 2014 г.

PHPUnit. Тестирование отправки почты с Mailcatcher.

Устанавливаем Mailcatcher, локальный smtp-сервер, вся отправляем почта остается на машине разработчика:
$ sudo apt-get install -y libsqlite3-dev ruby-dev

$sudo gem install mailcatcher

$ mailcatcher --help
Usage: mailcatcher [options]
        --ip IP                      Set the ip address of both servers
        --smtp-ip IP                 Set the ip address of the smtp server
        --smtp-port PORT             Set the port of the smtp server
        --http-ip IP                 Set the ip address of the http server
        --http-port PORT             Set the port address of the http server
    -f, --foreground                 Run in the foreground
    -v, --verbose                    Be more verbose
    -h, --help                       Display this help information

$ mailcatcher
Настраиваем запуск демона при перезагрузке: создаем /etc/init/mailcatcher.conf
description "Mailcatcher"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

exec /usr/bin/env $(which mailcatcher) --foreground --http-ip=0.0.0.0
Далее возможно управлять демоном:
sudo service mailcatcher status
sudo service mailcatcher start
sudo service mailcatcher restart
sudo service mailcatcher stop
Веб-интервейс сервиса теперь доступен по адресу http://localhost:1080
Настраиваем php на отправку почты через mailchecker:
echo "sendmail_path = /usr/bin/env $(which catchmail) -f test@local.dev" | sudo tee /etc/php5/mods-available/mailcatcher.ini

sudo php5enmod mailcatcher

# Перезапуск Apache если используем mod_php
sudo service apache2 restart

# Перезапуск PHP-FPM если используем FPM
sudo service php5-fpm restart
Тестируем отправку почты!
// EmailTestCase.php

class EmailTestCase extends PHPUnit_Framework_TestCase
{

    /**
     * @var \Guzzle\Http\Client
     */
    private $mailcatcher;

    public function setUp()
    {
        $this->mailcatcher = 
            new \Guzzle\Http\Client('http://127.0.0.1:1080');

        // clean emails between tests
        $this->cleanMessages();
    }
    
    public function tearDown()
    {
        $this->cleanMessages();
    }

    // api calls
    public function cleanMessages()
    {
        $this->mailcatcher->delete('/messages')->send();
    }

    public function getLastMessage()
    {
        $messages = $this->getMessages();
        if (empty($messages)) {
            $this->fail("No messages received");
        }
        // messages are in descending order
        return reset($messages);
    }

    public function getMessages()
    {
        $jsonResponse = $this->mailcatcher->get('/messages')->send();
        return json_decode($jsonResponse->getBody());
    }

    // assertions
    public function assertEmailIsSent($description = '')
    {
        $this->assertNotEmpty($this->getMessages(), $description);
    }

    public function assertEmailSubjectContains($needle, $email, 
        $description = '')
    {
        $this->assertContains(
            $needle,
            $email->subject, 
            $description
        );
    }

    public function assertEmailSubjectEquals($expected, $email, 
         $description = '')
    {
        $this->assertContains(
            $expected,
            $email->subject,
            $description
        );
    }

    public function assertEmailHtmlContains($needle, $email, 
         $description = '')
    {
        $response = $this->mailcatcher
            ->get("/messages/{$email->id}.html")->send();
        $this->assertContains(
            $needle, 
            (string) $response->getBody(), 
            $description
        );
    }

    public function assertEmailTextContains($needle, $email, 
         $description = '')
    {
        $response = $this->mailcatcher
             ->get("/messages/{$email->id}.plain")->send();
        $this->assertContains(
            $needle, 
            (string) $response->getBody(),
            $description
        );
    }

    public function assertEmailSenderEquals($expected, $email, 
         $description = '')
    {
        $response = $this->mailcatcher
            ->get("/messages/{$email->id}.json")->send();
        $email = json_decode($response->getBody());
        $this->assertEquals( 
             $expected,
             $email->sender,
             $description
        );
    }

    public function assertEmailRecipientsContain($needle, $email, 
         $description = '')
    {
        $response = $this->mailcatcher
            ->get("/messages/{$email->id}.json")->send();
        $email = json_decode($response->getBody());
        $this->assertContains( 
            $needle,
            $email->recipients,
            $description
        );
    }

}


// TableRecallsTest.php

require_once TEST_DIR . '/EmailTestCase.php';

class TableRecallsTest extends EmailTestCase
{

    protected $Table;

    public function setUp()
    {
        parent::setUp();
        $this->Table = new TableRecalls();
    }

    public function testSendOnRecall()
    {
        $params = array(
            'id' => 555,
            'position' => 'Test position',
            'email' => 'test@test.com'
        );
        $this->Table->sendOnRecall($params);
        $email = $this->getLastMessage();
        $this->assertEmailSenderEquals("", $email);
        $this->assertEmailRecipientsContain("<{$params['email']}>", $email);
        $this->assertEmailSubjectEquals( 
            TableRecalls::SUBJECT_ON_RECALL,
            $email
        );
        $this->assertEmailTextContains($params['position'], $email);
    }

}