diff --git a/features/admin/promotion/managing_promotions/adding_promotion.feature b/features/admin/promotion/managing_promotions/adding_promotion.feature
index a96941ac760..cc1a9b96e27 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion.feature
@@ -8,7 +8,7 @@ Feature: Adding a new promotion
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @todo @ui
+ @api @ui
Scenario: Adding a new promotion
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -17,7 +17,7 @@ Feature: Adding a new promotion
Then I should be notified that it has been successfully created
And the "Full metal promotion" promotion should appear in the registry
- @api @todo @ui
+ @api @ui
Scenario: Adding a new promotion with usage limit
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -27,7 +27,7 @@ Feature: Adding a new promotion
Then I should be notified that it has been successfully created
And the "Full metal promotion" promotion should be available to be used only 50 times
- @api @todo @ui
+ @api @ui
Scenario: Adding a new exclusive promotion
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -37,7 +37,7 @@ Feature: Adding a new promotion
Then I should be notified that it has been successfully created
And the "Full metal promotion" promotion should be exclusive
- @api @todo @ui
+ @api @ui
Scenario: Adding a new coupon based promotion
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -47,7 +47,7 @@ Feature: Adding a new promotion
Then I should be notified that it has been successfully created
And the "Full metal promotion" promotion should be coupon based
- @api @todo @ui
+ @api @ui
Scenario: Adding a new channels promotion
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -57,7 +57,7 @@ Feature: Adding a new promotion
Then I should be notified that it has been successfully created
And the "Full metal promotion" promotion should be applicable for the "United States" channel
- @api @todo @ui
+ @api @ui
Scenario: Adding a promotion with start and end date
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -66,7 +66,7 @@ Feature: Adding a new promotion
And I add it
Then I should be notified that it has been successfully created
- @api @todo @ui
+ @api @ui
Scenario: Adding a promotion not applies to discounted by catalog promotion items
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -75,3 +75,11 @@ Feature: Adding a new promotion
And I add it
Then I should be notified that it has been successfully created
And the "Full metal promotion" promotion should not applies to discounted items
+
+ @ui @javascript @no-api
+ Scenario: Seeing rule and action configuration forms
+ When I want to create a new promotion
+ And I add a new rule
+ And I add a new action
+ Then I should see the rule configuration form
+ And I should see the action configuration form
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature b/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature
index 341ee1305f9..12bcaed0682 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature
@@ -9,7 +9,7 @@ Feature: Adding promotion in different languages
And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales
And I am logged in as an administrator
- @api @todo @ui @javascript
+ @api @ui
Scenario: Adding a promotion with a label in a different language
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature
index 576b564e378..9aed8f50609 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature
@@ -8,7 +8,7 @@ Feature: Adding a new promotion with action
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a new promotion with fixed discount
When I want to create a new promotion
And I specify its code as "10_for_all_products"
@@ -18,7 +18,7 @@ Feature: Adding a new promotion with action
Then I should be notified that it has been successfully created
And the "$10.00 for all products!" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a promotion with item percentage discount
When I want to create a new promotion
And I specify its code as "promotion_for_all_product_items"
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature
index 4574ee79767..3620dcd099d 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature
@@ -9,7 +9,7 @@ Feature: Adding a new promotion with action configured in different channels
And the store also operates on another channel named "Web-GB" in "GBP" currency
And I am logged in as an administrator
- @todo @ui @mink:chromedriver @api
+ @ui @mink:chromedriver @api
Scenario: Adding a new promotion with item fixed discount
When I want to create a new promotion
And I specify its code as "20_for_all_products"
@@ -17,5 +17,4 @@ Feature: Adding a new promotion with action configured in different channels
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
And it is also configured with amount of "£16.00" for "Web-GB" channel
And I add it
- Then I should be notified that it has been successfully created
- And the "Item fixed discount for all products!" promotion should appear in the registry
+ Then the "Item fixed discount for all products!" promotion should be successfully created
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature
index 8ab12d48539..cce21ace28d 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature
@@ -8,7 +8,7 @@ Feature: Adding promotion with filter
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @todo @ui @mink:chromedriver
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with item fixed discount only for products over 10
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -16,10 +16,9 @@ Feature: Adding promotion with filter
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
And I specify that on "United States" channel this action should be applied to items with price greater than "$10.00"
And I add it
- Then I should be notified that it has been successfully created
- And the "$10 discount for all products over $10!" promotion should appear in the registry
+ Then the "$10 discount for all products over $10!" promotion should be successfully created
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a promotion with item fixed discount only for products between 10 and 100
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -30,31 +29,31 @@ Feature: Adding promotion with filter
Then I should be notified that it has been successfully created
And the "$10 discount for (almost) all products!" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with fixed discount for all t-shirts
Given the store classifies its products as "T-Shirts" and "Mugs"
When I want to create a new promotion
And I specify its code as "10_for_all_t_shirts"
And I name it "$10 discount for all T-Shirts!"
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
- And I specify that this action should be applied to items from "T-Shirts" category
+ And I specify that this action should be applied to items from "T-Shirts" category for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "$10 discount for all T-Shirts!" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with fixed discount for PHP T-Shirt
Given the store has a product "PHP T-Shirt" priced at "$100.00"
When I want to create a new promotion
And I specify its code as "10_for_php_t_shirt"
And I name it "$10 discount for PHP T-Shirts!"
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
- And I specify that this action should be applied to the "PHP T-Shirt" product
+ And I specify that this action should be applied to the "PHP T-Shirt" product for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "$10 discount for PHP T-Shirts!" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a promotion with item percentage discount only for products over 10
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -65,7 +64,7 @@ Feature: Adding promotion with filter
Then I should be notified that it has been successfully created
And the "$10 discount for all products over $10!" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a promotion with item percentage discount only for products between 10 and 100
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -76,26 +75,26 @@ Feature: Adding promotion with filter
Then I should be notified that it has been successfully created
And the "$10 discount for (almost) all products!" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with 10% percentage discount for all t-shirts
Given the store classifies its products as "T-Shirts" and "Mugs"
When I want to create a new promotion
And I specify its code as "10_for_all_t_shirts"
And I name it "$10 discount for all T-Shirts!"
And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel
- And I specify that this action should be applied to items from "T-Shirts" category
+ And I specify that this action should be applied to items from "T-Shirts" category for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "$10 discount for all T-Shirts!" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with 10% percentage discount for PHP T-Shirt
Given the store has a product "PHP T-Shirt" priced at "$100.00"
When I want to create a new promotion
And I specify its code as "10_for_php_t_shirt"
And I name it "10% discount for PHP T-Shirts!"
And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel
- And I specify that this action should be applied to the "PHP T-Shirt" product
+ And I specify that this action should be applied to the "PHP T-Shirt" product for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "10% discount for PHP T-Shirts!" promotion should appear in the registry
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature
index 5582400607f..74127af5b0e 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature
@@ -9,7 +9,7 @@ Feature: Adding a new promotion with rule
And the store classifies its products as "T-Shirts" and "Mugs"
And I am logged in as an administrator
- @api @todo @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with taxon rule
When I want to create a new promotion
And I specify its code as "HOLIDAY_SALE"
@@ -19,7 +19,7 @@ Feature: Adding a new promotion with rule
Then I should be notified that it has been successfully created
And the "Holiday sale" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with total price of items from taxon rule
When I want to create a new promotion
And I specify its code as "100_MUGS_PROMOTION"
@@ -29,7 +29,7 @@ Feature: Adding a new promotion with rule
Then I should be notified that it has been successfully created
And the "100 Mugs promotion" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with contains product rule
Given the store has a product "PHP T-Shirt" priced at "$100.00"
When I want to create a new promotion
@@ -40,7 +40,7 @@ Feature: Adding a new promotion with rule
Then I should be notified that it has been successfully created
And the "PHP T-Shirt promotion" promotion should appear in the registry
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a new group based promotion
Given the store has a customer group "Wholesale"
When I want to create a new promotion
@@ -50,11 +50,3 @@ Feature: Adding a new promotion with rule
And I add it
Then I should be notified that it has been successfully created
And the "Wholesale promotion" promotion should appear in the registry
-
- @todo @ui @javascript @no-api
- Scenario: Adding a new promotion of default type with one action
- When I want to create a new promotion
- And I add a new rule
- And I add a new action
- Then I should see the rule configuration form
- And I should see the action configuration form
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature
index ea880f49a1f..35be86e7e17 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature
@@ -9,12 +9,11 @@ Feature: Adding a new promotion with rule configured in different channels
And the store operates on a channel named "Web-GB" in "GBP" currency
And I am logged in as an administrator
- @todo @api @ui @mink:chromedriver
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with total price of items from taxon rule
When I want to create a new promotion
And I specify its code as "100_IN_EVERY_CURRENCY"
And I name it "100 in every currency"
And I add the "Item total" rule configured with "€100.00" amount for "United States" channel and "£100.00" amount for "Web-GB" channel
And I add it
- Then I should be notified that it has been successfully created
- And the "100 in every currency" promotion should appear in the registry
+ Then the "100 in every currency" promotion should be successfully created
diff --git a/features/admin/promotion/managing_promotions/deleting_promotion.feature b/features/admin/promotion/managing_promotions/deleting_promotion.feature
index 27374d22385..b032fde706f 100644
--- a/features/admin/promotion/managing_promotions/deleting_promotion.feature
+++ b/features/admin/promotion/managing_promotions/deleting_promotion.feature
@@ -9,7 +9,7 @@ Feature: Deleting a promotion
And there is a promotion "Christmas sale"
And I am logged in as an administrator
- @api @todo @ui
+ @api @ui
Scenario: Deleted promotion should disappear from the registry
When I delete a "Christmas sale" promotion
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/promotion/managing_promotions/editing_promotion.feature b/features/admin/promotion/managing_promotions/editing_promotion.feature
index 09198dbfd14..965214a267f 100644
--- a/features/admin/promotion/managing_promotions/editing_promotion.feature
+++ b/features/admin/promotion/managing_promotions/editing_promotion.feature
@@ -10,12 +10,12 @@ Feature: Editing promotion
And there is a promotion "Holiday sale" with priority 1
And I am logged in as an administrator
- @api @todo @ui
+ @api @ui
Scenario: Being unable to change code of promotion
When I want to modify a "Christmas sale" promotion
Then I should not be able to edit its code
- @api @todo @ui
+ @api @ui
Scenario: Editing promotions usage limit
When I want to modify a "Christmas sale" promotion
And I set its usage limit to 50
@@ -23,7 +23,7 @@ Feature: Editing promotion
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should be available to be used only 50 times
- @api @todo @ui
+ @api @ui
Scenario: Editing promotion exclusiveness
When I want to modify a "Christmas sale" promotion
And I set it as exclusive
@@ -31,7 +31,7 @@ Feature: Editing promotion
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should be exclusive
- @api @todo @ui
+ @api @ui
Scenario: Editing promotions coupon based option
When I want to modify a "Christmas sale" promotion
And I make it coupon based
@@ -39,7 +39,7 @@ Feature: Editing promotion
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should be coupon based
- @api @todo @ui
+ @api @ui
Scenario: Editing promotions channels
When I want to modify a "Christmas sale" promotion
And I make it applicable for the "United States" channel
@@ -47,7 +47,7 @@ Feature: Editing promotion
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should be applicable for the "United States" channel
- @api @todo @ui
+ @api @ui
Scenario: Editing a promotion with start and end date
When I want to modify a "Christmas sale" promotion
And I make it available from "12.12.2017" to "24.12.2017"
@@ -55,24 +55,34 @@ Feature: Editing promotion
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should be available from "12.12.2017" to "24.12.2017"
- @api @todo @ui
+ @api @ui
Scenario: Editing promotion after adding a new channel
Given this promotion gives "$10.00" discount to every order
When the store also operates on another channel named "EU-WEB"
Then I should be able to modify a "Christmas sale" promotion
- @todo @ui @no-api
- Scenario: Remove priority from existing promotion
+ @ui @no-api
+ Scenario: Removing priority from existing promotion
When I want to modify a "Christmas sale" promotion
And I remove its priority
And I save my changes
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should have priority 1
- @api @todo @ui
+ @api @ui
Scenario: Setting promotion to the lowest priority
When I want to modify a "Christmas sale" promotion
And I set its priority to "-1"
And I save my changes
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should have priority 1
+
+ @ui @javascript
+ Scenario: Removing rule and action from existing promotion
+ Given the promotion gives "$10.00" discount to every order with quantity at least 1
+ When I want to modify a "Holiday sale" promotion
+ And I remove its last rule
+ And I remove its last action
+ And I save my changes
+ Then I should not see the rule configuration form
+ And I should not see the action configuration form
diff --git a/features/admin/promotion/managing_promotions/preventing_deletion_of_promotions_in_use.feature b/features/admin/promotion/managing_promotions/preventing_deletion_of_promotions_in_use.feature
index bbe9656b046..44250833742 100644
--- a/features/admin/promotion/managing_promotions/preventing_deletion_of_promotions_in_use.feature
+++ b/features/admin/promotion/managing_promotions/preventing_deletion_of_promotions_in_use.feature
@@ -16,7 +16,7 @@ Feature: Prevent deletion of promotions applied to order
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @api @todo @ui
+ @api @ui
Scenario: Being unable to delete a promotion that was applied to an order
When I try to delete a "Christmas sale" promotion
Then I should be notified that it is in use and cannot be deleted
diff --git a/features/admin/promotion/managing_promotions/promotion_unique_code_validation.feature b/features/admin/promotion/managing_promotions/promotion_unique_code_validation.feature
index c70932ea7b9..7f290f63f06 100644
--- a/features/admin/promotion/managing_promotions/promotion_unique_code_validation.feature
+++ b/features/admin/promotion/managing_promotions/promotion_unique_code_validation.feature
@@ -9,7 +9,7 @@ Feature: Promotion unique code validation
And there is a promotion "No-VAT promotion" identified by "NO_VAT" code
And I am logged in as an administrator
- @api @todo @ui
+ @api @ui
Scenario: Trying to add promotion with taken code
When I want to create a new promotion
And I specify its code as "NO_VAT"
diff --git a/features/admin/promotion/managing_promotions/promotion_validation.feature b/features/admin/promotion/managing_promotions/promotion_validation.feature
index 615f4968489..b0e22f895f9 100644
--- a/features/admin/promotion/managing_promotions/promotion_validation.feature
+++ b/features/admin/promotion/managing_promotions/promotion_validation.feature
@@ -17,7 +17,7 @@ Feature: Promotion validation
And I try to save my changes
Then I should be notified that the locale is not available
- @api @todo @ui
+ @api @ui
Scenario: Trying to add a new promotion without specifying its code
When I want to create a new promotion
And I name it "No-VAT promotion"
@@ -26,7 +26,7 @@ Feature: Promotion validation
Then I should be notified that code is required
And promotion with name "No-VAT promotion" should not be added
- @api @todo @ui
+ @api @ui
Scenario: Trying to add a new promotion with a too long code
When I want to create a new promotion
And I name it "No-VAT promotion"
@@ -34,7 +34,7 @@ Feature: Promotion validation
And I try to add it
Then I should be notified that code is too long
- @api @todo @ui
+ @api @ui
Scenario: Trying to add a new promotion without specifying its name
When I want to create a new promotion
And I specify its code as "no_vat_promotion"
@@ -43,7 +43,7 @@ Feature: Promotion validation
Then I should be notified that name is required
And promotion with code "no_vat_promotion" should not be added
- @api @todo @ui
+ @api @ui
Scenario: Adding a promotion with start date set up after end date
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
@@ -52,7 +52,7 @@ Feature: Promotion validation
And I try to add it
Then I should be notified that promotion cannot end before it starts
- @api @todo @ui
+ @api @ui
Scenario: Trying to remove name from existing promotion
Given there is a promotion "Christmas sale"
When I want to modify this promotion
@@ -61,7 +61,7 @@ Feature: Promotion validation
Then I should be notified that name is required
And this promotion should still be named "Christmas sale"
- @api @todo @ui
+ @api @ui
Scenario: Trying to add start later then end date for existing promotion
Given there is a promotion "Christmas sale"
When I want to modify this promotion
@@ -69,7 +69,7 @@ Feature: Promotion validation
And I try to save my changes
Then I should be notified that promotion cannot end before it starts
- @api @todo @ui @mink:chromedriver
+ @api @ui
Scenario: Adding a promotion with label exceeding 255 characters
Given there is a promotion "Christmas sale"
When I want to modify this promotion
@@ -77,7 +77,7 @@ Feature: Promotion validation
And I try to save my changes
Then I should be notified that promotion label in "Polish (Poland)" locale is too long
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Trying to add a new promotion without specifying a order percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
@@ -87,7 +87,7 @@ Feature: Promotion validation
Then I should be notified that this value should not be blank
And promotion with name "Christmas sale" should not be added
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Trying to add a new promotion without specifying an item percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
@@ -97,7 +97,7 @@ Feature: Promotion validation
Then I should be notified that this value should not be blank
And promotion with name "Christmas sale" should not be added
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Trying to add a new promotion with a wrong order percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
@@ -107,7 +107,7 @@ Feature: Promotion validation
Then I should be notified that a percentage discount value must be between 0% and 100%
And promotion with name "Christmas sale" should not be added
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Trying to add a new promotion with a wrong item percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
diff --git a/features/admin/promotion/managing_promotions/promotions_filter_validation.feature b/features/admin/promotion/managing_promotions/promotions_filter_validation.feature
index d4e7cef4956..6fe1bd30444 100644
--- a/features/admin/promotion/managing_promotions/promotions_filter_validation.feature
+++ b/features/admin/promotion/managing_promotions/promotions_filter_validation.feature
@@ -8,7 +8,7 @@ Feature: Promotion filters validation
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a promotion with wrong minimum price on price range filter
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -19,7 +19,7 @@ Feature: Promotion filters validation
Then I should be notified that a minimum value should be a numeric value
And promotion with name "$10 discount for all products over $10!" should not be added
- @api @todo @ui @javascript
+ @api @ui @javascript
Scenario: Adding a promotion with wrong maximum price on price range filter
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
diff --git a/features/admin/promotion/managing_promotions/seeing_correct_percantage_discounts_while_editing_promotion_with_action_and_decimal_places.feature b/features/admin/promotion/managing_promotions/seeing_correct_percentage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
similarity index 96%
rename from features/admin/promotion/managing_promotions/seeing_correct_percantage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
rename to features/admin/promotion/managing_promotions/seeing_correct_percentage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
index 25d5349e7f9..33a6bb9fdfb 100644
--- a/features/admin/promotion/managing_promotions/seeing_correct_percantage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
+++ b/features/admin/promotion/managing_promotions/seeing_correct_percentage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
@@ -10,7 +10,7 @@ Feature: Seeing correct percentage discounts while editing promotion with action
And this promotion gives "12.00%" discount to every order
And I am logged in as an administrator
- @api @todo @ui
+ @api @ui
Scenario: Seeing an accurate percentage amount after editing the promotion including the value up to one decimal place
When I want to modify a "Cheap Stuff" promotion
And I edit this promotion percentage action to have "2.5%"
@@ -18,7 +18,7 @@ Feature: Seeing correct percentage discounts while editing promotion with action
Then I should be notified that it has been successfully edited
And it should have "2.50%" of order percentage discount
- @api @todo @ui
+ @api @ui
Scenario: Seeing an accurate percentage amount after editing the promotion including the value up to two decimal places
When I want to modify a "Cheap Stuff" promotion
And I edit this promotion percentage action to have "2.56%"
@@ -26,7 +26,7 @@ Feature: Seeing correct percentage discounts while editing promotion with action
Then I should be notified that it has been successfully edited
And it should have "2.56%" of order percentage discount
- @todo @ui @no-api
+ @ui @no-api
Scenario: Seeing an accurate percentage amount after using a comma as a decimal separator
When I want to modify a "Cheap Stuff" promotion
And I edit this promotion percentage action to have "2,56%"
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php
index 7e97d2ddfb1..f96533cfa61 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php
@@ -321,25 +321,27 @@ public function iAddAMinMaxPriceFilterRangeForChannel(ChannelInterface $channel,
}
/**
- * @When I specify that this action should be applied to items from :taxon category
+ * @When I specify that this action should be applied to items from :taxon category for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(TaxonInterface $taxon): void
- {
+ public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(
+ TaxonInterface $taxon,
+ ChannelInterface $channel,
+ ): void {
$actions = $this->getActions();
- $channelCode = key($actions[0]['configuration']);
- $actions[0]['configuration'][$channelCode]['filters']['taxons_filter']['taxons'] = [$taxon->getCode()];
+ $actions[0]['configuration'][$channel->getCode()]['filters']['taxons_filter']['taxons'] = [$taxon->getCode()];
$this->client->addRequestData('actions', $actions);
}
/**
- * @When I specify that this action should be applied to the :product product
+ * @When I specify that this action should be applied to the :product product for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(ProductInterface $product): void
- {
+ public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(
+ ProductInterface $product,
+ ChannelInterface $channel,
+ ): void {
$actions = $this->getActions();
- $channelCode = key($actions[0]['configuration']);
- $actions[0]['configuration'][$channelCode]['filters']['products_filter']['products'] = [$product->getCode()];
+ $actions[0]['configuration'][$channel->getCode()]['filters']['products_filter']['products'] = [$product->getCode()];
$this->client->addRequestData('actions', $actions);
}
@@ -562,6 +564,15 @@ public function promotionShouldNotExistInTheRegistry(PromotionInterface $promoti
);
}
+ /**
+ * @Then the :promotionName promotion should be successfully created
+ */
+ public function thePromotionShouldBeSuccessfullyCreated(string $promotionName): void
+ {
+ $this->iShouldBeNotifiedThatItHasBeenSuccessfullyCreated();
+ $this->thePromotionShouldAppearInTheRegistry($promotionName);
+ }
+
/**
* @Then I should be notified that it has been successfully created
*/
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php
index 54b92f67362..e92a9cd8fdb 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php
@@ -58,7 +58,7 @@ public function iWantToCreateANewPromotion(): void
* @When I want to browse promotions
* @When I browse promotions
*/
- public function iWantToBrowsePromotions()
+ public function iWantToBrowsePromotions(): void
{
$this->indexPage->open();
}
@@ -88,7 +88,7 @@ public function iNameIt($name = null)
*/
public function iRemoveItsPriority(?int $priority = null): void
{
- $this->formElement->prioritizeIt($priority);
+ $this->formElement->setPriority($priority);
}
/**
@@ -118,7 +118,7 @@ public function iAddIt()
*/
public function iSpecifyItsLabelInLocaleCode(string $label, string $localeCode): void
{
- $this->createPage->specifyLabel($label, $localeCode);
+ $this->formElement->setLabel($label, $localeCode);
}
/**
@@ -126,7 +126,7 @@ public function iSpecifyItsLabelInLocaleCode(string $label, string $localeCode):
*/
public function iSpecifyItsLabelWithAStringExceedingTheLimitInLocale(string $localeCode): void
{
- $this->createPage->specifyLabel(str_repeat('a', 256), $localeCode);
+ $this->formElement->setLabel(str_repeat('a', 256), $localeCode);
}
/**
@@ -135,7 +135,7 @@ public function iSpecifyItsLabelWithAStringExceedingTheLimitInLocale(string $loc
public function thePromotionShouldHaveLabelInLocale(PromotionInterface $promotion, string $label, string $localeCode): void
{
$this->updatePage->open(['id' => $promotion->getId()]);
- $this->createPage->hasLabel($label, $localeCode);
+ $this->formElement->hasLabel($label, $localeCode);
}
/**
@@ -144,19 +144,19 @@ public function thePromotionShouldHaveLabelInLocale(PromotionInterface $promotio
*/
public function iAddTheHasTaxonRuleConfiguredWith(string ...$taxons): void
{
- $this->createPage->addRule('Has at least one from taxons');
+ $this->formElement->addRule('Has at least one from taxons');
- $this->createPage->selectAutocompleteRuleOption('Taxons', $taxons, true);
+ $this->formElement->selectAutocompleteRuleOptions($taxons);
}
/**
* @When /^I add the "Total price of items from taxon" rule configured with "([^"]+)" taxon and "(?:€|£|\$)([^"]+)" amount for ("[^"]+" channel)$/
*/
- public function iAddTheRuleConfiguredWith($taxonName, $amount, ChannelInterface $channel)
+ public function iAddTheRuleConfiguredWith(string $taxonName, $amount, ChannelInterface $channel): void
{
- $this->createPage->addRule('Total price of items from taxon');
- $this->createPage->selectAutocompleteRuleOption('Taxon', $taxonName);
- $this->createPage->fillRuleOptionForChannel($channel->getCode(), 'Amount', $amount);
+ $this->formElement->addRule('Total price of items from taxon');
+ $this->formElement->selectAutocompleteRuleOptions([$taxonName], $channel->getCode());
+ $this->formElement->fillRuleOptionForChannel($channel->getCode(), 'Amount', $amount);
}
/**
@@ -168,9 +168,9 @@ public function iAddTheItemTotalRuleConfiguredWithTwoChannel(
$secondAmount,
ChannelInterface $secondChannel,
) {
- $this->createPage->addRule('Item total');
- $this->createPage->fillRuleOptionForChannel($firstChannel->getCode(), 'Amount', $firstAmount);
- $this->createPage->fillRuleOptionForChannel($secondChannel->getCode(), 'Amount', $secondAmount);
+ $this->formElement->addRule('Item total');
+ $this->formElement->fillRuleOptionForChannel($firstChannel->getCode(), 'Amount', $firstAmount);
+ $this->formElement->fillRuleOptionForChannel($secondChannel->getCode(), 'Amount', $secondAmount);
}
/**
@@ -178,8 +178,8 @@ public function iAddTheItemTotalRuleConfiguredWithTwoChannel(
*/
public function iAddTheActionConfiguredWithAmountForChannel($actionType, $amount, ChannelInterface $channel)
{
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
+ $this->formElement->addAction($actionType);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
}
/**
@@ -187,7 +187,7 @@ public function iAddTheActionConfiguredWithAmountForChannel($actionType, $amount
*/
public function itIsConfiguredWithAmountForChannel($amount, ChannelInterface $channel)
{
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
}
/**
@@ -195,7 +195,7 @@ public function itIsConfiguredWithAmountForChannel($amount, ChannelInterface $ch
*/
public function iAddAMinPriceFilterRangeForChannel(ChannelInterface $channel, $minimum)
{
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Min', $minimum);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Min', $minimum);
}
/**
@@ -203,7 +203,7 @@ public function iAddAMinPriceFilterRangeForChannel(ChannelInterface $channel, $m
*/
public function iAddAMaxPriceFilterRangeForChannel(ChannelInterface $channel, $maximum)
{
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Max', $maximum);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Max', $maximum);
}
/**
@@ -216,11 +216,11 @@ public function iAddAMinMaxPriceFilterRangeForChannel(ChannelInterface $channel,
}
/**
- * @When I specify that this action should be applied to items from :taxonName category
+ * @When I specify that this action should be applied to items from :taxonName category for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory($taxonName)
+ public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(string $taxonName, ChannelInterface $channel): void
{
- $this->createPage->selectAutoCompleteFilterOption('Taxons', $taxonName);
+ $this->formElement->selectAutocompleteActionFilterOptions([$taxonName], $channel->getCode(), 'taxons');
}
/**
@@ -231,8 +231,8 @@ public function iAddTheActionConfiguredWithAPercentageValueForChannel(
string $percentage,
ChannelInterface $channel,
): void {
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage);
+ $this->formElement->addAction($actionType);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage);
}
/**
@@ -242,8 +242,8 @@ public function iAddTheActionConfiguredWithoutAPercentageValueForChannel(
string $actionType,
ChannelInterface $channel,
): void {
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Percentage', '');
+ $this->formElement->addAction($actionType);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', '');
}
/**
@@ -252,8 +252,8 @@ public function iAddTheActionConfiguredWithoutAPercentageValueForChannel(
*/
public function iAddTheActionConfiguredWithAPercentageValue($actionType, $percentage = null)
{
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOption('Percentage', $percentage ?? '');
+ $this->formElement->addAction($actionType);
+ $this->formElement->fillActionOption('Percentage', $percentage ?? '');
}
/**
@@ -261,8 +261,8 @@ public function iAddTheActionConfiguredWithAPercentageValue($actionType, $percen
*/
public function iAddTheCustomerGroupRuleConfiguredForGroup($customerGroupName)
{
- $this->createPage->addRule('Customer group');
- $this->createPage->selectRuleOption('Customer group', $customerGroupName);
+ $this->formElement->addRule('Customer group');
+ $this->formElement->selectRuleOption('Customer group', $customerGroupName);
}
/**
@@ -273,6 +273,22 @@ public function iCheckThePromotion(string $promotionName): void
$this->indexPage->checkResourceOnPage(['name' => $promotionName]);
}
+ /**
+ * @When I remove its last rule
+ */
+ public function iRemoveItsLastRule(): void
+ {
+ $this->formElement->removeLastRule();
+ }
+
+ /**
+ * @When I remove its last action
+ */
+ public function iRemoveItsLastAction(): void
+ {
+ $this->formElement->removeLastAction();
+ }
+
/**
* @When I delete them
*/
@@ -354,7 +370,7 @@ public function iShouldBeNotifiedThatAMinimalValueShouldBeNumeric($element)
*/
public function iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists()
{
- Assert::same($this->createPage->getValidationMessage('code'), 'The promotion with given code already exists.');
+ Assert::same($this->formElement->getValidationMessage('code'), 'The promotion with given code already exists.');
}
/**
@@ -380,18 +396,15 @@ public function thereShouldStillBeOnlyOnePromotionWith($element, $value)
/**
* @When I set its usage limit to :usageLimit
*/
- public function iSetItsUsageLimitTo($usageLimit)
+ public function iSetItsUsageLimitTo(int $usageLimit): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->fillUsageLimit($usageLimit);
+ $this->formElement->setUsageLimit($usageLimit);
}
/**
* @Then the :promotion promotion should be available to be used only :usageLimit times
*/
- public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, $usageLimit)
+ public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, int $usageLimit): void
{
$this->iWantToModifyAPromotion($promotion);
@@ -403,10 +416,7 @@ public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $
*/
public function iSetItAsExclusive(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->makeExclusive();
+ $this->formElement->makeExclusive();
}
/**
@@ -414,16 +424,13 @@ public function iSetItAsExclusive(): void
*/
public function iSetItAsNotAppliesToDiscountedByCatalogPromotionItems(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->makeNotAppliesToDiscountedItem();
+ $this->formElement->makeNotAppliesToDiscountedItem();
}
/**
* @Then the :promotion promotion should be exclusive
*/
- public function thePromotionShouldBeExclusive(PromotionInterface $promotion)
+ public function thePromotionShouldBeExclusive(PromotionInterface $promotion): void
{
$this->assertIfFieldIsTrue($promotion, 'exclusive');
}
@@ -439,18 +446,15 @@ public function thePromotionShouldNotAppliesToDiscountedItems(PromotionInterface
/**
* @When I make it coupon based
*/
- public function iMakeItCouponBased()
+ public function iMakeItCouponBased(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->checkCouponBased();
+ $this->formElement->makeCouponBased();
}
/**
* @Then the :promotion promotion should be coupon based
*/
- public function thePromotionShouldBeCouponBased(PromotionInterface $promotion)
+ public function thePromotionShouldBeCouponBased(PromotionInterface $promotion): void
{
$this->assertIfFieldIsTrue($promotion, 'coupon_based');
}
@@ -458,18 +462,15 @@ public function thePromotionShouldBeCouponBased(PromotionInterface $promotion)
/**
* @When I make it applicable for the :channelName channel
*/
- public function iMakeItApplicableForTheChannel($channelName)
+ public function iMakeItApplicableForTheChannel(string $channelName): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->checkChannel($channelName);
+ $this->formElement->checkChannel($channelName);
}
/**
* @Then the :promotion promotion should be applicable for the :channelName channel
*/
- public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, $channelName)
+ public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, string $channelName): void
{
$this->iWantToModifyAPromotion($promotion);
@@ -549,13 +550,10 @@ public function iShouldBeNotifiedOfFailure()
/**
* @When I make it available from :startsDate to :endsDate
*/
- public function iMakeItAvailableFromTo(\DateTimeInterface $startsDate, \DateTimeInterface $endsDate)
+ public function iMakeItAvailableFromTo(\DateTimeInterface $startsDate, \DateTimeInterface $endsDate): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->setStartsAt($startsDate);
- $currentPage->setEndsAt($endsDate);
+ $this->formElement->setStartsAt($startsDate);
+ $this->formElement->setEndsAt($endsDate);
}
/**
@@ -566,7 +564,6 @@ public function thePromotionShouldBeAvailableFromTo(PromotionInterface $promotio
$this->iWantToModifyAPromotion($promotion);
Assert::true($this->updatePage->hasStartsAt($startsDate));
-
Assert::true($this->updatePage->hasEndsAt($endsDate));
}
@@ -575,19 +572,16 @@ public function thePromotionShouldBeAvailableFromTo(PromotionInterface $promotio
*/
public function iShouldBeNotifiedThatPromotionCannotEndBeforeItsEvenStarts(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- Assert::same($currentPage->getValidationMessage('ends_at'), 'End date cannot be set prior start date.');
+ Assert::same($this->formElement->getValidationMessage('ends_at_date'), 'End date cannot be set prior start date.');
}
/**
* @Then I should be notified that this value should not be blank
*/
- public function iShouldBeNotifiedThatThisValueShouldNotBeBlank()
+ public function iShouldBeNotifiedThatThisValueShouldNotBeBlank(): void
{
Assert::same(
- $this->createPage->getValidationMessageForAction(),
+ $this->formElement->getValidationMessageForAction(),
'This value should not be blank.',
);
}
@@ -600,7 +594,7 @@ public function iShouldBeNotifiedThatThisValueShouldNotBeBlank()
public function iShouldBeNotifiedThatPercentageDiscountShouldBeBetween(): void
{
Assert::same(
- $this->createPage->getValidationMessageForAction(),
+ $this->formElement->getValidationMessageForAction(),
'The percentage discount must be between 0% and 100%.',
);
}
@@ -621,18 +615,18 @@ public function thePromotionShouldBeUsedTime(PromotionInterface $promotion, $usa
/**
* @When I add the "Contains product" rule configured with the :productName product
*/
- public function iAddTheRuleConfiguredWithTheProduct($productName)
+ public function iAddTheRuleConfiguredWithTheProduct(string $productName): void
{
- $this->createPage->addRule('Contains product');
- $this->createPage->selectAutocompleteRuleOption('Product code', $productName);
+ $this->formElement->addRule('Contains product');
+ $this->formElement->selectAutocompleteRuleOptions([$productName]);
}
/**
- * @When I specify that this action should be applied to the :productName product
+ * @When I specify that this action should be applied to the :productName product for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToTheProduct($productName)
+ public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(string $productName, ChannelInterface $channel): void
{
- $this->createPage->selectAutoCompleteFilterOption('Products', $productName);
+ $this->formElement->selectAutocompleteActionFilterOptions([$productName], $channel->getCode(), 'products');
}
/**
@@ -686,7 +680,7 @@ public function thePromotionsShouldHavePriority(PromotionInterface $promotion, i
{
$this->iWantToModifyAPromotion($promotion);
- Assert::same($this->updatePage->getPriority(), $priority);
+ Assert::same($this->formElement->getPriority(), $priority);
}
/**
@@ -759,15 +753,15 @@ public function iFilterPromotionsByCouponCodeEqual(string $value): void
*/
public function iAddANewRule()
{
- $this->createPage->addRule(null);
+ $this->formElement->addRule(null);
}
/**
* @When I add a new action
*/
- public function iAddANewAction()
+ public function iAddANewAction(): void
{
- $this->createPage->addAction(null);
+ $this->formElement->addAction(null);
}
/**
@@ -789,9 +783,17 @@ public function iRemoveTheRuleAmountForChannel(ChannelInterface $channel): void
/**
* @Then I should see the rule configuration form
*/
- public function iShouldSeeTheRuleConfigurationForm()
+ public function iShouldSeeTheRuleConfigurationForm(): void
{
- Assert::true($this->createPage->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is not visible.');
+ Assert::true($this->formElement->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is not visible.');
+ }
+
+ /**
+ * @Then I should not see the rule configuration form
+ */
+ public function iShouldNotSeeTheRuleConfigurationForm(): void
+ {
+ Assert::false($this->formElement->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is visible.');
}
/**
@@ -813,9 +815,17 @@ public function itShouldHaveOfItemPercentageDiscount(string $amount, ChannelInte
/**
* @Then I should see the action configuration form
*/
- public function iShouldSeeTheActionConfigurationForm()
+ public function iShouldSeeTheActionConfigurationForm(): void
{
- Assert::true($this->createPage->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is not visible.');
+ Assert::true($this->formElement->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is not visible.');
+ }
+
+ /**
+ * @Then I should not see the action configuration form
+ */
+ public function iShouldNotSeeTheActionConfigurationForm(): void
+ {
+ Assert::false($this->formElement->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is visible.');
}
/**
@@ -850,11 +860,8 @@ public function iShouldBeNotifiedThatPromotionsHaveBeenUpdated(PromotionInterfac
*/
public function iShouldBeNotifiedThatPromotionLabelIsTooLong(string $localeCode): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
Assert::same(
- $currentPage->getValidationMessageForTranslation('label', $localeCode),
+ $this->formElement->getValidationMessageForTranslation('label', $localeCode),
'This value is too long. It should have 255 characters or less.',
);
}
@@ -883,12 +890,17 @@ public function iShouldBeViewingNonArchivalPromotions(): void
Assert::false($this->indexPage->isArchivalFilterEnabled());
}
- private function assertFieldValidationMessage(string $element, string $expectedMessage)
+ /**
+ * @Then the :promotion promotion should be successfully created
+ */
+ public function thePromotionShouldBeSuccessfullyCreated(PromotionInterface $promotion): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
+ $this->updatePage->verify(['id' => $promotion->getId()]);
+ }
- Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
+ private function assertFieldValidationMessage(string $element, string $expectedMessage)
+ {
+ Assert::same($this->formElement->getValidationMessage($element), $expectedMessage);
}
/**
diff --git a/src/Sylius/Behat/Element/Admin/Crud/FormElement.php b/src/Sylius/Behat/Element/Admin/Crud/FormElement.php
new file mode 100644
index 00000000000..1b41c771819
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Crud/FormElement.php
@@ -0,0 +1,47 @@
+getFieldElement($element);
+ if (null === $foundElement) {
+ throw new ElementNotFoundException($this->getSession(), 'Field element');
+ }
+
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
+ if (null === $validationMessage) {
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
+ }
+
+ return $validationMessage->getText();
+ }
+
+ /** @throws ElementNotFoundException */
+ private function getFieldElement(string $element): ?NodeElement
+ {
+ $element = $this->getElement($element);
+ while (null !== $element && !$element->hasClass('field')) {
+ $element = $element->getParent();
+ }
+
+ return $element;
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php
new file mode 100644
index 00000000000..364e3ec3731
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php
@@ -0,0 +1,22 @@
+getElement('priority')->getValue();
+ }
+
+ public function setPriority(?int $priority): void
{
$this->getElement('priority')->setValue($priority);
}
+ public function setStartsAt(\DateTimeInterface $dateTime): void
+ {
+ $timestamp = $dateTime->getTimestamp();
+
+ $this->getElement('starts_at_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('starts_at_time')->setValue(date('H:i', $timestamp));
+ }
+
+ public function setEndsAt(\DateTimeInterface $dateTime): void
+ {
+ $timestamp = $dateTime->getTimestamp();
+
+ $this->getElement('ends_at_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('ends_at_time')->setValue(date('H:i', $timestamp));
+ }
+
+ public function setUsageLimit(int $limit): void
+ {
+ $this->getElement('usage_limit')->setValue($limit);
+ }
+
+ public function makeExclusive(): void
+ {
+ $this->getElement('exclusive')->check();
+ }
+
+ public function makeNotAppliesToDiscountedItem(): void
+ {
+ $this->getElement('applies_to_discounted')->uncheck();
+ }
+
+ public function makeCouponBased(): void
+ {
+ $this->getElement('coupon_based')->check();
+ }
+
+ public function checkChannel(string $name): void
+ {
+ $this->getElement('channels')->checkField($name);
+ }
+
+ public function setLabel(string $label, string $localeCode): void
+ {
+ $this->getElement('label', ['%locale_code%' => $localeCode])->setValue($label);
+ }
+
+ public function hasLabel(string $label, string $localeCode): bool
+ {
+ return $label === $this->getElement('label', ['%locale_code%' => $localeCode])->getValue();
+ }
+
+ public function addAction(?string $actionName): void
+ {
+ $this->getElement('add_action_button')->press();
+ $this->waitForFormUpdate();
+
+ if (null !== $actionName) {
+ $this->selectActionOption('Type', $actionName);
+ $this->waitForFormUpdate();
+ }
+ }
+
+ public function removeLastAction(): void
+ {
+ $this->getLastAction()->find('css', 'button[data-test-delete-action]')->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function fillActionOption(string $option, string $value): void
+ {
+ $this->getLastAction()->fillField($option, $value);
+ }
+
+ public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void
+ {
+ $lastAction = $this->getChannelConfigurationOfLastAction($channelCode);
+ $lastAction->fillField($option, $value);
+ }
+
+ public function selectActionOption(string $option, string $value, bool $multiple = false): void
+ {
+ $this->getLastAction()->find('named', ['select', $option])->selectOption($value, $multiple);
+ }
+
+ public function addRule(?string $ruleName): void
+ {
+ $this->getElement('add_rule_button')->press();
+ $this->waitForFormUpdate();
+
+ if (null !== $ruleName) {
+ $this->selectRuleOption('Type', $ruleName);
+ $this->waitForFormUpdate();
+ }
+ }
+
+ public function removeLastRule(): void
+ {
+ $this->getLastRule()->find('css', 'button[data-test-delete-rule]')->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function selectRuleOption(string $option, string $value, bool $multiple = false): void
+ {
+ $this->getLastRule()->find('named', ['select', $option])->selectOption($value, $multiple);
+ }
+
+ public function fillRuleOption(string $option, string $value): void
+ {
+ $this->getLastRule()->fillField($option, $value);
+ }
+
+ public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void
+ {
+ $lastRule = $this->getChannelConfigurationOfLastRule($channelCode);
+ $lastRule->fillField($option, $value);
+ }
+
+ public function selectAutocompleteRuleOptions(array $values, ?string $channelCode = null): void
+ {
+ $count = count($this->getElement('rules')->findAll('css', '[data-test-promotion-rule]'));
+ $locator = $channelCode ?
+ sprintf('#sylius_promotion_rules_%d_configuration_%s select', $count - 1, $channelCode) :
+ sprintf('#sylius_promotion_rules_%d_configuration select', $count - 1)
+ ;
+ foreach ($values as $value) {
+ $this->autocompleteHelper->selectByName(
+ $this->getDriver(),
+ $this->getLastRule()->find('css', $locator)->getXpath(),
+ $value,
+ );
+ $this->waitForFormUpdate();
+ }
+ }
+
+ public function selectAutocompleteActionFilterOptions(array $values, string $channelCode, string $filterType): void
+ {
+ $count = count($this->getElement('actions')->findAll('css', '[data-test-promotion-action]'));
+ $locator = sprintf('#sylius_promotion_actions_%d_configuration_%s_filters_%s_filter select', $count - 1, $channelCode, $filterType);
+ foreach ($values as $value) {
+ $this->autocompleteHelper->selectByName(
+ $this->getDriver(),
+ $this->getLastAction()->find('css', $locator)->getXpath(),
+ $value,
+ );
+ }
+
+ $this->waitForFormUpdate();
+ }
+
+ public function checkIfRuleConfigurationFormIsVisible(): bool
+ {
+ return $this->hasElement('rule_count');
+ }
+
+ public function checkIfActionConfigurationFormIsVisible(): bool
+ {
+ return $this->hasElement('action_amount');
+ }
+
+ public function getValidationMessageForAction(): string
+ {
+ $actionForm = $this->getLastAction();
+
+ $foundElement = $actionForm->find('css', '.invalid-feedback');
+ if (null === $foundElement) {
+ throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.invalid-feedback');
+ }
+
+ return $foundElement->getText();
+ }
+
+ public function getValidationMessageForTranslation(string $element, string $localeCode): string
+ {
+ $foundElement = $this->getElement($element, ['%locale_code%' => $localeCode])->getParent();
+
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
+ if (null === $validationMessage) {
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
+ }
+
+ return $validationMessage->getText();
+ }
+
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
+ 'action_amount' => '#sylius_promotion_actions_0_configuration_WEB-US_amount',
+ 'actions' => '#sylius_promotion_actions',
+ 'add_action_button' => '#sylius_promotion_actions_add',
+ 'add_rule_button' => '#sylius_promotion_rules_add',
+ 'applies_to_discounted' => '#sylius_promotion_appliesToDiscounted',
+ 'channels' => '#sylius_promotion_channels',
+ 'code' => '#sylius_promotion_code',
+ 'coupon_based' => '#sylius_promotion_couponBased',
+ 'ends_at_date' => '#sylius_promotion_endsAt_date',
+ 'ends_at_time' => '#sylius_promotion_endsAt_time',
+ 'exclusive' => '#sylius_promotion_exclusive',
+ 'form' => '[data-live-name-value="sylius_admin:promotion:form"]',
+ 'label' => '[name="sylius_promotion[translations][%locale_code%][label]"]',
+ 'minimum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_min',
+ 'maximum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_max',
+ 'name' => '#sylius_promotion_name',
'priority' => '#sylius_promotion_priority',
+ 'rule_count' => '#sylius_promotion_rules_0_configuration_count',
+ 'rules' => '#sylius_promotion_rules',
+ 'starts_at_date' => '#sylius_promotion_startsAt_date',
+ 'starts_at_time' => '#sylius_promotion_startsAt_time',
+ 'translation_tab' => '[data-test-promotion-translations-accordion="%locale_code%"]',
+ 'usage_limit' => '#sylius_promotion_usageLimit',
]);
}
+
+ private function getLastAction(): NodeElement
+ {
+ $items = $this->getElement('actions')->findAll('css', '[data-test-promotion-action]');
+ Assert::notEmpty($items);
+
+ return end($items);
+ }
+
+ private function getChannelConfigurationOfLastAction(string $channelCode): NodeElement
+ {
+ $lastAction = $this->getLastAction();
+
+ TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode);
+
+ return $lastAction
+ ->find('css', sprintf('[id^="sylius_promotion_actions_"][id$="_configuration_%s"]', $channelCode))
+ ;
+ }
+
+ private function getLastRule(): NodeElement
+ {
+ $items = $this->getElement('rules')->findAll('css', '[data-test-promotion-rule]');
+ Assert::notEmpty($items);
+
+ return end($items);
+ }
+
+ private function getChannelConfigurationOfLastRule(string $channelCode): NodeElement
+ {
+ $lastRule = $this->getLastRule();
+
+ TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode);
+
+ return $lastRule->find(
+ 'css',
+ sprintf('[id^="sylius_promotion_rules_"][id$="_configuration_%s"]', $channelCode),
+ );
+ }
+
+ private function waitForFormUpdate(): void
+ {
+ $form = $this->getElement('form');
+ sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute
+ $form->waitFor(1500, function () use ($form) {
+ return !$form->hasAttribute('busy');
+ });
+ }
}
diff --git a/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php
index 55c792c454e..bdabe4b5b4b 100644
--- a/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php
+++ b/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php
@@ -13,7 +13,61 @@
namespace Sylius\Behat\Element\Admin\Promotion;
-interface FormElementInterface
+use Sylius\Behat\Element\Admin\Crud\FormElementInterface as BaseFormElementInterface;
+
+interface FormElementInterface extends BaseFormElementInterface
{
- public function prioritizeIt(?int $priority): void;
+ public function setPriority(?int $priority): void;
+
+ public function getPriority(): int;
+
+ public function setStartsAt(\DateTimeInterface $dateTime): void;
+
+ public function setEndsAt(\DateTimeInterface $dateTime): void;
+
+ public function setUsageLimit(int $limit): void;
+
+ public function makeExclusive(): void;
+
+ public function makeNotAppliesToDiscountedItem(): void;
+
+ public function makeCouponBased(): void;
+
+ public function checkChannel(string $name): void;
+
+ public function setLabel(string $label, string $localeCode): void;
+
+ public function hasLabel(string $label, string $localeCode): bool;
+
+ public function addAction(?string $actionName): void;
+
+ public function removeLastAction(): void;
+
+ public function fillActionOption(string $option, string $value): void;
+
+ public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void;
+
+ public function selectActionOption(string $option, string $value, bool $multiple = false): void;
+
+ public function addRule(?string $ruleName): void;
+
+ public function removeLastRule(): void;
+
+ public function selectRuleOption(string $option, string $value, bool $multiple = false): void;
+
+ public function fillRuleOption(string $option, string $value): void;
+
+ public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void;
+
+ public function selectAutocompleteRuleOptions(array $values, ?string $channelCode = null): void;
+
+ public function selectAutocompleteActionFilterOptions(array $values, string $channelCode, string $filterType): void;
+
+ public function checkIfRuleConfigurationFormIsVisible(): bool;
+
+ public function checkIfActionConfigurationFormIsVisible(): bool;
+
+ public function getValidationMessageForAction(): string;
+
+ public function getValidationMessageForTranslation(string $element, string $localeCode): string;
}
diff --git a/src/Sylius/Behat/Page/Admin/Product/FormTrait.php b/src/Sylius/Behat/Page/Admin/Product/FormTrait.php
index f5008bffc79..d0cfa1ba282 100644
--- a/src/Sylius/Behat/Page/Admin/Product/FormTrait.php
+++ b/src/Sylius/Behat/Page/Admin/Product/FormTrait.php
@@ -43,7 +43,7 @@ public function getDefinedFormElements(): array
'product_attribute_input' => 'input[name="product_attributes"]',
'product_attribute_tab' => '[data-test-product-attribute-tab="%name%"]',
'product_options_autocomplete' => '[data-test-product-options-autocomplete]',
- 'product_translation_accordion' => '[data-test-product-translation-accordion="%localeCode%"]',
+ 'product_translation_accordion' => '[data-test-product-translations-accordion="%localeCode%"]',
'side_navigation_tab' => '[data-test-side-navigation-tab="%name%"]',
];
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php b/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php
index 7347b83199e..4c735f29702 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php
@@ -18,249 +18,44 @@
use Sylius\Behat\Behaviour\NamesIt;
use Sylius\Behat\Behaviour\SpecifiesItsField;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
-use Sylius\Behat\Service\AutocompleteHelper;
-use Sylius\Behat\Service\TabsHelper;
-use Webmozart\Assert\Assert;
class CreatePage extends BaseCreatePage implements CreatePageInterface
{
use NamesIt;
use SpecifiesItsField;
- public function specifyLabel(string $label, string $localeCode): void
+ public function getValidationMessage(string $element): string
{
- $this->getDocument()->find('css', 'div[data-locale="' . $localeCode . '"]')->click();
-
- $this->getDocument()->fillField(sprintf('sylius_promotion_translations_%s_label', $localeCode), $label);
- }
-
- public function addRule(?string $ruleName): void
- {
- $count = count($this->getCollectionItems('rules'));
-
- $this->getDocument()->clickLink('Add rule');
-
- $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('rules')));
-
- if (null !== $ruleName) {
- $this->selectRuleOption('Type', $ruleName);
- }
- }
-
- public function selectRuleOption(string $option, string $value, bool $multiple = false): void
- {
- $this->getLastCollectionItem('rules')->find('named', ['select', $option])->selectOption($value, $multiple);
- }
-
- public function selectAutocompleteRuleOption(string $option, $value, bool $multiple = false): void
- {
- $option = strtolower(str_replace(' ', '_', $option));
-
- $ruleAutocomplete = $this
- ->getLastCollectionItem('rules')
- ->find('css', sprintf('input[type="hidden"][name*="[%s]"]', $option))
- ->getParent()
- ;
-
- if ($multiple && is_array($value)) {
- AutocompleteHelper::chooseValues($this->getSession(), $ruleAutocomplete, $value);
-
- return;
- }
-
- AutocompleteHelper::chooseValue($this->getSession(), $ruleAutocomplete, $value);
- }
-
- public function fillRuleOption(string $option, string $value): void
- {
- $this->getLastCollectionItem('rules')->fillField($option, $value);
- }
-
- public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void
- {
- $lastAction = $this->getChannelConfigurationOfLastRule($channelCode);
- $lastAction->fillField($option, $value);
- }
-
- public function addAction(?string $actionName): void
- {
- $count = count($this->getCollectionItems('actions'));
-
- $this->getDocument()->clickLink('Add action');
-
- $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('actions')));
-
- if (null !== $actionName) {
- $this->selectActionOption('Type', $actionName);
- }
- }
-
- public function selectActionOption(string $option, string $value, bool $multiple = false): void
- {
- $this->getLastCollectionItem('actions')->find('named', ['select', $option])->selectOption($value, $multiple);
- }
-
- public function fillActionOption(string $option, string $value): void
- {
- $this->getLastCollectionItem('actions')->fillField($option, $value);
- }
-
- public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void
- {
- $lastAction = $this->getChannelConfigurationOfLastAction($channelCode);
- $lastAction->fillField($option, $value);
- }
-
- public function fillUsageLimit(string $limit): void
- {
- $this->getDocument()->fillField('Usage limit', $limit);
- }
-
- public function makeExclusive(): void
- {
- $this->getDocument()->checkField('Exclusive');
- }
-
- public function makeNotAppliesToDiscountedItem(): void
- {
- $this->getDocument()->unCheckField('Applies to already discounted order items');
- }
-
- public function checkCouponBased(): void
- {
- $this->getDocument()->checkField('Coupon based');
- }
-
- public function checkChannel(string $name): void
- {
- $this->getDocument()->checkField($name);
- }
-
- public function setStartsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_startsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_startsAt_time', date('H:i', $timestamp));
- }
-
- public function setEndsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_endsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_endsAt_time', date('H:i', $timestamp));
- }
-
- public function getValidationMessageForAction(): string
- {
- $actionForm = $this->getLastCollectionItem('actions');
-
- $foundElement = $actionForm->find('css', '.sylius-validation-error');
+ $foundElement = $this->getFieldElement($element);
if (null === $foundElement) {
- throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Field element');
}
- return $foundElement->getText();
- }
-
- public function selectAutoCompleteFilterOption(string $option, $value, bool $multiple = false): void
- {
- $option = strtolower(str_replace(' ', '_', $option));
-
- $filterAutocomplete = $this
- ->getLastCollectionItem('actions')
- ->find('css', sprintf('input[type="hidden"][name*="[%s_filter]"]', $option))
- ->getParent()
- ;
-
- if ($multiple && is_array($value)) {
- AutocompleteHelper::chooseValues($this->getSession(), $filterAutocomplete, $value);
-
- return;
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
+ if (null === $validationMessage) {
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
}
- AutocompleteHelper::chooseValue($this->getSession(), $filterAutocomplete, $value);
- }
-
- public function checkIfRuleConfigurationFormIsVisible(): bool
- {
- return $this->hasElement('count');
- }
-
- public function checkIfActionConfigurationFormIsVisible(): bool
- {
- return $this->hasElement('amount');
- }
-
- public function hasLabel(string $label, string $localeCode): bool
- {
- $this->getDocument()->find('css', 'div[data-locale="' . $localeCode . '"]')->click();
-
- $labelElement = $this->getDocument()->find('css', sprintf('label:contains("%s")', $label));
- if (null === $labelElement) {
- return false;
- }
-
- return $labelElement->hasClass(sprintf('sylius-locale-%s', $localeCode));
+ return $validationMessage->getText();
}
protected function getDefinedElements(): array
{
- return [
- 'actions' => '#sylius_promotion_actions',
+ return array_merge(parent::getDefinedElements(), [
'code' => '#sylius_promotion_code',
- 'ends_at' => '#sylius_promotion_endsAt',
- 'minimum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_min',
- 'maximum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_max',
- 'name' => '#sylius_promotion_name',
+ 'form' => '[data-live-name-value="sylius_admin:promotion:form"]',
'rules' => '#sylius_promotion_rules',
- 'starts_at' => '#sylius_promotion_startsAt',
- 'count' => '#sylius_promotion_rules_0_configuration_count',
- 'amount' => '#sylius_promotion_actions_0_configuration_WEB-US_amount',
- ];
- }
-
- private function getChannelConfigurationOfLastAction(string $channelCode): NodeElement
- {
- $lastAction = $this->getLastCollectionItem('actions');
-
- TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode);
-
- return $lastAction
- ->find('css', sprintf('[id^="sylius_promotion_actions_"][id$="_configuration_%s"]', $channelCode))
- ;
+ ]);
}
- private function getChannelConfigurationOfLastRule(string $channelCode): NodeElement
+ /** @throws ElementNotFoundException */
+ private function getFieldElement(string $element): ?NodeElement
{
- $lastRule = $this->getLastCollectionItem('rules');
-
- TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode);
-
- return $lastRule
- ->find('css', sprintf('[id^="sylius_promotion_rules_"][id$="_configuration_%s"]', $channelCode))
- ;
- }
-
- private function getLastCollectionItem(string $collection): NodeElement
- {
- $items = $this->getCollectionItems($collection);
-
- Assert::notEmpty($items);
-
- return end($items);
- }
-
- /**
- * @return NodeElement[]
- */
- private function getCollectionItems(string $collection): array
- {
- $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]');
-
- Assert::isArray($items);
+ $element = $this->getElement($element);
+ while (null !== $element && !$element->hasClass('field')) {
+ $element = $element->getParent();
+ }
- return $items;
+ return $element;
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php
index 30a0fb094a2..c1102bfd662 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php
@@ -13,65 +13,13 @@
namespace Sylius\Behat\Page\Admin\Promotion;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
interface CreatePageInterface extends BaseCreatePageInterface
{
public function specifyCode(string $code): void;
- public function specifyLabel(string $label, string $localeCode): void;
-
public function nameIt(string $name): void;
- public function addRule(?string $ruleName): void;
-
- public function selectRuleOption(string $option, string $value, bool $multiple = false): void;
-
- /**
- * @param string|string[] $value
- */
- public function selectAutocompleteRuleOption(string $option, array|string $value, bool $multiple = false): void;
-
- public function fillRuleOption(string $option, string $value): void;
-
- public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void;
-
- public function addAction(?string $actionName): void;
-
- public function selectActionOption(string $option, string $value, bool $multiple = false): void;
-
- public function fillActionOption(string $option, string $value): void;
-
- public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void;
-
- public function fillUsageLimit(string $limit): void;
-
- public function makeExclusive(): void;
-
- public function makeNotAppliesToDiscountedItem(): void;
-
- public function checkCouponBased(): void;
-
- public function checkChannel(string $name): void;
-
- public function setStartsAt(\DateTimeInterface $dateTime): void;
-
- public function setEndsAt(\DateTimeInterface $dateTime): void;
-
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessageForAction(): string;
-
- /**
- * @param string|string[] $value
- */
- public function selectAutoCompleteFilterOption(string $option, array|string $value, bool $multiple = false): void;
-
- public function checkIfRuleConfigurationFormIsVisible(): bool;
-
- public function checkIfActionConfigurationFormIsVisible(): bool;
-
- public function hasLabel(string $label, string $localeCode): bool;
+ public function getValidationMessage(string $element): string;
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php
index f9072e2889e..ec46e6cf4ef 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php
@@ -14,7 +14,6 @@
namespace Sylius\Behat\Page\Admin\Promotion;
use Behat\Mink\Element\NodeElement;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
use Sylius\Behat\Behaviour\CountsChannelBasedErrors;
use Sylius\Behat\Behaviour\NamesIt;
@@ -26,16 +25,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
use CountsChannelBasedErrors;
use NamesIt;
- public function setPriority(?int $priority): void
- {
- $this->getDocument()->fillField('Priority', $priority);
- }
-
- public function getPriority(): int
- {
- return (int) $this->getElement('priority')->getValue();
- }
-
public function checkChannelsState(string $channelName): bool
{
$field = $this->getDocument()->findField($channelName);
@@ -43,42 +32,6 @@ public function checkChannelsState(string $channelName): bool
return (bool) $field->getValue();
}
- public function fillUsageLimit(string $limit): void
- {
- $this->getDocument()->fillField('Usage limit', $limit);
- }
-
- public function makeExclusive(): void
- {
- $this->getDocument()->checkField('Exclusive');
- }
-
- public function checkCouponBased(): void
- {
- $this->getDocument()->checkField('Coupon based');
- }
-
- public function checkChannel(string $name): void
- {
- $this->getDocument()->checkField($name);
- }
-
- public function setStartsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_startsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_startsAt_time', date('H:i', $timestamp));
- }
-
- public function setEndsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_endsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_endsAt_time', date('H:i', $timestamp));
- }
-
public function hasStartsAt(\DateTimeInterface $dateTime): bool
{
$timestamp = $dateTime->getTimestamp();
@@ -167,21 +120,6 @@ public function getRuleValidationErrorsCount(string $channelCode): int
return $this->countChannelErrors($this->getElement('rules'), $channelCode);
}
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessageForTranslation(string $element, string $localeCode): string
- {
- $foundElement = $this->getElement($element, ['%localeCode%' => $localeCode])->getParent();
-
- $validationMessage = $foundElement->find('css', '.sylius-validation-error');
- if (null === $validationMessage) {
- throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error');
- }
-
- return $validationMessage->getText();
- }
-
protected function getCodeElement(): NodeElement
{
return $this->getElement('code');
@@ -189,26 +127,25 @@ protected function getCodeElement(): NodeElement
protected function getDefinedElements(): array
{
- return [
+ return array_merge(parent::getDefinedElements(), [
'action_field' => '[id^="sylius_promotion_actions_"][id$="_configuration_%channelCode%_%field%"]',
'actions' => '#actions',
'applies_to_discounted' => '#sylius_promotion_appliesToDiscounted',
'code' => '#sylius_promotion_code',
- 'coupon_based' => '#sylius_promotion_couponBased',
'ends_at' => '#sylius_promotion_endsAt',
'ends_at_date' => '#sylius_promotion_endsAt_date',
'ends_at_time' => '#sylius_promotion_endsAt_time',
'exclusive' => '#sylius_promotion_exclusive',
- 'label' => '#sylius_promotion_translations_%localeCode%_label',
+ 'coupon_based' => '#sylius_promotion_couponBased',
'name' => '#sylius_promotion_name',
'order_percentage_action_field' => '[id^="sylius_promotion_actions_"][id$="_configuration_percentage"]',
'priority' => '#sylius_promotion_priority',
'rule_amount' => '[id^="sylius_promotion_rules_"][id$="_configuration_%channelCode%_amount"]',
'rules' => '#rules',
+ 'usage_limit' => '#sylius_promotion_usageLimit',
'starts_at' => '#sylius_promotion_startsAt',
'starts_at_date' => '#sylius_promotion_startsAt_date',
'starts_at_time' => '#sylius_promotion_startsAt_time',
- 'usage_limit' => '#sylius_promotion_usageLimit',
- ];
+ ]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php
index 3f3804b1ff4..be0d90f9675 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php
@@ -13,33 +13,16 @@
namespace Sylius\Behat\Page\Admin\Promotion;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
interface UpdatePageInterface extends BaseUpdatePageInterface
{
- public function setPriority(?int $priority): void;
-
- public function getPriority(): int;
-
public function nameIt(string $name): void;
public function checkChannelsState(string $channelName): bool;
public function isCodeDisabled(): bool;
- public function fillUsageLimit(string $limit): void;
-
- public function makeExclusive(): void;
-
- public function checkCouponBased(): void;
-
- public function checkChannel(string $name): void;
-
- public function setStartsAt(\DateTimeInterface $dateTime): void;
-
- public function setEndsAt(\DateTimeInterface $dateTime): void;
-
public function hasStartsAt(\DateTimeInterface $dateTime): bool;
public function hasEndsAt(\DateTimeInterface $dateTime): bool;
@@ -65,9 +48,4 @@ public function removeRuleAmount(string $channelCode): void;
public function getActionValidationErrorsCount(string $channelCode): int;
public function getRuleValidationErrorsCount(string $channelCode): int;
-
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessageForTranslation(string $element, string $localeCode): string;
}
diff --git a/src/Sylius/Behat/Resources/config/services/elements/admin.xml b/src/Sylius/Behat/Resources/config/services/elements/admin.xml
index 65c413b8487..b9c3ccbe71a 100644
--- a/src/Sylius/Behat/Resources/config/services/elements/admin.xml
+++ b/src/Sylius/Behat/Resources/config/services/elements/admin.xml
@@ -16,6 +16,8 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"
>
+
+
@@ -55,7 +57,9 @@
+ parent="sylius.behat.element.admin.crud.form"
+ >
+
+
diff --git a/src/Sylius/Behat/Service/TabsHelper.php b/src/Sylius/Behat/Service/TabsHelper.php
index 8adf746d2b9..50597bf6e79 100644
--- a/src/Sylius/Behat/Service/TabsHelper.php
+++ b/src/Sylius/Behat/Service/TabsHelper.php
@@ -27,15 +27,13 @@ public static function switchTab(Session $session, NodeElement $tabsContainer, s
return;
}
- $tab = $tabsContainer->find('css', sprintf('.item[data-tab*="%s"]', $dataTabHook));
+ $tab = $tabsContainer->find('css', sprintf('[data-test-tab*="%s"]', $dataTabHook));
if ($tab->hasClass('active')) {
return;
}
$tab->click();
- $tabContent = $tabsContainer->find('css', sprintf('.tab[data-tab*="%s"]', $dataTabHook));
-
- $session->getPage()->waitFor(5, fn () => $tabContent->isVisible());
+ $session->getPage()->waitFor(5, fn () => $tab->hasClass('active'));
}
}
diff --git a/src/Sylius/Bundle/AdminBundle/Autocompleter/ProductAutocompleter.php b/src/Sylius/Bundle/AdminBundle/Autocompleter/ProductAutocompleter.php
new file mode 100644
index 00000000000..17530dbcd81
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Autocompleter/ProductAutocompleter.php
@@ -0,0 +1,58 @@
+productClass;
+ }
+
+ /** @param EntityRepository $repository */
+ public function createFilteredQueryBuilder(EntityRepository $repository, string $query): QueryBuilder
+ {
+ return $repository->createQueryBuilder('o');
+ }
+
+ public function getLabel(object $entity): string
+ {
+ return $entity->getName();
+ }
+
+ public function getValue(object $entity): mixed
+ {
+ return $entity->getCode();
+ }
+
+ public function isGranted(Security $security): bool
+ {
+ return true;
+ }
+
+ /** @param array $options */
+ public function setOptions(array $options): void
+ {
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Autocompleter/TaxonAutocompleter.php b/src/Sylius/Bundle/AdminBundle/Autocompleter/TaxonAutocompleter.php
index 8ccc9b868b4..4d247b79ffc 100644
--- a/src/Sylius/Bundle/AdminBundle/Autocompleter/TaxonAutocompleter.php
+++ b/src/Sylius/Bundle/AdminBundle/Autocompleter/TaxonAutocompleter.php
@@ -38,7 +38,7 @@ public function createFilteredQueryBuilder(EntityRepository $repository, string
public function getLabel(object $entity): string
{
- return $entity->getFullName();
+ return $entity->getFullname();
}
public function getValue(object $entity): mixed
diff --git a/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Filter/ProductFilterConfigurationTypeExtension.php b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Filter/ProductFilterConfigurationTypeExtension.php
new file mode 100644
index 00000000000..8556def5fd0
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Filter/ProductFilterConfigurationTypeExtension.php
@@ -0,0 +1,47 @@
+ $productsToCodesTransformer */
+ public function __construct(private readonly DataTransformerInterface $productsToCodesTransformer)
+ {
+ }
+
+ /** @param array $options */
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ $builder
+ ->add('products', ProductAutocompleteChoiceType::class, [
+ 'label' => 'sylius.form.promotion_filter.products',
+ 'multiple' => true,
+ ])
+ ->get('products')->addModelTransformer($this->productsToCodesTransformer)
+ ;
+ }
+
+ /** @return iterable */
+ public static function getExtendedTypes(): iterable
+ {
+ return [ProductFilterConfigurationType::class];
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Filter/TaxonFilterConfigurationTypeExtension.php b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Filter/TaxonFilterConfigurationTypeExtension.php
new file mode 100644
index 00000000000..da550dd432b
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Filter/TaxonFilterConfigurationTypeExtension.php
@@ -0,0 +1,48 @@
+ $taxonsToCodesTransformer */
+ public function __construct(private readonly DataTransformerInterface $taxonsToCodesTransformer)
+ {
+ }
+
+ /** @param array $options */
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ $builder
+ ->add('taxons', TaxonAutocompleteChoiceType::class, [
+ 'label' => 'sylius.form.promotion_filter.taxons',
+ 'multiple' => true,
+ 'required' => false,
+ ])
+ ->get('taxons')->addModelTransformer($this->taxonsToCodesTransformer)
+ ;
+ }
+
+ /** @return iterable */
+ public static function getExtendedTypes(): iterable
+ {
+ return [TaxonFilterConfigurationType::class];
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/ContainsProductConfigurationTypeExtension.php b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/ContainsProductConfigurationTypeExtension.php
new file mode 100644
index 00000000000..325572bd0b1
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/ContainsProductConfigurationTypeExtension.php
@@ -0,0 +1,53 @@
+ $productRepository */
+ public function __construct(private readonly ProductRepositoryInterface $productRepository)
+ {
+ }
+
+ /** @param array $options */
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ $builder
+ ->add('product_code', ProductAutocompleteChoiceType::class, [
+ 'label' => 'sylius.form.promotion_action.add_product_configuration.product',
+ 'row_attr' => [
+ 'data-skip-morph' => '',
+ ],
+ ])
+ ->get('product_code')->addModelTransformer(
+ new ReversedTransformer(new ResourceToIdentifierTransformer($this->productRepository, 'code')),
+ )
+ ;
+ }
+
+ /** @return iterable */
+ public static function getExtendedTypes(): iterable
+ {
+ return [ContainsProductConfigurationType::class];
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/HasTaxonConfigurationTypeExtension.php b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/HasTaxonConfigurationTypeExtension.php
new file mode 100644
index 00000000000..9699171ceda
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/HasTaxonConfigurationTypeExtension.php
@@ -0,0 +1,50 @@
+ $taxonsToCodesTransformer */
+ public function __construct(private readonly DataTransformerInterface $taxonsToCodesTransformer)
+ {
+ }
+
+ /** @param array $options */
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ $builder
+ ->add('taxons', TaxonAutocompleteChoiceType::class, [
+ 'label' => 'sylius.form.promotion_rule.has_taxon.taxons',
+ 'multiple' => true,
+ 'row_attr' => [
+ 'data-skip-morph' => '',
+ ],
+ ])
+ ->get('taxons')->addModelTransformer($this->taxonsToCodesTransformer)
+ ;
+ }
+
+ /** @return iterable */
+ public static function getExtendedTypes(): iterable
+ {
+ return [HasTaxonConfigurationType::class];
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/TotalOfItemsFromTaxonConfigurationTypeExtension.php b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/TotalOfItemsFromTaxonConfigurationTypeExtension.php
new file mode 100644
index 00000000000..750643c6261
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Form/Extension/Promotion/Rule/TotalOfItemsFromTaxonConfigurationTypeExtension.php
@@ -0,0 +1,53 @@
+ $taxonRepository */
+ public function __construct(private readonly TaxonRepositoryInterface $taxonRepository)
+ {
+ }
+
+ /** @param array $options */
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ $builder
+ ->add('taxon', TaxonAutocompleteChoiceType::class, [
+ 'label' => 'sylius.form.promotion_rule.total_of_items_from_taxon.taxon',
+ 'row_attr' => [
+ 'data-skip-morph' => '',
+ ],
+ ])
+ ->get('taxon')->addModelTransformer(
+ new ReversedTransformer(new ResourceToIdentifierTransformer($this->taxonRepository, 'code')),
+ )
+ ;
+ }
+
+ /** @return iterable */
+ public static function getExtendedTypes(): iterable
+ {
+ return [TotalOfItemsFromTaxonConfigurationType::class];
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Form/Extension/PromotionTypeExtension.php b/src/Sylius/Bundle/AdminBundle/Form/Extension/PromotionTypeExtension.php
new file mode 100644
index 00000000000..e03af88e38b
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Form/Extension/PromotionTypeExtension.php
@@ -0,0 +1,55 @@
+ $options */
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ $builder
+ ->add('rules', LiveCollectionType::class, [
+ 'entry_type' => PromotionRuleType::class,
+ 'allow_add' => true,
+ 'allow_delete' => true,
+ 'by_reference' => false,
+ 'button_add_options' => [
+ 'label' => 'sylius.ui.add_rule',
+ ],
+ ])
+ ->add('actions', LiveCollectionType::class, [
+ 'entry_type' => PromotionActionType::class,
+ 'allow_add' => true,
+ 'allow_delete' => true,
+ 'by_reference' => false,
+ 'button_add_options' => [
+ 'label' => 'sylius.ui.add_action',
+ ],
+ ])
+ ;
+ }
+
+ /** @return iterable */
+ public static function getExtendedTypes(): iterable
+ {
+ return [PromotionType::class];
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Form/Type/ProductAutocompleteChoiceType.php b/src/Sylius/Bundle/AdminBundle/Form/Type/ProductAutocompleteChoiceType.php
new file mode 100644
index 00000000000..73d14128fbc
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Form/Type/ProductAutocompleteChoiceType.php
@@ -0,0 +1,47 @@
+setDefaults([
+ 'class' => $this->productClass,
+ 'choice_name' => 'name',
+ 'choice_value' => 'code',
+ ]);
+ }
+
+ public function getBlockPrefix(): string
+ {
+ return 'sylius_admin_product_autocomplete_choice';
+ }
+
+ public function getParent(): string
+ {
+ return BaseEntityAutocompleteType::class;
+ }
+}
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/app/config.yml b/src/Sylius/Bundle/AdminBundle/Resources/config/app/config.yml
index 4014da4db92..344389d905d 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/config/app/config.yml
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/app/config.yml
@@ -58,7 +58,7 @@ sylius_admin:
show: '@SyliusAdmin/Shared/Grid/ItemAction/_show.html.twig'
update: '@SyliusAdmin/Shared/Grid/ItemAction/_update.html.twig'
ship_with_tracking_code: '@SyliusAdmin/Shipment/Grid/Action/shipWithTrackingCode.html.twig'
- delete_catalog_promotion: "@SyliusAdmin/Promotion/Grid/Action/deleteCatalogPromotion.html.twig"
+ delete_catalog_promotion: "@SyliusAdmin/CatalogPromotion/Grid/Action/deleteCatalogPromotion.html.twig"
sylius_grid:
templates:
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/app/twig_hooks/promotion/create.yaml b/src/Sylius/Bundle/AdminBundle/Resources/config/app/twig_hooks/promotion/create.yaml
new file mode 100644
index 00000000000..f0469c40d66
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/app/twig_hooks/promotion/create.yaml
@@ -0,0 +1,62 @@
+twig_hooks:
+ hooks:
+ 'sylius_admin.promotion.create.content':
+ form:
+ component: 'sylius_admin:promotion:form'
+ data:
+ resource: '@=resource'
+ form: '@=form'
+ parentMainHook: '@=parent_main_hook'
+ parentFallbackHook: '@=parent_fallback_hook'
+ configuration:
+ render_rest: false
+
+ 'sylius_admin.promotion.create.content.form':
+ sections:
+ template: '@SyliusAdmin/promotion/form/sections.html.twig'
+
+ 'sylius_admin.promotion.create.content.form.sections':
+ general:
+ template: '@SyliusAdmin/promotion/form/sections/general.html.twig'
+ configuration:
+ template: '@SyliusAdmin/promotion/form/sections/configuration.html.twig'
+ translations:
+ template: '@SyliusAdmin/promotion/form/sections/translations.html.twig'
+ rules_and_actions:
+ template: '@SyliusAdmin/promotion/form/sections/rules_and_actions.html.twig'
+
+ 'sylius_admin.promotion.create.content.form.sections.general':
+ _name:
+ template: '@SyliusAdmin/promotion/form/sections/general/name.html.twig'
+ code:
+ template: '@SyliusAdmin/promotion/form/sections/general/code.html.twig'
+ description:
+ template: '@SyliusAdmin/promotion/form/sections/general/description.html.twig'
+ channels:
+ template: '@SyliusAdmin/promotion/form/sections/general/channels.html.twig'
+
+ 'sylius_admin.promotion.create.content.form.sections.configuration#left':
+ usage_limit:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/usage_limit.html.twig'
+ priority:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/priority.html.twig'
+ starts_at:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/starts_at.html.twig'
+ ends_at:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/ends_at.html.twig'
+
+ 'sylius_admin.promotion.create.content.form.sections.configuration#right':
+ header:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/header.html.twig'
+ coupon_based:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/coupon_based.html.twig'
+ exclusive:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/exclusive.html.twig'
+ applies_to_discounted:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/applies_to_discounted.html.twig'
+
+ 'sylius_admin.promotion.create.content.form.sections.rules_and_actions':
+ rules:
+ template: '@SyliusAdmin/promotion/form/sections/rules_and_actions/rules.html.twig'
+ actions:
+ template: '@SyliusAdmin/promotion/form/sections/rules_and_actions/actions.html.twig'
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/app/twig_hooks/promotion/update.yaml b/src/Sylius/Bundle/AdminBundle/Resources/config/app/twig_hooks/promotion/update.yaml
new file mode 100644
index 00000000000..4e84c8dfea2
--- /dev/null
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/app/twig_hooks/promotion/update.yaml
@@ -0,0 +1,62 @@
+twig_hooks:
+ hooks:
+ 'sylius_admin.promotion.update.content':
+ form:
+ component: 'sylius_admin:promotion:form'
+ data:
+ resource: '@=resource'
+ form: '@=form'
+ parentMainHook: '@=parent_main_hook'
+ parentFallbackHook: '@=parent_fallback_hook'
+ configuration:
+ method: 'PUT'
+
+ 'sylius_admin.promotion.update.content.form':
+ sections:
+ template: '@SyliusAdmin/promotion/form/sections.html.twig'
+
+ 'sylius_admin.promotion.update.content.form.sections':
+ general:
+ template: '@SyliusAdmin/promotion/form/sections/general.html.twig'
+ configuration:
+ template: '@SyliusAdmin/promotion/form/sections/configuration.html.twig'
+ translations:
+ template: '@SyliusAdmin/promotion/form/sections/translations.html.twig'
+ rules_and_actions:
+ template: '@SyliusAdmin/promotion/form/sections/rules_and_actions.html.twig'
+
+ 'sylius_admin.promotion.update.content.form.sections.general':
+ _name:
+ template: '@SyliusAdmin/promotion/form/sections/general/name.html.twig'
+ code:
+ template: '@SyliusAdmin/promotion/form/sections/general/code.html.twig'
+ description:
+ template: '@SyliusAdmin/promotion/form/sections/general/description.html.twig'
+ channels:
+ template: '@SyliusAdmin/promotion/form/sections/general/channels.html.twig'
+
+ 'sylius_admin.promotion.update.content.form.sections.configuration#left':
+ usage_limit:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/usage_limit.html.twig'
+ priority:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/priority.html.twig'
+ starts_at:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/starts_at.html.twig'
+ ends_at:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/ends_at.html.twig'
+
+ 'sylius_admin.promotion.update.content.form.sections.configuration#right':
+ header:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/header.html.twig'
+ coupon_based:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/coupon_based.html.twig'
+ exclusive:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/exclusive.html.twig'
+ applies_to_discounted:
+ template: '@SyliusAdmin/promotion/form/sections/configuration/applies_to_discounted.html.twig'
+
+ 'sylius_admin.promotion.update.content.form.sections.rules_and_actions':
+ rules:
+ template: '@SyliusAdmin/promotion/form/sections/rules_and_actions/rules.html.twig'
+ actions:
+ template: '@SyliusAdmin/promotion/form/sections/rules_and_actions/actions.html.twig'
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/grids/catalog_promotion.yaml b/src/Sylius/Bundle/AdminBundle/Resources/config/grids/catalog_promotion.yaml
index dffae96555a..402729249c9 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/config/grids/catalog_promotion.yaml
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/grids/catalog_promotion.yaml
@@ -44,7 +44,7 @@ sylius_grid:
label: sylius.ui.state
path: state
options:
- template: '@SyliusAdmin/Promotion/Grid/Field/state.html.twig'
+ template: '@SyliusAdmin/CatalogPromotion/Grid/Field/state.html.twig'
enabled:
type: twig
label: sylius.ui.enabled
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/grids/promotion.yml b/src/Sylius/Bundle/AdminBundle/Resources/config/grids/promotion.yml
index 7687e1f6f3a..da45cc3281c 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/config/grids/promotion.yml
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/grids/promotion.yml
@@ -13,7 +13,7 @@ sylius_grid:
label: sylius.ui.priority
sortable: ~
options:
- template: "@SyliusAdmin/Promotion/Grid/Field/priority.html.twig"
+ template: "@SyliusAdmin/promotion/grid/field/priority.html.twig"
code:
type: string
label: sylius.ui.code
@@ -36,7 +36,7 @@ sylius_grid:
path: .
sortable: used
options:
- template: "@SyliusAdmin/Promotion/Grid/Field/usage.html.twig"
+ template: "@SyliusAdmin/promotion/grid/field/usage.html.twig"
filters:
search:
type: string
@@ -62,6 +62,13 @@ sylius_grid:
create:
type: create
item:
+ update:
+ type: update
+ delete:
+ type: delete
+ archive:
+ type: archive
+ subitem:
coupons:
type: links
label: sylius.ui.manage_coupons
@@ -87,12 +94,6 @@ sylius_grid:
route: sylius_admin_promotion_coupon_generate
parameters:
promotionId: resource.id
- update:
- type: update
- delete:
- type: delete
- archive:
- type: archive
bulk:
delete:
type: delete
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/services/autocompleter.xml b/src/Sylius/Bundle/AdminBundle/Resources/config/services/autocompleter.xml
index c82510f975b..d0625a30423 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/config/services/autocompleter.xml
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/services/autocompleter.xml
@@ -13,11 +13,16 @@
-
+ %sylius.model.product_attribute.class%
+
+ %sylius.model.product.class%
+
+
+
%sylius.model.taxon.class%
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/services/form.xml b/src/Sylius/Bundle/AdminBundle/Resources/config/services/form.xml
index f49c9601086..b5182efcd07 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/config/services/form.xml
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/services/form.xml
@@ -67,6 +67,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %sylius.model.product.class%
+
+
+
+
+ %sylius.model.taxon.class%
+
+
+
%sylius.form.type.admin.password_reset_request.validation_groups%
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/config/services/twig/component.xml b/src/Sylius/Bundle/AdminBundle/Resources/config/services/twig/component.xml
index c4144f00de2..49c270a0df8 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/config/services/twig/component.xml
+++ b/src/Sylius/Bundle/AdminBundle/Resources/config/services/twig/component.xml
@@ -73,6 +73,13 @@
+
+
+ Sylius\Bundle\PromotionBundle\Form\Type\PromotionType
+ %sylius.promotion_rules%
+ %sylius.promotion_actions%
+
+
Sylius\Bundle\OrderBundle\Form\Type\OrderType
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Action/deleteCatalogPromotion.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/CatalogPromotion/Grid/Action/deleteCatalogPromotion.html.twig
similarity index 100%
rename from src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Action/deleteCatalogPromotion.html.twig
rename to src/Sylius/Bundle/AdminBundle/Resources/views/CatalogPromotion/Grid/Action/deleteCatalogPromotion.html.twig
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/state.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/CatalogPromotion/Grid/Field/state.html.twig
similarity index 100%
rename from src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/state.html.twig
rename to src/Sylius/Bundle/AdminBundle/Resources/views/CatalogPromotion/Grid/Field/state.html.twig
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Form/Sections/_translations.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Form/Sections/_translations.html.twig
index 4f00bd30279..2a6899b0721 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Form/Sections/_translations.html.twig
+++ b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Form/Sections/_translations.html.twig
@@ -39,6 +39,6 @@
{% endverbatim %}
{% endset %}
- {{ _translations.default(hookable_data.form.translations, body) }}
+ {{ _translations.default(hookable_data.form.translations, body, {accordionId: 'product-translations'}) }}
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Form/Sections/_translations.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Form/Sections/_translations.html.twig
index b0a803f3c61..a3a6480dd4f 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Form/Sections/_translations.html.twig
+++ b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Form/Sections/_translations.html.twig
@@ -11,6 +11,6 @@
{% endverbatim %}
{% endset %}
- {{ _translations.default(hookable_data.form.translations, body) }}
+ {{ _translations.default(hookable_data.form.translations, body, {accordionId: 'product-variant-translations'}) }}
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shared/Helper/translations.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shared/Helper/translations.html.twig
index 76c894b5483..31897a1c82c 100644
--- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shared/Helper/translations.html.twig
+++ b/src/Sylius/Bundle/AdminBundle/Resources/views/Shared/Helper/translations.html.twig
@@ -1,8 +1,4 @@
{% macro default(translationFields, body = null, options = {}) %}
- {% set options = {
- accordionId: 'product-translations'
- }|merge(options) %}
-
{% for locale, translationForm in translationFields %}