mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
Merge branch '2.0' into bootstrap-shop
* 2.0: (34 commits) [Admin] Change the name of the service to provide the logged in admin user [Admin] Extract logged in admin user providing [Admin] Fix 404 page when there is no route for url [Admin] Remove icon from existing avatar Fix missing template Fixes after CR [Admin] Add translation [Admin] Add twig hook, refactor behats [Admin] Add autocomplete and restrict list [Admin] Remove unused edit currency scenario [Admin] Enable currency behats [Docs] Update taxon-menu page to reflect current fixtures configuration [Admin] Fix path to form template in Twig Hooks for Tax Category [Admin] Remove unneeded deprecation [Admin][TaxCategory] Add filtering tests [Admin][TaxCategory] Enable behat tests [Admin] Managing tax category [Admin] Use the same generic form template for create and update actions [Admin] Add customer group live component that uses generic form template [Behat] Improve CustomerGroupsContext codestyle ...
This commit is contained in:
commit
ec1b8bdd52
123 changed files with 1545 additions and 711 deletions
|
|
@ -24,7 +24,7 @@ To render a simple menu of categories in any twig template use:
|
|||
|
||||
.. code-block:: twig
|
||||
|
||||
{{ render(url('sylius_shop_partial_taxon_index_by_code', {'code': 'category', 'template': '@SyliusShop/Taxon/_horizontalMenu.html.twig'})) }}
|
||||
{{ render(url('sylius_shop_partial_taxon_index_by_code', {'code': 'MENU_CATEGORY', 'template': '@SyliusShop/Taxon/_horizontalMenu.html.twig'})) }}
|
||||
|
||||
You can of course customize the template or enclose the menu into html to make it look better.
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Feature: Adding a new currency
|
|||
Background:
|
||||
Given I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui @mink:chromedriver
|
||||
Scenario: Adding a new currency
|
||||
When I want to add a new currency
|
||||
And I choose "Euro"
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ Feature: Browsing currencies
|
|||
Given the store has currency "Euro", "British Pound"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Browsing currencies in store
|
||||
When I want to browse currencies of the store
|
||||
Then I should see 2 currencies in the list
|
||||
And I should see the currency "British Pound" in the list
|
||||
Then I should see 2 currencies on the list
|
||||
And I should see the currency "British Pound" on the list
|
||||
|
|
|
|||
|
|
@ -8,10 +8,15 @@ Feature: Currency unique code validation
|
|||
Given the store has currency "Euro"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add currency with taken code
|
||||
When I want to add a new currency
|
||||
And I choose "Euro"
|
||||
And I try to add it
|
||||
Then I should be notified that currency code must be unique
|
||||
And there should still be only one currency with code "EUR"
|
||||
|
||||
@no-api @ui @mink:chromedriver
|
||||
Scenario: Trying to add new currency with used code
|
||||
When I want to add a new currency
|
||||
Then I should not be able to choose "Euro"
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
@managing_currencies
|
||||
Feature: Editing a currency
|
||||
In order to change currency configuration
|
||||
As an Administrator
|
||||
I want to be able to edit a currency
|
||||
|
||||
Background:
|
||||
Given I am logged in as an administrator
|
||||
|
||||
@todo @ui @no-api
|
||||
Scenario: Seeing disabled code field while editing currency
|
||||
Given the store has currency "Euro"
|
||||
When I want to edit this currency
|
||||
Then the code field should be disabled
|
||||
|
|
@ -8,18 +8,18 @@ Feature: Adding a new payment method
|
|||
Given the store operates on a single channel in "United States"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new payment method
|
||||
When I want to create a new Offline payment method
|
||||
When I want to create a new offline payment method
|
||||
And I name it "Offline" in "English (United States)"
|
||||
And I specify its code as "OFF"
|
||||
And I add it
|
||||
Then I should be notified that it has been successfully created
|
||||
And the payment method "Offline" should appear in the registry
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new payment method with description
|
||||
When I want to create a new Offline payment method
|
||||
When I want to create a new offline payment method
|
||||
And I name it "Offline" in "English (United States)"
|
||||
And I specify its code as "OFF"
|
||||
And I describe it as "Payment method Offline" in "English (United States)"
|
||||
|
|
@ -27,9 +27,9 @@ Feature: Adding a new payment method
|
|||
Then I should be notified that it has been successfully created
|
||||
And the payment method "Offline" should appear in the registry
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new payment method with instructions
|
||||
When I want to create a new Offline payment method
|
||||
When I want to create a new offline payment method
|
||||
And I name it "Offline" in "English (United States)"
|
||||
And I specify its code as "OFF"
|
||||
And I set its instruction as "Bank account: 0000 1111 2222 3333" in "English (United States)"
|
||||
|
|
@ -38,9 +38,9 @@ Feature: Adding a new payment method
|
|||
And the payment method "Offline" should appear in the registry
|
||||
And the payment method "Offline" should have instructions "Bank account: 0000 1111 2222 3333" in "English (United States)"
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new payment method for channel
|
||||
When I want to create a new Offline payment method
|
||||
When I want to create a new offline payment method
|
||||
And I name it "Offline" in "English (United States)"
|
||||
And I specify its code as "OFF"
|
||||
And make it available in channel "United States"
|
||||
|
|
@ -49,7 +49,7 @@ Feature: Adding a new payment method
|
|||
And the payment method "Offline" should appear in the registry
|
||||
And the payment method "Offline" should be available in channel "United States"
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new paypal payment method
|
||||
When I want to create a new payment method with "Paypal Express Checkout" gateway factory
|
||||
And I name it "Paypal Express Checkout" in "English (United States)"
|
||||
|
|
@ -59,7 +59,7 @@ Feature: Adding a new payment method
|
|||
Then I should be notified that it has been successfully created
|
||||
And the payment method "Paypal Express Checkout" should appear in the registry
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new stripe payment method
|
||||
When I want to create a new payment method with "Stripe Checkout" gateway factory
|
||||
And I name it "Stripe Checkout" in "English (United States)"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Feature: Being redirected to previous filtered page
|
|||
And this payment method has been disabled
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @no-api
|
||||
@no-api @ui
|
||||
Scenario: Being redirected to previous filtered page after cancelling creating a new payment method
|
||||
When I browse payment methods
|
||||
And I choose enabled filter
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Feature: Browsing payment methods
|
|||
Background:
|
||||
Given I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Browsing defined payment methods
|
||||
Given the store has a payment method "Offline" with a code "OFF"
|
||||
And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and "Paypal Express Checkout" gateway
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Feature: Deleting multiple payment methods
|
|||
And the store has also a payment method "PayPal Express Checkout" with a code "paypal" and "Paypal Express Checkout" gateway
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @mink:chromedriver @no-api
|
||||
@no-api @ui @mink:chromedriver
|
||||
Scenario: Deleting multiple payment methods at once
|
||||
When I browse payment methods
|
||||
And I check the "Offline" payment method
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Feature: Deleting payment methods
|
|||
Given the store has a payment method "Offline" with a code "Offline"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Deleted payment method should disappear from the registry
|
||||
When I delete the "Offline" payment method
|
||||
Then I should be notified that it has been successfully deleted
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Feature: Editing payment methods
|
|||
And the store has a payment method "Offline" with a code "Offline"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Renaming the payment method
|
||||
When I want to modify the "Offline" payment method
|
||||
And I rename it to "Cash on delivery" in "English (United States)"
|
||||
|
|
@ -17,7 +17,7 @@ Feature: Editing payment methods
|
|||
Then I should be notified that it has been successfully edited
|
||||
And this payment method "Name" should be "Cash on delivery"
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Disabling payment method
|
||||
When I want to modify the "Offline" payment method
|
||||
And I disable it
|
||||
|
|
@ -25,7 +25,7 @@ Feature: Editing payment methods
|
|||
Then I should be notified that it has been successfully edited
|
||||
And this payment method should be disabled
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Enabling payment method
|
||||
Given the payment method "Offline" is disabled
|
||||
When I want to modify the "Offline" payment method
|
||||
|
|
@ -34,12 +34,12 @@ Feature: Editing payment methods
|
|||
Then I should be notified that it has been successfully edited
|
||||
And this payment method should be enabled
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Being unable to edit code of an existing payment method
|
||||
When I want to modify the "Offline" payment method
|
||||
Then I should not be able to edit its code
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Being unable to edit gateway factory field of existing payment method
|
||||
When I want to modify the "Offline" payment method
|
||||
Then the factory name field should be disabled
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Feature: Editing payment method configured with a PayPal Express Checkout gatewa
|
|||
And the store has a payment method "PayPal Express Checkout" with a code "paypal" and "Paypal Express Checkout" gateway
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @no-api
|
||||
@no-api @ui
|
||||
Scenario: Changing gateway username
|
||||
When I want to modify the "PayPal Express Checkout" payment method
|
||||
And I update its "Username" with "new_username"
|
||||
|
|
@ -17,7 +17,7 @@ Feature: Editing payment method configured with a PayPal Express Checkout gatewa
|
|||
Then I should be notified that it has been successfully edited
|
||||
And its gateway configuration "Username" should be "new_username"
|
||||
|
||||
@ui @no-api
|
||||
@no-api @ui
|
||||
Scenario: Changing gateway password
|
||||
When I want to modify the "PayPal Express Checkout" payment method
|
||||
And I update its "Password" with "new_password"
|
||||
|
|
@ -25,7 +25,7 @@ Feature: Editing payment method configured with a PayPal Express Checkout gatewa
|
|||
Then I should be notified that it has been successfully edited
|
||||
And its gateway configuration "Password" should be "new_password"
|
||||
|
||||
@ui @no-api
|
||||
@no-api @ui
|
||||
Scenario: Changing gateway signature
|
||||
When I want to modify the "PayPal Express Checkout" payment method
|
||||
And I update its "Signature" with "new_signature"
|
||||
|
|
@ -33,7 +33,7 @@ Feature: Editing payment method configured with a PayPal Express Checkout gatewa
|
|||
Then I should be notified that it has been successfully edited
|
||||
And its gateway configuration "Signature" should be "new_signature"
|
||||
|
||||
@ui @no-api
|
||||
@no-api @ui
|
||||
Scenario: Changing gateway sandbox mode
|
||||
When I want to modify the "PayPal Express Checkout" payment method
|
||||
And I enable sandbox mode
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Feature: Editing payment method configured with a Stripe Checkout gateway
|
|||
And the store has a payment method "Stripe Checkout" with a code "stripe" and "Stripe Checkout" gateway
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @no-api
|
||||
@no-api @ui
|
||||
Scenario: Changing Stripe Checkout gateway publishable key
|
||||
When I want to modify the "Stripe Checkout" payment method
|
||||
And I update its "Publishable key" with "some_publishable_key"
|
||||
|
|
@ -17,7 +17,7 @@ Feature: Editing payment method configured with a Stripe Checkout gateway
|
|||
Then I should be notified that it has been successfully edited
|
||||
And this payment method "Publishable key" should be "some_publishable_key"
|
||||
|
||||
@ui @no-api
|
||||
@no-api @ui
|
||||
Scenario: Changing Stripe Checkout gateway secret key
|
||||
When I want to modify the "Stripe Checkout" payment method
|
||||
And I update its "Secret key" with "some_secret_key"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
@managing_payment_methods
|
||||
Feature: Filtering payment methods
|
||||
In order to quickly find the payment method I need
|
||||
As an Administrator
|
||||
I want to filter available payment methods
|
||||
|
||||
Background:
|
||||
Given the store operates on a single channel in "United States"
|
||||
And the store has a payment method "PayPal Express Checkout" with a code "paypal_xyz" and "Paypal Express Checkout" gateway
|
||||
And the store has a payment method "Offline" with a code "offline_abc"
|
||||
And this payment method is disabled
|
||||
And the store has a payment method "Cash on Delivery" with a code "cash_on_delivery_xyz"
|
||||
And I am logged in as an administrator
|
||||
And I am browsing payment methods
|
||||
|
||||
@todo-api @ui
|
||||
Scenario: Filtering payment methods by name
|
||||
When I search by "PayPal" name
|
||||
Then I should see a single payment method in the list
|
||||
And I should see the payment method "PayPal Express Checkout"
|
||||
|
||||
@todo-api @ui
|
||||
Scenario: Filtering payment methods by code
|
||||
When I search by "xyz" code
|
||||
Then I should see 2 payment methods in the list
|
||||
And I should not see the payment method "Offline"
|
||||
|
||||
@todo-api @ui
|
||||
Scenario: Filtering enabled payment methods
|
||||
When I choose enabled filter
|
||||
And I filter
|
||||
Then I should see 2 payment methods in the list
|
||||
And I should not see the payment method "Offline"
|
||||
|
|
@ -9,9 +9,9 @@ Feature: Payment method unique code validation
|
|||
And the store has a payment method "Offline" with a code "Offline"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add payment method with taken code
|
||||
When I want to create a new Offline payment method
|
||||
When I want to create a new offline payment method
|
||||
And I name it "Paypal Express Checkout" in "English (United States)"
|
||||
And I specify its code as "Offline"
|
||||
And I try to add it
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Feature: Payment method validation
|
|||
And the store has a payment method "Offline" with a code "Offline"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new payment method without specifying its code
|
||||
When I want to create a new payment method with "Paypal Express Checkout" gateway factory
|
||||
And I name it "Paypal Express Checkout" in "English (United States)"
|
||||
|
|
@ -18,14 +18,14 @@ Feature: Payment method validation
|
|||
Then I should be notified that code is required
|
||||
And the payment method with name "Paypal Express Checkout" should not be added
|
||||
|
||||
@no-ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add a new payment method translation in unexisting language
|
||||
When I want to modify the "Offline" payment method
|
||||
And I name it "Offline" in "French (France)"
|
||||
And I try to save my changes
|
||||
Then I should be notified that the locale is not available
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new payment method with a too long code
|
||||
When I want to create a new payment method with "Paypal Express Checkout" gateway factory
|
||||
And I name it "Paypal Express Checkout" in "English (United States)"
|
||||
|
|
@ -33,7 +33,7 @@ Feature: Payment method validation
|
|||
And I add it
|
||||
Then I should be notified that code is too long
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new payment method without specifying its name
|
||||
When I want to create a new payment method with "Paypal Express Checkout" gateway factory
|
||||
And I specify its code as "PEC"
|
||||
|
|
@ -42,7 +42,7 @@ Feature: Payment method validation
|
|||
Then I should be notified that I have to specify payment method name
|
||||
And the payment method with code "PEC" should not be added
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new paypal payment method without specifying password
|
||||
When I want to create a new payment method with "Paypal Express Checkout" gateway factory
|
||||
And I name it "Paypal Express Checkout" in "English (United States)"
|
||||
|
|
@ -53,7 +53,7 @@ Feature: Payment method validation
|
|||
Then I should be notified that I have to specify paypal password
|
||||
And the payment method with code "PEC" should not be added
|
||||
|
||||
@no-ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add a new paypal payment method without specifying sandbox
|
||||
When I want to create a new payment method with "Paypal Express Checkout" gateway factory
|
||||
And I name it "Paypal Express Checkout" in "English (United States)"
|
||||
|
|
@ -63,7 +63,7 @@ Feature: Payment method validation
|
|||
Then I should be notified that I have to specify paypal sandbox status
|
||||
And the payment method with code "PEC" should not be added
|
||||
|
||||
@no-ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add a new paypal payment method, but with sandbox that has wrong type
|
||||
When I want to create a new payment method with "Paypal Express Checkout" gateway factory
|
||||
And I name it "Paypal Express Checkout" in "English (United States)"
|
||||
|
|
@ -73,7 +73,7 @@ Feature: Payment method validation
|
|||
Then I should be notified that I have to specify paypal sandbox status that is boolean
|
||||
And the payment method with code "PEC" should not be added
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new stripe payment method with only publishable key specified
|
||||
When I want to create a new payment method with "Stripe Checkout" gateway factory
|
||||
And I name it "Stripe Checkout" in "English (United States)"
|
||||
|
|
@ -83,7 +83,7 @@ Feature: Payment method validation
|
|||
Then I should be notified that I have to specify stripe "Secret key"
|
||||
And the payment method with code "PEC" should not be added
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new stripe payment method with only secret key specified
|
||||
When I want to create a new payment method with "Stripe Checkout" gateway factory
|
||||
And I name it "Stripe Checkout" in "English (United States)"
|
||||
|
|
@ -93,7 +93,7 @@ Feature: Payment method validation
|
|||
Then I should be notified that I have to specify stripe "Publishable key"
|
||||
And the payment method with code "PEC" should not be added
|
||||
|
||||
@no-ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add a new payment method without gateway configuration
|
||||
When I want to create a new payment method without gateway configuration
|
||||
And I name it "Payment method without gateway configuration" in "English (United States)"
|
||||
|
|
@ -101,7 +101,7 @@ Feature: Payment method validation
|
|||
And I try to add it
|
||||
Then I should be notified that I have to specify gateway configuration
|
||||
|
||||
@no-ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add a new payment method without gateway name
|
||||
When I want to create a new payment method without gateway name
|
||||
And I name it "Payment method without gateway name" in "English (United States)"
|
||||
|
|
@ -109,7 +109,7 @@ Feature: Payment method validation
|
|||
And I try to add it
|
||||
Then I should be notified that I have to specify gateway name
|
||||
|
||||
@no-ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add a new payment method without factory name
|
||||
When I want to create a new payment method without factory name
|
||||
And I name it "Payment method without gateway factory name" in "English (United States)"
|
||||
|
|
@ -117,7 +117,7 @@ Feature: Payment method validation
|
|||
And I try to add it
|
||||
Then I should be notified that I have to specify factory name
|
||||
|
||||
@no-ui @api
|
||||
@api @no-ui
|
||||
Scenario: Trying to add a new payment method with wrong factory name
|
||||
When I want to create a new payment method with wrong factory name
|
||||
And I name it "Payment method with wrong gateway factory name" in "English (United States)"
|
||||
|
|
@ -125,7 +125,7 @@ Feature: Payment method validation
|
|||
And I try to add it
|
||||
Then I should be notified that I have to specify factory name that is available
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to remove name from an existing payment method
|
||||
When I want to modify the "Offline" payment method
|
||||
And I remove its name from "English (United States)" translation
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Feature: Prevent deletion of used payment method
|
|||
And the customer chose "DHL Express" shipping method to "United States" with "Cash on Delivery" payment
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Being unable to delete a payment method which is in use
|
||||
When I try to delete the "Cash on Delivery" payment method
|
||||
Then I should be notified that it is in use
|
||||
|
|
|
|||
|
|
@ -7,37 +7,37 @@ Feature: Sorting listed payment methods
|
|||
Background:
|
||||
Given the store operates on a single channel in "United States"
|
||||
And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales
|
||||
And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and "Paypal Express Checkout" gateway
|
||||
And the store has a payment method "PayPal Express Checkout" with a code "paypal" and "Paypal Express Checkout" gateway
|
||||
And this payment method is named "Ekspresowy Paypal" in the "Polish (Poland)" locale
|
||||
And the store has a payment method "Offline" with a code "Offline"
|
||||
And the store has a payment method "Offline" with a code "offline"
|
||||
And this payment method is named "Płatność Offline" in the "Polish (Poland)" locale
|
||||
And the store has a payment method "Cash on Delivery" with a code "cash_on_delivery"
|
||||
And this payment method is named "Płatność Przy Odbiorze" in the "Polish (Poland)" locale
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Payment methods can be sorted by their codes
|
||||
Given I am browsing payment methods
|
||||
When I start sorting payment methods by code
|
||||
Then I should see 3 payment methods in the list
|
||||
And the first payment method on the list should have code "cash_on_delivery"
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Changing the order of sorting payment methods by their codes
|
||||
Given I am browsing payment methods
|
||||
And the payment methods are already sorted by code
|
||||
When I switch the way payment methods are sorted to descending by code
|
||||
Then I should see 3 payment methods in the list
|
||||
And the first payment method on the list should have code "PAYPAL"
|
||||
And the first payment method on the list should have code "paypal"
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Payment methods can be sorted by their names
|
||||
Given I am browsing payment methods
|
||||
When I start sorting payment methods by name
|
||||
Then I should see 3 payment methods in the list
|
||||
And the first payment method on the list should have name "Cash on Delivery"
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Changing the order of sorting payment methods by their names
|
||||
Given I am browsing payment methods
|
||||
And the payment methods are already sorted by name
|
||||
|
|
@ -45,7 +45,7 @@ Feature: Sorting listed payment methods
|
|||
Then I should see 3 payment methods in the list
|
||||
And the first payment method on the list should have name "PayPal Express Checkout"
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Payment methods are always sorted in the default locale
|
||||
Given I change my locale to "Polish (Poland)"
|
||||
And I am browsing payment methods
|
||||
|
|
|
|||
|
|
@ -11,20 +11,20 @@ Feature: Sorting listed payment methods by position
|
|||
And the store allows paying with "Offline" at position 1
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Payment methods are sorted by position in ascending order by default
|
||||
When I browse payment methods
|
||||
Then I should see 3 payment methods in the list
|
||||
And the first payment method on the list should have name "Paypal Express Checkout"
|
||||
And the last payment method on the list should have name "Cash on Delivery"
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Payment method added at no position is added as the last one
|
||||
Given the store allows paying with "Credit Card"
|
||||
When I browse payment methods
|
||||
Then the last payment method on the list should have name "Credit Card"
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Payment method added at position 0 is added as the first one
|
||||
Given the store also allows paying with "Credit Card" at position 0
|
||||
When I browse payment methods
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ Feature: Creating a catalog promotion
|
|||
And it should have "winter_sale" code and "Winter sale" name
|
||||
And the "Winter sale" catalog promotion should apply to all variants of "T-Shirt" product
|
||||
|
||||
@api @todo-ui @mink:chromedriver
|
||||
@api @ui @mink:chromedriver
|
||||
Scenario: Creating a catalog promotion with start and end date
|
||||
When I want to create a new catalog promotion
|
||||
And I specify its code as "winter_sale"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Feature: Adding a new tax category
|
|||
Background:
|
||||
Given I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new tax category
|
||||
When I want to create a new tax category
|
||||
And I specify its code as "food_and_beverage"
|
||||
|
|
@ -16,7 +16,7 @@ Feature: Adding a new tax category
|
|||
Then I should be notified that it has been successfully created
|
||||
And the tax category "Food and Beverage" should appear in the registry
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new tax category with a description
|
||||
When I want to create a new tax category
|
||||
And I specify its code as "food_and_beverage"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Feature: Deleting multiple tax categories
|
|||
Given the store has tax categories "Alcohol", "Food" and "Books"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @mink:chromedriver @no-api
|
||||
@no-api @ui @mink:chromedriver @no-api
|
||||
Scenario: Deleting multiple tax categories at once
|
||||
When I browse tax categories
|
||||
And I check the "Alcohol" tax category
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Feature: Deleting a tax category
|
|||
Given the store has a tax category "Alcohol" with a code "alcohol"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Deleted tax category should disappear from the registry
|
||||
When I delete tax category "Alcohol"
|
||||
Then I should be notified that it has been successfully deleted
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ Feature: Editing tax category
|
|||
Given the store has a tax category "Alcohol" with a code "alcohol"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Inability of changing the code of an existing tax category
|
||||
When I want to modify a tax category "Alcohol"
|
||||
Then I should not be able to edit its code
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Renaming the tax category
|
||||
When I want to modify a tax category "Alcohol"
|
||||
And I rename it to "Food & Alcohol"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
@managing_tax_categories
|
||||
Feature: Filtering tax categories
|
||||
In order to quickly find the tax category I need
|
||||
As an Administrator
|
||||
I want to filter available tax categories
|
||||
|
||||
Background:
|
||||
Given the store has a tax category "Alcohol" with a code "alcohol"
|
||||
And the store has a tax category "Food" with a code "food"
|
||||
And the store has a tax category "Seafood" with a code "seafood"
|
||||
And I am logged in as an administrator
|
||||
And I am browsing tax categories
|
||||
|
||||
@todo-api @ui
|
||||
Scenario: Filtering tax categories by name
|
||||
When I search by "Food" name
|
||||
Then I should see 2 tax categories in the list
|
||||
But I should not see the tax category "Alcohol"
|
||||
|
||||
@todo-api @ui
|
||||
Scenario: Filtering tax categories by code
|
||||
When I search by "alcohol" code
|
||||
Then I should see a single tax category in the list
|
||||
And I should see the tax category "Alcohol"
|
||||
|
|
@ -8,7 +8,7 @@ Feature: Tax category unique code validation
|
|||
Given the store has a tax category "Alcohol" with a code "alcohol"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add tax category with taken code
|
||||
When I want to create a new tax category
|
||||
And I name it "Food and Beverage"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Feature: Tax category validation
|
|||
Background:
|
||||
Given I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new tax category without specifying its code
|
||||
When I want to create a new tax category
|
||||
And I name it "Food and Beverage"
|
||||
|
|
@ -16,7 +16,7 @@ Feature: Tax category validation
|
|||
Then I should be notified that code is required
|
||||
And tax category with name "Food and Beverage" should not be added
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new tax category with a too long code
|
||||
When I want to create a new tax category
|
||||
And I name it "Food and Beverage"
|
||||
|
|
@ -24,7 +24,7 @@ Feature: Tax category validation
|
|||
And I try to add it
|
||||
Then I should be notified that code is too long
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new tax category without specifying its name
|
||||
When I want to create a new tax category
|
||||
And I specify its code as "food_and_beverage"
|
||||
|
|
@ -33,7 +33,16 @@ Feature: Tax category validation
|
|||
Then I should be notified that name is required
|
||||
And tax category with code "food_and_beverage" should not be added
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new tax category with a too long name
|
||||
When I want to create a new tax category
|
||||
And I name it "Food and Beverage"
|
||||
And I specify a too long name
|
||||
And I specify its code as "food_and_beverage"
|
||||
And I try to add it
|
||||
Then I should be notified that name is too long
|
||||
|
||||
@api @ui
|
||||
Scenario: Trying to remove name from existing tax category
|
||||
Given the store has a tax category "Alcoholic Drinks" with a code "alcohol"
|
||||
When I want to modify this tax category
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Feature: Adding a new customer group
|
|||
Background:
|
||||
Given I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new customer group
|
||||
When I want to create a new customer group
|
||||
And I specify its code as "RETAIL"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Feature: Customer group unique code validation
|
|||
Given the store has a customer group "Retail" with "RETAIL" code
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new customer group with used code
|
||||
When I want to create a new customer group
|
||||
And I specify its code as "RETAIL"
|
||||
|
|
|
|||
|
|
@ -7,24 +7,24 @@ Feature: Customer group validation
|
|||
Background:
|
||||
Given I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to add a new customer group without a name
|
||||
When I want to create a new customer group
|
||||
And I try to add it
|
||||
Then I should be notified that name is required
|
||||
And I should be informed that this form contains errors
|
||||
# And I should be informed that this form contains errors #TODO: Uncomment when flash messages are brought back
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Trying to remove name from an existing customer group
|
||||
Given the store has a customer group "Retail"
|
||||
When I want to edit this customer group
|
||||
And I remove its name
|
||||
And I try to save my changes
|
||||
Then I should be notified that name is required
|
||||
And I should be informed that this form contains errors
|
||||
# And I should be informed that this form contains errors #TODO: Uncomment when flash messages are brought back
|
||||
And this customer group should still be named "Retail"
|
||||
|
||||
@ui @api
|
||||
@api @ui
|
||||
Scenario: Adding a new customer group with a too long code
|
||||
Given I want to create a new customer group
|
||||
And I specify its name as "Retail"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Feature: Deleting customer groups
|
|||
Given the store has a customer group "Retail"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Deleting a customer group
|
||||
When I delete the "Retail" customer group
|
||||
Then I should be notified that it has been successfully deleted
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Feature: Editing a customer group
|
|||
Given the store has a customer group "Retail"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Changing name of an existing customer group
|
||||
When I want to edit this customer group
|
||||
And I specify its name as "Wholesale"
|
||||
|
|
@ -16,7 +16,7 @@ Feature: Editing a customer group
|
|||
Then I should be notified that it has been successfully edited
|
||||
And this customer group with name "Wholesale" should appear in the store
|
||||
|
||||
@todo @ui @api
|
||||
@api @ui
|
||||
Scenario: Seeing disabled code field while editing customer group
|
||||
When I want to edit this customer group
|
||||
Then I should not be able to edit its code
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use Sylius\Behat\Client\ResponseCheckerInterface;
|
|||
use Sylius\Behat\Context\Api\Resources;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class ManagingCurrenciesContext implements Context
|
||||
final readonly class ManagingCurrenciesContext implements Context
|
||||
{
|
||||
public function __construct(
|
||||
private ApiClientInterface $client,
|
||||
|
|
@ -62,7 +62,7 @@ final class ManagingCurrenciesContext implements Context
|
|||
}
|
||||
|
||||
/**
|
||||
* @Then I should see :count currencies in the list
|
||||
* @Then I should see :count currencies on the list
|
||||
*/
|
||||
public function iShouldSeeCurrenciesInTheList(int $count): void
|
||||
{
|
||||
|
|
@ -72,7 +72,7 @@ final class ManagingCurrenciesContext implements Context
|
|||
}
|
||||
|
||||
/**
|
||||
* @Then I should see the currency :currencyName in the list
|
||||
* @Then I should see the currency :currencyName on the list
|
||||
* @Then the currency :currencyName should appear in the store
|
||||
*/
|
||||
public function currencyShouldAppearInTheStore(string $currencyName): void
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ final readonly class ManagingPaymentMethodsContext implements Context
|
|||
{
|
||||
$response = $this->client->index(Resources::PAYMENT_METHODS);
|
||||
|
||||
if ($field === 'Name') {
|
||||
if ($field === 'name') {
|
||||
$paymentMethods = $this->responseChecker->getCollection($response);
|
||||
|
||||
Assert::same(end($paymentMethods)['translations']['en_US']['name'], $value);
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ final readonly class PaymentContext implements Context
|
|||
|
||||
/**
|
||||
* @Given the payment method :paymentMethod is disabled
|
||||
* @Given /^(this payment method) has been disabled$/
|
||||
* @Given /^(this payment method) (?:has been|is) disabled$/
|
||||
* @When the payment method :paymentMethod gets disabled
|
||||
*/
|
||||
public function theStoreHasAPaymentMethodDisabled(PaymentMethodInterface $paymentMethod)
|
||||
|
|
|
|||
|
|
@ -14,25 +14,25 @@ declare(strict_types=1);
|
|||
namespace Sylius\Behat\Context\Ui\Admin;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Behat\Page\Admin\Currency\CreatePageInterface;
|
||||
use Sylius\Behat\Element\Admin\Currency\FormElementInterface;
|
||||
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
|
||||
use Sylius\Behat\Page\Admin\Currency\IndexPageInterface;
|
||||
use Sylius\Behat\Page\Admin\Currency\UpdatePageInterface;
|
||||
use Sylius\Component\Currency\Model\CurrencyInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class ManagingCurrenciesContext implements Context
|
||||
final readonly class ManagingCurrenciesContext implements Context
|
||||
{
|
||||
public function __construct(
|
||||
private IndexPageInterface $indexPage,
|
||||
private CreatePageInterface $createPage,
|
||||
private UpdatePageInterface $updatePage,
|
||||
private FormElementInterface $formElement,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I want to add a new currency
|
||||
*/
|
||||
public function iWantToAddNewCurrency()
|
||||
public function iWantToAddNewCurrency(): void
|
||||
{
|
||||
$this->createPage->open();
|
||||
}
|
||||
|
|
@ -40,103 +40,52 @@ final class ManagingCurrenciesContext implements Context
|
|||
/**
|
||||
* @When I choose :currencyName
|
||||
*/
|
||||
public function iChoose($currencyName)
|
||||
public function iChoose($currencyName): void
|
||||
{
|
||||
$this->createPage->chooseName($currencyName);
|
||||
$this->formElement->chooseCurrency($currencyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I add it
|
||||
* @When I try to add it
|
||||
*/
|
||||
public function iAddIt()
|
||||
public function iAddIt(): void
|
||||
{
|
||||
$this->createPage->create();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then the currency :currency should appear in the store
|
||||
* @Then I should see the currency :currency in the list
|
||||
* @Then I should see the currency :currency on the list
|
||||
*/
|
||||
public function currencyShouldAppearInTheStore(CurrencyInterface $currency)
|
||||
public function currencyShouldAppearInTheStore(CurrencyInterface $currency): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['code' => $currency->getCode()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I want to edit (this currency)$/
|
||||
*/
|
||||
public function iWantToEditThisCurrency(CurrencyInterface $currency)
|
||||
{
|
||||
$this->updatePage->open(['id' => $currency->getId()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I enable it
|
||||
*/
|
||||
public function iEnableIt()
|
||||
{
|
||||
$this->updatePage->enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I disable it
|
||||
*/
|
||||
public function iDisableIt()
|
||||
{
|
||||
$this->updatePage->disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I save my changes
|
||||
* @When I try to save my changes
|
||||
*/
|
||||
public function iSaveMyChanges()
|
||||
{
|
||||
$this->updatePage->saveChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then the code field should be disabled
|
||||
*/
|
||||
public function theCodeFiledShouldBeDisabled()
|
||||
{
|
||||
Assert::same($this->updatePage->getCodeDisabledAttribute(), 'disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be notified that currency code must be unique
|
||||
*/
|
||||
public function iShouldBeNotifiedThatCurrencyCodeMustBeUnique()
|
||||
{
|
||||
Assert::same($this->createPage->getValidationMessage('code'), 'Currency code must be unique.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then there should still be only one currency with :element :code
|
||||
*/
|
||||
public function thereShouldStillBeOnlyOneCurrencyWithCode($element, $codeValue)
|
||||
{
|
||||
$this->indexPage->open();
|
||||
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage([$element => $codeValue]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I want to browse currencies of the store
|
||||
*/
|
||||
public function iWantToSeeAllCurrenciesInStore()
|
||||
public function iWantToSeeAllCurrenciesInStore(): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^I should see (\d+) currencies in the list$/
|
||||
* @Then /^I should see (\d+) currencies on the list$/
|
||||
*/
|
||||
public function iShouldSeeCurrenciesInTheList($amountOfCurrencies)
|
||||
public function iShouldSeeCurrenciesInTheList(int $amountOfCurrencies): void
|
||||
{
|
||||
Assert::same($this->indexPage->countItems(), (int) $amountOfCurrencies);
|
||||
Assert::same($this->indexPage->countItems(), $amountOfCurrencies);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should not be able to choose :name
|
||||
*/
|
||||
public function iShouldNotBeAbleToChoose(string $name): void
|
||||
{
|
||||
Assert::false($this->formElement->isCurrencyAvailable($name));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
|
|||
use Sylius\Component\Customer\Model\CustomerGroupInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class ManagingCustomerGroupsContext implements Context
|
||||
final readonly class ManagingCustomerGroupsContext implements Context
|
||||
{
|
||||
use ValidationTrait;
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
/**
|
||||
* @When I want to create a new customer group
|
||||
*/
|
||||
public function iWantToCreateANewCustomerGroup()
|
||||
public function iWantToCreateANewCustomerGroup(): void
|
||||
{
|
||||
$this->createPage->open();
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
* @When I specify its name as :name
|
||||
* @When I remove its name
|
||||
*/
|
||||
public function iSpecifyItsNameAs($name = null)
|
||||
public function iSpecifyItsNameAs(string $name = null): void
|
||||
{
|
||||
$this->createPage->nameIt($name ?? '');
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
* @When I add it
|
||||
* @When I try to add it
|
||||
*/
|
||||
public function iAddIt()
|
||||
public function iAddIt(): void
|
||||
{
|
||||
$this->createPage->create();
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
/**
|
||||
* @Then the customer group :customerGroup should appear in the store
|
||||
*/
|
||||
public function theCustomerGroupShouldAppearInTheStore(CustomerGroupInterface $customerGroup)
|
||||
public function theCustomerGroupShouldAppearInTheStore(CustomerGroupInterface $customerGroup): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
/**
|
||||
* @When /^I want to edit (this customer group)$/
|
||||
*/
|
||||
public function iWantToEditThisCustomerGroup(CustomerGroupInterface $customerGroup)
|
||||
public function iWantToEditThisCustomerGroup(CustomerGroupInterface $customerGroup): void
|
||||
{
|
||||
$this->updatePage->open(['id' => $customerGroup->getId()]);
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
* @When I save my changes
|
||||
* @When I try to save my changes
|
||||
*/
|
||||
public function iSaveMyChanges()
|
||||
public function iSaveMyChanges(): void
|
||||
{
|
||||
$this->updatePage->saveChanges();
|
||||
}
|
||||
|
|
@ -117,7 +117,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
* @Then this customer group with name :name should appear in the store
|
||||
* @Then I should see the customer group :name in the list
|
||||
*/
|
||||
public function thisCustomerGroupWithNameShouldAppearInTheStore($name)
|
||||
public function thisCustomerGroupWithNameShouldAppearInTheStore(string $name): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
* @When I browse customer groups
|
||||
* @When I want to browse customer groups
|
||||
*/
|
||||
public function iWantToBrowseCustomerGroups()
|
||||
public function iWantToBrowseCustomerGroups(): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
}
|
||||
|
|
@ -141,23 +141,24 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
{
|
||||
$this->indexPage->open();
|
||||
|
||||
Assert::same($this->indexPage->countItems(), (int) $amountOfCustomerGroups);
|
||||
Assert::same($this->indexPage->countItems(), $amountOfCustomerGroups);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(this customer group) should still be named "([^"]+)"$/
|
||||
*/
|
||||
public function thisCustomerGroupShouldStillBeNamed(CustomerGroupInterface $customerGroup, $customerGroupName)
|
||||
public function thisCustomerGroupShouldStillBeNamed(CustomerGroupInterface $customerGroup, string $customerGroupName): void
|
||||
{
|
||||
$this->iWantToBrowseCustomerGroups();
|
||||
|
||||
Assert::same($customerGroup->getName(), $customerGroupName);
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $customerGroupName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be notified that name is required
|
||||
*/
|
||||
public function iShouldBeNotifiedThatNameIsRequired()
|
||||
public function iShouldBeNotifiedThatNameIsRequired(): void
|
||||
{
|
||||
Assert::same(
|
||||
$this->updatePage->getValidationMessage('name'),
|
||||
|
|
@ -168,7 +169,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
/**
|
||||
* @Then I should be notified that customer group with this code already exists
|
||||
*/
|
||||
public function iShouldBeNotifiedThatCustomerGroupWithThisCodeAlreadyExists()
|
||||
public function iShouldBeNotifiedThatCustomerGroupWithThisCodeAlreadyExists(): void
|
||||
{
|
||||
Assert::same($this->createPage->getValidationMessage('code'), 'Customer group code has to be unique.');
|
||||
}
|
||||
|
|
@ -176,7 +177,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
/**
|
||||
* @Then I should be informed that this form contains errors
|
||||
*/
|
||||
public function iShouldBeInformedThatThisFormContainsErrors()
|
||||
public function iShouldBeInformedThatThisFormContainsErrors(): void
|
||||
{
|
||||
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
|
||||
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
|
||||
|
|
@ -195,7 +196,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
/**
|
||||
* @When I delete the :customerGroup customer group
|
||||
*/
|
||||
public function iDeleteTheCustomerGroup(CustomerGroupInterface $customerGroup)
|
||||
public function iDeleteTheCustomerGroup(CustomerGroupInterface $customerGroup): void
|
||||
{
|
||||
$this->iWantToBrowseCustomerGroups();
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ final class ManagingCustomerGroupsContext implements Context
|
|||
/**
|
||||
* @Then /^(this customer group) should no longer exist in the registry$/
|
||||
*/
|
||||
public function thisCustomerGroupShouldNoLongerExistInTheRegistry(CustomerGroupInterface $customerGroup)
|
||||
public function thisCustomerGroupShouldNoLongerExistInTheRegistry(CustomerGroupInterface $customerGroup): void
|
||||
{
|
||||
Assert::false(
|
||||
$this->indexPage->isSingleResourceOnPage(['name' => $customerGroup->getName()]),
|
||||
|
|
|
|||
|
|
@ -255,6 +255,22 @@ final readonly class ManagingPaymentMethodsContext implements Context
|
|||
$this->indexPage->bulkDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see the payment method :paymentMethodName
|
||||
*/
|
||||
public function IShouldSeeThePaymentMethod(string $paymentMethodName): void
|
||||
{
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $paymentMethodName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should not see the payment method :paymentMethodName
|
||||
*/
|
||||
public function IShouldNotSeeThePaymentMethod(string $paymentMethodName): void
|
||||
{
|
||||
Assert::false($this->indexPage->isSingleResourceOnPage(['name' => $paymentMethodName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then the payment method :paymentMethodName should appear in the registry
|
||||
* @Then the payment method :paymentMethodName should be in the registry
|
||||
|
|
@ -262,9 +278,7 @@ final readonly class ManagingPaymentMethodsContext implements Context
|
|||
*/
|
||||
public function thePaymentMethodShouldAppearInTheRegistry(string $paymentMethodName): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $paymentMethodName]));
|
||||
$this->thereShouldStillBeOnlyOnePaymentMethodWith('name', $paymentMethodName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -14,48 +14,28 @@ declare(strict_types=1);
|
|||
namespace Sylius\Behat\Context\Ui\Admin;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
|
||||
use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait;
|
||||
use Sylius\Behat\Element\Admin\TaxCategory\FormElementInterface;
|
||||
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
|
||||
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
|
||||
use Sylius\Behat\Page\Admin\TaxCategory\CreatePageInterface;
|
||||
use Sylius\Behat\Page\Admin\TaxCategory\UpdatePageInterface;
|
||||
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
|
||||
use Sylius\Component\Taxation\Model\TaxCategoryInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class ManagingTaxCategoriesContext implements Context
|
||||
final readonly class ManagingTaxCategoriesContext implements Context
|
||||
{
|
||||
use ValidationTrait;
|
||||
|
||||
public function __construct(
|
||||
private IndexPageInterface $indexPage,
|
||||
private CreatePageInterface $createPage,
|
||||
private UpdatePageInterface $updatePage,
|
||||
private CurrentPageResolverInterface $currentPageResolver,
|
||||
private FormElementInterface $formElement,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I delete tax category :taxCategory
|
||||
*/
|
||||
public function iDeletedTaxCategory(TaxCategoryInterface $taxCategory)
|
||||
{
|
||||
$this->indexPage->open();
|
||||
$this->indexPage->deleteResourceOnPage(['code' => $taxCategory->getCode()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(this tax category) should no longer exist in the registry$/
|
||||
*/
|
||||
public function thisTaxCategoryShouldNoLongerExistInTheRegistry(TaxCategoryInterface $taxCategory)
|
||||
{
|
||||
Assert::false($this->indexPage->isSingleResourceOnPage(['code' => $taxCategory->getCode()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I want to create a new tax category
|
||||
*/
|
||||
public function iWantToCreateNewTaxCategory()
|
||||
public function iWantToCreateNewTaxCategory(): void
|
||||
{
|
||||
$this->createPage->open();
|
||||
}
|
||||
|
|
@ -66,7 +46,15 @@ final class ManagingTaxCategoriesContext implements Context
|
|||
*/
|
||||
public function iSpecifyItsCodeAs(?string $code = null): void
|
||||
{
|
||||
$this->createPage->specifyCode($code ?? '');
|
||||
$this->formElement->setCode($code ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I specify a too long :field
|
||||
*/
|
||||
public function iSpecifyATooLongCode(string $field): void
|
||||
{
|
||||
$this->formElement->fillElement(str_repeat('a', 256), $field);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,43 +63,33 @@ final class ManagingTaxCategoriesContext implements Context
|
|||
* @When I do not name it
|
||||
* @When I remove its name
|
||||
*/
|
||||
public function iNameIt($name = null)
|
||||
public function iNameIt($name = null): void
|
||||
{
|
||||
$this->createPage->nameIt($name ?? '');
|
||||
$this->formElement->setName($name ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I describe it as :description
|
||||
*/
|
||||
public function iDescribeItAs($description): void
|
||||
{
|
||||
$this->formElement->setDescription($description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I add it
|
||||
* @When I try to add it
|
||||
*/
|
||||
public function iAddIt()
|
||||
public function iAddIt(): void
|
||||
{
|
||||
$this->createPage->create();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see the tax category :taxCategoryName in the list
|
||||
* @Then the tax category :taxCategoryName should appear in the registry
|
||||
*/
|
||||
public function theTaxCategoryShouldAppearInTheRegistry(string $taxCategoryName): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['nameAndDescription' => $taxCategoryName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I describe it as :description
|
||||
*/
|
||||
public function iDescribeItAs($description)
|
||||
{
|
||||
$this->createPage->describeItAs($description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I want to modify a tax category :taxCategory
|
||||
* @When /^I want to modify (this tax category)$/
|
||||
*/
|
||||
public function iWantToModifyTaxCategory(TaxCategoryInterface $taxCategory)
|
||||
public function iWantToModifyTaxCategory(TaxCategoryInterface $taxCategory): void
|
||||
{
|
||||
$this->updatePage->open(['id' => $taxCategory->getId()]);
|
||||
}
|
||||
|
|
@ -120,12 +98,13 @@ final class ManagingTaxCategoriesContext implements Context
|
|||
* @When I save my changes
|
||||
* @When I try to save my changes
|
||||
*/
|
||||
public function iSaveMyChanges()
|
||||
public function iSaveMyChanges(): void
|
||||
{
|
||||
$this->updatePage->saveChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given I am browsing tax categories
|
||||
* @When I browse tax categories
|
||||
*/
|
||||
public function iWantToBrowseTaxCategories(): void
|
||||
|
|
@ -149,19 +128,46 @@ final class ManagingTaxCategoriesContext implements Context
|
|||
$this->indexPage->bulkDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I delete tax category :taxCategory
|
||||
*/
|
||||
public function iDeletedTaxCategory(TaxCategoryInterface $taxCategory): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
$this->indexPage->deleteResourceOnPage(['code' => $taxCategory->getCode()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(this tax category) should no longer exist in the registry$/
|
||||
*/
|
||||
public function thisTaxCategoryShouldNoLongerExistInTheRegistry(TaxCategoryInterface $taxCategory): void
|
||||
{
|
||||
Assert::false($this->indexPage->isSingleResourceOnPage(['code' => $taxCategory->getCode()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see the tax category :taxCategoryName in the list
|
||||
* @Then the tax category :taxCategoryName should appear in the registry
|
||||
*/
|
||||
public function theTaxCategoryShouldAppearInTheRegistry(string $taxCategoryName): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['nameAndDescription' => $taxCategoryName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should not be able to edit its code
|
||||
*/
|
||||
public function iShouldNotBeAbleToEditItsCode(): void
|
||||
{
|
||||
Assert::true($this->updatePage->isCodeDisabled());
|
||||
Assert::true($this->formElement->isCodeDisabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(this tax category) name should be "([^"]+)"$/
|
||||
* @Then /^(this tax category) should still be named "([^"]+)"$/
|
||||
*/
|
||||
public function thisTaxCategoryNameShouldBe(TaxCategoryInterface $taxCategory, $taxCategoryName)
|
||||
public function thisTaxCategoryNameShouldBe(TaxCategoryInterface $taxCategory, $taxCategoryName): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['code' => $taxCategory->getCode(), 'nameAndDescription' => $taxCategoryName]));
|
||||
|
|
@ -170,15 +176,15 @@ final class ManagingTaxCategoriesContext implements Context
|
|||
/**
|
||||
* @Then I should be notified that tax category with this code already exists
|
||||
*/
|
||||
public function iShouldBeNotifiedThatTaxCategoryWithThisCodeAlreadyExists()
|
||||
public function iShouldBeNotifiedThatTaxCategoryWithThisCodeAlreadyExists(): void
|
||||
{
|
||||
Assert::same($this->createPage->getValidationMessage('code'), 'The tax category with given code already exists.');
|
||||
Assert::same($this->formElement->getValidationMessage('code'), 'The tax category with given code already exists.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then there should still be only one tax category with :element :code
|
||||
*/
|
||||
public function thereShouldStillBeOnlyOneTaxCategoryWith($element, $code)
|
||||
public function thereShouldStillBeOnlyOneTaxCategoryWith($element, $code): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage([$element => $code]));
|
||||
|
|
@ -187,18 +193,15 @@ final class ManagingTaxCategoriesContext implements Context
|
|||
/**
|
||||
* @Then I should be notified that :element is required
|
||||
*/
|
||||
public function iShouldBeNotifiedThatIsRequired($element)
|
||||
public function iShouldBeNotifiedThatIsRequired($element): void
|
||||
{
|
||||
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
|
||||
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
|
||||
|
||||
Assert::same($currentPage->getValidationMessage($element), sprintf('Please enter tax category %s.', $element));
|
||||
Assert::same($this->formElement->getValidationMessage($element), sprintf('Please enter tax category %s.', $element));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then tax category with :element :name should not be added
|
||||
*/
|
||||
public function taxCategoryWithElementValueShouldNotBeAdded($element, $name)
|
||||
public function taxCategoryWithElementValueShouldNotBeAdded($element, $name): void
|
||||
{
|
||||
$this->indexPage->open();
|
||||
Assert::false($this->indexPage->isSingleResourceOnPage([$element => $name]));
|
||||
|
|
@ -206,14 +209,37 @@ final class ManagingTaxCategoriesContext implements Context
|
|||
|
||||
/**
|
||||
* @Then I should see a single tax category in the list
|
||||
* @Then I should see :amount tax categories in the list
|
||||
*/
|
||||
public function iShouldSeeTaxCategoriesInTheList(): void
|
||||
public function iShouldSeeTaxCategoriesInTheList(int $amount = 1): void
|
||||
{
|
||||
Assert::same($this->indexPage->countItems(), 1);
|
||||
Assert::same($this->indexPage->countItems(), $amount);
|
||||
}
|
||||
|
||||
protected function resolveCurrentPage(): SymfonyPageInterface
|
||||
/**
|
||||
* @Then I should see the tax category :taxCategoryName
|
||||
*/
|
||||
public function IShouldSeeTheTaxCategory(string $taxCategoryName): void
|
||||
{
|
||||
return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
|
||||
Assert::true($this->indexPage->isSingleResourceOnPage(['nameAndDescription' => $taxCategoryName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should not see the tax category :taxCategoryName
|
||||
*/
|
||||
public function IShouldNotSeeTheTaxCategory(string $taxCategoryName): void
|
||||
{
|
||||
Assert::false($this->indexPage->isSingleResourceOnPage(['nameAndDescription' => $taxCategoryName]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be notified that :field is too long
|
||||
*/
|
||||
public function iShouldBeNotifiedThatIsTooLong(string $field): void
|
||||
{
|
||||
Assert::contains(
|
||||
$this->formElement->getValidationMessage($field),
|
||||
'must not be longer than 255 characters.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ final class FormElement extends BaseFormElement implements FormElementInterface
|
|||
|
||||
$this->getElement('end_date_date')->setValue(date('Y-m-d', $timestamp));
|
||||
$this->getElement('end_date_time')->setValue(date('H:i', $timestamp));
|
||||
$this->waitForFormUpdate();
|
||||
}
|
||||
|
||||
public function addScope(string $type): void
|
||||
|
|
@ -210,6 +211,7 @@ final class FormElement extends BaseFormElement implements FormElementInterface
|
|||
'end_date_date' => '#sylius_admin_catalog_promotion_endDate_date',
|
||||
'end_date_time' => '#sylius_admin_catalog_promotion_endDate_time',
|
||||
'exclusive' => '#sylius_admin_catalog_promotion_exclusive',
|
||||
'form' => '[data-live-name-value="sylius_admin:catalog_promotion:form"]',
|
||||
'label' => '[name="sylius_admin_catalog_promotion[translations][%locale_code%][label]"]',
|
||||
'last_action' => '[data-test-actions] [data-test-entry-row]:last-child',
|
||||
'last_scope' => '[data-test-scopes] [data-test-entry-row]:last-child',
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ class FormElement extends Element implements FormElementInterface
|
|||
{
|
||||
private ?NodeElement $form = null;
|
||||
|
||||
public function fillElement(string $value, string $element, array $parameters = []): void
|
||||
{
|
||||
$foundElement = $this->getElement($element, $parameters);
|
||||
$foundElement->setValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $parameters
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ use Behat\Mink\Exception\ElementNotFoundException;
|
|||
|
||||
interface FormElementInterface
|
||||
{
|
||||
/**
|
||||
* @param array<string, string> $parameters
|
||||
*/
|
||||
public function fillElement(string $value, string $element, array $parameters = []): void;
|
||||
|
||||
/**
|
||||
* @param array<string, string> $parameters
|
||||
*/
|
||||
|
|
|
|||
64
src/Sylius/Behat/Element/Admin/Currency/FormElement.php
Normal file
64
src/Sylius/Behat/Element/Admin/Currency/FormElement.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Element\Admin\Currency;
|
||||
|
||||
use Behat\Mink\Session;
|
||||
use FriendsOfBehat\SymfonyExtension\Mink\MinkParameters;
|
||||
use Sylius\Behat\Element\Admin\Crud\FormElement as BaseFormElement;
|
||||
use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
|
||||
|
||||
final class FormElement extends BaseFormElement implements FormElementInterface
|
||||
{
|
||||
public function __construct(
|
||||
Session $session,
|
||||
array|MinkParameters $minkParameters,
|
||||
private readonly AutocompleteHelperInterface $autocompleteHelper,
|
||||
) {
|
||||
parent::__construct($session, $minkParameters);
|
||||
}
|
||||
|
||||
public function chooseCurrency(string $currencyName): void
|
||||
{
|
||||
$this->autocompleteHelper->selectByName(
|
||||
$this->getDriver(),
|
||||
$this->getElement('code')->getXpath(),
|
||||
$currencyName,
|
||||
);
|
||||
}
|
||||
|
||||
public function isCurrencyAvailable(string $currencyName): bool
|
||||
{
|
||||
$elements = $this->autocompleteHelper->search(
|
||||
$this->getDriver(),
|
||||
$this->getElement('code')->getXpath(),
|
||||
$currencyName,
|
||||
);
|
||||
|
||||
foreach ($elements as $element) {
|
||||
if ($element === $currencyName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '[data-test-code]',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Element\Admin\Currency;
|
||||
|
||||
interface FormElementInterface
|
||||
{
|
||||
public function chooseCurrency(string $currencyName): void;
|
||||
|
||||
public function isCurrencyAvailable(string $currencyName): bool;
|
||||
}
|
||||
48
src/Sylius/Behat/Element/Admin/TaxCategory/FormElement.php
Normal file
48
src/Sylius/Behat/Element/Admin/TaxCategory/FormElement.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Element\Admin\TaxCategory;
|
||||
|
||||
use Sylius\Behat\Element\Admin\Crud\FormElement as BaseFormElement;
|
||||
|
||||
final class FormElement extends BaseFormElement implements FormElementInterface
|
||||
{
|
||||
public function setCode(string $code): void
|
||||
{
|
||||
$this->getElement('code')->setValue($code);
|
||||
}
|
||||
|
||||
public function isCodeDisabled(): bool
|
||||
{
|
||||
return $this->getElement('code')->hasAttribute('disabled');
|
||||
}
|
||||
|
||||
public function setName(string $name): void
|
||||
{
|
||||
$this->getElement('name')->setValue($name);
|
||||
}
|
||||
|
||||
public function setDescription(string $description): void
|
||||
{
|
||||
$this->getElement('description')->setValue($description);
|
||||
}
|
||||
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '[data-test-code]',
|
||||
'description' => '[data-test-description]',
|
||||
'name' => '[data-test-name]',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Element\Admin\TaxCategory;
|
||||
|
||||
use Sylius\Behat\Element\Admin\Crud\FormElementInterface as BaseFormElementInterface;
|
||||
|
||||
interface FormElementInterface extends BaseFormElementInterface
|
||||
{
|
||||
public function setCode(string $code): void;
|
||||
|
||||
public function isCodeDisabled(): bool;
|
||||
|
||||
public function setName(string $name): void;
|
||||
|
||||
public function setDescription(string $description): void;
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\Currency;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Sylius\Behat\Behaviour\Toggles;
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
|
||||
|
||||
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
||||
{
|
||||
use Toggles;
|
||||
|
||||
public function canBeDisabled(): bool
|
||||
{
|
||||
$toggleableElement = $this->getToggleableElement();
|
||||
$this->assertCheckboxState($toggleableElement, true);
|
||||
|
||||
return $toggleableElement->hasAttribute('disabled');
|
||||
}
|
||||
|
||||
public function canHaveExchangeRateChanged(): bool
|
||||
{
|
||||
return $this->getElement('exchangeRate')->hasAttribute('disabled');
|
||||
}
|
||||
|
||||
public function changeExchangeRate(string $exchangeRate): void
|
||||
{
|
||||
$this->getDocument()->fillField('Exchange rate', $exchangeRate);
|
||||
}
|
||||
|
||||
public function getExchangeRateValue(): string
|
||||
{
|
||||
return $this->getElement('exchangeRate')->getValue();
|
||||
}
|
||||
|
||||
public function getCodeDisabledAttribute(): string
|
||||
{
|
||||
return $this->getElement('code')->getAttribute('disabled');
|
||||
}
|
||||
|
||||
protected function getToggleableElement(): NodeElement
|
||||
{
|
||||
return $this->getElement('enabled');
|
||||
}
|
||||
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '#sylius_admin_currency_code',
|
||||
'enabled' => '#sylius_admin_currency_enabled',
|
||||
'exchangeRate' => '#sylius_admin_currency_exchangeRate',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\Currency;
|
||||
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
|
||||
|
||||
interface UpdatePageInterface extends BaseUpdatePageInterface
|
||||
{
|
||||
public function enable(): void;
|
||||
|
||||
public function disable(): void;
|
||||
|
||||
public function canBeDisabled(): bool;
|
||||
|
||||
public function canHaveExchangeRateChanged(): bool;
|
||||
|
||||
public function changeExchangeRate(string $exchangeRate): void;
|
||||
|
||||
public function getExchangeRateValue(): string;
|
||||
|
||||
public function getCodeDisabledAttribute(): string;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\TaxCategory;
|
||||
|
||||
use Sylius\Behat\Behaviour\DescribesIt;
|
||||
use Sylius\Behat\Behaviour\NamesIt;
|
||||
use Sylius\Behat\Behaviour\SpecifiesItsField;
|
||||
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
|
||||
|
||||
class CreatePage extends BaseCreatePage implements CreatePageInterface
|
||||
{
|
||||
use SpecifiesItsField;
|
||||
use NamesIt;
|
||||
use DescribesIt;
|
||||
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '#sylius_admin_tax_category_code',
|
||||
'name' => '#sylius_admin_tax_category_name',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\TaxCategory;
|
||||
|
||||
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
|
||||
|
||||
interface CreatePageInterface extends BaseCreatePageInterface
|
||||
{
|
||||
public function specifyCode(string $code): void;
|
||||
|
||||
public function nameIt(string $name): void;
|
||||
|
||||
public function describeItAs(string $description): void;
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\TaxCategory;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
|
||||
use Sylius\Behat\Behaviour\NamesIt;
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
|
||||
|
||||
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
||||
{
|
||||
use ChecksCodeImmutability;
|
||||
use NamesIt;
|
||||
|
||||
protected function getCodeElement(): NodeElement
|
||||
{
|
||||
return $this->getElement('code');
|
||||
}
|
||||
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '#sylius_admin_tax_category_code',
|
||||
'description' => '#sylius_admin_tax_category_description',
|
||||
'name' => '#sylius_admin_tax_category_name',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\TaxCategory;
|
||||
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
|
||||
|
||||
interface UpdatePageInterface extends BaseUpdatePageInterface
|
||||
{
|
||||
public function isCodeDisabled(): bool;
|
||||
|
||||
public function nameIt(string $name): void;
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
<service id="sylius.behat.context.ui.admin.managing_currencies" class="Sylius\Behat\Context\Ui\Admin\ManagingCurrenciesContext">
|
||||
<argument type="service" id="sylius.behat.page.admin.currency.index" />
|
||||
<argument type="service" id="sylius.behat.page.admin.currency.create" />
|
||||
<argument type="service" id="sylius.behat.page.admin.currency.update" />
|
||||
<argument type="service" id="sylius.behat.element.admin.currency.form" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.behat.context.ui.admin.managing_customers" class="Sylius\Behat\Context\Ui\Admin\ManagingCustomersContext">
|
||||
|
|
@ -297,7 +297,7 @@
|
|||
<argument type="service" id="sylius.behat.page.admin.tax_category.index" />
|
||||
<argument type="service" id="sylius.behat.page.admin.tax_category.create" />
|
||||
<argument type="service" id="sylius.behat.page.admin.tax_category.update" />
|
||||
<argument type="service" id="sylius.behat.current_page_resolver" />
|
||||
<argument type="service" id="sylius.behat.element.admin.tax_category.form" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.behat.context.ui.admin.managing_translatable_entities" class="Sylius\Behat\Context\Ui\Admin\ManagingTranslatableEntitiesContext">
|
||||
|
|
|
|||
|
|
@ -115,5 +115,19 @@
|
|||
class="Sylius\Behat\Element\Admin\PromotionCoupon\FormElement"
|
||||
parent="sylius.behat.element.admin.crud.form"
|
||||
/>
|
||||
|
||||
<service
|
||||
id="sylius.behat.element.admin.tax_category.form"
|
||||
class="Sylius\Behat\Element\Admin\TaxCategory\FormElement"
|
||||
parent="sylius.behat.element.admin.crud.form"
|
||||
/>
|
||||
|
||||
<service
|
||||
id="sylius.behat.element.admin.currency.form"
|
||||
class="Sylius\Behat\Element\Admin\Currency\FormElement"
|
||||
parent="sylius.behat.element.admin.crud.form"
|
||||
>
|
||||
<argument type="service" id="Sylius\Behat\Service\Helper\AutocompleteHelperInterface" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@
|
|||
|
||||
<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.page.admin.currency.create.class">Sylius\Behat\Page\Admin\Currency\CreatePage</parameter>
|
||||
<parameter key="sylius.behat.page.admin.currency.create.class">%sylius.behat.page.admin.crud.create.class%</parameter>
|
||||
<parameter key="sylius.behat.page.admin.currency.index.class">Sylius\Behat\Page\Admin\Currency\IndexPage</parameter>
|
||||
<parameter key="sylius.behat.page.admin.currency.update.class">Sylius\Behat\Page\Admin\Currency\UpdatePage</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
|
|
@ -27,8 +26,5 @@
|
|||
<service id="sylius.behat.page.admin.currency.index" class="%sylius.behat.page.admin.currency.index.class%" parent="sylius.behat.page.admin.crud.index" public="false">
|
||||
<argument type="string">sylius_admin_currency_index</argument>
|
||||
</service>
|
||||
<service id="sylius.behat.page.admin.currency.update" class="%sylius.behat.page.admin.currency.update.class%" parent="sylius.behat.page.admin.crud.update" public="false">
|
||||
<argument type="string">sylius_admin_currency_update</argument>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
<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.page.admin.tax_category.create.class">Sylius\Behat\Page\Admin\TaxCategory\CreatePage</parameter>
|
||||
<parameter key="sylius.behat.page.admin.tax_category.create.class">%sylius.behat.page.admin.crud.create.class%</parameter>
|
||||
<parameter key="sylius.behat.page.admin.tax_category.index.class">%sylius.behat.page.admin.crud.index.class%</parameter>
|
||||
<parameter key="sylius.behat.page.admin.tax_category.update.class">Sylius\Behat\Page\Admin\TaxCategory\UpdatePage</parameter>
|
||||
<parameter key="sylius.behat.page.admin.tax_category.update.class">%sylius.behat.page.admin.crud.update.class%</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ default:
|
|||
|
||||
- sylius.behat.context.ui.admin.managing_payment_methods
|
||||
- sylius.behat.context.ui.admin.notification
|
||||
- sylius.behat.context.ui.admin.search_filter
|
||||
- sylius.behat.context.ui.shop.locale
|
||||
|
||||
filters:
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ default:
|
|||
|
||||
- sylius.behat.context.ui.admin.managing_tax_categories
|
||||
- sylius.behat.context.ui.admin.notification
|
||||
- sylius.behat.context.ui.admin.search_filter
|
||||
|
||||
filters:
|
||||
tags: "@managing_tax_categories&&@ui"
|
||||
|
|
|
|||
|
|
@ -14,10 +14,46 @@ declare(strict_types=1);
|
|||
namespace Sylius\Bundle\AdminBundle\Form\Type;
|
||||
|
||||
use Sylius\Bundle\CurrencyBundle\Form\Type\CurrencyType as BaseCurrencyType;
|
||||
use Sylius\Component\Currency\Model\CurrencyInterface;
|
||||
use Sylius\Component\Currency\Repository\CurrencyRepositoryInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CurrencyType as SymfonyCurrencyType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Intl\Currencies;
|
||||
|
||||
final class CurrencyType extends AbstractType
|
||||
{
|
||||
/** @param CurrencyRepositoryInterface<CurrencyInterface> $currencyRepository */
|
||||
public function __construct(private readonly CurrencyRepositoryInterface $currencyRepository)
|
||||
{
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void {
|
||||
$options = [
|
||||
'label' => 'sylius.form.currency.code',
|
||||
'choice_loader' => null,
|
||||
'autocomplete' => true,
|
||||
'placeholder' => 'sylius.form.currency.select',
|
||||
];
|
||||
|
||||
$currency = $event->getData();
|
||||
|
||||
if ($currency instanceof CurrencyInterface && null !== $currency->getCode()) {
|
||||
$options['disabled'] = true;
|
||||
$options['choices'] = [Currencies::getName($currency->getCode()) => $currency->getCode()];
|
||||
} else {
|
||||
$options['choices'] = array_flip($this->getAvailableCurrencies());
|
||||
}
|
||||
|
||||
$form = $event->getForm();
|
||||
$form->add('code', SymfonyCurrencyType::class, $options);
|
||||
});
|
||||
}
|
||||
|
||||
public function getBlockPrefix(): string
|
||||
{
|
||||
return 'sylius_admin_currency';
|
||||
|
|
@ -27,4 +63,21 @@ final class CurrencyType extends AbstractType
|
|||
{
|
||||
return BaseCurrencyType::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function getAvailableCurrencies(): array
|
||||
{
|
||||
$availableCurrencies = Currencies::getNames();
|
||||
|
||||
/** @var CurrencyInterface[] $definedCurrencies */
|
||||
$definedCurrencies = $this->currencyRepository->findAll();
|
||||
|
||||
foreach ($definedCurrencies as $currency) {
|
||||
unset($availableCurrencies[$currency->getCode()]);
|
||||
}
|
||||
|
||||
return $availableCurrencies;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\AdminBundle\Provider;
|
||||
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
final readonly class LoggedInAdminUserProvider implements LoggedInAdminUserProviderInterface
|
||||
{
|
||||
private const SECURITY_SESSION_KEY = '_security_admin';
|
||||
|
||||
/** @param UserRepositoryInterface<AdminUserInterface> $adminUserRepository */
|
||||
public function __construct(
|
||||
private Security $security,
|
||||
private TokenStorageInterface $tokenStorage,
|
||||
private RequestStack $requestStack,
|
||||
private UserRepositoryInterface $adminUserRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getUser(): ?AdminUserInterface
|
||||
{
|
||||
$user = $this->security->getUser();
|
||||
if ($user instanceof AdminUserInterface) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$user = $this->getUserFromTokenStorage();
|
||||
if (null !== $user) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
return $this->getUserFromSession();
|
||||
}
|
||||
|
||||
public function hasUser(): bool
|
||||
{
|
||||
return
|
||||
$this->security->getUser() instanceof AdminUserInterface ||
|
||||
null !== $this->getUserFromTokenStorage() ||
|
||||
null !== $this->getSerializedTokenFromSession()
|
||||
;
|
||||
}
|
||||
|
||||
private function getUserFromTokenStorage(): ?AdminUserInterface
|
||||
{
|
||||
$user = $this->tokenStorage->getToken()?->getUser();
|
||||
if ($user instanceof AdminUserInterface) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getUserFromSession(): ?AdminUserInterface
|
||||
{
|
||||
$serializedToken = $this->getSerializedTokenFromSession();
|
||||
if (null === $serializedToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$token = unserialize($serializedToken);
|
||||
if (!$token instanceof TokenInterface) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = $token->getUser();
|
||||
if (!$user instanceof AdminUserInterface) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->adminUserRepository->find($user->getId());
|
||||
}
|
||||
|
||||
private function getSerializedTokenFromSession(): ?string
|
||||
{
|
||||
try {
|
||||
$serializedToken = $this->requestStack->getMainRequest()?->getSession()->get(self::SECURITY_SESSION_KEY);
|
||||
if (null !== $serializedToken) {
|
||||
return $serializedToken;
|
||||
}
|
||||
|
||||
return $this->requestStack->getSession()->get(self::SECURITY_SESSION_KEY);
|
||||
} catch (SessionNotFoundException) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\AdminBundle\Provider;
|
||||
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
|
||||
interface LoggedInAdminUserProviderInterface
|
||||
{
|
||||
public function hasUser(): bool;
|
||||
|
||||
public function getUser(): ?AdminUserInterface;
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
import Modal from 'bootstrap/js/dist/modal';
|
||||
import { Modal } from 'bootstrap';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['modal', 'parent', 'csrfToken'];
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import './bootstrap';
|
|||
import './scripts/bulk-delete';
|
||||
import './scripts/check-all';
|
||||
import './scripts/choices';
|
||||
import './scripts/menu-search';
|
||||
import './scripts/statistics_chart';
|
||||
import './scripts/sticky-header';
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/* global document */
|
||||
|
||||
(function() {
|
||||
const menuSearchInput = document.querySelector('[data-menu-search]');
|
||||
const menuClearButton = document.querySelector('[data-menu-search-clear]');
|
||||
|
||||
const clearInput = () => {
|
||||
menuSearchInput.value = '';
|
||||
menuSearchInput.dispatchEvent(new Event('input'));
|
||||
};
|
||||
|
||||
if (menuSearchInput) {
|
||||
menuSearchInput.addEventListener('input', function(e) {
|
||||
const query = e.target.value.toLowerCase();
|
||||
const navItems = document.querySelectorAll('.sidebar .nav-item');
|
||||
|
||||
navItems.forEach(navItem => {
|
||||
const navLink = navItem.querySelector('.nav-link');
|
||||
const dropdownMenu = navItem.querySelector('.dropdown-menu');
|
||||
const dropdownItems = navItem.querySelectorAll('.dropdown-item');
|
||||
let matchFound = false;
|
||||
|
||||
dropdownItems.forEach(item => {
|
||||
const text = item.textContent.toLowerCase();
|
||||
if (query === '' || text.includes(query)) {
|
||||
item.style.display = '';
|
||||
matchFound = true;
|
||||
} else {
|
||||
item.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
if (matchFound || query === '') {
|
||||
navItem.style.display = '';
|
||||
} else {
|
||||
navItem.style.display = 'none';
|
||||
}
|
||||
|
||||
if (query !== '') {
|
||||
if (navLink) navLink.classList.add('d-flex');
|
||||
if (dropdownMenu) dropdownMenu.classList.add('d-flex');
|
||||
} else {
|
||||
if (navLink) navLink.classList.remove('d-flex');
|
||||
if (dropdownMenu) dropdownMenu.classList.remove('d-flex');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
menuSearchInput.addEventListener('keydown', function(event) {
|
||||
if (event.key === 'Escape') {
|
||||
clearInput();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (menuClearButton) {
|
||||
menuClearButton.addEventListener('click', function() {
|
||||
clearInput();
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
|
@ -47,3 +47,52 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-search {
|
||||
.btn,
|
||||
.form-control {
|
||||
border: 1px solid transparent;
|
||||
background: transparent;
|
||||
transition: opacity 0.1s;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding-left: 0.4rem;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
> * {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&:has(input[data-menu-search]:focus) {
|
||||
> * {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.btn,
|
||||
.form-control {
|
||||
border-color: var(--tblr-navbar-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
[data-menu-search-clear] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-menu-search-icon] {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
&:has(input[data-menu-search]:not(:placeholder-shown)) [data-menu-search-clear] {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
&:has(input[data-menu-search]:not(:placeholder-shown)) [data-menu-search-icon] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.admin_user.create.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/create/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.admin_user.update.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/update/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ twig_hooks:
|
|||
header:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/header.html.twig'
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/create/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: true
|
||||
footer:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ twig_hooks:
|
|||
header:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/header.html.twig'
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/update/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: true
|
||||
footer:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
twig_hooks:
|
||||
hooks:
|
||||
'sylius_admin.currency.create.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
'sylius_admin.currency.create.content.form':
|
||||
sections:
|
||||
template: '@SyliusAdmin/currency/form/sections.html.twig'
|
||||
|
||||
'sylius_admin.currency.create.content.form.sections':
|
||||
general:
|
||||
template: '@SyliusAdmin/currency/form/sections/general.html.twig'
|
||||
|
||||
'sylius_admin.currency.create.content.form.sections.general':
|
||||
code:
|
||||
template: '@SyliusAdmin/currency/form/sections/general/code.html.twig'
|
||||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.customer.create.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/create/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.customer.update.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/update/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
twig_hooks:
|
||||
hooks:
|
||||
'sylius_admin.customer_group.create.content':
|
||||
form:
|
||||
component: 'sylius_admin:customer_group:form'
|
||||
props:
|
||||
resource: '@=_context.resource'
|
||||
form: '@=_context.form'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
'sylius_admin.customer_group.create.content.form':
|
||||
sections:
|
||||
template: '@SyliusAdmin/customer_group/form/sections.html.twig'
|
||||
|
||||
'sylius_admin.customer_group.create.content.form.sections':
|
||||
details:
|
||||
template: '@SyliusAdmin/customer_group/form/sections/details.html.twig'
|
||||
|
||||
'sylius_admin.customer_group.create.content.form.sections.details':
|
||||
code:
|
||||
template: '@SyliusAdmin/customer_group/form/sections/details/code.html.twig'
|
||||
name:
|
||||
template: '@SyliusAdmin/customer_group/form/sections/details/name.html.twig'
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
twig_hooks:
|
||||
hooks:
|
||||
'sylius_admin.customer_group.update.content':
|
||||
form:
|
||||
component: 'sylius_admin:customer_group:form'
|
||||
props:
|
||||
resource: '@=_context.resource'
|
||||
form: '@=_context.form'
|
||||
configuration:
|
||||
render_rest: false
|
||||
method: 'PUT'
|
||||
|
||||
'sylius_admin.customer_group.update.content.form':
|
||||
sections:
|
||||
template: '@SyliusAdmin/customer_group/form/sections.html.twig'
|
||||
|
||||
'sylius_admin.customer_group.update.content.form.sections':
|
||||
details:
|
||||
template: '@SyliusAdmin/customer_group/form/sections/details.html.twig'
|
||||
|
||||
'sylius_admin.customer_group.update.content.form.sections.details':
|
||||
code:
|
||||
template: '@SyliusAdmin/customer_group/form/sections/details/code.html.twig'
|
||||
name:
|
||||
template: '@SyliusAdmin/customer_group/form/sections/details/name.html.twig'
|
||||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.product_association_type.create.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/create/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.product_association_type.update.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/update/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.product_review.update.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/update/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.promotion_coupon.create.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/create/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.promotion_coupon.update.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/update/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
twig_hooks:
|
||||
hooks:
|
||||
'sylius_admin.tax_category.create.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
'sylius_admin.tax_category.create.content.form':
|
||||
sections:
|
||||
template: '@SyliusAdmin/tax_category/form/sections.html.twig'
|
||||
|
||||
'sylius_admin.tax_category.create.content.form.sections':
|
||||
details:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details.html.twig'
|
||||
|
||||
'sylius_admin.tax_category.create.content.form.sections.details':
|
||||
name:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details/name.html.twig'
|
||||
code:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details/code.html.twig'
|
||||
description:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details/description.html.twig'
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
twig_hooks:
|
||||
hooks:
|
||||
'sylius_admin.tax_category.update.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
'sylius_admin.tax_category.update.content.form':
|
||||
sections:
|
||||
template: '@SyliusAdmin/tax_category/form/sections.html.twig'
|
||||
|
||||
'sylius_admin.tax_category.update.content.form.sections':
|
||||
details:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details.html.twig'
|
||||
|
||||
'sylius_admin.tax_category.update.content.form.sections.details':
|
||||
name:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details/name.html.twig'
|
||||
code:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details/code.html.twig'
|
||||
description:
|
||||
template: '@SyliusAdmin/tax_category/form/sections/details/description.html.twig'
|
||||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.tax_rate.create.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/create/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ twig_hooks:
|
|||
hooks:
|
||||
'sylius_admin.tax_rate.update.content':
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/update/content/form.html.twig'
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
render_rest: false
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ sylius_grid:
|
|||
label: sylius.ui.search
|
||||
options:
|
||||
fields: [code, translation.name]
|
||||
form_options:
|
||||
type: !php/const Sylius\Component\Grid\Filter\StringFilter::TYPE_CONTAINS
|
||||
enabled:
|
||||
type: boolean
|
||||
label: sylius.ui.enabled
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ sylius_grid:
|
|||
label: sylius.ui.search
|
||||
options:
|
||||
fields: [code, name]
|
||||
form_options:
|
||||
type: !php/const Sylius\Component\Grid\Filter\StringFilter::TYPE_CONTAINS
|
||||
actions:
|
||||
main:
|
||||
create:
|
||||
|
|
|
|||
|
|
@ -9,11 +9,4 @@ sylius_admin_tax_rate:
|
|||
form:
|
||||
type: Sylius\Bundle\AdminBundle\Form\Type\TaxRateType
|
||||
permission: true
|
||||
vars:
|
||||
all:
|
||||
subheader: sylius.ui.manage_taxation_of_your_products
|
||||
templates:
|
||||
form: "@SyliusAdmin/TaxRate/_form.html.twig"
|
||||
index:
|
||||
icon: money
|
||||
type: sylius.resource
|
||||
|
|
|
|||
|
|
@ -121,5 +121,13 @@
|
|||
<argument type="service" id="sylius.generator.taxon_slug" />
|
||||
</service>
|
||||
<service id="Sylius\Bundle\AdminBundle\Generator\TaxonSlugGeneratorInterface" alias="sylius_admin.generator.taxon_slug" />
|
||||
|
||||
<service id="sylius_admin.logged_in_admin_user_provider" class="Sylius\Bundle\AdminBundle\Provider\LoggedInAdminUserProvider">
|
||||
<argument type="service" id="security.helper" />
|
||||
<argument type="service" id="security.token_storage" />
|
||||
<argument type="service" id="request_stack" />
|
||||
<argument type="service" id="sylius.repository.admin_user" />
|
||||
</service>
|
||||
<service id="Sylius\Bundle\AdminBundle\Provider\LoggedInAdminUserProviderInterface" alias="sylius_admin.logged_in_admin_user_provider" />
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@
|
|||
</service>
|
||||
|
||||
<service id="sylius_admin.form.type.currency" class="Sylius\Bundle\AdminBundle\Form\Type\CurrencyType" >
|
||||
<argument type="service" id="sylius.repository.currency" />
|
||||
<tag name="form.type" />
|
||||
</service>
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,20 @@
|
|||
/>
|
||||
</service>
|
||||
|
||||
<service
|
||||
id="sylius_admin.twig.component.customer_group.form"
|
||||
class="Sylius\Bundle\AdminBundle\Twig\Component\CustomerGroup\FormComponent"
|
||||
>
|
||||
<argument type="service" id="form.factory" />
|
||||
<argument>Sylius\Bundle\AdminBundle\Form\Type\CustomerGroupType</argument>
|
||||
|
||||
<tag
|
||||
name="sylius.live_component"
|
||||
key="sylius_admin:customer_group:form"
|
||||
template="@SyliusAdmin/shared/crud/common/content/form.html.twig"
|
||||
/>
|
||||
</service>
|
||||
|
||||
<service
|
||||
id="sylius_admin.twig.component.product_option.form"
|
||||
class="Sylius\Bundle\AdminBundle\Twig\Component\ProductOption\FormComponent"
|
||||
|
|
@ -295,7 +309,7 @@
|
|||
>
|
||||
<argument type="service" id="router" />
|
||||
<argument type="service" id="translator" />
|
||||
<argument type="service" id="security.helper" />
|
||||
<argument type="service" id="sylius_admin.logged_in_admin_user_provider" />
|
||||
|
||||
<tag
|
||||
name="twig.component"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<services>
|
||||
<service id="sylius_admin.twig.error_template_finder" class="Sylius\Bundle\AdminBundle\Twig\ErrorTemplateFinder\ErrorTemplateFinder">
|
||||
<argument type="service" id="Sylius\Bundle\CoreBundle\SectionResolver\SectionProviderInterface" />
|
||||
<argument type="service" id="security.token_storage" />
|
||||
<argument type="service" id="sylius_admin.logged_in_admin_user_provider" />
|
||||
<argument type="service" id="twig" />
|
||||
<tag name="sylius.twig.error_template_finder" />
|
||||
</service>
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ sylius:
|
|||
product_not_active_in_channel: The product is not yet activated in this channel.
|
||||
product_variant: Product variant
|
||||
sales_summary: Sales summary
|
||||
search_menu: 'Search menu'
|
||||
shipment_for_order: Shipment for order
|
||||
show_history_for_channel_pricing: 'Show history for channel pricing'
|
||||
start_typing_to_search: 'Start typing to search'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\AdminBundle\Twig\Component\CustomerGroup;
|
||||
|
||||
use Sylius\Component\Customer\Model\CustomerGroup;
|
||||
use Sylius\TwigHooks\LiveComponent\HookableLiveComponentTrait;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
||||
use Symfony\UX\LiveComponent\Attribute\LiveProp;
|
||||
use Symfony\UX\LiveComponent\ComponentWithFormTrait;
|
||||
use Symfony\UX\LiveComponent\DefaultActionTrait;
|
||||
|
||||
#[AsLiveComponent]
|
||||
class FormComponent
|
||||
{
|
||||
use ComponentWithFormTrait;
|
||||
use DefaultActionTrait;
|
||||
use HookableLiveComponentTrait;
|
||||
|
||||
#[LiveProp(fieldName: 'formData')]
|
||||
public ?CustomerGroup $customerGroup = null;
|
||||
|
||||
/** @param class-string $formClass */
|
||||
public function __construct(
|
||||
private readonly FormFactoryInterface $formFactory,
|
||||
private readonly string $formClass,
|
||||
) {
|
||||
}
|
||||
|
||||
protected function instantiateForm(): FormInterface
|
||||
{
|
||||
return $this->formFactory->create($this->formClass, $this->customerGroup);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,9 +13,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\AdminBundle\Twig\Component\Shared\Navbar;
|
||||
|
||||
use Sylius\Component\User\Model\UserInterface;
|
||||
use Sylius\Bundle\AdminBundle\Provider\LoggedInAdminUserProviderInterface;
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;
|
||||
|
||||
|
|
@ -24,35 +24,28 @@ class UserDropdownComponent
|
|||
public function __construct(
|
||||
private UrlGeneratorInterface $urlGenerator,
|
||||
private TranslatorInterface $translator,
|
||||
private Security $security,
|
||||
private LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
) {
|
||||
}
|
||||
|
||||
#[ExposeInTemplate(name: 'user')]
|
||||
public function getUser(): UserInterface
|
||||
public function getUser(): AdminUserInterface
|
||||
{
|
||||
$user = $this->security->getUser();
|
||||
|
||||
if (!$user instanceof UserInterface) {
|
||||
throw new \RuntimeException('User must be an instance of Sylius\Component\User\Model\UserInterface');
|
||||
$user = $this->loggedInAdminUserProvider->getUser();
|
||||
if (!$user instanceof AdminUserInterface) {
|
||||
throw new \RuntimeException('User must be an instance of ' . AdminUserInterface::class . '.');
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<string, array{title?: string, url?: string, icon?: string, type?: string, class?: string}>>
|
||||
*
|
||||
* @psalm-suppress InvalidReturnType
|
||||
* @return array<array-key, array<array-key, array{title?: string, url?: string, icon?: string, type?: string, class?: string, attr?: array<string, mixed>}>>
|
||||
*/
|
||||
#[ExposeInTemplate(name: 'menu_items')]
|
||||
public function getMenuItems(): array
|
||||
{
|
||||
/**
|
||||
* @phpstan-ignore-next-line PHPStan complains the declared return type does not match the returned value
|
||||
*
|
||||
* @psalm-suppress InvalidReturnStatement
|
||||
*/
|
||||
// TODO: Would be nice to have these set via hook //
|
||||
return [
|
||||
[
|
||||
'title' => $this->translator->trans('sylius.ui.my_account'),
|
||||
|
|
|
|||
|
|
@ -13,18 +13,17 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\AdminBundle\Twig\ErrorTemplateFinder;
|
||||
|
||||
use Sylius\Bundle\AdminBundle\Provider\LoggedInAdminUserProviderInterface;
|
||||
use Sylius\Bundle\AdminBundle\SectionResolver\AdminSection;
|
||||
use Sylius\Bundle\CoreBundle\SectionResolver\SectionProviderInterface;
|
||||
use Sylius\Bundle\UiBundle\Twig\ErrorTemplateFinder\ErrorTemplateFinderInterface;
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
final readonly class ErrorTemplateFinder implements ErrorTemplateFinderInterface
|
||||
{
|
||||
public function __construct(
|
||||
private SectionProviderInterface $sectionProvider,
|
||||
private TokenStorageInterface $tokenStorage,
|
||||
private LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
private Environment $twig,
|
||||
) {
|
||||
}
|
||||
|
|
@ -33,7 +32,7 @@ final readonly class ErrorTemplateFinder implements ErrorTemplateFinderInterface
|
|||
{
|
||||
$section = $this->sectionProvider->getSection();
|
||||
|
||||
if ($section instanceof AdminSection && $this->isLoggedInAdmin()) {
|
||||
if ($section instanceof AdminSection && $this->loggedInAdminUserProvider->hasUser()) {
|
||||
$template = sprintf('@SyliusAdmin/errors/error%s.html.twig', $statusCode);
|
||||
if ($this->twig->getLoader()->exists($template)) {
|
||||
return $template;
|
||||
|
|
@ -47,9 +46,4 @@ final readonly class ErrorTemplateFinder implements ErrorTemplateFinderInterface
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function isLoggedInAdmin(): bool
|
||||
{
|
||||
return $this->tokenStorage->getToken()?->getUser() instanceof AdminUserInterface;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,272 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace spec\Sylius\Bundle\AdminBundle\Provider;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use Sylius\Bundle\AdminBundle\Provider\LoggedInAdminUserProviderInterface;
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
final class LoggedInAdminUserProviderSpec extends ObjectBehavior
|
||||
{
|
||||
private const SECURITY_SESSION_KEY = '_security_admin';
|
||||
private const SERIALIZED_TOKEN = 'O:74:"Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken":3:{i:0;N;i:1;s:5:"admin";i:2;a:5:{i:0;O:37:"Sylius\Component\Core\Model\AdminUser":8:{i:0;s:38:"sylius{x33enl1y0askgkgw8k0skocc4ko0kg}";i:1;s:30:"x33enl1y0askgkgw8k0skocc4ko0kg";i:2;s:6:"sylius";i:3;s:6:"sylius";i:4;b:0;i:5;b:1;i:6;i:404;i:7;s:9:"plaintext";}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:1:{i:0;s:26:"ROLE_ADMINISTRATION_ACCESS";}}}';
|
||||
|
||||
function let(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
UserRepositoryInterface $adminUserRepository,
|
||||
) {
|
||||
$this->beConstructedWith($security, $tokenStorage, $requestStack, $adminUserRepository);
|
||||
}
|
||||
|
||||
function it_implements_logged_in_admin_user_provider(): void
|
||||
{
|
||||
$this->shouldImplement(LoggedInAdminUserProviderInterface::class);
|
||||
}
|
||||
|
||||
function it_returns_true_when_user_is_in_security(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn($adminUser);
|
||||
|
||||
$tokenStorage->getToken()->shouldNotBeCalled();
|
||||
$requestStack->getMainRequest()->shouldNotBeCalled();
|
||||
$requestStack->getSession()->shouldNotBeCalled();
|
||||
|
||||
$this->hasUser()->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_returns_true_when_user_is_in_token_storage(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$tokenStorage->getToken()->willReturn($token);
|
||||
|
||||
$requestStack->getMainRequest()->shouldNotBeCalled();
|
||||
$requestStack->getSession()->shouldNotBeCalled();
|
||||
|
||||
$this->hasUser()->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_returns_true_when_user_is_in_main_request_session_token(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
Request $request,
|
||||
Session $session,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$session->get(self::SECURITY_SESSION_KEY)->willReturn('serialized_token');
|
||||
$request->getSession()->willReturn($session);
|
||||
|
||||
$requestStack->getMainRequest()->willReturn($request);
|
||||
$requestStack->getSession()->shouldNotBeCalled();
|
||||
|
||||
$this->hasUser()->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_returns_true_when_user_is_in_current_request_session_token(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
Session $session,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$session->get(self::SECURITY_SESSION_KEY)->willReturn('serialized_token');
|
||||
|
||||
$requestStack->getMainRequest()->willReturn(null);
|
||||
$requestStack->getSession()->willReturn($session);
|
||||
|
||||
$this->hasUser()->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_returns_false_when_there_is_no_user(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
Session $session,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
|
||||
$requestStack->getMainRequest()->willReturn(null);
|
||||
|
||||
$session->get(self::SECURITY_SESSION_KEY)->willReturn(null);
|
||||
$requestStack->getSession()->willReturn($session);
|
||||
|
||||
$this->hasUser()->shouldReturn(false);
|
||||
}
|
||||
|
||||
function it_returns_false_when_user_cannot_be_provided_and_session_is_not_available_in_current_request(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
|
||||
$requestStack->getMainRequest()->willReturn(null);
|
||||
$requestStack->getSession()->willThrow(SessionNotFoundException::class);
|
||||
|
||||
$this->hasUser()->shouldReturn(false);
|
||||
}
|
||||
|
||||
function it_returns_false_when_user_cannot_be_provided_and_session_is_not_available_in_main_request(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
Request $request,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
|
||||
$requestStack->getMainRequest()->willReturn($request);
|
||||
$request->getSession()->willThrow(SessionNotFoundException::class);
|
||||
|
||||
$this->hasUser()->shouldReturn(false);
|
||||
}
|
||||
|
||||
function it_gets_user_from_security(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
UserRepositoryInterface $adminUserRepository,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn($adminUser);
|
||||
|
||||
$tokenStorage->getToken()->shouldNotBeCalled();
|
||||
$requestStack->getMainRequest()->shouldNotBeCalled();
|
||||
$requestStack->getSession()->shouldNotBeCalled();
|
||||
$adminUserRepository->find(Argument::any())->shouldNotBeCalled();
|
||||
|
||||
$this->getUser()->shouldReturn($adminUser);
|
||||
}
|
||||
|
||||
function it_gets_user_from_token_storage(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
UserRepositoryInterface $adminUserRepository,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$tokenStorage->getToken()->willReturn($token);
|
||||
|
||||
$requestStack->getMainRequest()->shouldNotBeCalled();
|
||||
$requestStack->getSession()->shouldNotBeCalled();
|
||||
$adminUserRepository->find(Argument::any())->shouldNotBeCalled();
|
||||
|
||||
$this->getUser()->shouldReturn($adminUser);
|
||||
}
|
||||
|
||||
function it_gets_user_from_main_request_session(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
UserRepositoryInterface $adminUserRepository,
|
||||
Request $request,
|
||||
Session $session,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$session->get(self::SECURITY_SESSION_KEY)->willReturn(self::SERIALIZED_TOKEN);
|
||||
$request->getSession()->willReturn($session);
|
||||
$requestStack->getMainRequest()->willReturn($request);
|
||||
|
||||
$adminUser->getId()->willReturn(404);
|
||||
$adminUserRepository->find(404)->willReturn($adminUser);
|
||||
|
||||
$requestStack->getSession()->shouldNotBeCalled();
|
||||
|
||||
$this->getUser()->shouldReturn($adminUser);
|
||||
}
|
||||
|
||||
function it_gets_user_from_current_request_session(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
UserRepositoryInterface $adminUserRepository,
|
||||
Request $request,
|
||||
Session $session,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
$requestStack->getMainRequest()->willReturn(null);
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$session->get(self::SECURITY_SESSION_KEY)->willReturn(self::SERIALIZED_TOKEN);
|
||||
$request->getSession()->willReturn($session);
|
||||
$requestStack->getSession()->willReturn($session);
|
||||
|
||||
$adminUser->getId()->willReturn(404);
|
||||
$adminUserRepository->find(404)->willReturn($adminUser);
|
||||
|
||||
$this->getUser()->shouldReturn($adminUser);
|
||||
}
|
||||
|
||||
function it_returns_null_when_user_cannot_be_provided(
|
||||
Security $security,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
RequestStack $requestStack,
|
||||
UserRepositoryInterface $adminUserRepository,
|
||||
): void {
|
||||
$security->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
$requestStack->getMainRequest()->willReturn(null);
|
||||
$requestStack->getSession()->willThrow(SessionNotFoundException::class);
|
||||
|
||||
$adminUserRepository->find(Argument::any())->shouldNotBeCalled();
|
||||
|
||||
$this->getUser()->shouldReturn(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,17 +14,11 @@ declare(strict_types=1);
|
|||
namespace spec\Sylius\Bundle\AdminBundle\Twig\ErrorTemplateFinder;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Bundle\AdminBundle\Provider\LoggedInAdminUserProviderInterface;
|
||||
use Sylius\Bundle\AdminBundle\SectionResolver\AdminSection;
|
||||
use Sylius\Bundle\CoreBundle\SectionResolver\SectionInterface;
|
||||
use Sylius\Bundle\CoreBundle\SectionResolver\SectionProviderInterface;
|
||||
use Sylius\Bundle\UiBundle\Twig\ErrorTemplateFinder\ErrorTemplateFinderInterface;
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\LoaderInterface;
|
||||
|
||||
|
|
@ -32,9 +26,12 @@ final class ErrorTemplateFinderSpec extends ObjectBehavior
|
|||
{
|
||||
private const TEMPLATE_PREFIX = '@SyliusAdmin/errors';
|
||||
|
||||
function let(SectionProviderInterface $sectionProvider, TokenStorageInterface $tokenStorage, Environment $twig): void
|
||||
{
|
||||
$this->beConstructedWith($sectionProvider, $tokenStorage, $twig);
|
||||
function let(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
Environment $twig,
|
||||
): void {
|
||||
$this->beConstructedWith($sectionProvider, $loggedInAdminUserProvider, $twig);
|
||||
}
|
||||
|
||||
function it_implements_error_template_finder_interface(): void
|
||||
|
|
@ -44,58 +41,26 @@ final class ErrorTemplateFinderSpec extends ObjectBehavior
|
|||
|
||||
function it_does_not_find_template_for_other_sections_than_admin(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
Environment $twig,
|
||||
SectionInterface $section,
|
||||
): void {
|
||||
$sectionProvider->getSection()->willReturn($section);
|
||||
|
||||
$tokenStorage->getToken()->shouldNotBeCalled();
|
||||
$loggedInAdminUserProvider->hasUser()->shouldNotBeCalled();
|
||||
$twig->getLoader()->shouldNotBeCalled();
|
||||
|
||||
$this->findTemplate(404)->shouldReturn(null);
|
||||
}
|
||||
|
||||
function it_does_not_find_template_when_there_is_no_token_in_admin_section(
|
||||
function it_does_not_find_template_when_there_is_no_admin_user(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
Environment $twig,
|
||||
): void {
|
||||
$sectionProvider->getSection()->willReturn(new AdminSection());
|
||||
$tokenStorage->getToken()->willReturn(null);
|
||||
|
||||
$twig->getLoader()->shouldNotBeCalled();
|
||||
|
||||
$this->findTemplate(404)->shouldReturn(null);
|
||||
}
|
||||
|
||||
function it_does_not_find_template_when_there_is_no_token_user_in_admin_section(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
Environment $twig,
|
||||
TokenInterface $token,
|
||||
): void {
|
||||
$sectionProvider->getSection()->willReturn(new AdminSection());
|
||||
|
||||
$token->getUser()->willReturn(null);
|
||||
$tokenStorage->getToken()->willReturn($token);
|
||||
|
||||
$twig->getLoader()->shouldNotBeCalled();
|
||||
|
||||
$this->findTemplate(404)->shouldReturn(null);
|
||||
}
|
||||
|
||||
function it_does_not_find_template_when_the_token_user_is_not_an_admin_in_admin_section(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
Environment $twig,
|
||||
TokenInterface $token,
|
||||
UserInterface $user,
|
||||
): void {
|
||||
$sectionProvider->getSection()->willReturn(new AdminSection());
|
||||
|
||||
$token->getUser()->willReturn($user);
|
||||
$tokenStorage->getToken()->willReturn($token);
|
||||
$loggedInAdminUserProvider->hasUser()->willReturn(false);
|
||||
|
||||
$twig->getLoader()->shouldNotBeCalled();
|
||||
|
||||
|
|
@ -104,18 +69,14 @@ final class ErrorTemplateFinderSpec extends ObjectBehavior
|
|||
|
||||
function it_finds_template_for_admin(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
Environment $twig,
|
||||
LoaderInterface $loader,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$templateName = self::TEMPLATE_PREFIX . '/error404.html.twig';
|
||||
|
||||
$sectionProvider->getSection()->willReturn(new AdminSection());
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$tokenStorage->getToken()->willReturn($token);
|
||||
$loggedInAdminUserProvider->hasUser()->willReturn(true);
|
||||
|
||||
$twig->getLoader()->willReturn($loader);
|
||||
$loader->exists($templateName)->shouldBeCalled()->willReturn(true);
|
||||
|
|
@ -125,19 +86,15 @@ final class ErrorTemplateFinderSpec extends ObjectBehavior
|
|||
|
||||
function it_returns_null_if_neither_template_can_be_found(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
Environment $twig,
|
||||
LoaderInterface $loader,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$templateName = self::TEMPLATE_PREFIX . '/error404.html.twig';
|
||||
$fallbackTemplateName = self::TEMPLATE_PREFIX . '/error.html.twig';
|
||||
|
||||
$sectionProvider->getSection()->willReturn(new AdminSection());
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$tokenStorage->getToken()->willReturn($token);
|
||||
$loggedInAdminUserProvider->hasUser()->willReturn(true);
|
||||
|
||||
$twig->getLoader()->willReturn($loader);
|
||||
$loader->exists($templateName)->shouldBeCalled()->willReturn(false);
|
||||
|
|
@ -148,19 +105,15 @@ final class ErrorTemplateFinderSpec extends ObjectBehavior
|
|||
|
||||
function it_finds_fallback_template_for_admin(
|
||||
SectionProviderInterface $sectionProvider,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
LoggedInAdminUserProviderInterface $loggedInAdminUserProvider,
|
||||
Environment $twig,
|
||||
LoaderInterface $loader,
|
||||
TokenInterface $token,
|
||||
AdminUserInterface $adminUser,
|
||||
): void {
|
||||
$templateName = self::TEMPLATE_PREFIX . '/error404.html.twig';
|
||||
$fallbackTemplateName = self::TEMPLATE_PREFIX . '/error.html.twig';
|
||||
|
||||
$sectionProvider->getSection()->willReturn(new AdminSection());
|
||||
|
||||
$token->getUser()->willReturn($adminUser);
|
||||
$tokenStorage->getToken()->willReturn($token);
|
||||
$loggedInAdminUserProvider->hasUser()->willReturn(true);
|
||||
|
||||
$twig->getLoader()->willReturn($loader);
|
||||
$loader->exists($templateName)->shouldBeCalled()->willReturn(false);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
<div class="row">
|
||||
{% hook 'sections' %}
|
||||
</div>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<div class="col-12 p-2">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
{{ 'sylius.ui.general'|trans }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center">
|
||||
{% hook 'general' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<div class="mb-3">
|
||||
{{ form_row(hookable_metadata.context.form.code, sylius_test_form_attribute('code')) }}
|
||||
</div>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<div class="row">
|
||||
{% hook 'sections' %}
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue