mirror of
https://github.com/Oreolek/kangana.git
synced 2024-06-16 15:01:09 +03:00
Renamed subscriptions to courses. Added a test.
This commit is contained in:
parent
e1433eedf1
commit
ee62fd61b2
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -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
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Subscription controller.
|
||||
* Course controller.
|
||||
**/
|
||||
class Controller_Subscription extends Controller_Layout {
|
||||
class Controller_Course extends Controller_Layout {
|
||||
protected $secure_actions = array(
|
||||
'index','create', 'edit', 'delete', 'view'
|
||||
);
|
||||
|
@ -16,9 +16,9 @@ class Controller_Subscription extends Controller_Layout {
|
|||
|
||||
public function action_index()
|
||||
{
|
||||
$this->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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Subscription model.
|
||||
* Subscription is an ordered collection of letters.
|
||||
* Course model.
|
||||
* Course is an ordered collection of letters.
|
||||
* It has a period in days. Every <period> 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();
|
||||
}
|
|
@ -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 = '')
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Subscription index view controller.
|
||||
* Course index view controller.
|
||||
* @package Views
|
||||
* @author Oreolek
|
||||
**/
|
||||
class View_Subscription_Index extends View_Index {
|
||||
class View_Course_Index extends View_Index {
|
||||
protected $is_admin = TRUE; // admin only view
|
||||
public $show_date = FALSE;
|
||||
public function get_header()
|
|
@ -1,8 +1,8 @@
|
|||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Subscription form view controller
|
||||
* Course subscription form view controller
|
||||
**/
|
||||
class View_Subscription_Subscribe extends View_Edit {
|
||||
class View_Course_Subscribe extends View_Edit {
|
||||
public $_layout = 'empty';
|
||||
}
|
|
@ -77,7 +77,7 @@ class View_Layout {
|
|||
else
|
||||
{
|
||||
$navigation = array_merge($navigation, array(
|
||||
__('Subscriptions') => 'subscription/index',
|
||||
__('Courses') => 'course/index',
|
||||
'Клиенты' => 'client/index',
|
||||
'Поиск клиентов' => 'client/search',
|
||||
));
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -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' => 'Описание',
|
||||
|
|
50
application/tests/CoursesTest.php
Normal file
50
application/tests/CoursesTest.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Test for course workflow.
|
||||
* @category Tests
|
||||
* @author Oreolek
|
||||
* @license AGPL
|
||||
**/
|
||||
class CoursesTest extends Unittest_Database_TestCase
|
||||
{
|
||||
protected $_database_connection = 'test';
|
||||
|
||||
protected function getdataset()
|
||||
{
|
||||
return $this->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);
|
||||
}
|
||||
}
|
11
application/tests/bootstrap.php
Normal file
11
application/tests/bootstrap.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
require_once '../../modules/unittest/bootstrap.php';
|
||||
class PHPUnit_Extensions_Database_Operation_MySQL55Truncate extends PHPUnit_Extensions_Database_Operation_Truncate
|
||||
{
|
||||
public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) {
|
||||
$connection->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");
|
||||
}
|
||||
}
|
13
application/tests/phpunit.xml
Normal file
13
application/tests/phpunit.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit colors="true" bootstrap="./bootstrap.php">
|
||||
<testsuites>
|
||||
<testsuite name="Application Tests">
|
||||
<file>../../modules/unittest/tests.php</file>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>kohana</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
</phpunit>
|
67
application/tests/test_data/courses.xml
Normal file
67
application/tests/test_data/courses.xml
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" ?>
|
||||
<dataset>
|
||||
<table name="courses">
|
||||
<column>id</column>
|
||||
<column>title</column>
|
||||
<column>description</column>
|
||||
<column>period</column>
|
||||
<column>price</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>Test course</value>
|
||||
<value>Application testing purposes</value>
|
||||
<value>1</value>
|
||||
<value>0</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="clients">
|
||||
<column>id</column>
|
||||
<column>email</column>
|
||||
<column>name</column>
|
||||
<column>token</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>test@example.com</value>
|
||||
<value>Test User</value>
|
||||
<value></value><!-- empty token -->
|
||||
</row>
|
||||
</table>
|
||||
<table name="clients_courses">
|
||||
<column>id</column>
|
||||
<column>client_id</column>
|
||||
<column>course_id</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="letters">
|
||||
<column>id</column>
|
||||
<column>text</column>
|
||||
<column>course_id</column>
|
||||
<column>order</column>
|
||||
<column>subject</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>This is a test message. Please ignore it.</value>
|
||||
<value>1</value>
|
||||
<value>0</value>
|
||||
<value>Test message #1</value>
|
||||
</row>
|
||||
<row>
|
||||
<value>2</value>
|
||||
<value>This is a test message number two. Please ignore it.</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>Test message #2</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="tasks">
|
||||
<column>id</column>
|
||||
<column>letter_id</column>
|
||||
<column>client_id</column>
|
||||
<column>date</column>
|
||||
<column>status</column>
|
||||
</table>
|
||||
</dataset>
|
1
modules/unittest
Submodule
1
modules/unittest
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 8db01f00d6d94781e0e8750cc7d586221e771cc7
|
Loading…
Reference in a new issue