1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-05-08 11:58:21 +03:00

Added Behat and Mink (for tests). Created fixtures loader and simple fixtures for blog, user and topics.

This commit is contained in:
Stepan Tanasiychuk 2012-10-25 21:54:16 +03:00
parent 3f0c53dc02
commit f4cbae56d6
17 changed files with 1708 additions and 12 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@
/logs/
/tmp/
/config/config.local.php
/config/config.test.php

View file

@ -0,0 +1,37 @@
<?php
/*-------------------------------------------------------
*
* LiveStreet Engine Social Networking
* Copyright © 2008 Mzhelskiy Maxim
*
*--------------------------------------------------------
*
* Official site: www.livestreet.ru
* Contact e-mail: rus.engine@gmail.com
*
* GNU General Public License, version 2:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
---------------------------------------------------------
*/
/**
* Настройки для локального сервера.
* Для использования - переименовать файл в config.local.php
*/
/**
* Настройка базы данных
*/
$config['db']['params']['host'] = 'localhost';
$config['db']['params']['port'] = '3306';
$config['db']['params']['user'] = 'root';
$config['db']['params']['pass'] = '';
$config['db']['params']['type'] = 'mysql';
$config['db']['params']['dbname'] = 'social_test';
$config['db']['table']['prefix'] = 'prefix_';
$config['sys']['cache']['use'] = false; // использовать кеширование или нет
$config['sys']['cache']['solid'] = false;
return $config;
?>

View file

@ -48,7 +48,7 @@ if ($hDirConfig = opendir($sDirConfig)) {
// то сливаем старые и новое значения ассоциативно
Config::Set(
$sKey,
func_array_merge_assoc(Config::Get($sKey), $aConfig)
func_array_merge_assoc(Config::Get($sKey), $aConfig)
);
}
}
@ -114,7 +114,7 @@ if ($hDirConfig = opendir($sDirConfig)) {
// то сливаем старые и новое значения ассоциативно
Config::Set(
$sKey,
func_array_merge_assoc(Config::Get($sKey), $aConfig)
func_array_merge_assoc(Config::Get($sKey), $aConfig)
);
}
}
@ -124,14 +124,23 @@ if ($hDirConfig = opendir($sDirConfig)) {
closedir($hDirConfig);
}
/**
* Подгружаем файлы локального и продакшн-конфига
*/
if(file_exists(Config::Get('path.root.server').'/config/config.local.php')) {
Config::LoadFromFile(Config::Get('path.root.server').'/config/config.local.php',false);
}
if(file_exists(Config::Get('path.root.server').'/config/config.stable.php')) {
Config::LoadFromFile(Config::Get('path.root.server').'/config/config.stable.php',false);
if(isset($_SERVER['HTTP_APP_ENV']) && $_SERVER['HTTP_APP_ENV']=='test') {
/**
* Подгружаем файл тестового конфига
*/
if(file_exists(Config::Get('path.root.server').'/config/config.test.php')) {
Config::LoadFromFile(Config::Get('path.root.server').'/config/config.test.php',false);
}
} else {
/**
* Подгружаем файлы локального и продакшн-конфига
*/
if(file_exists(Config::Get('path.root.server').'/config/config.local.php')) {
Config::LoadFromFile(Config::Get('path.root.server').'/config/config.local.php',false);
}
if(file_exists(Config::Get('path.root.server').'/config/config.stable.php')) {
Config::LoadFromFile(Config::Get('path.root.server').'/config/config.stable.php',false);
}
}
/**
@ -157,7 +166,7 @@ if($aPluginsList=@file($sPluginsListFile)) {
// то сливаем старые и новое значения ассоциативно
Config::Set(
$sKey,
func_array_merge_assoc(Config::Get($sKey), $aConfig)
func_array_merge_assoc(Config::Get($sKey), $aConfig)
);
}
}
@ -170,7 +179,7 @@ if($aPluginsList=@file($sPluginsListFile)) {
if($aIncludeFiles and count($aIncludeFiles)) {
foreach ($aIncludeFiles as $sPath) {
require_once($sPath);
}
}
}
}
}

View file

@ -0,0 +1,87 @@
<?php
/**
* Abstract class for LiveStreet fixtures
*/
abstract class AbstractFixtures
{
/**
* @var Engine
*/
protected $oEngine;
/**
* Objects references
*
* @var array
*/
private $aReferences = array();
/**
* @param Engine $oEngine
* @param array $aReferences
* @return void
*/
public function __construct(Engine $oEngine, $aReferences)
{
$this->oEngine = $oEngine;
$this->aReferences = $aReferences;
}
/**
* Add reference
*
* @param string $name
* @param array $data
* @return void
*/
public function addReference($name, $data)
{
$this->aReferences[$name] = $data;
}
/**
* Get reference by key
*
* @param string $key
* @throws Exception if reference is not exist
* @return array aReferences
* @return void
*/
public function getReference($key)
{
if (isset($this->aReferences[$key])) {
return $this->aReferences[$key];
}
throw new Exception("Fixture reference \"$key\" is not exist");
}
/**
* Get all references
*
* @return array aReferences
*/
public function getReferences()
{
return $this->aReferences;
}
/**
* Creating entities and saving them to DB
*
* @return void
*/
abstract public function load();
/**
* Get order number for fixture
*
* @return int
*/
public static function getOrder() {
return 0;
}
}

141
tests/LoadFixtures.php Normal file
View file

@ -0,0 +1,141 @@
<?php
require_once("config/loader.php");
require_once("engine/classes/Engine.class.php");
/**
* Class for load fixtures
*/
class LoadFixtures
{
/**
* Main objects references array
*
* @var array $aReferences
*/
private $aReferences = array();
/**
* @var Engine
*/
private $oEngine;
/**
* The directory of the fixtures for tests
*
* @var string $sDirFixtures
*/
private $sDirFixtures;
public function __construct() {
if (file_exists(Config::Get('path.root.server') . '/config/config.test.php')) {
Config::LoadFromFile(Config::Get('path.root.server') . '/config/config.test.php', false);
}
$this->oEngine = Engine::getInstance();
$this->oEngine->Init();
$this->sDirFixtures = realpath((dirname(__FILE__)) . "/fixtures/");
}
public function load() {
$this->loadFixtures();
}
/**
* Recreate database from SQL dumps
*
* @return bool
*/
public function purgeDB() {
$sDbname = Config::Get('db.params.dbname');
if (mysql_select_db($sDbname)) {
mysql_query("DROP DATABASE $sDbname");
echo "DROP DATABASE $sDbname \n";
}
if (mysql_query("CREATE DATABASE $sDbname") === false) {
return mysql_error();
}
echo "CREATE DATABASE $sDbname \n";
if (mysql_select_db($sDbname) === false) {
return mysql_error();
}
echo "SELECTED DATABASE $sDbname \n";
// Load dump from install_base.sql
$result = $this->oEngine->Database_ExportSQL(dirname(__FILE__) . '/fixtures/sql/install_base.sql');
if (!$result['result']) {
return $result['errors'];
}
// Load dump from geo_base.sql
$result = $this->oEngine->Database_ExportSQL(dirname(__FILE__) . '/fixtures/sql/geo_base.sql');
if (!$result['result']) {
return $result['errors'];
}
echo "ExportSQL DATABASE $sDbname \n";
echo "ExportSQL DATABASE $sDbname -> geo_base \n";
return true;
}
/**
* Function of loading fixtures from tests/fixtures/
*
* @var array $aFiles
* @var array $iOrder
* @return void
*/
private function loadFixtures() {
$aFiles = glob("{$this->sDirFixtures}/*Fixtures.php");
$aFixtures = array();
foreach ($aFiles as $sFilePath) {
require_once "{$sFilePath}";
$iOrder = BlogFixtures::getOrder();
preg_match("/([a-zA-Z]+Fixtures).php$/", $sFilePath, $matches);
$sClassName = $matches[1];
$iOrder = forward_static_call(array($sClassName, 'getOrder'));
if (!array_key_exists($iOrder, $aFixtures)) {
$aFixtures[$iOrder] = $sClassName;
} else {
//@todo разруливание одинаковых ордеров
throw new Exception("Duplicated order number $iOrder in $sClassName");
}
}
ksort($aFixtures);
if (count($aFixtures)) {
foreach ($aFixtures as $iOrder => $sClassName) {
// @todo референсы дублируются в каждом объекте фиксту + в этом объекте
$oFixtures = new $sClassName($this->oEngine, $this->aReferences);
$oFixtures->load();
$aFixtureReference = $oFixtures->getReferences();
$this->aReferences = array_merge($this->aReferences, $aFixtureReference);
}
}
}
/**
* Function of loading plugin fixtures
*
* @param string $plugin
* @return void
*/
public function loadPluginFixtures($plugin){
$sPath = Config::Get('path.root.server').'/plugins/' . $plugin . '/tests/fixtures';
if (!is_dir($sPath)) {
throw new InvalidArgumentException('Plugin not found by LS directory: ' . $sPath, 10);
}
$this->sDirFixtures = $sPath;
$this->loadFixtures();
}
}

47
tests/Readme.RU.md Normal file
View file

@ -0,0 +1,47 @@
Запуск функциональных тестов
============================
Для запуска тестов проекта нужно:
1. Переименовать файл config/config.test.php.dist в config/config.test.php и
изменить настройки подключения к тестовой БД.
ВАЖНО! Информация в этой БД будет перезаписываться при каждом запуске теста.
2. В конфиге для Behat (tests/behat/behat.yml) сменить значение опции base_url на хост, под которым проект доступен локально.
3. Выполнить команду ```cd tests/behat; php behat.phar```. Примерный вывод результата работы команды:
DROP DATABASE social_test
CREATE DATABASE social_test
SELECTED DATABASE social_test
ExportSQL DATABASE social_test
ExportSQL DATABASE social_test -> geo_base
Feature: LiveStreet standart features
Test base functionality of LiveStreet
Scenario: See main page # features/base.feature:4
Given I am on homepage # FeatureContext::iAmOnHomepage()
When I press "Войти" # FeatureContext::pressButton()
Then the response status code should be 200 # FeatureContext::assertResponseStatus()
Scenario: See Colective Blog # features/base.feature:9
Given I am on "/blog/gadgets" # FeatureContext::visit()
Then I should see "Gadgets" # FeatureContext::assertPageContainsText()
Then I should see "Offers latest gadget reviews" # FeatureContext::assertPageContainsText()
Scenario: See list of blogs # features/base.feature:14
Given I am on "/blogs/" # FeatureContext::visit()
Then I should see "Gadgets" # FeatureContext::assertPageContainsText()
Scenario: See All Topic # features/base.feature:18
Given I am on "/index/newall/" # FeatureContext::visit()
Then I should see "iPad 3 rumored to come this March with quad-core chip and 4G LTE " # FeatureContext::assertPageContainsText()
Then I should see "Toshiba unveils 13.3-inch AT330 Android ICS 4.0 tablet" # FeatureContext::assertPageContainsText()
Scenario: See User Profile # features/base.feature:23
Given I am on "/profile/Golfer/" # FeatureContext::visit()
Then I should see "Sergey Doryba" # FeatureContext::assertPageContainsText()
Then I should see "... Sergey Doryba profile description" # FeatureContext::assertPageContainsText()
5 scenarios (5 passed)
14 steps (14 passed)
0m2.225s

BIN
tests/behat/behat.phar Normal file

Binary file not shown.

9
tests/behat/behat.yml Normal file
View file

@ -0,0 +1,9 @@
# behat.yml
default:
extensions:
mink_extension.phar:
base_url: http://livestreet.test/
mink_loader: mink.phar
goutte:
server_parameters:
APP_ENV: test

View file

@ -0,0 +1,26 @@
Feature: LiveStreet standart features
Test base functionality of LiveStreet
Scenario: See main page
Given I am on homepage
When I press "Войти"
Then the response status code should be 200
Scenario: See Colective Blog
Given I am on "/blog/gadgets"
Then I should see "Gadgets"
Then I should see "Offers latest gadget reviews"
Scenario: See list of blogs
Given I am on "/blogs/"
Then I should see "Gadgets"
Scenario: See All Topic
Given I am on "/index/newall/"
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"
Scenario: See User Profile
Given I am on "/profile/Golfer/"
Then I should see "Sergey Doryba"
Then I should see "... Sergey Doryba profile description"

View file

@ -0,0 +1,59 @@
<?php
use Behat\Behat\Context\ClosuredContextInterface,
Behat\Behat\Context\TranslatedContextInterface,
Behat\Behat\Context\BehatContext,
Behat\MinkExtension\Context\MinkContext,
Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
Behat\Gherkin\Node\TableNode;
$sDirRoot = dirname(realpath((dirname(__FILE__)) . "/../../../"));
set_include_path(get_include_path().PATH_SEPARATOR.$sDirRoot);
require_once("tests/LoadFixtures.php");
/**
* LiveStreet custom feature context
*/
class FeatureContext extends MinkContext
{
protected static $fixturesLoader = null;
/**
* Get fixtures loader
* @return LoadFixtures
*/
protected static function getFixturesLoader()
{
if (is_null(self::$fixturesLoader)) {
self::$fixturesLoader = new LoadFixtures();
}
return self::$fixturesLoader;
}
/**
* Purge DB and load fixtures before running each test
*
* @BeforeSuite
*/
public static function prepare($event){
$fixturesLoader = self::getFixturesLoader();
$fixturesLoader->purgeDB();
$fixturesLoader->load();
}
/**
* Loading fixture for plugin
*
* @Given /^I load fixtures for plugin "([^"]*)"$/
*/
public function loadFixturesForPlugin($plugin)
{
$fixturesLoader = $this->getFixturesLoader();
$fixturesLoader->loadPluginFixtures($plugin);
}
}

BIN
tests/behat/mink.phar Normal file

Binary file not shown.

Binary file not shown.

31
tests/fixtures/BlogFixtures.php vendored Normal file
View file

@ -0,0 +1,31 @@
<?php
require_once(realpath((dirname(__FILE__)) . "/../AbstractFixtures.php"));
class BlogFixtures extends AbstractFixtures
{
public static function getOrder()
{
return 1;
}
public function load()
{
$oUserStfalcon = $this->getReference('user-golfer');
/* @var $oBlogGadgets ModuleBlog_EntityBlog */
$oBlogGadgets = Engine::GetEntity('Blog');
$oBlogGadgets->setOwnerId($oUserStfalcon->getId());
$oBlogGadgets->setTitle("Gadgets");
$oBlogGadgets->setDescription('Offers latest gadget reviews');
$oBlogGadgets->setType('open');
$oBlogGadgets->setDateAdd(date("Y-m-d H:i:s")); // @todo freeze
$oBlogGadgets->setUrl('gadgets');
$oBlogGadgets->setLimitRatingTopic(0);
$this->oEngine->Blog_AddBlog($oBlogGadgets);
$this->addReference('blog-gadgets', $oBlogGadgets);
}
}

78
tests/fixtures/TopicFixtures.php vendored Normal file
View file

@ -0,0 +1,78 @@
<?php
require_once(realpath((dirname(__FILE__)) . "/../AbstractFixtures.php"));
class TopicFixtures extends AbstractFixtures
{
public static function getOrder()
{
return 2;
}
public function load()
{
$oUserGolfer = $this->getReference('user-golfer');
$oBlogGadgets = $this->getReference('blog-gadgets');
$oTopicToshiba = $this->_createTopic($oBlogGadgets->getBlogId(), $oUserGolfer->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 itll come equipped with HDMI port, on-board 32GB storage thats expandable via an full-sized SD card slot. Itll also have a built-in TV tuner and a collapsible antenna.Itll 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');
$this->addReference('topic-toshiba', $oTopicToshiba);
$oTopicIpad = $this->_createTopic($oBlogGadgets->getBlogId(), $oUserGolfer->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');
$this->addReference('topic-ipad', $oTopicIpad);
$oPersonalBlogGolfer = $this->oEngine->Blog_GetPersonalBlogByUserId($oUserGolfer->getId());
$oTopicSony = $this->_createTopic($oPersonalBlogGolfer->getBlogId(), $oUserGolfer->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. Its also backward compatible with USB 2.0.',
'sony, flash, gadget');
$this->addReference('topic-sony', $oTopicSony);
}
/**
* Create topic with default values
*
* @param int $iBlogId
* @param int $iUserId
* @param string $sTitle
* @param string $sText
* @param string $sTags
*
* @return ModuleTopic_EntityTopic
*/
private function _createTopic($iBlogId, $iUserId, $sTitle, $sText, $sTags)
{
$oTopic = Engine::GetEntity('Topic');
/* @var $oTopic ModuleTopic_EntityTopic */
$oTopic->setBlogId($iBlogId);
$oTopic->setUserId($iUserId);
$oTopic->setUserIp('127.0.0.1');
$oTopic->setForbidComment(false);
$oTopic->setType('topic');
$oTopic->setTitle($sTitle);
$oTopic->setPublish(true);
$oTopic->setPublishIndex(true);
$oTopic->setPublishDraft(true);
$oTopic->setDateAdd(date("Y-m-d H:i:s")); // @todo freeze
$oTopic->setTextSource($sText);
list($sTextShort, $sTextNew, $sTextCut) = $this->oEngine->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
$oTopic->setText($this->oEngine->Text_Parser($sTextNew));
$oTopic->setTextShort($this->oEngine->Text_Parser($sTextShort));
$oTopic->setTextHash(md5($oTopic->getType() . $oTopic->getTextSource() . $oTopic->getTitle()));
$oTopic->setTags($sTags);
$this->oEngine->Topic_AddTopic($oTopic);
return $oTopic;
}
}

36
tests/fixtures/UserFixtures.php vendored Normal file
View file

@ -0,0 +1,36 @@
<?php
require_once(realpath((dirname(__FILE__)) . "/../AbstractFixtures.php"));
class UserFixtures extends AbstractFixtures
{
public static function getOrder()
{
return 0;
}
public function load()
{
$oUserGolfer = Engine::GetEntity('User');
$oUserGolfer->setLogin('golfer');
$oUserGolfer->setPassword(md5('qwerty'));
$oUserGolfer->setMail('golfer@gmail.com');
$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_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);
}
}

104
tests/fixtures/sql/geo_base.sql vendored Normal file
View file

@ -0,0 +1,104 @@
--
-- Структура таблицы `prefix_geo_city`
--
CREATE TABLE IF NOT EXISTS `prefix_geo_city` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country_id` int(11) NOT NULL,
`region_id` int(11) NOT NULL,
`name_ru` varchar(50) NOT NULL,
`name_en` varchar(50) NOT NULL,
`sort` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `sort` (`sort`),
KEY `country_id` (`country_id`),
KEY `region_id` (`region_id`),
KEY `name_ru` (`name_ru`),
KEY `name_en` (`name_en`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=17590 ;
--
-- Структура таблицы `prefix_geo_country`
--
CREATE TABLE IF NOT EXISTS `prefix_geo_country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name_ru` varchar(50) NOT NULL,
`name_en` varchar(50) NOT NULL,
`code` varchar(5) NOT NULL,
`sort` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `sort` (`sort`),
KEY `name_ru` (`name_ru`),
KEY `name_en` (`name_en`),
KEY `code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=219 ;
--
-- Структура таблицы `prefix_geo_region`
--
CREATE TABLE IF NOT EXISTS `prefix_geo_region` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country_id` int(11) NOT NULL,
`name_ru` varchar(50) NOT NULL,
`name_en` varchar(50) NOT NULL,
`sort` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `sort` (`sort`),
KEY `country_id` (`country_id`),
KEY `name_ru` (`name_ru`),
KEY `name_en` (`name_en`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1612 ;
--
-- Структура таблицы `prefix_geo_target`
--
CREATE TABLE IF NOT EXISTS `prefix_geo_target` (
`geo_type` varchar(20) NOT NULL,
`geo_id` int(11) NOT NULL,
`target_type` varchar(20) NOT NULL,
`target_id` int(11) NOT NULL,
`country_id` int(11) DEFAULT NULL,
`region_id` int(11) DEFAULT NULL,
`city_id` int(11) DEFAULT NULL,
PRIMARY KEY (`geo_type`,`geo_id`,`target_type`,`target_id`),
KEY `target_type` (`target_type`,`target_id`),
KEY `country_id` (`country_id`),
KEY `region_id` (`region_id`),
KEY `city_id` (`city_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Дамп данных таблицы `prefix_geo_target`
--
--
-- Ограничения внешнего ключа сохраненных таблиц
--
--
-- Ограничения внешнего ключа таблицы `prefix_geo_city`
--
ALTER TABLE `prefix_geo_city`
ADD CONSTRAINT `prefix_geo_city_ibfk_2` FOREIGN KEY (`region_id`) REFERENCES `prefix_geo_region` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `prefix_geo_city_ibfk_1` FOREIGN KEY (`country_id`) REFERENCES `prefix_geo_country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Ограничения внешнего ключа таблицы `prefix_geo_region`
--
ALTER TABLE `prefix_geo_region`
ADD CONSTRAINT `prefix_geo_region_ibfk_1` FOREIGN KEY (`country_id`) REFERENCES `prefix_geo_country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Ограничения внешнего ключа таблицы `prefix_geo_target`
--
ALTER TABLE `prefix_geo_target`
ADD CONSTRAINT `prefix_geo_target_ibfk_3` FOREIGN KEY (`city_id`) REFERENCES `prefix_geo_city` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `prefix_geo_target_ibfk_1` FOREIGN KEY (`country_id`) REFERENCES `prefix_geo_country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `prefix_geo_target_ibfk_2` FOREIGN KEY (`region_id`) REFERENCES `prefix_geo_region` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

1031
tests/fixtures/sql/install_base.sql vendored Normal file

File diff suppressed because it is too large Load diff