diff --git a/application/modules/admin/controllers/NewsletterController.php b/application/modules/admin/controllers/NewsletterController.php index 99e5a7c2a1a3fd6d89e968b610f5d5b163d73c83..95fddc32a97a5af45ae265faeb4f4b4030c0e353 100644 --- a/application/modules/admin/controllers/NewsletterController.php +++ b/application/modules/admin/controllers/NewsletterController.php @@ -112,8 +112,13 @@ function sendNewsletterClick(event) { public function sendAction() { - if ($newsletter = Class_Newsletter::find((int)$this->_getParam('id'))) - $newsletter->send(); + if (!$newsletter = Class_Newsletter::find((int)$this->_getParam('id'))) { + $this->_helper->notify($this->_('Envoi impossible : Newsletter inconnue')); + return $this->_redirectToIndex(); + } + + if (!$newsletter->send()) + $this->_helper->notify($this->_('Envoi impossible : erreur à la création de la commande d\'envoi')); $this->_redirectToIndex(); } @@ -272,4 +277,12 @@ function sendNewsletterClick(event) { 'id' => $model->getId()], null, true), ['prependBase' => false]); } + + + public function showStatusAction() { + $this->view->titre = $this->_('Détails de l\'erreur'); + $this->view->model = Class_Newsletter_Dispatch::find((int)$this->_getParam('id')); + if (!$this->view->model) + throw new Zend_Controller_Action_Exception($this->_('Désolé, cette page n\'existe pas'), 404); + } } \ No newline at end of file diff --git a/application/modules/admin/views/scripts/newsletter/show-status.phtml b/application/modules/admin/views/scripts/newsletter/show-status.phtml new file mode 100644 index 0000000000000000000000000000000000000000..bd088d639a92460e982fc092562f19475b2445ff --- /dev/null +++ b/application/modules/admin/views/scripts/newsletter/show-status.phtml @@ -0,0 +1,2 @@ +<?php +echo $this->tag('p', nl2br($this->model->getErrorMessage())); diff --git a/cosmogramme/php/_init.php b/cosmogramme/php/_init.php index b567a79e5386d5ee557ad2581425fc6778956231..5842c641e270bb809fa84d2d297cc099f2cd6173 100644 --- a/cosmogramme/php/_init.php +++ b/cosmogramme/php/_init.php @@ -1,7 +1,7 @@ <?php error_reporting(E_ERROR | E_PARSE); -define("PATCH_LEVEL","312"); +define("PATCH_LEVEL","313"); define("APPLI","cosmogramme"); define("COSMOPATH", "/var/www/html/vhosts/opac2/www/htdocs"); diff --git a/cosmogramme/sql/patch/patch_313.php b/cosmogramme/sql/patch/patch_313.php new file mode 100644 index 0000000000000000000000000000000000000000..6f2409fa08ce6770a38fac39ff6023c1b3f5fc22 --- /dev/null +++ b/cosmogramme/sql/patch/patch_313.php @@ -0,0 +1,5 @@ +<?php +try { + Zend_Db_Table_Abstract::getDefaultAdapter() + ->query('alter table newsletter_dispatch add error longtext'); +} catch(Exception $e) {} \ No newline at end of file diff --git a/library/Class/Batch/SendNewsletters.php b/library/Class/Batch/SendNewsletters.php index 5da4957ddde360faf27c310ec09b3a9fa664f8d4..d20de23df186ef0af68fc4fa096ecb866c2830ad 100644 --- a/library/Class/Batch/SendNewsletters.php +++ b/library/Class/Batch/SendNewsletters.php @@ -55,16 +55,36 @@ class Class_Batch_SendNewsletters extends Class_Batch_Abstract { public function run() { - $this->getCommand() - ->exec('/usr/bin/php -f ' - . realpath(dirname(__FILE__)) . '/../../../scripts/sendNewsletter.php ' - . $this->getExecParams() - . ' > /dev/null &'); + $shell = '/usr/bin/php -f ' + . realpath(dirname(__FILE__)) . '/../../../scripts/sendNewsletter.php ' + . $this->getExecParams() + . ' > /dev/null & echo $!'; + + $command = $this->getCommand(); + $command->exec($shell); + if ((!$output = $command->getOutput()) + || !is_array($output) + || !$output[0]) { + $this->_endWithError('Unable to run ' . $shell); + return false; + } - return $this; + $command->exec('ps '. $output[0]); + + if (!$success = 0 === $command->getReturnVar()) + $this->_endWithError('Unable to run ' . $shell); + + return $success; } + protected function _endWithError($message) { + $this->_dispatch + ->setError(json_encode(['message' => $message])) + ->beEnded() + ; + } + public function sendOne($email) { if (!$this->_dispatch) @@ -136,6 +156,11 @@ class Class_Batch_SendNewsletters extends Class_Batch_Abstract { } + protected function _checksum($params) { + return sha1(serialize($params)); + } + + public function getTimeLimit() { if (!$this->_time_limit) $this->_time_limit = Class_Systeme_TimeLimit::getInstance(); diff --git a/library/Class/Newsletter.php b/library/Class/Newsletter.php index be96e8d56dc275005074b22d06e0d73d5c5540a1..c030c17eac4689748eedb57bb813aa73e5eaf63a 100644 --- a/library/Class/Newsletter.php +++ b/library/Class/Newsletter.php @@ -99,10 +99,15 @@ class Class_Newsletter extends Storm_Model_Abstract { public function send() { - if (!$dispatch = $this->getLastDispatchInProgress()) - $dispatch = Class_Newsletter_Dispatch::newFrom($this); + return (new Class_Batch_SendNewsletters($this->_getOrCreateDispatchToRun())) + ->run(); + } + - return (new Class_Batch_SendNewsletters($dispatch))->run(); + protected function _getOrCreateDispatchToRun() { + return ($dispatch = $this->getLastDispatch()) && $dispatch->isRunnable() + ? $dispatch->resetError() + : Class_Newsletter_Dispatch::newFrom($this); } @@ -404,11 +409,17 @@ class Class_Newsletter extends Storm_Model_Abstract { return $this->getTitre(); } + public function getLastDispatchInProgress() { return Class_Newsletter_Dispatch::lastDispatchInProgressFor($this); } + public function getLastDispatch() { + return Class_Newsletter_Dispatch::lastDispatchFor($this); + } + + public function getSortedRecipientsByDedicatedAndLabel() { $groups = $this->getRecipientsGroups(); usort( diff --git a/library/Class/Newsletter/Dispatch.php b/library/Class/Newsletter/Dispatch.php index 9cd117e1f585348e83e5c5195ded5e1e875662a7..151d7139f9c3c8e9c225f8f25264e41bfd1cdee9 100644 --- a/library/Class/Newsletter/Dispatch.php +++ b/library/Class/Newsletter/Dispatch.php @@ -46,6 +46,13 @@ class Newsletter_DispatchLoader extends Storm_Model_Loader { 'ended_on' => null]); } + + + public function lastDispatchFor($newsletter) { + return Class_Newsletter_Dispatch::findFirstBy(['newsletter_id' => $newsletter->getId(), + 'order' => 'created_on desc']); + + } } @@ -69,7 +76,8 @@ class Class_Newsletter_Dispatch extends Storm_Model_Abstract { 'users' => ['through' => 'dispatch_users']]; protected $_default_attribute_values = ['collected' => 0, - 'ended_on' => null]; + 'ended_on' => null, + 'error' => null]; public function beforeSave() { @@ -114,10 +122,10 @@ class Class_Newsletter_Dispatch extends Storm_Model_Abstract { $params = ['dispatch_id' => $this->getId(), 'user_id' => $model->getId()]; - if (Class_Newsletter_DispatchUser::findFirstBy($params)) - return; - if (in_array( $model->getMail(),$blacklist_mails)) + if (Class_Newsletter_DispatchUser::findFirstBy($params) + || in_array($model->getMail(), $blacklist_mails)) return; + Class_Newsletter_DispatchUser::newInstance(['dispatch_id' => $this->getId(), 'user_id' => $model->getId(), 'mail' => $model->getMail()]) @@ -146,4 +154,44 @@ class Class_Newsletter_Dispatch extends Storm_Model_Abstract { $this->getNewsletter()->setLastDistributionDateWithFormat(); return $this; } + + + public function getErrorMessage() { + if (!$this->hasError() + || (!$json = json_decode($this->getError(), true)) + || !array_key_exists('message', $json)) + return ''; + + return $json['message']; + } + + + public function isRunnable() { + return $this->isInProgress() || $this->canRetry(); + } + + + public function canRetry() { + return $this->hasError() + && $this->getCollected() + && $this->numberOfDoneUsers() < $this->numberOfDispatchUsers(); + } + + + public function isInProgress() { + return !$this->hasEndedOn(); + } + + + public function resetError() { + if (!$this->canRetry()) + return $this; + + $this + ->setError(null) + ->setEndedOn(null) + ->save(); + + return $this; + } } diff --git a/library/ZendAfi/View/Helper/GetSendProgressJsonFor.php b/library/ZendAfi/View/Helper/GetSendProgressJsonFor.php index 2594f408ce1444c54eac1dac4d672621f31d15c2..c65a3d540cbeebbe080ef3e285701f49211e00a5 100644 --- a/library/ZendAfi/View/Helper/GetSendProgressJsonFor.php +++ b/library/ZendAfi/View/Helper/GetSendProgressJsonFor.php @@ -21,27 +21,39 @@ class ZendAfi_View_Helper_getSendProgressJsonFor extends ZendAfi_View_Helper_BaseHelper { public function getSendProgressJsonFor($newsletter) { - if(!$newsletter) + if (!$newsletter) return $this->_toStatus($this->_('Newsletter inconnue')); - ($last_date = DateTime::createFromFormat("Y-m-d H:i:s", $newsletter->getLastDistributionDate())) - ? $last_date_text = $this->_toStatus($last_date->format("d/m/Y H:i")) + ($last_date = DateTime::createFromFormat('Y-m-d H:i:s', $newsletter->getLastDistributionDate())) + ? $last_date_text = $this->_toStatus($last_date->format('d/m/Y H:i')) : $last_date_text = $this->_toStatus($this->_('Aucune')); - if(!$dispatch = $newsletter->getLastDispatchInProgress()) + if (!$dispatch = $newsletter->getLastDispatch()) return $last_date_text; - if($dispatch->getCollected() && (!$dispatch->hasEndedOn())) - return array_merge($this->_toStatus($this->_('en cours')), + if (!$dispatch->hasEndedOn()) + return array_merge($this->_toStatus(!$dispatch->getCollected() + ? $this->_('collecte des destinataires') + : $this->_('envoi en cours')), ['done' => $dispatch->numberOfDoneUsers(), 'total' => $dispatch->numberOfDispatchUsers()]); - if(!$last_date) { - $dispatch->delete(); - return $last_date_text; - } + return $dispatch->hasError() + ? $this->_toStatus($this->_tag('a', $this->_('Erreur lors de l\'envoi'), + ['data-popup' => 'true', + 'href' => $this->view->url(['module' => 'admin', + 'controller' => 'newsletter', + 'action' => 'show-status', + 'id' => $dispatch->getId()], + null, true)]) + . ($dispatch->getCollected() + ? $this->_(', envoyé à %s sur %s', + $dispatch->numberOfDoneUsers(), + $dispatch->numberOfDispatchUsers()) + : $this->_(', aucun mail envoyé'))) - return $this->_toStatus($this->_('échec de l\'envoi')); + : $this->_toStatus($last_date->format('d/m/Y H:i') + . $this->_(', %s mails envoyés', $dispatch->numberOfDoneUsers())); } diff --git a/library/ZendAfi/View/Helper/TagProgressBarForNewsletter.php b/library/ZendAfi/View/Helper/TagProgressBarForNewsletter.php index edb05a1547c30f36aa19335b763fd79fcda07997..61aaf0fa303ba9b6c7ec14ebb9d432ef9b9232ae 100644 --- a/library/ZendAfi/View/Helper/TagProgressBarForNewsletter.php +++ b/library/ZendAfi/View/Helper/TagProgressBarForNewsletter.php @@ -25,20 +25,25 @@ class ZendAfi_View_Helper_TagProgressBarForNewsletter extends ZendAfi_View_Helpe $data_url = $this->view->url(['module'=>'admin', 'controller' => 'newsletter', 'action' => 'send-progress', - 'id' => $newsletter->getId()],null,true); + 'id' => $newsletter->getId()], + null, true); + $progress_data = 'function getNewsletterProgress'.$newsletter->getId().'(){$.getJSON("'.$data_url.'", function (data) {'. - 'if(!data.done || !data.total) {'. - '$("#progress_bar_newsletter_'.$newsletter->getId().'").text(data.status); return true;'. + '$("#progress_bar_newsletter_'.$newsletter->getId().' span").html(data.status);'. + 'if(!data.total) {'. + '$("#progress_bar_newsletter_'.$newsletter->getId().'").html(data.status);'. + 'initializePopups();'. + 'return true;'. '}'. '$("#progress_bar_newsletter_'.$newsletter->getId().'").progressbar({value: data.done, max: data.total});'. - 'setTimeout(function() {getNewsletterProgress'.$newsletter->getId().'()}, 100);'. + 'setTimeout(function() {getNewsletterProgress'.$newsletter->getId().'();}, 100);'. '})};'; Class_ScriptLoader::getInstance() ->addInlineScript($progress_data) ->addJQueryReady('getNewsletterProgress'.$newsletter->getId().'()'); - return $this->_tag('div', '', + return $this->_tag('div', $this->_tag('span', ''), ['id' => 'progress_bar_newsletter_' . $newsletter->getId()]); } } \ No newline at end of file diff --git a/scripts/sendNewsletter.php b/scripts/sendNewsletter.php index 467cf67a308039bc00a7bbdb43bb7a0889458ae5..a90e862f4877919ab885d9686dfe0d932592ecb0 100644 --- a/scripts/sendNewsletter.php +++ b/scripts/sendNewsletter.php @@ -22,22 +22,29 @@ define('BASE_URL', $argv[3]); $_SERVER['SERVER_NAME'] = $argv[2]; $_SERVER['HTTP_HOST'] = $argv[1]; +$dispatch_id = $argv[4]; -set_include_path('.' - . PATH_SEPARATOR .realpath(dirname(__FILE__)). '/../library' - . PATH_SEPARATOR .realpath(dirname(__FILE__)). '/../library/storm/zf/library' - . PATH_SEPARATOR .realpath(dirname(__FILE__)). '/../library/storm/src' - . PATH_SEPARATOR .realpath(dirname(__FILE__)).'/../library/Class' - . PATH_SEPARATOR .realpath(dirname(__FILE__)).'/../library/ZendAfi' -. PATH_SEPARATOR . realpath(dirname(__FILE__)).'/../application/modules' -. PATH_SEPARATOR . realpath(dirname(__FILE__)).'/application/modules' - ); +require_once 'includes.php'; -include_once "local.php"; -include_once "fonctions/fonctions.php"; -require_once "Zend/Loader.php"; -require_once "startup.php"; +$bokeh = (new Bokeh_Engine())->warmUp(); +if ('test' != $dispatch_id + && (!$dispatch = Class_Newsletter_Dispatch::find($dispatch_id))) { + printf("Unkown dispatch %s\n", $dispatch_id); + exit(1); +} -setupOpac(); +$my_shutdown = function() use ($dispatch) { + if (!$error = error_get_last()) + return; -Class_Newsletter_Dispatch::find($argv[4])->sendBy(20); \ No newline at end of file + if (E_ERROR === $error['type']) + $dispatch->setError(json_encode($error)) + ->beEnded(); +}; + +register_shutdown_function($my_shutdown); + +$bokeh->powerOn(); + +if ($dispatch) + $dispatch->sendBy(20); \ No newline at end of file diff --git a/tests/application/modules/admin/controllers/NewsletterControllerTest.php b/tests/application/modules/admin/controllers/NewsletterControllerTest.php index ba176878c36da75407e33f2ea74bcf06fd71796d..44b5a7511761730bb0a84d0fe93fd707689504bb 100644 --- a/tests/application/modules/admin/controllers/NewsletterControllerTest.php +++ b/tests/application/modules/admin/controllers/NewsletterControllerTest.php @@ -485,15 +485,15 @@ class Admin_NewsletterControllerSendInProgressActionTest extends Admin_Newslette parent::setUp(); $this->_command = $this->mock() - ->whenCalled('exec') - ->answers(true); + ->whenCalled('exec')->answers(true) + ->whenCalled('getOutput')->answers(['999']) + ->whenCalled('getReturnVar')->answers(0); Class_Batch_SendNewsletters::setCommand($this->_command); Class_Newsletter_Dispatch::setTimeSource(new TimeSourceForTest('2016-07-21 11:21:38')); - $dispatch=Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(2)); + $dispatch = Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(2)); $dispatch->assertSave(); - $dispatch->collectRecipients(); $this->dispatch('/admin/newsletter/send/id/2', true); $this->_dispatch = Class_Newsletter::find(2)->getDispatchs()[0]; @@ -514,7 +514,108 @@ class Admin_NewsletterControllerSendInProgressActionTest extends Admin_Newslette -class Admin_NewsletterControllerSendActionTest extends Admin_NewsletterControllerTestCase { +class Admin_NewsletterControllerSendPreviouslyNotCollectedErrorActionTest + extends Admin_NewsletterControllerTestCase { + + protected + $_command, + $_dispatch; + + public function setUp() { + parent::setUp(); + + $this->_command = $this->mock() + ->whenCalled('exec')->answers(true) + ->whenCalled('getOutput')->answers(['999']) + ->whenCalled('getReturnVar')->answers(0); + + Class_Batch_SendNewsletters::setCommand($this->_command); + Class_Newsletter_Dispatch::setTimeSource(new TimeSourceForTest('2016-07-21 11:21:38')); + + Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(2)) + ->setError(json_encode(['message' => 'An error occurred'])) + ->setEndedOn('2012-10-26 12:03:45') + ->assertSave(); + + $this->dispatch('/admin/newsletter/send/id/2', true); + } + + + public function tearDown() { + Class_Batch_SendNewsletters::setCommand(null); + parent::tearDown(); + } + + + /** @test */ + public function shouldHaveCreateAnotherDispatch() { + $this->assertEquals(2, Class_Newsletter::find(2)->numberOfDispatchs()); + } + + + /** @test */ + public function shouldHaveADispatchInProgress() { + $this->assertNotNull(Class_Newsletter::find(2)->getLastDispatchInProgress()); + } +} + + + +class Admin_NewsletterControllerSendPreviouslyCollectedErrorActionTest + extends Admin_NewsletterControllerTestCase { + + protected + $_command, + $_dispatch; + + public function setUp() { + parent::setUp(); + + $this->_command = $this->mock() + ->whenCalled('exec')->answers(true) + ->whenCalled('getOutput')->answers(['999']) + ->whenCalled('getReturnVar')->answers(0); + + Class_Batch_SendNewsletters::setCommand($this->_command); + Class_Newsletter_Dispatch::setTimeSource(new TimeSourceForTest('2016-07-21 11:21:38')); + + Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(2)) + ->setCollected(true) + ->setDispatchUsers([$this->fixture('Class_Newsletter_DispatchUser', + ['id' => '15', 'sent' => 1]), + $this->fixture('Class_Newsletter_DispatchUser', + ['id' => '16', 'sent' => 0])]) + ->setError(json_encode(['message' => 'An error occurred'])) + ->setEndedOn('201-10-26 12:03:45') + ->assertSave(); + + $this->dispatch('/admin/newsletter/send/id/2', true); + } + + + public function tearDown() { + Class_Batch_SendNewsletters::setCommand(null); + parent::tearDown(); + } + + + /** @test */ + public function shouldHaveOnlyOneDispatch() { + $this->assertEquals(1, Class_Newsletter::find(2)->numberOfDispatchs()); + } + + + /** @test */ + public function shouldHaveADispatchInProgress() { + $this->assertNotNull(Class_Newsletter::find(2)->getLastDispatchInProgress()); + } +} + + + +class Admin_NewsletterControllerSendPreviouslyCollectedErrorButAllSentActionTest + extends Admin_NewsletterControllerTestCase { + protected $_command, $_dispatch; @@ -523,8 +624,61 @@ class Admin_NewsletterControllerSendActionTest extends Admin_NewsletterControlle parent::setUp(); $this->_command = $this->mock() - ->whenCalled('exec') - ->answers(true); + ->whenCalled('exec')->answers(true) + ->whenCalled('getOutput')->answers(['999']) + ->whenCalled('getReturnVar')->answers(0); + + Class_Batch_SendNewsletters::setCommand($this->_command); + Class_Newsletter_Dispatch::setTimeSource(new TimeSourceForTest('2016-07-21 11:21:38')); + + Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(2)) + ->setCollected(true) + ->setDispatchUsers([$this->fixture('Class_Newsletter_DispatchUser', + ['id' => '15', 'sent' => 1]), + $this->fixture('Class_Newsletter_DispatchUser', + ['id' => '16', 'sent' => 1])]) + ->setError(json_encode(['message' => 'An error occurred'])) + ->setEndedOn('201-10-26 12:03:45') + ->assertSave(); + + $this->dispatch('/admin/newsletter/send/id/2', true); + } + + + public function tearDown() { + Class_Batch_SendNewsletters::setCommand(null); + parent::tearDown(); + } + + + /** @test */ + public function shouldHaveOnlyOneDispatch() { + $this->assertEquals(2, Class_Newsletter::find(2)->numberOfDispatchs()); + } + + + /** @test */ + public function shouldHaveADispatchInProgress() { + $this->assertNotNull(Class_Newsletter::find(2)->getLastDispatchInProgress()); + } +} + + + +class Admin_NewsletterControllerSendActionTest + extends Admin_NewsletterControllerTestCase { + + protected + $_command, + $_dispatch; + + public function setUp() { + parent::setUp(); + + $this->_command = $this->mock() + ->whenCalled('exec')->answers(true) + ->whenCalled('getOutput')->answers(['999']) + ->whenCalled('getReturnVar')->answers(0); Class_Batch_SendNewsletters::setCommand($this->_command); Class_Newsletter_Dispatch::setTimeSource(new TimeSourceForTest('2016-07-21 11:21:38')); @@ -555,7 +709,14 @@ class Admin_NewsletterControllerSendActionTest extends Admin_NewsletterControlle /** @test */ public function commandShouldHaveBeenCalledWithDispatchId() { $this->assertContains(' "' . $this->_dispatch->getId() . '" ', - $this->_command->getFirstAttributeForLastCallOn('exec')); + $this->_command->getFirstAttributeForMethodCallAt('exec', 0)); + } + + + /** @test */ + public function commandShouldHaveBeenCalledWithBackgroudProcessId() { + $this->assertEquals('ps 999', + $this->_command->getFirstAttributeForMethodCallAt('exec', 1)); } @@ -589,6 +750,54 @@ Lien pour se désinscrire de cette lettre d\'information : '. ROOT_URL . BASE_UR +class Admin_NewsletterControllerSendActionWithCommandFailureTest extends Admin_NewsletterControllerTestCase { + protected + $_command, + $_dispatch; + + public function setUp() { + parent::setUp(); + + $this->_command = $this->mock() + ->whenCalled('exec')->answers(true) + ->whenCalled('getOutput')->answers(['999']) + ->whenCalled('getReturnVar')->answers(1); + + Class_Batch_SendNewsletters::setCommand($this->_command); + Class_Newsletter_Dispatch::setTimeSource(new TimeSourceForTest('2016-07-21 11:21:38')); + + $this->dispatch('/admin/newsletter/send/id/2', true); + $this->_dispatch = Class_Newsletter::find(2)->getDispatchs()[0]; + } + + + public function tearDown() { + Class_Batch_SendNewsletters::setCommand(null); + parent::tearDown(); + } + + + /** @test */ + public function shouldNotifyCommandError() { + $this->assertFlashMessengerContentContains('Envoi impossible : erreur à la création de la commande d\'envoi'); + } + + + /** @test */ + public function dispatchShouldHaveError() { + $this->assertContains('Unable to run /usr/bin/php -f', + $this->_dispatch->getErrorMessage()); + } + + + /** @test */ + public function dispatchShouldBeEnded() { + $this->assertTrue($this->_dispatch->hasEndedOn()); + } +} + + + class Admin_NewsletterControllerPreviewActionTest extends Admin_NewsletterControllerTestCase { public function setUp() { @@ -1252,10 +1461,7 @@ class Admin_NewsletterControllerScriptTest extends Admin_NewsletterControllerTes abstract class Admin_NewsletterControllerSendProgressTestCase extends Admin_NewsletterControllerTestCase { - protected - $_storm_default_to_volatile = true, - $_json; - + protected $_json; public function setUp() { parent::setUp(); @@ -1278,7 +1484,7 @@ class Admin_NewsletterControllerSendProgressWithWrongNewsletterIdTest extends Ad /** @test */ - public function progressShouldReturnJsonUnknownNewsletter() { + public function statusShouldBeUnknownNewsletter() { $this->assertEquals('Newsletter inconnue', $this->_json->status); } @@ -1290,81 +1496,99 @@ class Admin_NewsletterControllerSendProgressWithWrongNewsletterIdTest extends Ad -class Admin_NewsletterControllerSendProgressErrorTest extends Admin_NewsletterControllerSendProgressTestCase { - - /** @test */ - public function progressShouldReturnError() { - $this->assertEquals('échec de l\'envoi', $this->_json->status); - } - +class Admin_NewsletterControllerSendProgressWithErrorAndNothingSentTest + extends Admin_NewsletterControllerSendProgressTestCase { protected function _dispatch() { - Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(1))->assertSave(); + Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(1)) + ->setError(json_encode(['message' => 'an error occured'])) + ->setEndedOn('2016-10-27') + ->assertSave(); + parent::_dispatch(); } -} - - -class Admin_NewsletterControllerSendProgressWithErrorTest extends Admin_NewsletterControllerSendProgressTestCase { /** @test */ - public function progressShouldReturnError() { - $this->assertEquals('Aucune', $this->_json->status); + public function statusShouldContainsError() { + $this->assertContains('Erreur lors de l\'envoi', $this->_json->status); } /** @test */ - public function newsletterDispatchTableShouldBeEmpty() { - $this->assertEmpty(Class_Newsletter_Dispatch::findAll()); + public function statusShouldContainsNothingSent() { + $this->assertContains('aucun mail envoyé', $this->_json->status); } +} + +class Admin_NewsletterControllerSendProgressWithErrorAnd1Of2SentTest + extends Admin_NewsletterControllerSendProgressTestCase { + protected function _dispatch() { - $newsletter = Class_Newsletter::find(1); - $newsletter->setLastDistributionDate('')->assertSave(); - Class_Newsletter_Dispatch::newFrom($newsletter)->assertSave(); + $albator = $this->fixture('Class_Newsletter_DispatchUser', + ['id' => '15', 'sent' => 1]); + $nausicaa = $this->fixture('Class_Newsletter_DispatchUser', + ['id' => '16', 'sent' => 0]); + + Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(1)) + ->setCollected(true) + ->setDispatchUsers([$albator, $nausicaa]) + ->setError(json_encode(['message' => 'an error occured'])) + ->setEndedOn('2016-10-27') + ->assertSave(); + parent::_dispatch(); } -} + /** @test */ + public function statusShouldContainsError() { + $this->assertContains('Erreur lors de l\'envoi', $this->_json->status); + } + -class Admin_NewsletterControllerSendProgressTest extends Admin_NewsletterControllerSendProgressTestCase { /** @test */ - public function progressShouldReturnSending() { - $this->assertEquals('{"status":"en cours","done":0,"total":3}', $this->_response->getBody()); + public function statusShouldContains1Of2Sent() { + $this->assertContains('envoyé à 1 sur 2', $this->_json->status); } +} - protected function _dispatch() { - $dispatch = Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(1)); - $dispatch->assertSave(); - $dispatch->collectRecipients(); +class Admin_NewsletterControllerSendProgressNeverSentTest + extends Admin_NewsletterControllerSendProgressTestCase { + + protected function _dispatch() { + Class_Newsletter::find(1)->setLastDistributionDate('')->assertSave(); parent::_dispatch(); } + + + /** @test */ + public function progressShouldReturnNeverSent() { + $this->assertEquals('Aucune', $this->_json->status); + } } -class Admin_NewsletterControllerNeverSendTest extends Admin_NewsletterControllerTestCase { - public function setUp() { - parent::setUp(); +class Admin_NewsletterControllerSendProgressWorkingTest + extends Admin_NewsletterControllerSendProgressTestCase { - $this->fixture('Class_Newsletter', - ['id' => 3, - 'titre' => 'News of the Juny', - 'contenu' => 'A lot of new stuff', - 'last_distribution_date' => '']); + protected function _dispatch() { + $dispatch = Class_Newsletter_Dispatch::newFrom(Class_Newsletter::find(1)); + $dispatch->assertSave(); + $dispatch->collectRecipients(); - $this->dispatch('admin/newsletter/send-progress/id/3', true); + parent::_dispatch(); } /** @test */ - public function progressShouldReturnNeverSendSending() { - $this->assertEquals('{"status":"Aucune"}', $this->_response->getBody()); + public function progressShouldReturnSending() { + $this->assertEquals('{"status":"envoi en cours","done":0,"total":3}', $this->_response->getBody()); } } @@ -1574,3 +1798,34 @@ class Admin_NewsletterControllerEditSubcsriberReSubscriptionTest } } + + + +class Admin_NewsletterControllerShowStatusActionTest + extends Admin_NewsletterControllerTestCase { + + /** @test */ + public function withErrorShouldDisplayMessage() { + $this->fixture('Class_Newsletter_Dispatch', ['id' => 14]) + ->setCollected(true) + ->setError(json_encode(['message' => 'An error occurred'])) + ->setEndedOn('201-10-26 12:03:45') + ->assertSave(); + + $this->dispatch('/admin/newsletter/show-status/id/14', true); + $this->assertXPathContentContains('//p', 'An error occurred', + $this->_response->getBody()); + } + + + /** @test */ + public function withoutDispatchShouldBe404Error() { + try { + $this->dispatch('/admin/newsletter/show-status/id/14', true); + } catch(Zend_Controller_Action_Exception $e) { + $this->assertEquals(404, $e->getCode()); + return; + } + $this->fail('should have 404 error'); + } +} \ No newline at end of file diff --git a/tests/db/UpgradeDBTest.php b/tests/db/UpgradeDBTest.php index 273b0d3d5b6d1f954efc32c78532e16abd552124..180c2838f5a89f680a7194a5998e790f54c16a0d 100644 --- a/tests/db/UpgradeDBTest.php +++ b/tests/db/UpgradeDBTest.php @@ -1134,3 +1134,19 @@ class UpgradeDB_312_Test extends UpgradeDBTestCase { $this->assertFieldType('ouvertures', 'multimedia', 'tinyint(1)'); } } + + + +class UpgradeDB_313_Test extends UpgradeDBTestCase { + public function prepare() { + try { + $this->query('alter table newsletter_dispatch drop column error'); + } catch(Exception $e) {} + } + + + /** @test */ + public function dispatchShouldHaveErrorColumn() { + $this->assertFieldType('newsletter_dispatch', 'error', 'longtext'); + } +} diff --git a/tests/scripts/SendNewsletterTest.php b/tests/scripts/SendNewsletterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6e7ec3e7f9a8358ad5a06f387cb124e08eba5ef7 --- /dev/null +++ b/tests/scripts/SendNewsletterTest.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class Scripts_SendNewsletterTest extends PHPUnit_Framework_TestCase { + /** @test */ + public function shouldSucceed() { + exec('cd ' . __DIR__ . '/../.. && php -f scripts/sendNewsletter.php "localhost" "localhost" "" "test"', + $output, $result); + + $this->assertEquals(0, $result, implode("\n", $output)); + } +} \ No newline at end of file