From e1f4d6795c7922f5e3330b3d5296314094e6844b Mon Sep 17 00:00:00 2001
From: diosmosis <benakamoorthi@fastmail.fm>
Date: Fri, 4 Apr 2014 19:57:20 +0100
Subject: [PATCH] Add new console command to setup fixture outside of a test so
 manual testing can be done w/ existing fixtures and so specific custom data
 can be added by creating a fixture. Includes slight refactor to Fixture.php.

---
 plugins/CoreConsole/Commands/SetupFixture.php | 154 ++++++++++++++++++
 plugins/CoreConsole/CoreConsole.php           |   1 +
 tests/PHPUnit/DatabaseTestCase.php            |   2 +-
 tests/PHPUnit/Fixture.php                     |   5 +-
 tests/PHPUnit/Fixtures/UITestFixture.php      |   4 +-
 .../Core/CronArchive/SharedSiteIdsTest.php    |   2 +-
 tests/PHPUnit/IntegrationTestCase.php         |   2 +-
 .../support/setupDatabase.php                 |   2 +-
 .../support/teardownDatabase.php              |   2 +-
 9 files changed, 164 insertions(+), 10 deletions(-)
 create mode 100644 plugins/CoreConsole/Commands/SetupFixture.php

diff --git a/plugins/CoreConsole/Commands/SetupFixture.php b/plugins/CoreConsole/Commands/SetupFixture.php
new file mode 100644
index 0000000000..e756baca50
--- /dev/null
+++ b/plugins/CoreConsole/Commands/SetupFixture.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Plugins\CoreConsole\Commands;
+
+use Piwik\Url;
+use Piwik\Piwik;
+use Piwik\Config;
+use Piwik\Plugin\ConsoleCommand;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Console commands that sets up a fixture either in a local MySQL database or a remote one.
+ *
+ * TODO: use this console command in UI tests instead of setUpDatabase.php/tearDownDatabase.php scripts
+ */
+class SetupFixture extends ConsoleCommand
+{
+    protected function configure()
+    {
+        $this->setName('tests:setup-fixture');
+        $this->setDescription('Create a database and fill it with data using a Piwik test fixture.');
+
+        $this->addArgument('fixture', InputArgument::REQUIRED,
+            "The class name of the fixture to apply. Doesn't need to have a namespace if it exists in the " .
+            "Piwik\\Tests\\Fixtures namespace.");
+
+        $this->addOption('db-name', null, InputOption::VALUE_REQUIRED,
+            "The name of the database that will contain the fixture data. This option is required to be set.");
+        $this->addOption('file', null, InputOption::VALUE_REQUIRED,
+            "The file location of the fixture. If this option is included the file will be required explicitly.");
+        $this->addOption('db-host', null, InputOption::VALUE_REQUIRED,
+            "The hostname of the MySQL database to use. Uses the default config value if not specified.");
+        $this->addOption('db-user', null, InputOption::VALUE_REQUIRED,
+            "The name of the MySQL user to use. Uses the default config value if not specified.");
+        $this->addOption('db-pass', null, InputOption::VALUE_REQUIRED,
+            "The MySQL user password to use. Uses the default config value if not specified.");
+        $this->addOption('teardown', null, InputOption::VALUE_NONE,
+            "If specified, the fixture will be torn down and the database deleted. Won't work if the --db-name " .
+            "option isn't supplied.");
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $dbName = $input->getOption('db-name');
+        if (!$dbName) {
+            throw new \Exception("Required argument --db-name is not set.");
+        }
+
+        $file = $input->getOption('file');
+        if ($file) {
+            if (is_file($file)) {
+                require_once $file;
+            } else if (is_file(PIWIK_INCLUDE_PATH . '/' . $file)) {
+                require_once PIWIK_INCLUDE_PATH . '/' . $file;
+            } else {
+                throw new \Exception("Cannot find --file option file '$file'.");
+            }
+        }
+
+        if (empty(Url::getHost())) {
+            Url::setHost('localhost');
+        }
+
+        $this->requireFixtureFiles();
+        $this->setIncludePathAsInTestBootstrap();
+
+        // get the fixture class
+        $fixtureClass = $input->getArgument('fixture');
+        if (class_exists("Piwik\\Tests\\Fixtures\\" . $fixtureClass)) {
+            $fixtureClass = "Piwik\\Tests\\Fixtures\\" . $fixtureClass;
+        }
+
+        if (!class_exists($fixtureClass)) {
+            throw new \Exception("Cannot find fixture class '$fixtureClass'.");
+        }
+
+        // create the fixture
+        $fixture = new $fixtureClass();
+        $fixture->dbName = $dbName;
+
+        Config::getInstance()->setTestEnvironment();
+        $fixture->createConfig = false;
+
+        // setup database overrides
+        $testingEnvironment = $fixture->getTestEnvironment();
+
+        $optionsToOverride = array(
+            'dbname' => $dbName,
+            'host' => $input->getOption('db-host'),
+            'user' => $input->getOption('db-user'),
+            'password' => $input->getOption('db-pass')
+        );
+        foreach ($optionsToOverride as $configOption => $value) {
+            if ($value) {
+                $configOverride = $testingEnvironment->configOverride;
+                $configOverride['database_tests'][$configOption] = $configOverride['database'][$configOption] = $value;
+                $testingEnvironment->configOverride = $configOverride;
+
+                Config::getInstance()->database[$configOption] = $value;
+            }
+        }
+
+        // perform setup and/or teardown
+        if ($input->getOption('teardown')) {
+            $testingEnvironment->save();
+            $fixture->performTearDown();
+        } else {
+            $fixture->performSetUp();
+        }
+
+        $this->writeSuccessMessage($output, array("Fixture successfully setup!"));
+    }
+
+    private function requireFixtureFiles()
+    {
+        require_once "PHPUnit/Autoload.php";
+
+        require_once PIWIK_INCLUDE_PATH . '/libs/PiwikTracker/PiwikTracker.php';
+        require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/FakeAccess.php';
+        require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/TestingEnvironment.php';
+        require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Fixture.php';
+
+        $fixturesToLoad = array(
+            '/tests/PHPUnit/Fixtures/*.php',
+            '/tests/PHPUnit/UI/Fixtures/*.php',
+        );
+        foreach($fixturesToLoad as $fixturePath) {
+            foreach (glob(PIWIK_INCLUDE_PATH . $fixturePath) as $file) {
+                require_once $file;
+            }
+        }
+    }
+
+    private function setIncludePathAsInTestBootstrap()
+    {
+        if (!defined('PIWIK_INCLUDE_SEARCH_PATH')) {
+            define('PIWIK_INCLUDE_SEARCH_PATH', get_include_path()
+                . PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/core'
+                . PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/libs'
+                . PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/plugins');
+        }
+        @ini_set('include_path', PIWIK_INCLUDE_SEARCH_PATH);
+        @set_include_path(PIWIK_INCLUDE_SEARCH_PATH);
+    }
+}
\ No newline at end of file
diff --git a/plugins/CoreConsole/CoreConsole.php b/plugins/CoreConsole/CoreConsole.php
index 585d79a356..80e6212ab7 100644
--- a/plugins/CoreConsole/CoreConsole.php
+++ b/plugins/CoreConsole/CoreConsole.php
@@ -42,5 +42,6 @@ class CoreConsole extends \Piwik\Plugin
         $commands[] = 'Piwik\Plugins\CoreConsole\Commands\SyncUITestScreenshots';
         $commands[] = 'Piwik\Plugins\CoreConsole\Commands\ManagePlugin';
         $commands[] = 'Piwik\Plugins\CoreConsole\Commands\ManageTestFiles';
+        $commands[] = 'Piwik\Plugins\CoreConsole\Commands\SetupFixture';
     }
 }
diff --git a/tests/PHPUnit/DatabaseTestCase.php b/tests/PHPUnit/DatabaseTestCase.php
index ef3540f50b..eea23e45e3 100644
--- a/tests/PHPUnit/DatabaseTestCase.php
+++ b/tests/PHPUnit/DatabaseTestCase.php
@@ -37,7 +37,7 @@ class DatabaseTestCase extends PHPUnit_Framework_TestCase
 
         $this->fixture = new Fixture();
         $this->configureFixture();
-        $this->fixture->performSetUp(__CLASS__);
+        $this->fixture->performSetUp();
     }
 
     /**
diff --git a/tests/PHPUnit/Fixture.php b/tests/PHPUnit/Fixture.php
index 057401f9fb..76f8ac4f62 100644
--- a/tests/PHPUnit/Fixture.php
+++ b/tests/PHPUnit/Fixture.php
@@ -81,10 +81,8 @@ class Fixture extends PHPUnit_Framework_Assert
         // empty
     }
 
-    public function performSetUp($testCase, $setupEnvironmentOnly = false)
+    public function performSetUp($setupEnvironmentOnly = false)
     {
-        $this->getTestEnvironment()->delete();
-
         try {
             if ($this->createConfig) {
                 Config::getInstance()->setTestEnvironment();
@@ -197,6 +195,7 @@ class Fixture extends PHPUnit_Framework_Assert
     {
         if ($this->testEnvironment === null) {
             $this->testEnvironment = new Piwik_TestingEnvironment();
+            $this->testEnvironment->delete();
         }
         return $this->testEnvironment;
     }
diff --git a/tests/PHPUnit/Fixtures/UITestFixture.php b/tests/PHPUnit/Fixtures/UITestFixture.php
index cfaf75c94c..a3e12abc23 100644
--- a/tests/PHPUnit/Fixtures/UITestFixture.php
+++ b/tests/PHPUnit/Fixtures/UITestFixture.php
@@ -51,9 +51,9 @@ class UITestFixture extends OmniFixture
         VisitsSummaryAPI::getInstance()->get($this->idSite, 'year', $date, urlencode($this->segment));
     }
 
-    public function performSetUp($testCase, $setupEnvironmentOnly = false)
+    public function performSetUp($setupEnvironmentOnly = false)
     {
-        parent::performSetUp($testCase, $setupEnvironmentOnly);
+        parent::performSetUp($setupEnvironmentOnly);
 
         $this->createSegments();
         $this->setupDashboards();
diff --git a/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php b/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php
index 7985f3f0ba..63f35cc1af 100644
--- a/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php
+++ b/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php
@@ -21,7 +21,7 @@ class SharedSiteIdsTest extends DatabaseTestCase
     public function setUp()
     {
         parent::setUp();
-        $this->fixture->performSetUp(null, true);
+        $this->fixture->performSetUp(true);
 
         $this->sharedSiteIds = new SharedSiteIds(array(1,2,5,9));
     }
diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php
index 2851d80a68..63e353ae10 100755
--- a/tests/PHPUnit/IntegrationTestCase.php
+++ b/tests/PHPUnit/IntegrationTestCase.php
@@ -86,7 +86,7 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase
         }
 
         try {
-            $fixture->performSetUp(get_called_class());
+            $fixture->performSetUp();
         } catch (Exception $e) {
             static::fail("Failed to setup fixture: " . $e->getMessage() . "\n" . $e->getTraceAsString());
         }
diff --git a/tests/lib/screenshot-testing/support/setupDatabase.php b/tests/lib/screenshot-testing/support/setupDatabase.php
index 9f7bc0d350..6556707354 100644
--- a/tests/lib/screenshot-testing/support/setupDatabase.php
+++ b/tests/lib/screenshot-testing/support/setupDatabase.php
@@ -35,7 +35,7 @@ if (!empty($fixtureClass)) {
         $fixture->resetPersistedFixture = true;
     }
     $fixture->printToScreen = true;
-    $fixture->performSetUp("");
+    $fixture->performSetUp();
 }
 
 // make sure symbolic links exist (phantomjs doesn't support symlink-ing yet)
diff --git a/tests/lib/screenshot-testing/support/teardownDatabase.php b/tests/lib/screenshot-testing/support/teardownDatabase.php
index 3ef3e8e1f7..572e3d9608 100644
--- a/tests/lib/screenshot-testing/support/teardownDatabase.php
+++ b/tests/lib/screenshot-testing/support/teardownDatabase.php
@@ -27,5 +27,5 @@ if (!class_exists($fixtureClass)) {
 $fixture = new $fixtureClass();
 $fixture->dropDatabaseInSetUp = false;
 $fixture->printToScreen = true;
-$fixture->performSetUp("", $environmentOnly = true);
+$fixture->performSetUp($environmentOnly = true);
 $fixture->performTearDown("");
\ No newline at end of file
-- 
GitLab