From 47281c16a5ab9d43a6257fd31ac7a1572a724662 Mon Sep 17 00:00:00 2001 From: dantleech Date: Sat, 24 Jan 2015 15:19:13 +0000 Subject: [PATCH 1/3] Load the profile after setting the config from the Input --- CHANGELOG.md | 1 + src/PHPCR/Shell/Config/Profile.php | 2 +- src/PHPCR/Shell/DependencyInjection/Container.php | 10 +++++----- src/PHPCR/Shell/Transport/Transport/DoctrineDbal.php | 3 ++- src/PHPCR/Shell/Transport/Transport/JackalopeFs.php | 3 ++- src/PHPCR/Shell/Transport/Transport/Jackrabbit.php | 3 ++- src/PHPCR/Shell/Transport/TransportInterface.php | 4 +++- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca231e0c..35a4e6ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ dev-master ### Bug fixes - [embedded] No exit code returned +- [profile] Profile configuration overwritten by session parameters beta1 ----- diff --git a/src/PHPCR/Shell/Config/Profile.php b/src/PHPCR/Shell/Config/Profile.php index e1b476f3..0771b027 100644 --- a/src/PHPCR/Shell/Config/Profile.php +++ b/src/PHPCR/Shell/Config/Profile.php @@ -80,7 +80,7 @@ public function get($domain, $key = null) $this->validateDomain($domain); if (null === $key) { - return $this->profile[$domain]; + return new Config($this->profile[$domain]); } if (!isset($this->profile[$domain][$key])) { diff --git a/src/PHPCR/Shell/DependencyInjection/Container.php b/src/PHPCR/Shell/DependencyInjection/Container.php index fd07365e..8743169f 100644 --- a/src/PHPCR/Shell/DependencyInjection/Container.php +++ b/src/PHPCR/Shell/DependencyInjection/Container.php @@ -104,6 +104,11 @@ public function registerPhpcr() public function registerEvent() { if ($this->mode === PhpcrShell::MODE_STANDALONE) { + $this->register( + 'event.subscriber.profile_from_session_input', + 'PHPCR\Shell\Subscriber\ProfileFromSessionInputSubscriber' + )->addTag('event.subscriber'); + $this->register( 'event.subscriber.profile_loader', 'PHPCR\Shell\Subscriber\ProfileLoaderSubscriber' @@ -112,11 +117,6 @@ public function registerEvent() ->addArgument(new Reference('helper.question')) ->addTag('event.subscriber'); - $this->register( - 'event.subscriber.profile_from_session_input', - 'PHPCR\Shell\Subscriber\ProfileFromSessionInputSubscriber' - )->addTag('event.subscriber'); - $this->register( 'event.subscriber.profile_writer', 'PHPCR\Shell\Subscriber\ProfileWriterSubscriber' diff --git a/src/PHPCR/Shell/Transport/Transport/DoctrineDbal.php b/src/PHPCR/Shell/Transport/Transport/DoctrineDbal.php index fb394aff..1ed9edd2 100644 --- a/src/PHPCR/Shell/Transport/Transport/DoctrineDbal.php +++ b/src/PHPCR/Shell/Transport/Transport/DoctrineDbal.php @@ -14,6 +14,7 @@ use Doctrine\DBAL\DriverManager; use Jackalope\RepositoryFactoryDoctrineDBAL; use PHPCR\Shell\Transport\TransportInterface; +use PHPCR\Shell\Config\Config; class DoctrineDbal implements TransportInterface { @@ -22,7 +23,7 @@ public function getName() return 'doctrine-dbal'; } - public function getRepository(array $config) + public function getRepository(Config $config) { $connection = DriverManager::getConnection($ops = array( 'user' => $config['db_username'], diff --git a/src/PHPCR/Shell/Transport/Transport/JackalopeFs.php b/src/PHPCR/Shell/Transport/Transport/JackalopeFs.php index 979e37f8..8f56cd1e 100644 --- a/src/PHPCR/Shell/Transport/Transport/JackalopeFs.php +++ b/src/PHPCR/Shell/Transport/Transport/JackalopeFs.php @@ -13,6 +13,7 @@ use PHPCR\Shell\Transport\TransportInterface; use Jackalope\RepositoryFactoryFilesystem; +use PHPCR\Shell\Config\Config; class JackalopeFs implements TransportInterface { @@ -21,7 +22,7 @@ public function getName() return 'jackalope-fs'; } - public function getRepository(array $config) + public function getRepository(Config $config) { $params = array( 'path' => $config['repo_path'], diff --git a/src/PHPCR/Shell/Transport/Transport/Jackrabbit.php b/src/PHPCR/Shell/Transport/Transport/Jackrabbit.php index 459fecd6..51e8a2fc 100644 --- a/src/PHPCR/Shell/Transport/Transport/Jackrabbit.php +++ b/src/PHPCR/Shell/Transport/Transport/Jackrabbit.php @@ -13,6 +13,7 @@ use Jackalope\RepositoryFactoryJackrabbit; use PHPCR\Shell\Transport\TransportInterface; +use PHPCR\Shell\Config\Config; class Jackrabbit implements TransportInterface { @@ -21,7 +22,7 @@ public function getName() return 'jackrabbit'; } - public function getRepository(array $config) + public function getRepository(Config $config) { $params = array( 'jackalope.jackrabbit_uri' => $config['repo_url'], diff --git a/src/PHPCR/Shell/Transport/TransportInterface.php b/src/PHPCR/Shell/Transport/TransportInterface.php index a48ca039..9b1f4809 100644 --- a/src/PHPCR/Shell/Transport/TransportInterface.php +++ b/src/PHPCR/Shell/Transport/TransportInterface.php @@ -11,6 +11,8 @@ namespace PHPCR\Shell\Transport; +use PHPCR\Shell\Config\Config; + /** * All phpcr-shell transports must implement this interface * @@ -20,5 +22,5 @@ interface TransportInterface { public function getName(); - public function getRepository(array $config); + public function getRepository(Config $config); } From 4c8c649cfcd100f1726bae00d5c06df4714e742a Mon Sep 17 00:00:00 2001 From: dantleech Date: Wed, 4 Feb 2015 12:19:28 +0000 Subject: [PATCH 2/3] Composer self-update --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b39d3e9f..f8979df6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ php: - 5.4 before_script: + - composer self-update - composer require "symfony/symfony" "2.6.*" --no-update - composer install - bash tests/bin/travis_jackrabbit.sh From 29ca2d6f4738277e3d0c161c39da968db90ce85a Mon Sep 17 00:00:00 2001 From: dantleech Date: Wed, 4 Feb 2015 17:27:30 +0000 Subject: [PATCH 3/3] Added doctrine-dbal connection tests --- behat.yml | 5 + features/all/phpcr_node_edit.feature | 4 +- features/cli/doctrine-dbal.feature | 31 +++++ .../jackalope-doctrine-dbal-cli-config.php | 39 ++++++ spec/PHPCR/Shell/Config/ProfileSpec.php | 5 +- .../Subscriber/ProfileWriterSubscriber.php | 12 +- src/PHPCR/Shell/Test/CliContext.php | 125 ++++++++++++++++++ 7 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 features/cli/doctrine-dbal.feature create mode 100644 features/fixtures/jackalope-doctrine-dbal-cli-config.php create mode 100644 src/PHPCR/Shell/Test/CliContext.php diff --git a/behat.yml b/behat.yml index fcff41d1..8662b180 100644 --- a/behat.yml +++ b/behat.yml @@ -14,3 +14,8 @@ default: - PHPCR\Shell\Test\EmbeddedContext paths: - features/all + cli: + contexts: + - PHPCR\Shell\Test\CliContext + paths: + - features/cli diff --git a/features/all/phpcr_node_edit.feature b/features/all/phpcr_node_edit.feature index 41209f7c..1d7af9d3 100644 --- a/features/all/phpcr_node_edit.feature +++ b/features/all/phpcr_node_edit.feature @@ -7,7 +7,7 @@ Feature: Edit a node Given that I am logged in as "testuser" And the "cms.xml" fixtures are loaded - Scenario: Make a nutral edit + Scenario: Make a neutral edit Given I have an editor which produces the following: """" weight: @@ -91,7 +91,7 @@ Feature: Edit a node And I save the session Then the command should not fail And the property "/cms/products/product1/weight" should have type "Long" and value "10" - And the property "/cms/products/product1/cost" should have type "Long" and value "100" + And the property "/cms/products/product1/cost" should have type "Double" and value "100" And the property "/cms/products/product1/size" should have type "String" and value "XXL" And the property "/cms/products/product1/name" should have type "String" and value "Product One" And the property "/cms/products/product1/jcr:primaryType" should have type "Name" and value "nt:unstructured" diff --git a/features/cli/doctrine-dbal.feature b/features/cli/doctrine-dbal.feature new file mode 100644 index 00000000..b34ed12b --- /dev/null +++ b/features/cli/doctrine-dbal.feature @@ -0,0 +1,31 @@ +Feature: Connect to a doctrine dbal repository + In order to use the jackalope doctrine-dbal repository + As a user + I need to be able to connect to it + + Background: + Given I initialize doctrine dbal + + Scenario: Connect to doctrine-dbal session + Given I run PHPCR shell with "--transport=doctrine-dbal --db-driver=pdo_sqlite --db-path=./app.sqlite --command='ls'" + Then the command should not fail + + Scenario: Connect to doctrine-dbal session create a new profile + Given I run PHPCR shell with "--transport=doctrine-dbal --db-driver=pdo_sqlite --db-path=./app.sqlite --profile=new --no-interaction --command='ls'" + Then the command should not fail + + Scenario: Connect to an existing profile + Given the following profile "phpcrtest" exists: + """ + transport: + name: doctrine-dbal + db_name: phpcrtest + db_path: app.sqlite + db_driver: pdo_sqlite + phpcr: + workspace: default + username: admin + password: admin + """ + And I run PHPCR shell with "--profile=phpcrtest --no-interaction --command='ls'" + Then the command should not fail diff --git a/features/fixtures/jackalope-doctrine-dbal-cli-config.php b/features/fixtures/jackalope-doctrine-dbal-cli-config.php new file mode 100644 index 00000000..693044e5 --- /dev/null +++ b/features/fixtures/jackalope-doctrine-dbal-cli-config.php @@ -0,0 +1,39 @@ + 'pdo_sqlite', + 'dbname' => 'test', + 'path' => __DIR__.'/app.sqlite', +)); + +/* + * configuration + */ +$workspace = 'default'; // phpcr workspace to use +$user = 'admin'; +$pass = 'admin'; + +$factory = new \Jackalope\RepositoryFactoryDoctrineDBAL(); +$repository = $factory->getRepository(array('jackalope.doctrine_dbal_connection' => $dbConn)); + +$credentials = new \PHPCR\SimpleCredentials($user, $pass); + +/* only create a session if this is not about the server control command */ +if (isset($argv[1]) + && $argv[1] != 'jackalope:init:dbal' + && $argv[1] != 'list' + && $argv[1] != 'help' +) { + $session = $repository->login($credentials, $workspace); + + $helperSet = new \Symfony\Component\Console\Helper\HelperSet(array( + 'dialog' => new \Symfony\Component\Console\Helper\DialogHelper(), + 'phpcr' => new \PHPCR\Util\Console\Helper\PhpcrHelper($session), + 'phpcr_console_dumper' => new \PHPCR\Util\Console\Helper\PhpcrConsoleDumperHelper(), + )); +} else if (isset($argv[1]) && $argv[1] == 'jackalope:init:dbal') { + // special case: the init command needs the db connection, but a session is impossible if the db is not yet initialized + $helperSet = new \Symfony\Component\Console\Helper\HelperSet(array( + 'connection' => new \Jackalope\Tools\Console\Helper\DoctrineDbalHelper($dbConn) + )); +} + diff --git a/spec/PHPCR/Shell/Config/ProfileSpec.php b/spec/PHPCR/Shell/Config/ProfileSpec.php index 268c180c..a458332d 100644 --- a/spec/PHPCR/Shell/Config/ProfileSpec.php +++ b/spec/PHPCR/Shell/Config/ProfileSpec.php @@ -12,6 +12,7 @@ namespace spec\PHPCR\Shell\Config; use PhpSpec\ObjectBehavior; +use PHPCR\Shell\Config\Config; class ProfileSpec extends ObjectBehavior { @@ -39,9 +40,7 @@ public function it_has_a_method_to_get_config() 'foo' => 'bar' )); - $this->get('transport')->shouldReturn(array( - 'foo' => 'bar' - )); + $this->get('transport')->shouldHaveType('PHPCR\Shell\Config\Config'); $this->get('transport', 'foo')->shouldReturn('bar'); } diff --git a/src/PHPCR/Shell/Subscriber/ProfileWriterSubscriber.php b/src/PHPCR/Shell/Subscriber/ProfileWriterSubscriber.php index 01a8aa61..c147234b 100644 --- a/src/PHPCR/Shell/Subscriber/ProfileWriterSubscriber.php +++ b/src/PHPCR/Shell/Subscriber/ProfileWriterSubscriber.php @@ -40,6 +40,7 @@ public function handleProfileInit(ProfileInitEvent $e) $profile = $e->getProfile(); $input = $e->getInput(); $output = $e->getOutput(); + $noInteraction = $input->getOption('no-interaction'); $transport = $input->getOption('transport'); $profileName = $input->getOption('profile'); @@ -50,10 +51,17 @@ public function handleProfileInit(ProfileInitEvent $e) $overwrite = false; if (file_exists($this->profileLoader->getProfilePath($profileName))) { - $res = $this->questionHelper->askConfirmation($output, sprintf('Update existing profile "%s"?', $profileName)); + $res = true; + if (false === $noInteraction) { + $res = $this->questionHelper->askConfirmation($output, sprintf('Update existing profile "%s"?', $profileName)); + } $overwrite = true; } else { - $res = $this->questionHelper->askConfirmation($output, sprintf('Create new profile "%s"?', $profileName)); + $res = true; + + if (false === $noInteraction) { + $res = $this->questionHelper->askConfirmation($output, sprintf('Create new profile "%s"?', $profileName)); + } } if ($res) { diff --git a/src/PHPCR/Shell/Test/CliContext.php b/src/PHPCR/Shell/Test/CliContext.php new file mode 100644 index 00000000..bc533720 --- /dev/null +++ b/src/PHPCR/Shell/Test/CliContext.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PHPCR\Shell\Test; + +use Jackalope\RepositoryFactoryJackrabbit; +use PHPCR\SimpleCredentials; +use PHPCR\Util\NodeHelper; +use Symfony\Component\Filesystem\Filesystem; +use PHPCR\PathNotFoundException; +use PHPCR\Util\PathHelper; +use PHPCR\PropertyInterface; +use PHPCR\PropertyType; +use Behat\Behat\Context\SnippetAcceptingContext; +use Behat\Behat\Context\Context; +use PHPCR\NodeInterface; +use Behat\Gherkin\Node\PyStringNode; +use Behat\Gherkin\Node\TableNode; + +/** + * Features context. + */ +class CliContext implements Context, SnippetAcceptingContext +{ + private $output = array(); + private $rootPath; + private $lastExitCode; + private $fixturesDir; + + /** + * Initializes context. + * Every scenario gets it's own context object. + * + * @BeforeScenario + */ + public function beforeScenario() + { + $this->output = array(); + + $this->rootPath = realpath(__DIR__ . '/../../../..'); + $dir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpcr-shell' . DIRECTORY_SEPARATOR . + md5(microtime() * rand(0, 10000)); + $this->fixturesDir = realpath(__DIR__.'/../../../../features/fixtures/'); + + $this->workingDir = $dir; + putenv('PHPCRSH_HOME=' . $dir); + + mkdir($this->workingDir, 0777, true); + mkdir($this->workingDir . '/profiles'); + chdir($this->workingDir); + $this->filesystem = new Filesystem(); + } + + /** + * Cleans test folders in the temporary directory. + * + * @AfterSuite + */ + public static function cleanTestFolders() + { + $fs = new Filesystem(); + $fs->remove(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpcr-shell'); + } + + private function exec($command) + { + exec($command, $output, $return); + $this->output += $output; + $this->lastExitCode = $return; + } + + /** + * @Given I run PHPCR shell with ":argsAndOptions" + */ + public function execShell($argsAndOptions) + { + $this->exec(sprintf('%s/bin/phpcrsh %s', $this->rootPath, $argsAndOptions)); + } + + /** + * @Given print output + */ + public function printOutput() + { + foreach ($this->output as $line) { + echo $line . PHP_EOL; + } + } + + /** + * @Given the following profile ":profileName" exists: + */ + public function iHaveTheFollowingProfile($profileName, PyStringNode $text) + { + file_put_contents($this->workingDir . '/profiles/' . $profileName . '.yml', $text->getRaw()); + } + + /** + * @Given I initialize doctrine dbal + */ + public function initializeDoctrineDbal() + { + $this->filesystem->copy( + $this->fixturesDir . '/jackalope-doctrine-dbal-cli-config.php', + $this->workingDir . '/cli-config.php' + ); + $this->exec($this->rootPath . '/vendor/jackalope/jackalope-doctrine-dbal/bin/jackalope jackalope:init:dbal --force'); + } + + /** + * @Then the command should not fail + */ + public function theCommandShouldNotFail() + { + \PHPUnit_Framework_Assert::assertEquals(0, $this->lastExitCode); + } +}