diff --git a/tests/LoadFixtures.php b/tests/LoadFixtures.php index 97ef4ee1..5eef0bc0 100644 --- a/tests/LoadFixtures.php +++ b/tests/LoadFixtures.php @@ -28,9 +28,8 @@ class LoadFixtures */ private $sDirFixtures; - public function __construct() { - $this->oEngine = Engine::getInstance(); - $this->oEngine->Init(); + public function __construct($oEngine) { + $this->oEngine = $oEngine; $this->sDirFixtures = realpath((dirname(__FILE__)) . "/fixtures/"); } @@ -53,7 +52,7 @@ class LoadFixtures WHERE TABLE_SCHEMA = '" . $sDbname . "'"); mysql_query('SET FOREIGN_KEY_CHECKS = 0'); - echo "TRUNCATE TABLE FROM TEST BASE"; + echo "TRUNCATE TABLE FROM TEST BASE\n"; while ($row = mysql_fetch_row($result)) { if (!mysql_query($row[0])) { // exception @@ -82,7 +81,7 @@ class LoadFixtures throw new Exception("DB is not exported with file sql.sql"); return $result['errors']; } - echo "ExportSQL DATABASE $sDbname -> sql.sql \n"; + echo "ExportSQL DATABASE $sDbname -> install_base.sql \n"; // Load dump from geo_base.sql $result = $this->oEngine->Database_ExportSQL(dirname(__FILE__) . '/fixtures/sql/geo_base.sql'); @@ -95,6 +94,17 @@ class LoadFixtures } } + + // Load dump from INSERT_BASE (SQL-Query) + $result = $this->oEngine->Database_ExportSQL(dirname(__FILE__) . '/fixtures/sql/insert.sql'); + + if (!$result['result']) { + // exception + throw new Exception("DB is not exported with file insert.sql"); + return $result['errors']; + } + echo "Export INSERT SQL to DATABASE $sDbname\n"; + return true; } @@ -124,6 +134,9 @@ class LoadFixtures foreach ($aClassNames as $sClassName) { // @todo референсы дублируются в каждом объекте фиксту + в этом объекте $oFixtures = new $sClassName($this->oEngine, $this->aReferences); + if (!$oFixtures instanceof AbstractFixtures) { + throw new Exception($sClassName . " must extend of AbstractFixtures"); + } $oFixtures->load(); $aFixtureReference = $oFixtures->getReferences(); $this->aReferences = array_merge($this->aReferences, $aFixtureReference); @@ -146,16 +159,7 @@ class LoadFixtures $this->sDirFixtures = $sPath; $this->loadFixtures(); + echo "Load Fixture Plugin ... ---> {$plugin}\n"; } - - /** - * Function of activate plugin - * - * @param string $plugin - */ - public function activationPlugin($plugin){ - $this->oEngine->ModulePlugin_Toggle($plugin,'Activate'); - } - } diff --git a/tests/README.md b/tests/README.md index d21255b9..949ceb9e 100644 --- a/tests/README.md +++ b/tests/README.md @@ -47,3 +47,17 @@ Feature: LiveStreet standart features 14 steps (14 passed) 0m2.225s ``` + +4) Для тестирования плагинов используется команда + HTTP_APP_ENV=test php behat.phar --config='../../plugins/(название плагина)/tests/behat/behat.yml' + + +5) При написании дополнительных тестов используются следующие правила: + а) Доступ из базового контекcта к контексту MINK должен производится через функцию getMinkContext() + Пример получения доступа к сессии: $this->getMinkContext()->getSession() + +б) Получение доступа к базовому обьекту Engine производится посредством метода: $this->getEngine() + +Прим: public function getEngine() { + return $this->getSubcontext('base')->getEngine(); + } diff --git a/tests/behat/features/base.feature b/tests/behat/features/base.feature index ecdabe86..1e16e7e8 100644 --- a/tests/behat/features/base.feature +++ b/tests/behat/features/base.feature @@ -4,9 +4,9 @@ Feature: LiveStreet standart features Scenario: See main page Given I am on homepage Then the response status code should be 200 - + Then I should see "Sony MicroVault Mach USB 3.0 flash drive" - Then I should see "Blogger's name golfer" + Then I should see "Blogger's name user-golfer" Then I should see "iPad 3 rumored to come this March with quad-core chip and 4G LTE " Then I should see "Toshiba unveils 13.3-inch AT330 Android ICS 4.0 tablet" @@ -24,7 +24,7 @@ Feature: LiveStreet standart features Then the response status code should be 200 Then I should see "Gadgets" - Then I should see "golfer" + Then I should see "user-golfer" Scenario: See all new topics Given I am on "/index/newall/" @@ -35,8 +35,8 @@ Feature: LiveStreet standart features Then I should see "Toshiba unveils 13.3-inch AT330 Android ICS 4.0 tablet" Scenario: See user profile - Given I am on "/profile/Golfer/" + Given I am on "/profile/user-golfer/" Then the response status code should be 200 - Then I should see "Sergey Doryba" - Then I should see "... Sergey Doryba profile description" + Then I should see "user-golfer" + Then I should see "... Golfer profile description" \ No newline at end of file diff --git a/tests/behat/features/bootstrap/BaseFeatureContext.php b/tests/behat/features/bootstrap/BaseFeatureContext.php index 871ca3eb..2c3b1cee 100644 --- a/tests/behat/features/bootstrap/BaseFeatureContext.php +++ b/tests/behat/features/bootstrap/BaseFeatureContext.php @@ -4,6 +4,7 @@ use Behat\Behat\Context\ClosuredContextInterface, Behat\Behat\Context\TranslatedContextInterface, Behat\Behat\Context\BehatContext, Behat\MinkExtension\Context\MinkContext, + Behat\Mink\Exception\ExpectationException, Behat\Behat\Exception\PendingException; use Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; @@ -16,22 +17,46 @@ require_once("tests/LoadFixtures.php"); /** * LiveStreet custom feature context */ -class BaseFeatureContext extends MinkContext +class BaseFeatureContext extends BehatContext { - protected static $fixturesLoader = null; + protected $fixturesLoader = null; + protected $oEngine = NULL; + + public function __construct() + { + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; + } + + public function getEngine() + { + return $this->oEngine; + } + + public function initEngine() + { + if(!$this->oEngine) { + $this->oEngine = Engine::getInstance(); + $this->oEngine->Init(); + } + } /** * Get fixtures loader * @return LoadFixtures */ - protected static function getFixturesLoader() + protected function getFixturesLoader() { - if (is_null(self::$fixturesLoader)) { - self::$fixturesLoader = new LoadFixtures(); + if (is_null($this->fixturesLoader)) { + $this->fixturesLoader = new LoadFixtures($this->getEngine()); } - return self::$fixturesLoader; + return $this->fixturesLoader; + } + + public function getMinkContext() + { + return $this->getMainContext(); } /** @@ -39,8 +64,10 @@ class BaseFeatureContext extends MinkContext * * @BeforeScenario */ - public static function prepare($event){ - $fixturesLoader = self::getFixturesLoader(); + public function prepare($event) + { + $this->initEngine(); + $fixturesLoader = $this->getFixturesLoader(); $fixturesLoader->purgeDB(); $fixturesLoader->load(); } @@ -56,22 +83,105 @@ class BaseFeatureContext extends MinkContext $fixturesLoader->loadPluginFixtures($plugin); } - - /** - * @Given /^I am activated plugin "([^"]*)"$/ - */ - public function ActivatedPlugin($plugin) - { - $pluginActivation = new LoadFixtures(); - $pluginActivation->activationPlugin($plugin); - } - /** * @Then /^I wait "([^"]*)"$/ */ public function iWait($time_wait) { - $this->getSession()->wait($time_wait); + $this->getMinkContext()->getSession()->wait($time_wait); } + /** + * Check is sets are present in content + * + * @Then /^the response have sets:$/ + */ + public function ResponseHaveSets( $table) + { + $actual = $this->getMinkContext()->getSession()->getPage()->getContent(); + + foreach ($table->getHash() as $genreHash) { + $regex = '/'.preg_quote($genreHash['value'], '/').'/ui'; + if (!preg_match($regex, $actual)) { + $message = sprintf('The string "%s" was not found anywhere in the HTML response of the current page.', $genreHash['value']); + throw new ExpectationException($message, $this->getMinkContext()->getSession()); + } + } + } + + /** + * @Then /^I should see in element "([^"]*)" values:$/ + */ + public function iShouldSeeInContainerValues($objectId, TableNode $table) + { + $element = $this->getMinkContext()->getSession()->getPage()->find('css', "#{$objectId}"); + + if ($element) { + $content = $element->getHtml(); + + foreach ($table->getHash() as $genreHash) { + $regex = '/'.preg_quote($genreHash['value'], '/').'/ui'; + if (!preg_match($regex, $content)) { + $message = sprintf('The string "%s" was not found anywhere in container', $genreHash['value']); + throw new ExpectationException($message, $this->getMinkContext()->getSession()); + } + } + } + else { + throw new ExpectationException('Container not found', $this->getMinkContext()->getSession()); + } + } + + + /** + * Get content type and compare with set + * + * @Then /^content type is "([^"]*)"$/ + */ + public function contentTypeIs($contentType) + { + $header = $this->getMinkContext()->getSession()->getResponseHeaders(); + + if ($contentType != $header['Content-Type']) { + $message = sprintf('Current content type is "%s", but "%s" expected.', $header['Content-Type'], $contentType); + throw new ExpectationException($message, $this->getMinkContext()->getSession()); + } + } + + /** + * Try to login user + * + * @Then /^I want to login as "([^"]*)"$/ + */ + public function iWantToLoginAs($sUserLogin) + { + $oUser = $this->getEngine()->User_GetUserByLogin($sUserLogin); + if (!$oUser) { + throw new ExpectationException( sprintf('User %s not found', $sUserLogin), $this->getMinkContext()->getSession()); + } + + $this->getEngine()->User_Authorization($oUser, true); + $oSession = $this->getEngine()->User_GetSessionByUserId($oUser->getId()); + if (!$oSession) { + throw new ExpectationException( 'Session non created', $this->getMinkContext()->getSession()); + } + + $this->getMinkContext()->getSession()->getDriver()->setCookie("key", $oSession->getKey()); + } + + /** + * Checking for activity of plugin + * + * @Then /^check is plugin active "([^"]*)"$/ + */ + public function CheckIsPluginActive($sPluginName) + { + $activePlugins = $this->getEngine()->Plugin_GetActivePlugins(); + + if (!in_array($sPluginName, $activePlugins)) { + throw new ExpectationException( sprintf('Plugin %s is not active', $sPluginName), $this->getMinkContext()->getSession()); + } + } + + } diff --git a/tests/behat/features/bootstrap/FeatureContext.php b/tests/behat/features/bootstrap/FeatureContext.php index 4ddf1abc..2ef84b29 100644 --- a/tests/behat/features/bootstrap/FeatureContext.php +++ b/tests/behat/features/bootstrap/FeatureContext.php @@ -1,11 +1,20 @@ parameters = $parameters; + $this->useContext('base', new BaseFeatureContext($parameters)); + } + + public function getEngine() { + return $this->getSubcontext('base')->getEngine(); + } } diff --git a/tests/fixtures/BlogFixtures.php b/tests/fixtures/BlogFixtures.php index e5079418..532a2f90 100644 --- a/tests/fixtures/BlogFixtures.php +++ b/tests/fixtures/BlogFixtures.php @@ -11,11 +11,11 @@ class BlogFixtures extends AbstractFixtures public function load() { - $oUserStfalcon = $this->getReference('user-golfer'); + $oUserFirst = $this->getReference('user-golfer'); /* @var $oBlogGadgets ModuleBlog_EntityBlog */ $oBlogGadgets = Engine::GetEntity('Blog'); - $oBlogGadgets->setOwnerId($oUserStfalcon->getId()); + $oBlogGadgets->setOwnerId($oUserFirst->getId()); $oBlogGadgets->setTitle("Gadgets"); $oBlogGadgets->setDescription('Offers latest gadget reviews'); $oBlogGadgets->setType('open'); diff --git a/tests/fixtures/TopicFixtures.php b/tests/fixtures/TopicFixtures.php index ddfde830..015a43e3 100644 --- a/tests/fixtures/TopicFixtures.php +++ b/tests/fixtures/TopicFixtures.php @@ -5,6 +5,7 @@ require_once(realpath((dirname(__FILE__)) . "/../AbstractFixtures.php")); class TopicFixtures extends AbstractFixtures { + protected $aActivePlugins = array(); public static function getOrder() { return 2; @@ -12,23 +13,23 @@ class TopicFixtures extends AbstractFixtures public function load() { - $oUserGolfer = $this->getReference('user-golfer'); + $oUserFirst = $this->getReference('user-golfer'); $oBlogGadgets = $this->getReference('blog-gadgets'); - $oTopicToshiba = $this->_createTopic($oBlogGadgets->getBlogId(), $oUserGolfer->getId(), + $oTopicToshiba = $this->_createTopic($oBlogGadgets->getBlogId(), $oUserFirst->getId(), 'Toshiba unveils 13.3-inch AT330 Android ICS 4.0 tablet', 'Toshiba is to add a new Android 4.0 ICS to the mass which is known as Toshiba AT330. The device is equipped with a multi-touch capacitive touch display that packs a resolution of 1920 x 1200 pixels. The Toshiba AT330 tablet is currently at its prototype stage. We have very little details about the tablet, knowing that it’ll come equipped with HDMI port, on-board 32GB storage that’s expandable via an full-sized SD card slot. It’ll also have a built-in TV tuner and a collapsible antenna.It’ll also run an NVIDIA Tegra 3 quad-core processor. Other goodies will be a 1.3MP front-facing camera and a 5MP rear-facing camera. Currently, there is no information about its price and availability. A clip is included below showing it in action.', 'gadget', '2012-10-21 00:10:20'); $this->addReference('topic-toshiba', $oTopicToshiba); - $oTopicIpad = $this->_createTopic($oBlogGadgets->getBlogId(), $oUserGolfer->getId(), + $oTopicIpad = $this->_createTopic($oBlogGadgets->getBlogId(), $oUserFirst->getId(), 'iPad 3 rumored to come this March with quad-core chip and 4G LTE', 'Another rumor for the iPad 3 has surfaced with some details given by Bloomberg, claiming that the iPad 3 production is already underway and will be ready for a launch as early as March.', 'apple, ipad', '2012-10-21 1:20:30'); $this->addReference('topic-ipad', $oTopicIpad); - $oPersonalBlogGolfer = $this->oEngine->Blog_GetPersonalBlogByUserId($oUserGolfer->getId()); - $oTopicSony = $this->_createTopic($oPersonalBlogGolfer->getBlogId(), $oUserGolfer->getId(), + $oPersonalBlogGolfer = $this->oEngine->Blog_GetPersonalBlogByUserId($oUserFirst->getId()); + $oTopicSony = $this->_createTopic($oPersonalBlogGolfer->getBlogId(), $oUserFirst->getId(), 'Sony MicroVault Mach USB 3.0 flash drive', 'Want more speeds and better protection for your data? The Sony MicroVault Mach flash USB 3.0 drive is what you need. It offers the USB 3.0 interface that delivers data at super high speeds of up to 5Gbps. It’s also backward compatible with USB 2.0.', 'sony, flash, gadget', '2012-10-21 2:30:40'); @@ -49,6 +50,8 @@ class TopicFixtures extends AbstractFixtures */ private function _createTopic($iBlogId, $iUserId, $sTitle, $sText, $sTags, $sDate) { + $this->aActivePlugins = $this->oEngine->Plugin_GetActivePlugins(); + $oTopic = Engine::GetEntity('Topic'); /* @var $oTopic ModuleTopic_EntityTopic */ $oTopic->setBlogId($iBlogId); @@ -70,6 +73,13 @@ class TopicFixtures extends AbstractFixtures $oTopic->setTextHash(md5($oTopic->getType() . $oTopic->getTextSource() . $oTopic->getTitle())); $oTopic->setTags($sTags); + //with active plugin l10n added a field topic_lang + if (in_array('l10n', $this->aActivePlugins)) { + $oTopic->setTopicLang(Config::Get('lang.current')); + } + // @todo refact this + $oTopic->_setValidateScenario('topic'); + $oTopic->_Validate(); $this->oEngine->Topic_AddTopic($oTopic); diff --git a/tests/fixtures/UserFixtures.php b/tests/fixtures/UserFixtures.php index ad510383..788a679f 100644 --- a/tests/fixtures/UserFixtures.php +++ b/tests/fixtures/UserFixtures.php @@ -11,26 +11,42 @@ class UserFixtures extends AbstractFixtures public function load() { + $oUserFirst = $this->_createUser('user-golfer', 'qwerty','user_first@info.com', '2012-11-1 00:10:20'); - $oUserGolfer = Engine::GetEntity('User'); - $oUserGolfer->setLogin('golfer'); - $oUserGolfer->setPassword(md5('qwerty')); - $oUserGolfer->setMail('golfer@gmail.com'); + $oUserFirst->getId(); + $oUserFirst->setProfileName('Golfer FullName'); + $oUserFirst->setProfileAbout('... Golfer profile description'); + $oUserFirst->setProfileSex('man'); - $oUserGolfer->setUserDateRegister(date("Y-m-d H:i:s")); // @todo freeze - $oUserGolfer->setUserIpRegister('127.0.0.1'); - $oUserGolfer->setUserActivate('1'); - $oUserGolfer->setUserActivateKey('0'); + $this->oEngine->User_Update($oUserFirst); + $this->addReference('user-golfer', $oUserFirst); - $this->oEngine->User_Add($oUserGolfer); - - $oUserGolfer->setProfileName('Sergey Doryba'); - $oUserGolfer->setProfileAbout('... Sergey Doryba profile description'); - $oUserGolfer->setProfileSex('man'); - - $this->oEngine->User_Update($oUserGolfer); - $this->addReference('user-golfer', $oUserGolfer); } -} + /** + * Create user with default values + * + * @param string $sUserName + * @param string $sPassword + * @param string $sMail + * @param string $sDate + * + * @return ModuleTopic_EntityUser + */ + private function _createUser($sUserName, $sPassword,$sMail,$sDate) + { + $oUser = Engine::GetEntity('User'); + $oUser->setLogin($sUserName); + $oUser->setPassword(md5($sPassword)); + $oUser->setMail($sMail); + $oUser->setUserDateRegister($sDate); + $oUser->setUserIpRegister('127.0.0.1'); + $oUser->setUserActivate('1'); + $oUser->setUserActivateKey('0'); + $this->oEngine->User_Add($oUser); + + return $oUser; + } + +} \ No newline at end of file diff --git a/tests/fixtures/sql/insert.sql b/tests/fixtures/sql/insert.sql new file mode 100644 index 00000000..f46c69f8 --- /dev/null +++ b/tests/fixtures/sql/insert.sql @@ -0,0 +1,45 @@ +-- -------------------------------------------------------- + +-- +-- Дамп данных таблицы `prefix_user` +-- + +INSERT INTO `prefix_user` (`user_id`, `user_login`, `user_password`, `user_mail`, `user_skill`, `user_date_register`, `user_date_activate`, `user_date_comment_last`, `user_ip_register`, `user_rating`, `user_count_vote`, `user_activate`, `user_activate_key`, `user_profile_name`, `user_profile_sex`, `user_profile_country`, `user_profile_region`, `user_profile_city`, `user_profile_birthday`, `user_profile_about`, `user_profile_date`, `user_profile_avatar`, `user_profile_foto`, `user_settings_notice_new_topic`, `user_settings_notice_new_comment`, `user_settings_notice_new_talk`, `user_settings_notice_reply_comment`, `user_settings_notice_new_friend`, `user_settings_timezone`) VALUES +(1, 'admin', 'd8578edf8458ce06fbc5bb76a58c5ca4', 'admin@admin.adm', 0.000, '2012-10-1 00:00:00', NULL, NULL, '127.0.0.1', 0.000, 0, 1, NULL, NULL, 'other', NULL, NULL, NULL, NULL, NULL, NULL, '0', NULL, 1, 1, 1, 1, 1, NULL); + +-- -------------------------------------------------------- + + +-- +-- Дамп данных таблицы `prefix_user_administrator` +-- + +INSERT INTO `prefix_user_administrator` (`user_id`) VALUES +(1); + +-- -------------------------------------------------------- + + +-- +-- Дамп данных таблицы `prefix_user_field` +-- + +INSERT INTO `prefix_user_field` (`id`, `type`, `name`, `title`, `pattern`) VALUES +(1, 'contact', 'phone', 'Телефон', ''), +(2, 'contact', 'mail', 'E-mail', '{*}'), +(3, 'contact', 'skype', 'Skype', '{*}'), +(4, 'contact', 'icq', 'ICQ', '{*}'), +(5, 'contact', 'www', 'Сайт', '{*}'), +(6, 'social', 'twitter', 'Twitter', '{*}'), +(7, 'social', 'facebook', 'Facebook', '{*}'), +(8, 'social', 'vkontakte', 'ВКонтакте', '{*}'), +(9, 'social', 'odnoklassniki', 'Одноклассники', '{*}'); + +-- -------------------------------------------------------- + +-- +-- Дамп данных таблицы `prefix_blog` +-- + +INSERT INTO `prefix_blog` (`blog_id`, `user_owner_id`, `blog_title`, `blog_description`, `blog_type`, `blog_date_add`, `blog_date_edit`, `blog_rating`, `blog_count_vote`, `blog_count_user`, `blog_count_topic`, `blog_limit_rating_topic`, `blog_url`, `blog_avatar`) VALUES +(1, 1, 'Blog by admin', 'This is Admin personal blog.', 'personal', '2012-11-07 09:20:00', NULL, 0.000, 0, 0, 0, -1000.000, NULL, '0');