From ee62fd61b2118a03edb5315ba06dc7c160fa5b6f Mon Sep 17 00:00:00 2001 From: Oreolek Date: Wed, 5 Feb 2014 15:10:05 +0700 Subject: [PATCH] Renamed subscriptions to courses. Added a test. --- .gitmodules | 3 + .../{Subscription.php => Course.php} | 40 +++++------ application/classes/Controller/Letter.php | 4 +- .../Model/{Subscription.php => Course.php} | 42 +++++------ application/classes/Model/Letter.php | 6 +- application/classes/Task/Prepare.php | 25 ++++--- .../View/{Subscription => Course}/Index.php | 4 +- .../{Subscription => Course}/Subscribe.php | 4 +- application/classes/View/Layout.php | 2 +- application/config/database.php.example | 15 ++-- application/i18n/ru.php | 7 ++ .../{subscription => course}/index.mustache | 0 .../subscribe.mustache | 0 application/tests/CoursesTest.php | 50 +++++++++++++ application/tests/bootstrap.php | 11 +++ application/tests/phpunit.xml | 13 ++++ application/tests/test_data/courses.xml | 67 ++++++++++++++++++ model.mwb | Bin 10200 -> 12010 bytes modules/unittest | 1 + 19 files changed, 221 insertions(+), 73 deletions(-) rename application/classes/Controller/{Subscription.php => Course.php} (74%) rename application/classes/Model/{Subscription.php => Course.php} (70%) rename application/classes/View/{Subscription => Course}/Index.php (93%) rename application/classes/View/{Subscription => Course}/Subscribe.php (52%) rename application/templates/{subscription => course}/index.mustache (100%) rename application/templates/{subscription => course}/subscribe.mustache (100%) create mode 100644 application/tests/CoursesTest.php create mode 100644 application/tests/bootstrap.php create mode 100644 application/tests/phpunit.xml create mode 100644 application/tests/test_data/courses.xml create mode 160000 modules/unittest diff --git a/.gitmodules b/.gitmodules index 1e71b55..2e44f28 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "modules/cache"] path = modules/cache url = git@github.com:Oreolek/cache.git +[submodule "modules/unittest"] + path = modules/unittest + url = git@github.com:kohana/unittest.git diff --git a/application/classes/Controller/Subscription.php b/application/classes/Controller/Course.php similarity index 74% rename from application/classes/Controller/Subscription.php rename to application/classes/Controller/Course.php index fbac2a1..949f387 100644 --- a/application/classes/Controller/Subscription.php +++ b/application/classes/Controller/Course.php @@ -1,9 +1,9 @@ template = new View_Subscription_Index; - $this->template->title = __('Subscription index'); - $this->template->items = ORM::factory('Subscription') + $this->template = new View_Course_Index; + $this->template->title = __('Course index'); + $this->template->items = ORM::factory('Course') ->filter_by_page($this->request->param('page')) ->find_all(); } @@ -26,17 +26,17 @@ class Controller_Subscription extends Controller_Layout { public function action_create() { $this->template = new View_Edit; - $this->template->model = ORM::factory('Subscription'); - $this->template->title = __('New subscription'); + $this->template->model = ORM::factory('Course'); + $this->template->title = __('New course'); $this->_edit($this->template->model); } public function action_edit() { $this->template = new View_Edit; - $this->template->title = __('Edit subscription'); + $this->template->title = __('Edit course'); $id = $this->request->param('id'); - $model = ORM::factory('Subscription', $id); + $model = ORM::factory('Course', $id); if (!$model->loaded()) { $this->redirect('error/404'); @@ -48,12 +48,12 @@ class Controller_Subscription extends Controller_Layout { { $this->template = new View_Delete; $id = $this->request->param('id'); - $model = ORM::factory('Subscription', $id); + $model = ORM::factory('Course', $id); if (!$model->loaded()) { $this->redirect('error/404'); } - $this->template->title = __('Delete subscription'); + $this->template->title = __('Delete course'); $this->template->content_title = $model->title; $this->template->content = $model->description; @@ -67,13 +67,13 @@ class Controller_Subscription extends Controller_Layout { { $this->template = new View_Letter_Index; $id = $this->request->param('id'); - $model = ORM::factory('Subscription', $id)->with('letters'); + $model = ORM::factory('Course', $id)->with('letters'); if (!$model->loaded()) { $this->redirect('error/404'); } - $this->template->title = __('Subscription').' '.$model->title; - $this->template->subscription_id = $id; + $this->template->title = __('Course').' '.$model->title; + $this->template->course_id = $id; $this->template->items = $model->letters ->filter_by_page($this->request->param('page')) ->order_by('order') @@ -82,14 +82,14 @@ class Controller_Subscription extends Controller_Layout { public function action_subscribe() { - $this->template = new View_Subscription_Subscribe; + $this->template = new View_Course_Subscribe; $id = $this->request->param('id'); - $subscription = ORM::factory('Subscription', $id); - if (!$subscription->loaded()) + $course = ORM::factory('Course', $id); + if (!$course->loaded()) { $this->redirect('error/404'); } - $this->template->title = __('Subscribe to ').$subscription->title; + $this->template->title = __('Subscribe to ').$course->title; $controls = array( 'name' => 'input', 'email' => 'input' @@ -108,9 +108,9 @@ class Controller_Subscription extends Controller_Layout { if ($validation->check()) { $model->save(); - $model->add('subscription', $subscription); + $model->add('course', $course); $task = ORM::factory('Task'); - $letter = $subscription->next_letter(); + $letter = $course->next_letter(); $task->letter_id = $letter->id; $task->client_id = $model->id; // now we break the abstraction to speed things up diff --git a/application/classes/Controller/Letter.php b/application/classes/Controller/Letter.php index 2acfb3a..d05f854 100644 --- a/application/classes/Controller/Letter.php +++ b/application/classes/Controller/Letter.php @@ -16,12 +16,12 @@ class Controller_Letter extends Controller_Layout { { $this->template = new View_Edit; $id = $this->request->param('id'); - if (!Model_Subscription::exists($id)) + if (!Model_Course::exists($id)) { $this->redirect('error/500'); } $this->template->model = ORM::factory('Letter'); - $this->template->model->subscription_id = $id; + $this->template->model->course_id = $id; $this->template->title = __('New letter'); $this->_edit($this->template->model); } diff --git a/application/classes/Model/Subscription.php b/application/classes/Model/Course.php similarity index 70% rename from application/classes/Model/Subscription.php rename to application/classes/Model/Course.php index 84b8755..6133d7b 100644 --- a/application/classes/Model/Subscription.php +++ b/application/classes/Model/Course.php @@ -1,16 +1,16 @@ days a client receives a letter from the collection. * @package Models * @author Oreolek **/ -class Model_Subscription extends ORM { +class Model_Course extends ORM { protected $_has_many = array( 'client' => array( 'model' => 'Client', - 'through' => 'clients_subscriptions' + 'through' => 'clients_courses' ), 'letters' => array( 'model' => 'Letter' @@ -62,7 +62,7 @@ class Model_Subscription extends ORM { public static function count_letters($id) { - return DB::select(array(DB::expr('COUNT(*)'), 'cnt'))->from('letters')->where('subscription_id', '=', $id)->execute()->get('cnt'); + return DB::select(array(DB::expr('COUNT(*)'), 'cnt'))->from('letters')->where('course_id', '=', $id)->execute()->get('cnt'); } /** @@ -70,55 +70,55 @@ class Model_Subscription extends ORM { **/ public function count_clients() { - return DB::select(array(DB::expr('COUNT(client_id)'), 'cnt'))->from('clients_subscriptions')->where('subscription_id', '=', $this->id)->execute()->get('cnt'); + return DB::select(array(DB::expr('COUNT(client_id)'), 'cnt'))->from('clients_courses')->where('course_id', '=', $this->id)->execute()->get('cnt'); } public static function exists($id) { - $count = DB::select(array(DB::expr('COUNT(*)'), 'cnt'))->from('subscriptions')->where('id', '=', $id)->execute()->get('cnt'); + $count = DB::select(array(DB::expr('COUNT(*)'), 'cnt'))->from('courses')->where('id', '=', $id)->execute()->get('cnt'); return ($count == 1); } public static function get_ids() { - return DB::select('id')->from('subscriptions')->execute()->get('id'); + return DB::select('id')->from('courses')->execute()->get('id'); } - public static function get_period($subscription_id) + public static function get_period($course_id) { return DB::select('period') - ->from('subscriptions') - ->where('subscription_id', '=', $subscription_id) + ->from('courses') + ->where('course_id', '=', $course_id) ->execute() ->get('period'); } - public static function get_letter_ids($subscription_id) + public static function get_letter_ids($course_id) { return DB::select('id') ->from('letters') - ->where('subscription_id', '=', $subscription_id) + ->where('course_id', '=', $course_id) ->order_by('order') ->execute() ->get('id'); } - public static function get_client_ids($subscription_id) + public static function get_client_ids($course_id) { return DB::select('client_id') - ->from('clients_subscriptions') - ->where('subscription_id', '=', $subscription_id) + ->from('clients_courses') + ->where('course_id', '=', $course_id) ->execute() ->get('client_id'); } /** - * Get next letter in subscription + * Get next letter in course * @param int $offset search offset (typically number of already sent letters) **/ public function next_letter($offset = 0) { return ORM::factory('Letter') - ->where('subscription_id', '=', $this->id) + ->where('course_id', '=', $this->id) ->order_by('order', 'ASC') ->limit(1) ->offset($offset) @@ -139,10 +139,10 @@ class Model_Subscription extends ORM { } $query->execute(); DB::delete('letters') - ->where('subscription_id', '=', $this->id) + ->where('course_id', '=', $this->id) ->execute(); - DB::delete('clients_subscriptions') - ->where('subscription_id', '=', $this->id) + DB::delete('clients_courses') + ->where('course_id', '=', $this->id) ->execute(); return parent::delete(); } diff --git a/application/classes/Model/Letter.php b/application/classes/Model/Letter.php index 7db2162..6ea971d 100644 --- a/application/classes/Model/Letter.php +++ b/application/classes/Model/Letter.php @@ -7,7 +7,7 @@ **/ class Model_Letter extends ORM { protected $belongs_to = array( - 'subscription' + 'course' ); /** @@ -44,7 +44,7 @@ class Model_Letter extends ORM { { if(empty($this->order)) { - $this->order = Model_Subscription::count_letters($this->subscription_id) + 1; + $this->order = Model_Course::count_letters($this->course_id) + 1; } } @@ -62,7 +62,7 @@ class Model_Letter extends ORM { * @param $address string or array of strings - email addresses * @param $text message body * @param $subject message subject - * @param $token user subscription token + * @param $token user course token **/ public static function _send($address, $text, $subject, $token = '') { diff --git a/application/classes/Task/Prepare.php b/application/classes/Task/Prepare.php index 925791d..238daa7 100644 --- a/application/classes/Task/Prepare.php +++ b/application/classes/Task/Prepare.php @@ -10,16 +10,16 @@ class Task_Prepare extends Minion_Task { protected $_options = array(); /** - * @param int $subscription subscription ID + * @param int $course course ID **/ - protected function prepare_subscription($subscription) + protected function prepare_course($course) { - $count = Model_Subscription::count_letters($subscription); + $count = Model_Course::count_letters($course); if ($count == 0) return; - $period = Model_Subscription::get_period($subscription); - $clients = Model_Subscription::get_client_ids($subscription, $period); - $letters = Model_Subscription::get_letter_ids($subscription); + $period = Model_Course::get_period($course); + $clients = Model_Course::get_client_ids($course, $period); + $letters = Model_Course::get_letter_ids($course); if (!is_array($clients)) { $this->prepare_letters($clients, $letters, $period); @@ -47,7 +47,7 @@ class Task_Prepare extends Minion_Task /** * Prepare letters to be sent out. - * If a client received less letters from subscription than there is in subscription, + * If a client received less letters from course than there is in course, * a task is formed. * * @return null @@ -58,17 +58,16 @@ class Task_Prepare extends Minion_Task $db->begin(); try { - $subscriptions = Model_Subscription::get_ids(); - echo __('Total subscription count').': '.count($subscriptions)."\n"; - if (!is_array($subscriptions)) + $courses = Model_Course::get_ids(); + if (!is_array($courses)) { - $this->prepare_subscription($subscriptions); + $this->prepare_course($courses); } else { - foreach ($subscriptions as $subscription) + foreach ($courses as $course) { - $this->prepare_subscription($subscription); + $this->prepare_course($course); } } $db->commit(); diff --git a/application/classes/View/Subscription/Index.php b/application/classes/View/Course/Index.php similarity index 93% rename from application/classes/View/Subscription/Index.php rename to application/classes/View/Course/Index.php index fc65ece..1e2129f 100644 --- a/application/classes/View/Subscription/Index.php +++ b/application/classes/View/Course/Index.php @@ -1,11 +1,11 @@ 'subscription/index', + __('Courses') => 'course/index', 'Клиенты' => 'client/index', 'Поиск клиентов' => 'client/search', )); diff --git a/application/config/database.php.example b/application/config/database.php.example index 9c27f1b..afdb162 100644 --- a/application/config/database.php.example +++ b/application/config/database.php.example @@ -28,18 +28,15 @@ return array 'caching' => TRUE, 'profiling' => FALSE, ), - 'sphinx' => array( - 'type' => 'MySQLi', + 'test' => array( + 'type' => 'MySQL', 'connection' => array( - 'hostname' => 'localhost:9306', - 'database' => 'oreolek', // index name from sphinx config + 'hostname' => 'localhost', + 'database' => 'oreolek', 'username' => '', 'password' => '', 'persistent' => FALSE, - ), - 'charset' => 'utf8', - 'caching' => TRUE, - 'profiling' => FALSE, - ), + ) + ) ); diff --git a/application/i18n/ru.php b/application/i18n/ru.php index 3a8bfa3..912ba42 100644 --- a/application/i18n/ru.php +++ b/application/i18n/ru.php @@ -16,6 +16,7 @@ return array( 'Mailing date' => 'Дата отправки', 'Status' => 'Статус', 'Subscriptions' => 'Рассылки', + 'Courses' => 'Курсы', 'No objects found to show' => 'Не найдено объектов для отображения.', 'Add' => 'Добавить', 'Edit' => 'Редактировать', @@ -27,6 +28,11 @@ return array( 'Edit subscription' => 'Редактировать рассылку', 'Subscribe to ' => 'Подписка на ', 'Subscription' => 'Рассылка', + 'Course' => 'Курс', + 'New course' => 'Новый курс', + 'Course index' => 'Список курсов', + 'Delete course' => 'Удалить курс', + 'Edit course' => 'Редактировать курс', 'Name' => 'Имя', 'You were subscribed. A welcome email has been sent to you. Please check your inbox.' => 'Вы были подписаны. Вам было выслано вступительное письмо; пожалуйста, проверьте входящие сообщения.', 'New letter' => 'Новое письмо', @@ -36,6 +42,7 @@ return array( 'Message subject' => 'Тема письма', 'The password was successfully changed.' => 'Пароль был успешно изменён.', 'Total subscription count' => 'Всего подписок', + 'Total course count' => 'Всего курсов', 'Sending letter with subject "%subject" to address %address' => 'Отсылаю письмо с темой %subject на адрес %address', 'Clients' => 'Клиенты', 'Description' => 'Описание', diff --git a/application/templates/subscription/index.mustache b/application/templates/course/index.mustache similarity index 100% rename from application/templates/subscription/index.mustache rename to application/templates/course/index.mustache diff --git a/application/templates/subscription/subscribe.mustache b/application/templates/course/subscribe.mustache similarity index 100% rename from application/templates/subscription/subscribe.mustache rename to application/templates/course/subscribe.mustache diff --git a/application/tests/CoursesTest.php b/application/tests/CoursesTest.php new file mode 100644 index 0000000..d642826 --- /dev/null +++ b/application/tests/CoursesTest.php @@ -0,0 +1,50 @@ +createXMLDataSet(Kohana::find_file('tests', 'test_data/courses', 'xml')); + } + + public function getSetUpOperation() { + // whether you want cascading truncates + // set false if unsure + $cascadeTruncates = false; + + return new PHPUnit_Extensions_Database_Operation_Composite(array( + new PHPUnit_Extensions_Database_Operation_MySQL55Truncate($cascadeTruncates), + PHPUnit_Extensions_Database_Operation_Factory::INSERT() + )); + } + + /** + * @group Mail + **/ + function testPrepareCourse() + { + Minion_Task::factory(array('task' => 'prepare'))->execute(); + $status = DB::select('status')->from('tasks')->where('letter_id', '=', '1')->and_where('client_id','=','1')->execute()->get('status'); + $this->assertEquals(Model_Task::STATUS_PENDING, $status); + } + + function testSendCourse() + { + $status = DB::select('status')->from('tasks')->where('letter_id', '=', '1')->and_where('client_id','=','1')->execute()->get('status'); + if (is_null($status)) + { + DB::insert('tasks', array('letter_id', 'client_id', 'date', 'status'))->values(array('1','1',date('Y-m-d'), Model_Task::STATUS_PENDING))->execute(); + } + Minion_Task::factory(array('task' => 'send'))->execute(); + $status = DB::select('status')->from('tasks')->where('letter_id', '=', '1')->and_where('client_id','=','1')->execute()->get('status'); + $this->assertEquals(Model_Task::STATUS_SENT, $status); + } +} diff --git a/application/tests/bootstrap.php b/application/tests/bootstrap.php new file mode 100644 index 0000000..52b23ed --- /dev/null +++ b/application/tests/bootstrap.php @@ -0,0 +1,11 @@ +getConnection()->query("SET @PHAKE_PREV_foreign_key_checks = @@foreign_key_checks"); + $connection->getConnection()->query("SET foreign_key_checks = 0"); + parent::execute($connection, $dataSet); + $connection->getConnection()->query("SET foreign_key_checks = @PHAKE_PREV_foreign_key_checks"); + } +} diff --git a/application/tests/phpunit.xml b/application/tests/phpunit.xml new file mode 100644 index 0000000..b5e743b --- /dev/null +++ b/application/tests/phpunit.xml @@ -0,0 +1,13 @@ + + + + + ../../modules/unittest/tests.php + + + + + kohana + + + diff --git a/application/tests/test_data/courses.xml b/application/tests/test_data/courses.xml new file mode 100644 index 0000000..03bd0e8 --- /dev/null +++ b/application/tests/test_data/courses.xml @@ -0,0 +1,67 @@ + + + + id + title + description + period + price + + 1 + Test course + Application testing purposes + 1 + 0 + +
+ + id + email + name + token + + 1 + test@example.com + Test User + + +
+ + id + client_id + course_id + + 1 + 1 + 1 + +
+ + id + text + course_id + order + subject + + 1 + This is a test message. Please ignore it. + 1 + 0 + Test message #1 + + + 2 + This is a test message number two. Please ignore it. + 1 + 1 + Test message #2 + +
+ + id + letter_id + client_id + date + status +
+
diff --git a/model.mwb b/model.mwb index cdf23c1f944c1d72fb06e454bf9b91861bf349ec..a4b901a884d2e86f3776bf3fbd0a2df9cbddda1a 100644 GIT binary patch delta 11612 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 DPUC}{ delta 9739 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 Jd