1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 
<?php
namespace Omeka\Test;

use Zend\Mvc\Application;

/**
 * Database test case.
 *
 * Tests that need access to Doctrine's entity manager (e.g. for writing to and
 * querying the database) should extend off this class. For every test, this
 * starts a transaction during setUp, and rolls back any changes to the database
 * during tearDown. A fresh database should have been installed when
 * bootstrapping PHPUnit.
 */
class DbTestCase extends TestCase
{
    /**
     * The test application.
     *
     * @var Application
     */
    protected static $application;

    /**
     * Set the test application and begin a transaction during setUp.
     * Child classes should call parent::setUp() in their own setUp.
     */
    public function setUp()
    {
        self::getApplication()->getServiceManager()->get('Omeka\EntityManager')
            ->getConnection()->beginTransaction();
    }

    /**
     * Rollback the transaction during tear down.
     */
    public function tearDown()
    {
        self::getApplication()->getServiceManager()->get('Omeka\EntityManager')
            ->getConnection()->rollback();
    }

    /**
     * Get the test application.
     *
     * @return Application
     */
    public static function getApplication()
    {
        // Return the application immediately if already set.
        if (self::$application instanceof Application) {
            return self::$application;
        }
        $config = require OMEKA_PATH . '/application/config/application.config.php';
        $reader = new \Zend\Config\Reader\Ini;
        $testConfig = [
            'connection' => $reader->fromFile(OMEKA_PATH . '/application/test/config/database.ini'),
        ];
        $config = array_merge($config, $testConfig);
        \Zend\Console\Console::overrideIsConsole(false);
        self::$application = Application::init($config);
        return self::$application;
    }

    /**
     * Drop the test database schema.
     */
    public static function dropSchema()
    {
        $connection = self::getApplication()->getServiceManager()
            ->get('Omeka\EntityManager')->getConnection();
        $connection->query('SET FOREIGN_KEY_CHECKS=0');
        foreach ($connection->getSchemaManager()->listTableNames() as $table) {
            $connection->executeUpdate(
                $connection->getDatabasePlatform()
                    ->getDropTableSQL($table)
            );
        }
        $connection->query('SET FOREIGN_KEY_CHECKS=1');
    }

    /**
     * Install the test database schema.
     */
    public static function installSchema()
    {
        $application = self::getApplication();
        $serviceLocator = $application->getServiceManager();

        $status = $serviceLocator->get('Omeka\Status');
        if (!$status->isInstalled()) {
            // Without this, at some point during install the view helper Url
            // will throw an exception 'Request URI has not been set'
            $router = $serviceLocator->get('Router');
            $router->setRequestUri(new \Zend\Uri\Http('http://example.com'));

            $installer = $serviceLocator->get('Omeka\Installer');
            $installer->registerVars(
                'Omeka\Installation\Task\CreateFirstUserTask', [
                    'name' => 'Admin',
                    'email' => 'admin@example.com',
                    'password' => 'root',
                ]);
            $installer->registerVars(
                'Omeka\Installation\Task\AddDefaultSettingsTask', [
                    'administrator_email' => 'admin@example.com',
                    'installation_title' => 'Omeka S Test',
                    'time_zone' => 'UTC',
                    'locale' => 'en_US',
                ]);

            if (!$installer->install()) {
                file_put_contents('php://stdout', "Error(s) installing:\n");
                foreach ($installer->getErrors() as $error) {
                    file_put_contents('php://stdout', "\t$error\n");
                }
                exit;
            }
        }
    }
}