mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
Add behat page object extension
Loading services in test environment, introduce shared storage First approach to behat steps with new workflow [WIP] Security service for handling programatically log user in Add custom page factory to inject router Small refactoring in checkoutContext Split checkout context Update composer.lock Relocate setup contexts Contexts clean up and fix security issues Create decorated channel factory Check if user has privilege to show thank you page Small refactoring Get rid of container, kernel in behat contexts
This commit is contained in:
parent
6246312a1d
commit
d55f78dc9f
53 changed files with 2467 additions and 21 deletions
|
|
@ -397,6 +397,44 @@ default:
|
|||
filters:
|
||||
tags: "@security"
|
||||
|
||||
ui-checkout:
|
||||
contexts:
|
||||
- Sylius\Behat\Context\Setup\ChannelContext:
|
||||
defaultFranceChannelFactory: '@sylius.behat.default_france_channel_factory'
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
- Sylius\Behat\Context\Setup\CurrencyContext:
|
||||
currencyRepository: '@sylius.repository.currency'
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
currencyFactory: '@sylius.factory.currency'
|
||||
- Sylius\Behat\Context\Setup\PaymentContext:
|
||||
paymentMethodRepository: '@sylius.repository.payment_method'
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
paymentMethodFactory: '@sylius.factory.payment_method'
|
||||
- Sylius\Behat\Context\Setup\SecurityContext:
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
securityService: '@sylius.behat.security'
|
||||
- Sylius\Behat\Context\Setup\UserContext:
|
||||
userRepository: '@sylius.repository.user'
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
userFactory: '@sylius.factory.user'
|
||||
customerFactory: '@sylius.factory.customer'
|
||||
- Sylius\Behat\Context\Setup\ProductContext:
|
||||
productRepository: '@sylius.repository.product'
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
productFactory: '@sylius.factory.product'
|
||||
- Sylius\Behat\Context\Ui\CheckoutContext:
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
productRepository: '@sylius.repository.product'
|
||||
orderRepository: '@sylius.repository.order'
|
||||
- Sylius\Behat\Context\Hook\DoctrineORMContext:
|
||||
entityManager: '@doctrine.orm.entity_manager'
|
||||
- Sylius\Behat\Context\Setup\ShippingContext:
|
||||
shippingMethodRepository: '@sylius.repository.shipping_method'
|
||||
shippingMethodFactory: '@sylius.factory.shipping_method'
|
||||
sharedStorage: '@sylius.behat.shared_storage'
|
||||
filters:
|
||||
tags: "@ui-checkout"
|
||||
|
||||
extensions:
|
||||
Lakion\Behat\MinkDebugExtension:
|
||||
directory: etc/build
|
||||
|
|
@ -409,6 +447,11 @@ default:
|
|||
kernel:
|
||||
class: TestKernel
|
||||
path: app/TestKernel.php
|
||||
SensioLabs\Behat\PageObjectExtension:
|
||||
factory: sylius.page_object.factory
|
||||
namespaces:
|
||||
page: [Sylius\Behat\Page]
|
||||
Sylius\Behat\Extension\SyliusPageObjectExtension: ~
|
||||
|
||||
gherkin:
|
||||
filters:
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@
|
|||
"lakion/mink-debug-extension": "^1.0.1",
|
||||
"lakion/api-test-case": "^1.0@dev",
|
||||
"coduo/php-matcher": "^2.1@dev",
|
||||
"sensiolabs/behat-page-object-extension": "^2.0@dev",
|
||||
"phpunit/phpunit": "~4.1"
|
||||
},
|
||||
"replace": {
|
||||
|
|
|
|||
84
composer.lock
generated
84
composer.lock
generated
|
|
@ -4,8 +4,8 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "a5f092674e0c71c684765d612ab6b82f",
|
||||
"content-hash": "64dec9562cf51236c97f1514c66b2737",
|
||||
"hash": "da79832911ae4d93c0bff9440f146e76",
|
||||
"content-hash": "17d2280091ae14ae467a8991886a457a",
|
||||
"packages": [
|
||||
{
|
||||
"name": "a2lix/translation-form-bundle",
|
||||
|
|
@ -2692,9 +2692,9 @@
|
|||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"name": "Johannes M. Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
|
|
@ -5692,9 +5692,9 @@
|
|||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"name": "Johannes M. Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
|
|
@ -7773,7 +7773,7 @@
|
|||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "William Durand",
|
||||
"name": "William DURAND",
|
||||
"email": "william.durand1@gmail.com",
|
||||
"homepage": "http://www.willdurand.fr"
|
||||
}
|
||||
|
|
@ -9213,8 +9213,7 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Chris Boulton",
|
||||
"homepage": "http://github.com/chrisboulton",
|
||||
"role": "Original developer"
|
||||
"homepage": "http://github.com/chrisboulton"
|
||||
}
|
||||
],
|
||||
"description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
|
||||
|
|
@ -10148,13 +10147,78 @@
|
|||
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
||||
"homepage": "https://github.com/sebastianbergmann/version",
|
||||
"time": "2015-06-21 13:59:46"
|
||||
},
|
||||
{
|
||||
"name": "sensiolabs/behat-page-object-extension",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sensiolabs/BehatPageObjectExtension.git",
|
||||
"reference": "58404070265f58ca40a13b62bb3b69b83e27de20"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sensiolabs/BehatPageObjectExtension/zipball/58404070265f58ca40a13b62bb3b69b83e27de20",
|
||||
"reference": "58404070265f58ca40a13b62bb3b69b83e27de20",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"behat/behat": "^3.0",
|
||||
"behat/mink-extension": "^2.0",
|
||||
"ocramius/proxy-manager": "^1.0",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"behat/mink-goutte-driver": "~1.0",
|
||||
"bossa/phpspec2-expect": "~1.0",
|
||||
"phpspec/phpspec": "~2.0",
|
||||
"symfony/filesystem": "^2.3|^3.0",
|
||||
"symfony/process": "^2.3|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"bossa/phpspec2-expect": "Allows to use PHPSpec2 matchers in Behat context files"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"SensioLabs\\Behat\\PageObjectExtension\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marcello Duarte",
|
||||
"email": "mduarte@inviqa.com"
|
||||
},
|
||||
{
|
||||
"name": "Jakub Zalas",
|
||||
"email": "jzalas@sensiolabs.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Page object extension for Behat",
|
||||
"homepage": "https://github.com/sensiolabs/BehatPageObjectExtension",
|
||||
"keywords": [
|
||||
"BDD",
|
||||
"Behat",
|
||||
"page"
|
||||
],
|
||||
"time": "2016-01-18 10:49:11"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"lakion/api-test-case": 20,
|
||||
"coduo/php-matcher": 20
|
||||
"coduo/php-matcher": 20,
|
||||
"sensiolabs/behat-page-object-extension": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ Feature: Checkout finalization
|
|||
And I select the "Dummy" radio button
|
||||
And I press "Continue"
|
||||
When I click "Place order"
|
||||
Then I should be on the store homepage
|
||||
And I should see "Thank you for your order!"
|
||||
Then I should see "Thank you"
|
||||
And I am on my account orders page
|
||||
And I should see "All your orders"
|
||||
And I should see 1 orders in the list
|
||||
|
|
@ -85,5 +84,4 @@ Feature: Checkout finalization
|
|||
And I select the "Dummy" radio button
|
||||
And I press "Continue"
|
||||
When I click "Place order"
|
||||
Then I should be on the store homepage
|
||||
And I should see "Thank you for your order!"
|
||||
Then I should see "Thank you"
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ Feature: Checkout security
|
|||
And I select the "Dummy" radio button
|
||||
And I press "Continue"
|
||||
And I click "Place order"
|
||||
Then I should be on the store homepage
|
||||
Then I should be on the checkout thank you page
|
||||
And I should see "Thank you for your order!"
|
||||
|
||||
Scenario: Creating account without first and last name
|
||||
|
|
|
|||
20
features/shop/checkout_with_offline_payment.feature
Normal file
20
features/shop/checkout_with_offline_payment.feature
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
@ui-checkout
|
||||
Feature: Checkout with offline payment
|
||||
In order to pay with cash or by external means
|
||||
As a Customer
|
||||
I want to be able to complete checkout process without paying
|
||||
|
||||
Background:
|
||||
Given that store is operating on the France channel
|
||||
And default currency is "EUR"
|
||||
And there is user "john@example.com" identified by "password123"
|
||||
And catalog has a product "PHP T-Shirt" priced at $19.99
|
||||
And store has free shipping method
|
||||
And store allows paying offline
|
||||
|
||||
Scenario: Successfully placing an order
|
||||
Given I am logged in as "john@example.com"
|
||||
And I added product "PHP T-Shirt" to the cart
|
||||
When I proceed selecting "Offline" payment method
|
||||
And I confirm my order
|
||||
Then I should see the thank you page
|
||||
|
|
@ -65,5 +65,6 @@ suites:
|
|||
UserBundle: { namespace: Sylius\Bundle\UserBundle, psr4_prefix: Sylius\Bundle\UserBundle, spec_path: src/Sylius/Bundle/UserBundle, src_path: src/Sylius/Bundle/UserBundle }
|
||||
VariationBundle: { namespace: Sylius\Bundle\VariationBundle, psr4_prefix: Sylius\Bundle\VariationBundle, spec_path: src/Sylius/Bundle/VariationBundle, src_path: src/Sylius/Bundle/VariationBundle }
|
||||
|
||||
SyliusBehat: { namespace: Sylius\Behat, psr4_prefix: Sylius\Behat, spec_path: src/Sylius/Behat, src_path: src/Sylius/Behat }
|
||||
extensions:
|
||||
- Akeneo\SkipExampleExtension
|
||||
|
|
|
|||
71
src/Sylius/Behat/Context/FeatureContext.php
Normal file
71
src/Sylius/Behat/Context/FeatureContext.php
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context;
|
||||
|
||||
use SensioLabs\Behat\PageObjectExtension\Context\PageObjectContext;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Behat\MinkExtension\Context\MinkAwareContext;
|
||||
use Behat\Mink\Mink;
|
||||
use Behat\Mink\Session;
|
||||
use Behat\Mink\WebAssert;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
abstract class FeatureContext extends PageObjectContext implements MinkAwareContext
|
||||
{
|
||||
/**
|
||||
* @var Mink
|
||||
*/
|
||||
protected $mink;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $minkParameters;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMink(Mink $mink)
|
||||
{
|
||||
$this->mink = $mink;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMinkParameters(array $parameters)
|
||||
{
|
||||
$this->minkParameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $name name of the session OR active session will be used
|
||||
*
|
||||
* @return Session
|
||||
*/
|
||||
public function getSession($name = null)
|
||||
{
|
||||
return $this->mink->getSession($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $name name of the session OR active session will be used
|
||||
*
|
||||
* @return WebAssert
|
||||
*/
|
||||
public function assertSession($name = null)
|
||||
{
|
||||
return $this->mink->assertSession($name);
|
||||
}
|
||||
}
|
||||
50
src/Sylius/Behat/Context/Hook/DoctrineORMContext.php
Normal file
50
src/Sylius/Behat/Context/Hook/DoctrineORMContext.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Hook;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class DoctrineORMContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
/**
|
||||
* @param EntityManagerInterface $entityManager
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @BeforeScenario
|
||||
*/
|
||||
public function purgeDatabase()
|
||||
{
|
||||
if (null === $this->entityManager) {
|
||||
throw new \RuntimeException('Cannot purge database. Entity manager is not set');
|
||||
}
|
||||
|
||||
$this->entityManager->getConnection()->getConfiguration()->setSQLLogger(null);
|
||||
$purger = new ORMPurger($this->entityManager);
|
||||
$purger->purge();
|
||||
$this->entityManager->clear();
|
||||
}
|
||||
}
|
||||
53
src/Sylius/Behat/Context/Setup/ChannelContext.php
Normal file
53
src/Sylius/Behat/Context/Setup/ChannelContext.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Setup;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Component\Core\Test\Services\DefaultStoreDataInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class ChannelContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var DefaultStoreDataInterface
|
||||
*/
|
||||
private $defaultFranceChannelFactory;
|
||||
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @param DefaultStoreDataInterface $defaultFranceChannelFactory
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
*/
|
||||
public function __construct(
|
||||
DefaultStoreDataInterface $defaultFranceChannelFactory,
|
||||
SharedStorageInterface $sharedStorage
|
||||
) {
|
||||
$this->defaultFranceChannelFactory = $defaultFranceChannelFactory;
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given that store is operating on the France channel
|
||||
*/
|
||||
public function thatStoreIsOperatingOnTheFranceChannel()
|
||||
{
|
||||
$defaultData = $this->defaultFranceChannelFactory->create();
|
||||
$this->sharedStorage->setClipboard($defaultData);
|
||||
}
|
||||
}
|
||||
67
src/Sylius/Behat/Context/Setup/CurrencyContext.php
Normal file
67
src/Sylius/Behat/Context/Setup/CurrencyContext.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Setup;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class CurrencyContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $currencyRepository;
|
||||
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $currencyFactory;
|
||||
|
||||
/**
|
||||
* @param RepositoryInterface $currencyRepository
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param FactoryInterface $currencyFactory
|
||||
*/
|
||||
public function __construct(
|
||||
RepositoryInterface $currencyRepository,
|
||||
SharedStorageInterface $sharedStorage,
|
||||
FactoryInterface $currencyFactory
|
||||
) {
|
||||
$this->currencyRepository = $currencyRepository;
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
$this->currencyFactory = $currencyFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given default currency is :currencyCode
|
||||
*/
|
||||
public function defaultCurrencyIs($currencyCode)
|
||||
{
|
||||
$currency = $this->currencyFactory->createNew();
|
||||
$currency->setCode($currencyCode);
|
||||
$currency->setExchangeRate(1.0);
|
||||
$channel = $this->sharedStorage->getCurrentResource('channel');
|
||||
$channel->setDefaultCurrency($currency);
|
||||
|
||||
$this->currencyRepository->add($currency);
|
||||
}
|
||||
}
|
||||
67
src/Sylius/Behat/Context/Setup/PaymentContext.php
Normal file
67
src/Sylius/Behat/Context/Setup/PaymentContext.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Setup;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class PaymentContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $paymentMethodRepository;
|
||||
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $paymentMethodFactory;
|
||||
|
||||
/**
|
||||
* @param $paymentMethodRepository
|
||||
* @param $sharedStorage
|
||||
* @param $paymentMethodFactory
|
||||
*/
|
||||
public function __construct(RepositoryInterface $paymentMethodRepository, SharedStorageInterface $sharedStorage, FactoryInterface $paymentMethodFactory)
|
||||
{
|
||||
$this->paymentMethodRepository = $paymentMethodRepository;
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
$this->paymentMethodFactory = $paymentMethodFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given store allows paying offline
|
||||
*/
|
||||
public function storeAllowsPayingOffline()
|
||||
{
|
||||
$paymentMethod = $this->paymentMethodFactory->createNew();
|
||||
$paymentMethod->setCode('PM1');
|
||||
$paymentMethod->setGateway('dummy');
|
||||
$paymentMethod->setName('Offline');
|
||||
$paymentMethod->setDescription('Offline payment method');
|
||||
|
||||
$channel = $this->sharedStorage->getCurrentResource('channel');
|
||||
$channel->addPaymentMethod($paymentMethod);
|
||||
|
||||
$this->paymentMethodRepository->add($paymentMethod);
|
||||
}
|
||||
}
|
||||
66
src/Sylius/Behat/Context/Setup/ProductContext.php
Normal file
66
src/Sylius/Behat/Context/Setup/ProductContext.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Setup;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class ProductContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $productRepository;
|
||||
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $productFactory;
|
||||
|
||||
/**
|
||||
* @param RepositoryInterface $productRepository
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param FactoryInterface $productFactory
|
||||
*/
|
||||
public function __construct(RepositoryInterface $productRepository, SharedStorageInterface $sharedStorage, FactoryInterface $productFactory)
|
||||
{
|
||||
$this->productRepository = $productRepository;
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
$this->productFactory = $productFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given catalog has a product :productName priced at $:price
|
||||
*/
|
||||
public function catalogHasAProductPricedAt($productName, $price)
|
||||
{
|
||||
$product = $this->productFactory->createNew();
|
||||
$product->setName($productName);
|
||||
$product->setPrice((int) $price);
|
||||
$product->setDescription('Awesome star wars mug');
|
||||
|
||||
$channel = $this->sharedStorage->getCurrentResource('channel');
|
||||
$product->addChannel($channel);
|
||||
|
||||
$this->productRepository->add($product);
|
||||
}
|
||||
}
|
||||
50
src/Sylius/Behat/Context/Setup/SecurityContext.php
Normal file
50
src/Sylius/Behat/Context/Setup/SecurityContext.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Setup;
|
||||
|
||||
use Sylius\Behat\Context\FeatureContext;
|
||||
use Sylius\Bundle\CoreBundle\Test\Services\SecurityServiceInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class SecurityContext extends FeatureContext
|
||||
{
|
||||
/**
|
||||
* @var SecurityServiceInterface
|
||||
*/
|
||||
private $securityService;
|
||||
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param SecurityServiceInterface $securityService
|
||||
*/
|
||||
public function __construct(SharedStorageInterface $sharedStorage, SecurityServiceInterface $securityService)
|
||||
{
|
||||
$this->securityService = $securityService;
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given I am logged in as :email
|
||||
*/
|
||||
public function iAmLoggedInAs($email)
|
||||
{
|
||||
$this->securityService->logIn($email, 'main', $this->getSession());
|
||||
}
|
||||
}
|
||||
72
src/Sylius/Behat/Context/Setup/ShippingContext.php
Normal file
72
src/Sylius/Behat/Context/Setup/ShippingContext.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Setup;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
use Sylius\Component\Shipping\Calculator\DefaultCalculators;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class ShippingContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $shippingMethodRepository;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $shippingMethodFactory;
|
||||
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @param RepositoryInterface $shippingMethodRepository
|
||||
* @param FactoryInterface $shippingMethodFactory
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
*/
|
||||
public function __construct(
|
||||
RepositoryInterface $shippingMethodRepository,
|
||||
FactoryInterface $shippingMethodFactory,
|
||||
SharedStorageInterface $sharedStorage
|
||||
) {
|
||||
$this->shippingMethodRepository = $shippingMethodRepository;
|
||||
$this->shippingMethodFactory = $shippingMethodFactory;
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given store has free shipping method
|
||||
*/
|
||||
public function storeHasFreeShippingMethod()
|
||||
{
|
||||
$zone = $this->sharedStorage->getCurrentResource('zone');
|
||||
|
||||
$shippingMethod = $this->shippingMethodFactory->createNew();
|
||||
$shippingMethod->setCode('SM1');
|
||||
$shippingMethod->setName('Free');
|
||||
$shippingMethod->setCurrentLocale('FR');
|
||||
$shippingMethod->setConfiguration(array('amount' => 0));
|
||||
$shippingMethod->setCalculator(DefaultCalculators::PER_ITEM_RATE);
|
||||
$shippingMethod->setZone($zone);
|
||||
|
||||
$this->shippingMethodRepository->add($shippingMethod);
|
||||
}
|
||||
}
|
||||
83
src/Sylius/Behat/Context/Setup/UserContext.php
Normal file
83
src/Sylius/Behat/Context/Setup/UserContext.php
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Setup;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class UserContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $userRepository;
|
||||
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $userFactory;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $customerFactory;
|
||||
|
||||
/**
|
||||
* @param RepositoryInterface $userRepository
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param FactoryInterface $userFactory
|
||||
* @param FactoryInterface $customerFactory
|
||||
*/
|
||||
public function __construct(
|
||||
RepositoryInterface $userRepository,
|
||||
SharedStorageInterface $sharedStorage,
|
||||
FactoryInterface $userFactory,
|
||||
FactoryInterface $customerFactory
|
||||
) {
|
||||
$this->userRepository = $userRepository;
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
$this->userFactory = $userFactory;
|
||||
$this->customerFactory = $customerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given there is user :email identified by :password
|
||||
*/
|
||||
public function thereIsUserIdentifiedBy($email, $password)
|
||||
{
|
||||
/** @var UserInterface $user */
|
||||
$user = $this->userFactory->createNew();
|
||||
$customer = $this->customerFactory->createNew();
|
||||
$customer->setFirstName('John');
|
||||
$customer->setLastName('Doe');
|
||||
|
||||
$user->setCustomer($customer);
|
||||
$user->setUsername('John Doe');
|
||||
$user->setEmail($email);
|
||||
$user->setPlainPassword($password);
|
||||
$user->addRole('ROLE_USER');
|
||||
|
||||
$this->sharedStorage->setCurrentResource('user', $user);
|
||||
$this->userRepository->add($user);
|
||||
}
|
||||
}
|
||||
111
src/Sylius/Behat/Context/Ui/CheckoutContext.php
Normal file
111
src/Sylius/Behat/Context/Ui/CheckoutContext.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Context\Ui;
|
||||
|
||||
use Sylius\Behat\Context\FeatureContext;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
use Sylius\Component\Product\Model\ProductInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class CheckoutContext extends FeatureContext
|
||||
{
|
||||
/**
|
||||
* @var SharedStorageInterface
|
||||
*/
|
||||
private $sharedStorage;
|
||||
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $productRepository;
|
||||
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $orderRepository;
|
||||
|
||||
/**
|
||||
* @param SharedStorageInterface $sharedStorage
|
||||
* @param RepositoryInterface $productRepository
|
||||
* @param RepositoryInterface $orderRepository
|
||||
*/
|
||||
public function __construct(SharedStorageInterface $sharedStorage, RepositoryInterface $productRepository, RepositoryInterface $orderRepository)
|
||||
{
|
||||
$this->sharedStorage = $sharedStorage;
|
||||
$this->productRepository = $productRepository;
|
||||
$this->orderRepository = $orderRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given I added product :name to the cart
|
||||
*/
|
||||
public function iAddedProductToTheCart($name)
|
||||
{
|
||||
/** @var ProductInterface $product */
|
||||
$product = $this->productRepository->findOneBy(array('name' => $name));
|
||||
|
||||
$productShowPage = $this->getPage('Product\ProductShowPage')->openSpecificProductPage($product);
|
||||
$productShowPage->addToCart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I proceed selecting :paymentMethodName payment method
|
||||
*/
|
||||
public function iProceedSelectingOfflinePaymentMethod($paymentMethodName)
|
||||
{
|
||||
$checkoutAddressingPage = $this->getPage('Checkout\CheckoutAddressingStep')->open();
|
||||
$addressingDetails = array(
|
||||
'firstName' => 'John',
|
||||
'lastName' => 'Doe',
|
||||
'country' => 'France',
|
||||
'street' => '0635 Myron Hollow Apt. 711',
|
||||
'city' => 'North Bridget',
|
||||
'postcode' => '93-554',
|
||||
'phoneNumber' => '321123456'
|
||||
);
|
||||
$checkoutAddressingPage->fillAddressingDetails($addressingDetails);
|
||||
$checkoutAddressingPage->pressButton('Continue');
|
||||
|
||||
$checkoutShippingPage = $this->getPage('Checkout\CheckoutShippingStep');
|
||||
$checkoutShippingPage->pressRadio('Free');
|
||||
$checkoutShippingPage->pressButton('Continue');
|
||||
|
||||
$checkoutPaymentPage = $this->getPage('Checkout\CheckoutPaymentStep');
|
||||
$checkoutPaymentPage->pressRadio($paymentMethodName);
|
||||
$checkoutPaymentPage->pressButton('Continue');
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I confirm my order
|
||||
*/
|
||||
public function iConfirmMyOrder()
|
||||
{
|
||||
$checkoutFinalizePage = $this->getPage('Checkout\CheckoutFinalizeStep');
|
||||
$checkoutFinalizePage->assertRoute();
|
||||
$checkoutFinalizePage->clickLink('Place order');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see the thank you page
|
||||
*/
|
||||
public function iShouldSeeTheThankYouPage()
|
||||
{
|
||||
$user = $this->sharedStorage->getCurrentResource('user');
|
||||
$customer = $user->getCustomer();
|
||||
$thankYouPage = $this->getPage('Checkout\CheckoutThankYouPage');
|
||||
$thankYouPage->assertRoute();
|
||||
$this->assertSession()->elementTextContains('css', '#thanks', sprintf('Thank you %s', $customer->getFullName()));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Extension\Factory;
|
||||
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\DriverFactory;
|
||||
use Sylius\Behat\Extension\SyliusPageObjectExtension;
|
||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
final class IsolatedSymfonyFactory implements DriverFactory
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDriverName()
|
||||
{
|
||||
return 'symfony2';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsJavascript()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configure(ArrayNodeDefinition $builder)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildDriver(array $config)
|
||||
{
|
||||
if (!class_exists('Behat\Mink\Driver\BrowserKitDriver')) {
|
||||
throw new \RuntimeException(
|
||||
'Install MinkBrowserKitDriver in order to use the symfony2 driver.'
|
||||
);
|
||||
}
|
||||
|
||||
return new Definition('Behat\Symfony2Extension\Driver\KernelDriver', array(
|
||||
new Reference(SyliusPageObjectExtension::DRIVER_KERNEL_ID),
|
||||
'%mink.base_url%',
|
||||
));
|
||||
}
|
||||
}
|
||||
139
src/Sylius/Behat/Extension/Factory/PageObjectFactory.php
Normal file
139
src/Sylius/Behat/Extension/Factory/PageObjectFactory.php
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Extension\Factory;
|
||||
|
||||
use Behat\Mink\Mink;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Element;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Factory\ClassNameResolver;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\InlineElement;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\PageObject;
|
||||
use Symfony\Cmf\Component\Routing\ChainRouterInterface;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Factory;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class PageObjectFactory implements Factory
|
||||
{
|
||||
/**
|
||||
* @var ClassNameResolver
|
||||
*/
|
||||
private $classNameResolver;
|
||||
|
||||
/**
|
||||
* @var Factory
|
||||
*/
|
||||
private $defaultFactory;
|
||||
|
||||
/**
|
||||
* @var Mink
|
||||
*/
|
||||
private $mink = null;
|
||||
|
||||
/**
|
||||
* @var ChainRouterInterface
|
||||
*/
|
||||
private $router;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $pageParameters = array();
|
||||
|
||||
/**
|
||||
* @param ClassNameResolver $classNameResolver
|
||||
* @param Factory $defaultFactory
|
||||
* @param Mink $mink
|
||||
* @param ChainRouterInterface $router
|
||||
* @param array $pageParameters
|
||||
*/
|
||||
public function __construct(
|
||||
ClassNameResolver $classNameResolver,
|
||||
Factory $defaultFactory,
|
||||
Mink $mink,
|
||||
ChainRouterInterface $router,
|
||||
array $pageParameters
|
||||
) {
|
||||
$this->classNameResolver = $classNameResolver;
|
||||
$this->defaultFactory = $defaultFactory;
|
||||
$this->mink = $mink;
|
||||
$this->router = $router;
|
||||
$this->pageParameters = $pageParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
*
|
||||
* @return PageObject
|
||||
*/
|
||||
public function instantiate($class)
|
||||
{
|
||||
return $this->defaultFactory->instantiate($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Page
|
||||
*/
|
||||
public function createPage($name)
|
||||
{
|
||||
$pageClass = $this->classNameResolver->resolvePage($name);
|
||||
|
||||
return $this->instantiatePage($pageClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Element
|
||||
*/
|
||||
public function createElement($name)
|
||||
{
|
||||
return $this->defaultFactory->createElement($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $selector
|
||||
*
|
||||
* @return InlineElement
|
||||
*/
|
||||
public function createInlineElement($selector)
|
||||
{
|
||||
return $this->defaultFactory->createInlineElement($selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pageObjectClass
|
||||
*
|
||||
* @return PageObject
|
||||
*/
|
||||
public function create($pageObjectClass)
|
||||
{
|
||||
return $this->defaultFactory->create($pageObjectClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pageClass
|
||||
*
|
||||
* @return Page
|
||||
*/
|
||||
private function instantiatePage($pageClass)
|
||||
{
|
||||
if (!is_subclass_of($pageClass, 'Sylius\Behat\Page\SymfonyPage')) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid page object class: %s, to use this factory you need to extend SymfonyPage', $pageClass));
|
||||
}
|
||||
|
||||
return new $pageClass($this->mink->getSession(), $this, $this->pageParameters, $this->router);
|
||||
}
|
||||
}
|
||||
78
src/Sylius/Behat/Extension/SyliusPageObjectExtension.php
Normal file
78
src/Sylius/Behat/Extension/SyliusPageObjectExtension.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Extension;
|
||||
|
||||
use Behat\Symfony2Extension\ServiceContainer\Symfony2Extension;
|
||||
use Behat\Testwork\ServiceContainer\Extension as TestworkExtension;
|
||||
use Behat\Testwork\ServiceContainer\ExtensionManager;
|
||||
use Sylius\Behat\Extension\Factory\IsolatedSymfonyFactory;
|
||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class SyliusPageObjectExtension implements TestworkExtension
|
||||
{
|
||||
const DRIVER_KERNEL_ID = 'sylius_extension.kernel';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfigKey()
|
||||
{
|
||||
return 'sylius_page_object';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize(ExtensionManager $extensionManager)
|
||||
{
|
||||
if (null !== $minkExtension = $extensionManager->getExtension('mink')) {
|
||||
$minkExtension->registerDriverFactory(new IsolatedSymfonyFactory());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configure(ArrayNodeDefinition $builder)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(ContainerBuilder $container, array $config)
|
||||
{
|
||||
$container->setDefinition(self::DRIVER_KERNEL_ID, $container->getDefinition(Symfony2Extension::KERNEL_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}S
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$classNameResolver = $container->get('sensio_labs.page_object_extension.class_name_resolver.camelcased');
|
||||
$defaultFactory = $container->get('sensio_labs.page_object_extension.page_factory.default');
|
||||
$kernel = $container->get('symfony2_extension.kernel');
|
||||
$appContainer = clone $kernel->getContainer();
|
||||
$router = $appContainer->get('router');
|
||||
|
||||
$definition = new Definition('Sylius\Behat\Extension\Factory\PageObjectFactory');
|
||||
$definition->setArguments(array($classNameResolver, $defaultFactory, new Reference('mink'), $router, '%mink.parameters%'));
|
||||
$container->setDefinition('sylius.page_object.factory', $definition);
|
||||
}
|
||||
}
|
||||
45
src/Sylius/Behat/Page/Checkout/CheckoutAddressingStep.php
Normal file
45
src/Sylius/Behat/Page/Checkout/CheckoutAddressingStep.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Page\Checkout;
|
||||
|
||||
use Sylius\Behat\Page\SymfonyPage;
|
||||
use Behat\Mink\Exception\ElementNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class CheckoutAddressingStep extends SymfonyPage
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteName()
|
||||
{
|
||||
return 'sylius_checkout_addressing';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $addressingDetails
|
||||
*
|
||||
* @throws ElementNotFoundException
|
||||
*/
|
||||
public function fillAddressingDetails(array $addressingDetails)
|
||||
{
|
||||
$this->fillField('First name', $addressingDetails['firstName']);
|
||||
$this->fillField('Last name', $addressingDetails['lastName']);
|
||||
$this->selectFieldOption('Country', $addressingDetails['country']);
|
||||
$this->fillField('Street', $addressingDetails['street']);
|
||||
$this->fillField('City', $addressingDetails['city']);
|
||||
$this->fillField('Postcode', $addressingDetails['postcode']);
|
||||
$this->fillField('Phone number', $addressingDetails['phoneNumber']);
|
||||
}
|
||||
}
|
||||
28
src/Sylius/Behat/Page/Checkout/CheckoutFinalizeStep.php
Normal file
28
src/Sylius/Behat/Page/Checkout/CheckoutFinalizeStep.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Page\Checkout;
|
||||
|
||||
use Sylius\Behat\Page\SymfonyPage;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class CheckoutFinalizeStep extends SymfonyPage
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteName()
|
||||
{
|
||||
return 'sylius_checkout_finalize';
|
||||
}
|
||||
}
|
||||
28
src/Sylius/Behat/Page/Checkout/CheckoutPaymentStep.php
Normal file
28
src/Sylius/Behat/Page/Checkout/CheckoutPaymentStep.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Page\Checkout;
|
||||
|
||||
use Sylius\Behat\Page\SymfonyPage;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class CheckoutPaymentStep extends SymfonyPage
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteName()
|
||||
{
|
||||
return 'sylius_checkout_payment';
|
||||
}
|
||||
}
|
||||
28
src/Sylius/Behat/Page/Checkout/CheckoutShippingStep.php
Normal file
28
src/Sylius/Behat/Page/Checkout/CheckoutShippingStep.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Page\Checkout;
|
||||
|
||||
use Sylius\Behat\Page\SymfonyPage;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class CheckoutShippingStep extends SymfonyPage
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteName()
|
||||
{
|
||||
return 'sylius_checkout_shipping';
|
||||
}
|
||||
}
|
||||
28
src/Sylius/Behat/Page/Checkout/CheckoutThankYouPage.php
Normal file
28
src/Sylius/Behat/Page/Checkout/CheckoutThankYouPage.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Page\Checkout;
|
||||
|
||||
use Sylius\Behat\Page\SymfonyPage;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class CheckoutThankYouPage extends SymfonyPage
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteName()
|
||||
{
|
||||
return 'sylius_checkout_thank_you';
|
||||
}
|
||||
}
|
||||
48
src/Sylius/Behat/Page/Product/ProductShowPage.php
Normal file
48
src/Sylius/Behat/Page/Product/ProductShowPage.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Page\Product;
|
||||
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Factory;
|
||||
use Sylius\Behat\Page\SymfonyPage;
|
||||
use Sylius\Component\Product\Model\ProductInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class ProductShowPage extends SymfonyPage
|
||||
{
|
||||
/**
|
||||
* @param ProductInterface $product
|
||||
*
|
||||
* @return ProductShowPage
|
||||
*/
|
||||
public function openSpecificProductPage(ProductInterface $product)
|
||||
{
|
||||
$url = $this->router->generate($product);
|
||||
$this->getSession()->visit($url);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addToCart()
|
||||
{
|
||||
$this->pressButton('Add to cart');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getRouteName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
82
src/Sylius/Behat/Page/SymfonyPage.php
Normal file
82
src/Sylius/Behat/Page/SymfonyPage.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Behat\Page;
|
||||
|
||||
use Behat\Mink\Session;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Factory;
|
||||
use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
abstract class SymfonyPage extends Page
|
||||
{
|
||||
/**
|
||||
* @var RouterInterface
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* @param Session $session
|
||||
* @param Factory $factory
|
||||
* @param array $parameters
|
||||
* @param RouterInterface $router
|
||||
*/
|
||||
public function __construct(Session $session, Factory $factory, array $parameters = array(), RouterInterface $router)
|
||||
{
|
||||
parent::__construct($session, $factory, $parameters);
|
||||
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locator
|
||||
*
|
||||
* @throws ElementNotFoundException
|
||||
*/
|
||||
public function pressRadio($locator)
|
||||
{
|
||||
$radio = $this->findField($locator);
|
||||
|
||||
if (null === $radio) {
|
||||
throw new ElementNotFoundException(sprintf('"%s" element is not present on the page', $locator));
|
||||
}
|
||||
|
||||
$this->fillField($radio->getAttribute('name'), $radio->getAttribute('value'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $urlParameters
|
||||
*/
|
||||
public function assertRoute(array $urlParameters = array())
|
||||
{
|
||||
$this->verify($urlParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $urlParameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getUrl(array $urlParameters = array())
|
||||
{
|
||||
if (null === $this->getRouteName()) {
|
||||
throw new \RuntimeException('You need to provide route name, null given');
|
||||
}
|
||||
|
||||
return $this->router->generate($this->getRouteName(), $urlParameters, true);
|
||||
}
|
||||
|
||||
abstract public function getRouteName();
|
||||
}
|
||||
54
src/Sylius/Behat/spec/Context/Setup/ChannelContextSpec.php
Normal file
54
src/Sylius/Behat/spec/Context/Setup/ChannelContextSpec.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Behat\Context\Setup;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Core\Test\Services\DefaultStoreDataInterface;
|
||||
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class ChannelContextSpec extends ObjectBehavior
|
||||
{
|
||||
function let(
|
||||
DefaultStoreDataInterface $defaultFranceChannelFactory,
|
||||
SharedStorageInterface $sharedStorage
|
||||
) {
|
||||
$this->beConstructedWith($defaultFranceChannelFactory, $sharedStorage);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Behat\Context\Setup\ChannelContext');
|
||||
}
|
||||
|
||||
function it_is_context()
|
||||
{
|
||||
$this->shouldImplement('Behat\Behat\Context\Context');
|
||||
}
|
||||
|
||||
function it_sets_default_france_channel_in_to_shared_storage(
|
||||
$defaultFranceChannelFactory,
|
||||
$sharedStorage,
|
||||
ChannelInterface $channel,
|
||||
ZoneInterface $zone
|
||||
) {
|
||||
$defaultData = array('channel' => $channel, 'zone' => $zone);
|
||||
$defaultFranceChannelFactory->create()->willReturn($defaultData);
|
||||
$sharedStorage->setClipboard($defaultData)->shouldBeCalled();
|
||||
|
||||
$this->thatStoreIsOperatingOnTheFranceChannel();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Bundle\ChannelBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Sylius\Component\Resource\Factory\Factory;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class RegisterChannelFactoryPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('sylius.factory.channel')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$baseChannelFactoryDefinition = new Definition(
|
||||
Factory::class,
|
||||
[
|
||||
new Parameter('sylius.model.channel.class'),
|
||||
]
|
||||
);
|
||||
|
||||
$channelFactoryDefinition = new Definition(
|
||||
$container->getParameter('sylius.factory.channel.class'),
|
||||
[
|
||||
$baseChannelFactoryDefinition,
|
||||
]
|
||||
);
|
||||
|
||||
$container->setDefinition('sylius.factory.channel', $channelFactoryDefinition);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ use Sylius\Bundle\ChannelBundle\Form\Type\ChannelType;
|
|||
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceChoiceType;
|
||||
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
|
||||
use Sylius\Component\Channel\Factory\ChannelFactory;
|
||||
use Sylius\Component\Channel\Model\Channel;
|
||||
use Sylius\Component\Channel\Model\ChannelInterface;
|
||||
use Sylius\Component\Resource\Factory\Factory;
|
||||
|
|
@ -72,7 +73,7 @@ class Configuration implements ConfigurationInterface
|
|||
->scalarNode('interface')->defaultValue(ChannelInterface::class)->cannotBeEmpty()->end()
|
||||
->scalarNode('controller')->defaultValue(ResourceController::class)->cannotBeEmpty()->end()
|
||||
->scalarNode('repository')->cannotBeEmpty()->end()
|
||||
->scalarNode('factory')->defaultValue(Factory::class)->end()
|
||||
->scalarNode('factory')->defaultValue(ChannelFactory::class)->end()
|
||||
->arrayNode('form')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@
|
|||
|
||||
namespace Sylius\Bundle\ChannelBundle;
|
||||
|
||||
use Sylius\Bundle\ChannelBundle\DependencyInjection\Compiler\RegisterChannelFactoryPass;
|
||||
use Sylius\Bundle\ResourceBundle\AbstractResourceBundle;
|
||||
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
|
||||
use Sylius\Component\Channel\Model\ChannelInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Channels bundle.
|
||||
|
|
@ -32,6 +34,16 @@ class SyliusChannelBundle extends AbstractResourceBundle
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
parent::build($container);
|
||||
|
||||
$container->addCompilerPass(new RegisterChannelFactoryPass());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Bundle\ChannelBundle\DependencyInjection\Compiler;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Channel\Factory\ChannelFactory;
|
||||
use Sylius\Component\Resource\Factory\Factory;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class RegisterChannelFactoryPassSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Bundle\ChannelBundle\DependencyInjection\Compiler\RegisterChannelFactoryPass');
|
||||
}
|
||||
|
||||
function it_implements_compiler_pass_interface()
|
||||
{
|
||||
$this->shouldImplement(CompilerPassInterface::class);
|
||||
}
|
||||
|
||||
function it_creates_default_definition_of_channel_factory(
|
||||
ContainerBuilder $container
|
||||
) {
|
||||
$container->hasDefinition('sylius.factory.channel')->willReturn(true);
|
||||
|
||||
$baseChannelFactoryDefinition = new Definition(
|
||||
Factory::class,
|
||||
[
|
||||
new Parameter('sylius.model.channel.class'),
|
||||
]
|
||||
);
|
||||
|
||||
$container->getParameter('sylius.factory.channel.class')->willReturn(ChannelFactory::class);
|
||||
|
||||
$channelFactoryDefinition = new Definition(
|
||||
ChannelFactory::class,
|
||||
[
|
||||
$baseChannelFactoryDefinition,
|
||||
]
|
||||
);
|
||||
|
||||
$container->setDefinition('sylius.factory.channel', $channelFactoryDefinition)->shouldBeCalled();
|
||||
|
||||
$this->process($container);
|
||||
}
|
||||
|
||||
function it_does_not_create_default_definition_of_channel_factory_if_channel_factory_is_not_set(
|
||||
ContainerBuilder $container
|
||||
) {
|
||||
$container->hasDefinition('sylius.factory.channel')->willReturn(false);
|
||||
|
||||
$baseChannelFactoryDefinition = new Definition(
|
||||
Factory::class,
|
||||
[
|
||||
new Parameter('sylius.model.channel.class'),
|
||||
]
|
||||
);
|
||||
|
||||
$container->getParameter('sylius.factory.channel.class')->shouldNotBeCalled();
|
||||
|
||||
$channelFactoryDefinition = new Definition(
|
||||
ChannelFactory::class,
|
||||
[
|
||||
$baseChannelFactoryDefinition,
|
||||
]
|
||||
);
|
||||
|
||||
$container->setDefinition('sylius.factory.channel', $channelFactoryDefinition)->shouldNotBeCalled();
|
||||
|
||||
$this->process($container);
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ class CheckoutProcessScenario implements ProcessScenarioInterface
|
|||
->add('purchase', 'sylius_checkout_purchase')
|
||||
->setDisplayRoute('sylius_checkout_display')
|
||||
->setForwardRoute('sylius_checkout_forward')
|
||||
->setRedirect('sylius_homepage')
|
||||
->setRedirect('sylius_checkout_thank_you')
|
||||
->validate(function () {
|
||||
return !$this->getCurrentCart()->isEmpty();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ class FinalizeStep extends CheckoutStep
|
|||
*/
|
||||
protected function completeOrder(OrderInterface $order)
|
||||
{
|
||||
$this->get('session')->set('sylius_order_id', $order->getId());
|
||||
$this->dispatchCheckoutEvent(SyliusOrderEvents::PRE_CREATE, $order);
|
||||
$this->dispatchCheckoutEvent(SyliusCheckoutEvents::FINALIZE_PRE_COMPLETE, $order);
|
||||
|
||||
|
|
|
|||
|
|
@ -193,6 +193,19 @@ class CheckoutController extends FOSRestController
|
|||
}
|
||||
|
||||
/**
|
||||
* @return Response
|
||||
*/
|
||||
public function thankYouAction()
|
||||
{
|
||||
$id = $this->get('session')->get('sylius_order_id');
|
||||
$order = $this->findOrderOr404($id);
|
||||
|
||||
return $this->render('SyliusWebBundle:Frontend/Checkout/Step:thankYou.html.twig', array('order' => $order));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object manager.
|
||||
*
|
||||
* @return ObjectManager
|
||||
*/
|
||||
protected function getManager()
|
||||
|
|
|
|||
|
|
@ -79,6 +79,11 @@ class SyliusCoreExtension extends AbstractResourceExtension implements PrependEx
|
|||
'email.xml',
|
||||
);
|
||||
|
||||
$env = $container->getParameter('kernel.environment');
|
||||
if ('test' === $env || 'test_cached' === $env) {
|
||||
$configFiles[] = 'test_services.xml';
|
||||
}
|
||||
|
||||
foreach ($configFiles as $configFile) {
|
||||
$loader->load($configFile);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
This file is part of the Sylius package.
|
||||
|
||||
(c) Paweł Jędrzejewski
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
|
||||
-->
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||||
http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
<parameters>
|
||||
<parameter key="sylius.behat.shared_storage.class">Sylius\Component\Core\Test\Services\SharedStorage</parameter>
|
||||
<parameter key="sylius.behat.security.class">Sylius\Bundle\CoreBundle\Test\Services\SecurityService</parameter>
|
||||
|
||||
<parameter key="sylius.behat.default_france_channel_factory.class">Sylius\Component\Core\Test\Services\DefaultFranceChannelFactory</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<service id="sylius.behat.shared_storage" class="%sylius.behat.shared_storage.class%" />
|
||||
<service id="sylius.behat.security" class="%sylius.behat.security.class%">
|
||||
<argument type="service" id="sylius.repository.user" />
|
||||
<argument type="service" id="session" />
|
||||
</service>
|
||||
|
||||
<!--Default Store Data-->
|
||||
<service id="sylius.behat.default_france_channel_factory" class="%sylius.behat.default_france_channel_factory.class%">
|
||||
<argument type="service" id="sylius.repository.channel" />
|
||||
<argument type="service" id="sylius.repository.country" />
|
||||
<argument type="service" id="sylius.repository.zone_member" />
|
||||
<argument type="service" id="sylius.repository.zone" />
|
||||
<argument type="service" id="sylius.factory.channel" />
|
||||
<argument type="service" id="sylius.factory.country" />
|
||||
<argument type="service" id="sylius.factory.zone_member" />
|
||||
<argument type="service" id="sylius.factory.zone" />
|
||||
</service>
|
||||
</services>
|
||||
|
||||
</container>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Bundle\CoreBundle\Test\Services;
|
||||
|
||||
use Behat\Mink\Session;
|
||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class SecurityService implements SecurityServiceInterface
|
||||
{
|
||||
/**
|
||||
* @var UserRepositoryInterface
|
||||
*/
|
||||
private $userRepository;
|
||||
|
||||
/**
|
||||
* @var SessionInterface
|
||||
*/
|
||||
private $session;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(
|
||||
UserRepositoryInterface $userRepository,
|
||||
SessionInterface $session
|
||||
) {
|
||||
$this->userRepository = $userRepository;
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function logIn($email, $providerKey, Session $minkSession)
|
||||
{
|
||||
$user = $this->userRepository->findOneBy(array('username' => $email));
|
||||
|
||||
if (null === $user) {
|
||||
throw new \InvalidArgumentException(sprintf('There is no user with email %s', $email));
|
||||
}
|
||||
|
||||
$token = new UsernamePasswordToken($user, $user->getPassword(), $providerKey, $user->getRoles());
|
||||
|
||||
$this->session->set('_security_user', serialize($token));
|
||||
$this->session->save();
|
||||
|
||||
$minkSession->setCookie($this->session->getName(), $this->session->getId());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Bundle\CoreBundle\Test\Services;
|
||||
|
||||
use Behat\Mink\Session;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
interface SecurityServiceInterface
|
||||
{
|
||||
/**
|
||||
* @param string $email
|
||||
* @param string $providerKey
|
||||
* @param Session $minkSession
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function logIn($email, $providerKey, Session $minkSession);
|
||||
}
|
||||
|
|
@ -40,19 +40,21 @@ class CheckoutProcessScenarioSpec extends ObjectBehavior
|
|||
$this->shouldImplement(ProcessScenarioInterface::class);
|
||||
}
|
||||
|
||||
function it_builds_checkout_process_with_proper_steps(ProcessBuilderInterface $builder)
|
||||
function it_builds_checkout_process_with_proper_steps(ProcessBuilderInterface $builder, $cart)
|
||||
{
|
||||
$builder->add('security', 'sylius_checkout_security')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->add('addressing', 'sylius_checkout_addressing')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->add('shipping', 'sylius_checkout_shipping')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->add('payment', 'sylius_checkout_payment')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->add('finalize', 'sylius_checkout_finalize')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->add("purchase", "sylius_checkout_purchase")->willReturn($builder)->shouldBeCalled();
|
||||
$builder->add('purchase', 'sylius_checkout_purchase')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->setRedirect('sylius_checkout_thank_you')->willReturn($builder)->shouldBeCalled();
|
||||
|
||||
$cart->getId()->willReturn(1);
|
||||
|
||||
$builder->setDisplayRoute('sylius_checkout_display')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->setForwardRoute('sylius_checkout_forward')->willReturn($builder)->shouldBeCalled();
|
||||
|
||||
$builder->setRedirect('sylius_homepage')->willReturn($builder)->shouldBeCalled();
|
||||
$builder->validate(Argument::any())->willReturn($builder)->shouldBeCalled();
|
||||
|
||||
$this->build($builder);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Bundle\CoreBundle\Test\Services;
|
||||
|
||||
use Behat\Mink\Session;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use Sylius\Component\User\Model\UserInterface;
|
||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class SecurityServiceSpec extends ObjectBehavior
|
||||
{
|
||||
function let(
|
||||
UserRepositoryInterface $userRepository,
|
||||
SessionInterface $session
|
||||
) {
|
||||
$this->beConstructedWith($userRepository, $session);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Bundle\CoreBundle\Test\Services\SecurityService');
|
||||
}
|
||||
|
||||
function it_implements_security_service_interface()
|
||||
{
|
||||
$this->shouldImplement('Sylius\Bundle\CoreBundle\Test\Services\SecurityServiceInterface');
|
||||
}
|
||||
|
||||
function it_logs_user_in(
|
||||
$userRepository,
|
||||
$session,
|
||||
UserInterface $user,
|
||||
Session $minkSession
|
||||
) {
|
||||
$userRoles = ['ROLE_USER'];
|
||||
$userRepository->findOneBy(array('username' => 'sylius@example.com'))->willReturn($user);
|
||||
$user->getRoles()->willReturn($userRoles);
|
||||
$user->getPassword()->willReturn('xyz');
|
||||
$user->serialize()->willReturn('serialized_user');
|
||||
|
||||
$session->set('_security_user', Argument::any())->shouldBeCalled();
|
||||
$session->save()->shouldBeCalled();
|
||||
$session->getName()->willReturn('MOCKEDSID');
|
||||
$session->getId()->willReturn('xyzc123');
|
||||
|
||||
$minkSession->setCookie('MOCKEDSID', 'xyzc123')->shouldBeCalled();
|
||||
|
||||
$this->logIn('sylius@example.com', 'default', $minkSession);
|
||||
}
|
||||
|
||||
function it_does_not_log_user_in_if_user_was_not_found(
|
||||
$userRepository,
|
||||
$session,
|
||||
UserInterface $user,
|
||||
Session $minkSession
|
||||
) {
|
||||
$userRoles = ['ROLE_USER'];
|
||||
$userRepository->findOneBy(array('username' => 'sylius@example.com'))->willReturn(null);
|
||||
$user->getRoles()->willReturn($userRoles);
|
||||
$user->getPassword()->willReturn('xyz');
|
||||
$user->serialize()->willReturn('serialized_user');
|
||||
|
||||
$session->set('_security_user', Argument::any())->shouldNotBeCalled();
|
||||
$session->save()->shouldNotBeCalled();
|
||||
$session->getName()->willReturn('MOCKEDSID');
|
||||
$session->getId()->willReturn('xyzc123');
|
||||
|
||||
$minkSession->setCookie('MOCKEDSID', 'xyzc123')->shouldNotBeCalled();
|
||||
$this->shouldThrow(new \InvalidArgumentException(sprintf('There is no user with email sylius@example.com')))->during('logIn', array('sylius@example.com', 'default', $minkSession));
|
||||
}
|
||||
}
|
||||
|
|
@ -613,7 +613,7 @@ class WebContext extends BaseWebContext implements SnippetAcceptingContext
|
|||
$this->iSelectTheRadioButton('Credit Card');
|
||||
$this->pressButton('Continue');
|
||||
$this->iClick('Place order');
|
||||
$this->assertSession()->pageTextContains('Thank you for your order!');
|
||||
$this->assertSession()->pageTextContains('Thank you');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ sylius_checkout_start:
|
|||
path: /
|
||||
defaults: { _controller: sylius.controller.process:startAction, scenarioAlias: 'sylius_checkout' }
|
||||
|
||||
sylius_checkout_thank_you:
|
||||
path: /thank-you
|
||||
methods: [GET]
|
||||
defaults: { _controller: sylius.controller.checkout:thankYouAction }
|
||||
|
||||
sylius_checkout_display:
|
||||
path: /{stepName}
|
||||
defaults: { _controller: sylius.controller.process:displayAction, scenarioAlias: 'sylius_checkout' }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
{% extends 'SyliusWebBundle:Frontend:layout.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<h1 id="thanks">Thank you {{ order.customer.fullName }}</h1>
|
||||
{% endblock %}
|
||||
49
src/Sylius/Component/Channel/Factory/ChannelFactory.php
Normal file
49
src/Sylius/Component/Channel/Factory/ChannelFactory.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Channel\Factory;
|
||||
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class ChannelFactory implements ChannelFactoryInterface
|
||||
{
|
||||
private $defaultFactory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(FactoryInterface $defaultFactory)
|
||||
{
|
||||
$this->defaultFactory = $defaultFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createNew()
|
||||
{
|
||||
return $this->defaultFactory->createNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createNamed($name)
|
||||
{
|
||||
$channel = $this->defaultFactory->createNew();
|
||||
$channel->setName($name);
|
||||
|
||||
return $channel;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Channel\Factory;
|
||||
|
||||
use Sylius\Component\Channel\Model\ChannelInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
interface ChannelFactoryInterface extends FactoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return ChannelInterface
|
||||
*/
|
||||
public function createNamed($name);
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Component\Channel\Factory;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Channel\Model\ChannelInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class ChannelFactorySpec extends ObjectBehavior
|
||||
{
|
||||
function let(
|
||||
FactoryInterface $defaultFactory
|
||||
) {
|
||||
$this->beConstructedWith($defaultFactory);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Component\Channel\Factory\ChannelFactory');
|
||||
}
|
||||
|
||||
function it_implements_channel_factory_interface()
|
||||
{
|
||||
$this->shouldImplement('Sylius\Component\Channel\Factory\ChannelFactoryInterface');
|
||||
}
|
||||
|
||||
function it_creates_channel_with_name($defaultFactory, ChannelInterface $channel)
|
||||
{
|
||||
$defaultFactory->createNew()->willReturn($channel);
|
||||
|
||||
$channel->setName('United States Webstore')->shouldBeCalled();
|
||||
|
||||
$this->createNamed('United States Webstore')->shouldReturn($channel);
|
||||
}
|
||||
|
||||
function it_creates_empty_channel($defaultFactory, ChannelInterface $channel)
|
||||
{
|
||||
$defaultFactory->createNew()->willReturn($channel);
|
||||
|
||||
$this->createNew()->shouldReturn($channel);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Core\Test\Services;
|
||||
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneMemberInterface;
|
||||
use Sylius\Component\Channel\Factory\ChannelFactoryInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class DefaultFranceChannelFactory implements DefaultStoreDataInterface
|
||||
{
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $channelRepository;
|
||||
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $countryRepository;
|
||||
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $zoneMemberRepository;
|
||||
|
||||
/**
|
||||
* @var RepositoryInterface
|
||||
*/
|
||||
private $zoneRepository;
|
||||
|
||||
/**
|
||||
* @var ChannelFactoryInterface
|
||||
*/
|
||||
private $channelFactory;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $countryFactory;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $zoneMemberFactory;
|
||||
|
||||
/**
|
||||
* @var FactoryInterface
|
||||
*/
|
||||
private $zoneFactory;
|
||||
|
||||
/**
|
||||
* @param RepositoryInterface $channelRepository
|
||||
* @param RepositoryInterface $countryRepository
|
||||
* @param RepositoryInterface $zoneMemberRepository
|
||||
* @param RepositoryInterface $zoneRepository
|
||||
* @param FactoryInterface $channelFactory
|
||||
* @param FactoryInterface $countryFactory
|
||||
* @param FactoryInterface $zoneMemberFactory
|
||||
* @param FactoryInterface $zoneFactory
|
||||
*/
|
||||
public function __construct(
|
||||
RepositoryInterface $channelRepository,
|
||||
RepositoryInterface $countryRepository,
|
||||
RepositoryInterface $zoneMemberRepository,
|
||||
RepositoryInterface $zoneRepository,
|
||||
FactoryInterface $channelFactory,
|
||||
FactoryInterface $countryFactory,
|
||||
FactoryInterface $zoneMemberFactory,
|
||||
FactoryInterface $zoneFactory
|
||||
) {
|
||||
$this->channelRepository = $channelRepository;
|
||||
$this->countryRepository = $countryRepository;
|
||||
$this->zoneMemberRepository = $zoneMemberRepository;
|
||||
$this->zoneRepository = $zoneRepository;
|
||||
$this->channelFactory = $channelFactory;
|
||||
$this->countryFactory = $countryFactory;
|
||||
$this->zoneMemberFactory = $zoneMemberFactory;
|
||||
$this->zoneFactory = $zoneFactory;
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$defaultData['channel'] = $this->createChannel();
|
||||
$defaultData['country'] = $this->createCountry();
|
||||
$defaultData['zone_member'] = $this->createZoneMember();
|
||||
$defaultData['zone'] = $this->createZone($defaultData['zone_member']);
|
||||
|
||||
$this->channelRepository->add($defaultData['channel']);
|
||||
$this->countryRepository->add($defaultData['country']);
|
||||
$this->zoneRepository->add($defaultData['zone']);
|
||||
$this->zoneMemberRepository->add($defaultData['zone_member']);
|
||||
|
||||
return $defaultData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ChannelInterface
|
||||
*/
|
||||
private function createChannel()
|
||||
{
|
||||
$channel = $this->channelFactory->createNamed('France');
|
||||
$channel->setCode('WEB-FR');
|
||||
|
||||
return $channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CountryInterface
|
||||
*/
|
||||
private function createCountry()
|
||||
{
|
||||
$country = $this->countryFactory->createNew();
|
||||
$country->setCode('FR');
|
||||
|
||||
return $country;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ZoneMemberInterface
|
||||
*/
|
||||
private function createZoneMember()
|
||||
{
|
||||
$zoneMember = $this->zoneMemberFactory->createNew();
|
||||
$zoneMember->setCode('FR');
|
||||
|
||||
return $zoneMember;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZoneMemberInterface $zoneMember
|
||||
*
|
||||
* @return ZoneInterface
|
||||
*/
|
||||
private function createZone(ZoneMemberInterface $zoneMember)
|
||||
{
|
||||
$zone = $this->zoneFactory->createNew();
|
||||
$zone->setCode('FR');
|
||||
$zone->setName('France');
|
||||
$zone->setType(ZoneInterface::TYPE_COUNTRY);
|
||||
$zone->addMember($zoneMember);
|
||||
|
||||
return $zone;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Core\Test\Services;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
interface DefaultStoreDataInterface
|
||||
{
|
||||
public function create();
|
||||
}
|
||||
75
src/Sylius/Component/Core/Test/Services/SharedStorage.php
Normal file
75
src/Sylius/Component/Core/Test/Services/SharedStorage.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Core\Test\Services;
|
||||
|
||||
use Sylius\Component\Resource\Model\ResourceInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class SharedStorage implements SharedStorageInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $clipboard = array();
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $latestKey = null;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setCurrentResource($key, ResourceInterface $resource, $override = false)
|
||||
{
|
||||
if (isset($this->clipboard[$key]) && !$override) {
|
||||
throw new \RuntimeException('This key is already used, if you want override set override flag');
|
||||
}
|
||||
|
||||
$this->clipboard[$key] = $resource;
|
||||
$this->latestKey = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCurrentResource($key)
|
||||
{
|
||||
if (!isset($this->clipboard[$key])) {
|
||||
throw new \InvalidArgumentException(sprintf('There is no current resource for "%s"!', $key));
|
||||
}
|
||||
|
||||
return $this->clipboard[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLatestResource()
|
||||
{
|
||||
return $this->clipboard[$this->latestKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setClipboard(array $clipboard, $override = false)
|
||||
{
|
||||
if (!empty($this->clipboard) && !$override) {
|
||||
throw new \RuntimeException('Clipboard is not empty, if you want override set override flag');
|
||||
}
|
||||
|
||||
$this->clipboard = $clipboard;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Component\Core\Test\Services;
|
||||
|
||||
use Sylius\Component\Resource\Model\ResourceInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
interface SharedStorageInterface
|
||||
{
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return ResourceInterface
|
||||
*/
|
||||
public function getCurrentResource($key);
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param ResourceInterface $resource
|
||||
* @param bool $override
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function setCurrentResource($key, ResourceInterface $resource, $override = false);
|
||||
|
||||
/**
|
||||
* @param array $clipboard
|
||||
* @param bool $override
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function setClipboard(array $clipboard, $override = false);
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Component\Core\Test\Services;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneMemberInterface;
|
||||
use Sylius\Component\Channel\Factory\ChannelFactoryInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class DefaultFranceChannelFactorySpec extends ObjectBehavior
|
||||
{
|
||||
function let(
|
||||
RepositoryInterface $channelRepository,
|
||||
RepositoryInterface $countryRepository,
|
||||
RepositoryInterface $zoneMemberRepository,
|
||||
RepositoryInterface $zoneRepository,
|
||||
ChannelFactoryInterface $channelFactory,
|
||||
FactoryInterface $countryFactory,
|
||||
FactoryInterface $zoneMemberFactory,
|
||||
FactoryInterface $zoneFactory
|
||||
) {
|
||||
$this->beConstructedWith(
|
||||
$channelRepository,
|
||||
$countryRepository,
|
||||
$zoneMemberRepository,
|
||||
$zoneRepository,
|
||||
$channelFactory,
|
||||
$countryFactory,
|
||||
$zoneMemberFactory,
|
||||
$zoneFactory
|
||||
);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Component\Core\Test\Services\DefaultFranceChannelFactory');
|
||||
}
|
||||
|
||||
function it_is_default_store_data()
|
||||
{
|
||||
$this->shouldImplement('Sylius\Component\Core\Test\Services\DefaultStoreDataInterface');
|
||||
}
|
||||
|
||||
function it_creates_france_country_and_zone(
|
||||
$channelRepository,
|
||||
$countryRepository,
|
||||
$zoneMemberRepository,
|
||||
$zoneRepository,
|
||||
$channelFactory,
|
||||
$countryFactory,
|
||||
$zoneMemberFactory,
|
||||
$zoneFactory,
|
||||
CountryInterface $country,
|
||||
ZoneMemberInterface $zoneMember,
|
||||
ZoneInterface $zone,
|
||||
ChannelInterface $channel
|
||||
) {
|
||||
$channel->getName()->willReturn('France');
|
||||
$channelFactory->createNamed('France')->willReturn($channel);
|
||||
$countryFactory->createNew()->willReturn($country);
|
||||
$zoneMemberFactory->createNew()->willReturn($zoneMember);
|
||||
$zoneFactory->createNew()->willReturn($zone);
|
||||
|
||||
$channel->setCode('WEB-FR')->shouldBeCalled();
|
||||
$country->setCode('FR')->shouldBeCalled();
|
||||
$zoneMember->setCode('FR')->shouldBeCalled();
|
||||
$zone->setCode('FR')->shouldBeCalled();
|
||||
$zone->setName('France')->shouldBeCalled();
|
||||
$zone->setType(ZoneInterface::TYPE_COUNTRY)->shouldBeCalled();
|
||||
$zone->addMember($zoneMember)->shouldBeCalled();
|
||||
|
||||
$channelRepository->add($channel)->shouldBeCalled();
|
||||
$countryRepository->add($country)->shouldBeCalled();
|
||||
$zoneRepository->add($zone)->shouldBeCalled();
|
||||
$zoneMemberRepository->add($zoneMember)->shouldBeCalled();
|
||||
|
||||
$this->create();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace spec\Sylius\Component\Core\Test\Services;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
class SharedStorageSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Component\Core\Test\Services\SharedStorage');
|
||||
}
|
||||
|
||||
function it_implements_shared_storage_interface()
|
||||
{
|
||||
$this->shouldImplement('Sylius\Component\Core\Test\Services\SharedStorageInterface');
|
||||
}
|
||||
|
||||
function it_has_resources_in_clipboard(ChannelInterface $channel, ProductInterface $product)
|
||||
{
|
||||
$this->setCurrentResource('channel1', $channel);
|
||||
$this->getCurrentResource('channel1')->shouldReturn($channel);
|
||||
|
||||
$this->setCurrentResource('product1', $product);
|
||||
$this->getCurrentResource('product1')->shouldReturn($product);
|
||||
}
|
||||
|
||||
function it_returns_latest_added_resource(ChannelInterface $channel, ProductInterface $product)
|
||||
{
|
||||
$this->setCurrentResource('channel1', $channel);
|
||||
$this->setCurrentResource('product1', $product);
|
||||
$this->getLatestResource()->shouldReturn($product);
|
||||
}
|
||||
|
||||
function it_prevents_setting_resource_at_used_key(ChannelInterface $channel, ChannelInterface $channel1)
|
||||
{
|
||||
$this->setCurrentResource('channel', $channel);
|
||||
|
||||
$this->shouldThrow(new \RuntimeException('This key is already used, if you want override set override flag'))->during('setCurrentResource', array('channel', $channel1));
|
||||
}
|
||||
|
||||
function it_overrides_existing_resource_key(ChannelInterface $channel, ChannelInterface $channel1)
|
||||
{
|
||||
$this->setCurrentResource('channel', $channel);
|
||||
$this->setCurrentResource('channel', $channel1, true);
|
||||
|
||||
$this->getCurrentResource('channel')->shouldReturn($channel1);
|
||||
}
|
||||
|
||||
function it_prevents_setting_clipboard_if_it_is_not_empty(ChannelInterface $channel)
|
||||
{
|
||||
$this->setCurrentResource('channel', $channel);
|
||||
|
||||
$this->shouldThrow(new \RuntimeException('Clipboard is not empty, if you want override set override flag'))->during('setClipboard', array(array()));
|
||||
}
|
||||
|
||||
function it_overrides_clipboard(ChannelInterface $channel)
|
||||
{
|
||||
$this->setCurrentResource('channel', $channel);
|
||||
|
||||
$this->setClipboard(array(), true);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue