diff --git a/README.md b/README.md
index 889fd072..b91f2605 100644
--- a/README.md
+++ b/README.md
@@ -379,7 +379,7 @@ This plugin will also import product associations. It's a zero configuration imp
### Launch data import from CLI
-To actually import data you must first create queue items with the **enqueue command** and then you can import them with the **consume command**.
+To actually import data from CLI you can use the **import command** (see below).
#### Schedule Akeneo PIM import button
@@ -387,77 +387,43 @@ This button allows you to queue a product directly from the admin index page. By

-#### Enqueue command
+#### Import command
-To create queue items you can use the `webgriffe:akeneo:enqueue` console command:
+To create queue items you can use the `webgriffe:akeneo:import` console command:
```bash
-bin/console webgriffe:akeneo:enqueue --since="2020-01-30"
+bin/console webgriffe:akeneo:import --since="2020-01-30"
```
-This will enqueue all Akeneo entities updated after the provided date.
+This will import all Akeneo entities updated after the provided date.
You can also use a "since file" where to read the since date:
```bash
echo "2020-01-30" > var/storage/akeneo-sincefile.txt
-bin/console webgriffe:akeneo:enqueue --since-file="var/storage/akeneo-sincefile.txt"
+bin/console webgriffe:akeneo:import --since-file="var/storage/akeneo-sincefile.txt"
```
-When run with the since file, the enqueue command will write the current date/time to the since file after the enqueueing process is terminated. This is useful when you put the enqueue command in cron:
+When run with the since file, the import command will write the current date/time to the since file after the importing process is terminated. This is useful when you put the import command in cron:
```
-* * * * * /usr/bin/php /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:enqueue --since-file=/path/to/sylius/var/storage/akeneo-enqueue-sincefile.txt
+* * * * * /usr/bin/php /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:import --since-file=/path/to/sylius/var/storage/akeneo-import-sincefile.txt
```
-This way the enqueue command is run repeatedly enqueuing only producs modified since the last command execution.
+This way the import command is run repeatedly importing only products modified since the last command execution.
-You can also enqueue items only for specific importers:
+You can also import items only for specific importers:
```bash
-bin/console webgriffe:akeneno:enqueue --importer="Product" --importer="MyImporter" --since="2020-01-30"
+bin/console webgriffe:akeneno:import --importer="Product" --importer="MyImporter" --since="2020-01-30"
```
-You can also enqueue items regardless of their last update date:
+You can also import items regardless of their last update date:
```bash
-bin/console webgriffe:akeneno:enqueue --all
+bin/console webgriffe:akeneno:import --all
```
-
-#### Consume command
-
-To import the Akeneo entities that are in the queue you can use the `webgriffe:akeneo:consume` console command:
-
-```bash
-bin/console webgriffe:akeneo:consume
-```
-
-This will consume all queue items which are not imported yet.
-
-Of course you can put this command in cron as well:
-
-```
-* * * * * /usr/bin/php /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:consume
-```
-
-### Browsing queue items in the admin
-
-You can examine the Akeneo import queue from the admin panel at **Catalog -> Akeneo PIM import**. You can filter and sort items and see their error message:
-
-
-
-### Queue clear
-
-Sometimes it may be a good idea to clear the queue of imported items. This can also be useful in development to keep only items not imported due to errors or yet to be consumed.
-You can clear the queue of elements by launching the following command:
-
-```bash
-bin/console webgriffe:akeneo:cleanup-queue {days}
-```
-
-Where {days} should be replaced by the number of days back from which to start deleting the queue of items.
-If the number is not entered, the default value 10 will be used.
-So, if for example today is 2020-12-15 and you use the parameter days = 10, all the elements imported before 2020-12-05 will be deleted.
+Import command assume that Symfony Messenger is working as required since Sylius v1.11.
### Products reconciliation
@@ -474,20 +440,18 @@ It could be useful to add also this command to your scheduler to run automatical
To make all importers and other plugin features work automatically the following is the suggested crontab:
```
-0 * * * * /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:enqueue --all --importer="AttributeOptions"
-* * * * * /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:enqueue --since-file=/path/to/sylius/var/storage/akeneo-enqueue-sincefile.txt --importer="Product" --importer="ProductAssociations"
-* * * * * /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:consume
-0 0 * * * /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:cleanup-queue
+0 * * * * /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:import --all --importer="AttributeOptions"
+* * * * * /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:import --since-file=/path/to/sylius/var/storage/akeneo-import-sincefile.txt --importer="Product" --importer="ProductAssociations"
0 */6 * * * /path/to/sylius/bin/console -e prod -q webgriffe:akeneo:reconcile
```
This will:
-* Enqueue the update of all attribute options every hour
+* Import the update of all attribute options every hour
* Import, every minute, all products that have been modified since the last execution, along with their associations
* Clean the imported items queue older than 10 days, every day at midnight
* Reconcile Akeneo deleted products every 6 hours
-Enqueue, Consume and Reconcile commands uses a [lock mechanism](https://symfony.com/doc/current/console/lockable_trait.html) which prevents running them if another instance of the same command is already running.
+Import and Reconcile commands uses a [lock mechanism](https://symfony.com/doc/current/console/lockable_trait.html) which prevents running them if another instance of the same command is already running.
## Architecture & customization
diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md
index 8461cdd6..35dce359 100644
--- a/UPGRADE-2.0.md
+++ b/UPGRADE-2.0.md
@@ -64,7 +64,7 @@ Removed all deprecations of the v1.x releases.
##### Removed
- [BC] Property Webgriffe\SyliusAkeneoPlugin\DependencyInjection\WebgriffeSyliusAkeneoExtension::$valueHandlersTypesDefinitions was removed
- [BC] Removed the service `webgriffe_sylius_akeneo_plugin.repository.cleanable_queue_item`, use the `webgriffe_sylius_akeneo.repository.cleanable_queue_item` instead.
- - [BC] Removed the service `webgriffe_sylius_akeneo_plugin.controller.product_enqueue_controller`, use the `webgriffe_sylius_akeneo.controller.product_enqueue_controller` instead.
+ - [BC] Removed the service `webgriffe_sylius_akeneo_plugin.controller.product_enqueue_controller`, use the `webgriffe_sylius_akeneo.controller.product_import_controller` instead.
- [BC] Removed the resource `webgriffe_sylius_akeneo_plugin.queue_item` use the `webgriffe_sylius_akeneo.queue_item` instead.
### Test changes
diff --git a/features/cleaning_queue.feature b/features/cleaning_queue.feature
deleted file mode 100644
index 7c85e917..00000000
--- a/features/cleaning_queue.feature
+++ /dev/null
@@ -1,39 +0,0 @@
-@cleaning_queue
-Feature: cleaning queue
- In order to have better performances during the akeneo pim import
- As a store owner
- I want to clean old already imported queue items.
-
- @cli
- Scenario: Cleaning the queue when there are no imported queue items
- Given there is a not imported item with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- When I clean the queue
- Then I should be notified that there are no items to clean
-
- @cli
- Scenario: Cleaning the queue when there are some imported items to clean
- Given there is an already imported item with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And this item has been imported 15 days ago
- When I clean the queue
- Then I should be notified that 1 item has been deleted
- And there shouldn't be any more item to clean
-
- @cli
- Scenario: Cleaning the queue specifying the retention number of days
- Given there is an already imported item with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And this item has been imported 15 days ago
- And there is an already imported item with identifier "braided-hat-s" for the "Product" importer in the Akeneo queue
- And this item has been imported 20 days ago
- When I clean the queue specifying 16 days of retention
- Then I should be notified that 1 item has been deleted
- And there shouldn't be any more item to clean
-
- @cli
- Scenario: Cleaning the queue specifying zero as retention number of days
- Given there is an already imported item with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And this item has been imported now
- And there is an already imported item with identifier "braided-hat-s" for the "Product" importer in the Akeneo queue
- And this item has been imported 20 days ago
- When I clean the queue specifying 0 days of retention
- Then I should be notified that 2 items have been deleted
- And there shouldn't be any more items to clean
diff --git a/features/enqueuing_generic_items.feature b/features/enqueuing_generic_items.feature
deleted file mode 100644
index dc2fe730..00000000
--- a/features/enqueuing_generic_items.feature
+++ /dev/null
@@ -1,52 +0,0 @@
-@enqueuing_generic_items
-Feature: Enqueuing items
- In order to import data from Akeneo
- As a Store Owner
- I want to add enqueue items to the Akeneo PIM queue
-
- @cli
- Scenario: Enqueueing items when no item is modified since the given date
- When I enqueue items for all importers modified since date "2020-01-20 01:00:00"
- Then there should be no item in the Akeneo queue
-
- @cli
- Scenario: Enqueueing items without a since date
- When I enqueue items for all importers with no since date
- Then I should be notified that a since date is required
- And there should be no item in the Akeneo queue
-
- @cli
- Scenario: Enqueueing items with an invalid since date
- When I enqueue items for all importers with invalid since date
- Then I should be notified that the since date must be a valid date
-
- @cli
- Scenario: Enqueueing items with a since date specified from a not existent file
- When I enqueue items with since date specified from a not existent file
- Then I should be notified that the since date file does not exists
-
- @cli
- Scenario: Avoiding to enqueue two times the same item if it has not been imported yet
- Given there is a product "product-1" updated at "2020-01-20 22:23:13" on Akeneo
- And there is one item to import with identifier "product-1" for the "Product" importer in the Akeneo queue
- When I enqueue items for all importers modified since date "2020-01-20 01:00:00"
- Then there should be only one queue item with identifier "product-1" for the "Product" importer in the Akeneo queue
-
- @cli
- Scenario: Enqueuing all items regardless last modified date
- Given there are 3 products on Akeneo
- When I enqueue all items for all importers
- Then there should be 3 items for the "Product" importer in the Akeneo queue
- And there should be 3 items for the "ProductAssociations" importer in the Akeneo queue
-
- @cli
- Scenario: Enqueuing all items for one importer only
- Given there are 3 products on Akeneo
- When I enqueue all items for the "Product" importer
- Then there should be 3 items for the "Product" importer in the Akeneo queue
- And there should be items for the "Product" importer only in the Akeneo queue
-
- @cli
- Scenario: Enqueuing all items for a not existent importer
- When I enqueue all items for a not existent importer
- Then I should be notified that the importer does not exists
diff --git a/features/enqueuing_products.feature b/features/enqueuing_products.feature
deleted file mode 100644
index 54fc55cf..00000000
--- a/features/enqueuing_products.feature
+++ /dev/null
@@ -1,64 +0,0 @@
-@enqueuing_products
-Feature: Enqueuing products
- In order to import my products from Akeneo
- As a Store Owner
- I want to add them to the Akeneo PIM queue
-
- @cli
- Scenario: Enqueuing products modified since a given date
- Given there is a product "product-1" updated at "2020-01-10 22:23:13" on Akeneo
- And there is a product "product-2" updated at "2020-01-21 09:54:12" on Akeneo
- And there is a product "product-3" updated at "2020-01-22 08:15:08" on Akeneo
- When I enqueue items for all importers modified since date "2020-01-20 01:00:00"
- Then the queue item with identifier "product-1" for the "Product" importer should not be in the Akeneo queue
- And the queue item with identifier "product-2" for the "Product" importer should be in the Akeneo queue
- And the queue item with identifier "product-3" for the "Product" importer should be in the Akeneo queue
-
- @cli
- Scenario: There are no products modified since datetime read in file
- Given there is a file with name "last-date" and content "2020-01-20 01:00:00"
- And current date time is "2020-01-25T12:00:00+01:00"
- When I enqueue items for all importers modified since date specified from file "last-date"
- Then there should be no item in the queue for the "Product" importer
- And there is a file with name "last-date" that contains "2020-01-25T12:00:00+01:00"
-
- @cli
- Scenario: Enqueuing products modified since datetime read in file
- Given there is a product "product-1" updated at "2020-01-10 22:23:13" on Akeneo
- And there is a product "product-2" updated at "2020-01-21 09:54:12" on Akeneo
- And there is a file with name "last-date" and content "2020-01-20 01:00:00"
- And current date time is "2020-01-25T12:00:00+01:00"
- When I enqueue items for all importers modified since date specified from file "last-date"
- Then the queue item with identifier "product-1" for the "Product" importer should not be in the Akeneo queue
- And the queue item with identifier "product-2" for the "Product" importer should be in the Akeneo queue
- And there is a file with name "last-date" that contains "2020-01-25T12:00:00+01:00"
-
- @ui
- Scenario: Enqueuing a simple product
- Given I am logged in as an administrator
- And the store has a product "Braided hat m"
- When I browse products
- And I schedule an Akeneo PIM import for the "Braided hat m" product
- Then I should be notified that it has been successfully enqueued
- And I should see 1, not imported, item in the Akeneo queue items list
-
- @ui
- Scenario: Enqueuing a product already enqueued
- Given I am logged in as an administrator
- And the store has a product "Braided hat l"
- And there is one item to import with identifier "BRAIDED_HAT_L" for the "Product" importer in the Akeneo queue
- When I browse products
- And I schedule an Akeneo PIM import for the "Braided hat l" product
- Then I should be notified that it has been already enqueued
- And I should see 1, not imported, item in the Akeneo queue items list
-
- @ui
- Scenario: Enqueuing a configurable product
- Given the store operates on a single channel
- And the store has a "Braided hat" configurable product
- And this product has "Small", "Medium" and "Large" variants
- And I am logged in as an administrator
- When I browse products
- And I schedule an Akeneo PIM import for the "Braided hat" product
- Then I should be notified that it has been successfully enqueued
- And I should see 3, not imported, items in the Akeneo queue items list
diff --git a/features/enqueuing_products_associations.feature b/features/enqueuing_products_associations.feature
deleted file mode 100644
index f0367f1b..00000000
--- a/features/enqueuing_products_associations.feature
+++ /dev/null
@@ -1,15 +0,0 @@
-@enqueuing_products_associations
-Feature: Enqueuing products associations
- In order to import my products associations from Akeneo
- As a Store Owner
- I want to add them to the Akeneo PIM queue
-
- @cli
- Scenario: Enqueuing products associations for products modified since a given date
- Given there is a product "product-1" updated at "2020-01-10 22:23:13" on Akeneo
- And there is a product "product-2" updated at "2020-01-21 09:54:12" on Akeneo
- And there is a product "product-3" updated at "2020-01-22 08:15:08" on Akeneo
- When I enqueue items for all importers modified since date "2020-01-20 01:00:00"
- Then the queue item with identifier "product-1" for the "ProductAssociations" importer should not be in the Akeneo queue
- And the queue item with identifier "product-2" for the "ProductAssociations" importer should be in the Akeneo queue
- And the queue item with identifier "product-3" for the "ProductAssociations" importer should be in the Akeneo queue
diff --git a/features/importing_generic_items.feature b/features/importing_generic_items.feature
new file mode 100644
index 00000000..ff05f506
--- /dev/null
+++ b/features/importing_generic_items.feature
@@ -0,0 +1,63 @@
+@importing_generic_items
+Feature: Importing items
+ In order to import data from Akeneo
+ As an Administrator
+ I want to import items from the Akeneo PIM
+
+ Background:
+ Given I am logged in as an administrator
+ And the store has a product association type "Pack" with a code "PACK"
+
+ @cli @ui
+ Scenario: Importing items when no item is modified since the given date
+ When I import items for all importers modified since date "2020-01-20 01:00:00"
+ And I browse products
+ Then I should see 0 products in the list
+
+ @cli @ui
+ Scenario: Importing items without a since date
+ When I import items for all importers with no since date
+ Then I should be notified that a since date is required
+ When I browse products
+ Then I should see 0 products in the list
+
+ @cli @ui
+ Scenario: Importing items with an invalid since date
+ When I import items for all importers with invalid since date
+ Then I should be notified that the since date must be a valid date
+ When I browse products
+ Then I should see 0 products in the list
+
+ @cli @ui
+ Scenario: Importing items with a since date specified from a not existent file
+ When I import items with since date specified from a not existent file
+ Then I should be notified that the since date file does not exists
+ When I browse products
+ Then I should see 0 products in the list
+
+ @cli @ui
+ Scenario: Importing all items regardless last modified date
+ Given there is a product "1314976" updated at "2022-06-15" on Akeneo
+ And there is a product "10597353" updated at "2022-07-23" on Akeneo
+ And there is a product "11164822" updated at "2022-08-01" on Akeneo
+ When I import all items for all importers
+ And I browse products
+ Then I should see 3 products in the list
+ And the product with code "11164822" should have an association "Pack" with product "10597353"
+
+ @cli @ui
+ Scenario: Importing all items for one importer only
+ Given there is a product "1314976" updated at "2022-06-15" on Akeneo
+ And there is a product "10597353" updated at "2022-07-23" on Akeneo
+ And there is a product "11164822" updated at "2022-08-01" on Akeneo
+ When I import all items for the "Product" importer
+ And I browse products
+ Then I should see 3 products in the list
+ And the product with code "11164822" should not have an association "Pack" with product "10597353"
+
+ @cli @ui
+ Scenario: Importing all items for a not existent importer
+ When I import all items for a not existent importer
+ Then I should be notified that the importer does not exists
+ When I browse products
+ Then I should see 0 products in the list
diff --git a/features/importing_product_associations_from_queue.feature b/features/importing_product_associations.feature
similarity index 86%
rename from features/importing_product_associations_from_queue.feature
rename to features/importing_product_associations.feature
index da8618a1..28b5fce1 100644
--- a/features/importing_product_associations_from_queue.feature
+++ b/features/importing_product_associations.feature
@@ -10,8 +10,8 @@ Feature: Importing product associations from queue
And the store has a product "10627329"
And the store has a product "upsell-product-1" with code "upsell-product-1"
And the store has a product "upsell-product-2" with code "upsell-product-2"
- And there is one product associations to import with identifier "10627329" in the Akeneo queue
And the store has a product association type "Upsell" with a code "UPSELL"
- When I import all items in queue
+ And there is a product "10627329" on Akeneo
+ When I import all from Akeneo
Then the product "10627329" should be associated to product "upsell-product-1" for association with code "UPSELL"
And the product "10627329" should be associated to product "upsell-product-2" for association with code "UPSELL"
diff --git a/features/importing_products.feature b/features/importing_products.feature
new file mode 100644
index 00000000..85449549
--- /dev/null
+++ b/features/importing_products.feature
@@ -0,0 +1,50 @@
+@importing_products
+Feature: Importing products
+ In order to show updated data about my products
+ As a Store Owner
+ I want to import products from Akeneo PIM
+
+ Background:
+ Given there is a product "BRAIDED_HAT_M" on Akeneo
+ And there is a product "BRAIDED_HAT_L" on Akeneo
+
+ @cli
+ Scenario: Importing single product model and its variants
+ Given the store operates on a single channel
+ And the store is also available in "it_IT"
+ When I import all from Akeneo
+ Then the product "MODEL_BRAIDED_HAT" should exists with the right data
+ And the product variant "BRAIDED_HAT_M" of product "MODEL_BRAIDED_HAT" should exists with the right data
+ And the product variant "BRAIDED_HAT_L" of product "MODEL_BRAIDED_HAT" should exists with the right data
+
+ @cli
+ Scenario: Importing products with images should not leave temporary files in temporary files directory
+ Given the store operates on a single channel
+ And the store is also available in "it_IT"
+ When I import all from Akeneo
+ Then there should not be any temporary file in the temporary files directory
+
+ @ui
+ Scenario: Importing a simple product
+ Given there is a product "11164822" on Akeneo
+ And I am logged in as an administrator
+ And the store has a product "11164822"
+ When I browse products
+ And I schedule an Akeneo PIM import for the "11164822" product
+ Then I should be notified that it has been successfully enqueued
+ And the product "11164822" should exists with the right data
+ And the product variant "11164822" of product "11164822" should exists with the right data
+
+ @ui
+ Scenario: Importing a configurable product
+ Given the store operates on a single channel
+ And the store has a "Model Braided Hat" configurable product
+ And this product has "Braided Hat S", "Braided Hat M" and "Braided Hat L" variants
+ And I am logged in as an administrator
+ When I browse products
+ And I schedule an Akeneo PIM import for the "Model Braided Hat" product
+ Then I should be notified that it has been successfully enqueued
+ Then the product "MODEL_BRAIDED_HAT" should exists with the right data
+ And the product variant "BRAIDED_HAT_S" of product "MODEL_BRAIDED_HAT" should exists with the right data
+ And the product variant "BRAIDED_HAT_M" of product "MODEL_BRAIDED_HAT" should exists with the right data
+ And the product variant "BRAIDED_HAT_L" of product "MODEL_BRAIDED_HAT" should exists with the right data
diff --git a/features/importing_products_from_queue.feature b/features/importing_products_from_queue.feature
deleted file mode 100644
index f3d21b14..00000000
--- a/features/importing_products_from_queue.feature
+++ /dev/null
@@ -1,47 +0,0 @@
-@importing_products
-Feature: Importing products from queue
- In order to show updated data about my products
- As a Store Owner
- I want to import products from Akeneo PIM queue
-
- @cli
- Scenario: Importing single product model and its variants from queue
- Given the store operates on a single channel
- And the store is also available in "it_IT"
- And there is one item to import with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And there is one item to import with identifier "braided-hat-l" for the "Product" importer in the Akeneo queue
- When I import all items in queue
- Then the product "model-braided-hat" should exists with the right data
- And the product variant "braided-hat-m" of product "model-braided-hat" should exists with the right data
- And the product variant "braided-hat-l" of product "model-braided-hat" should exists with the right data
-
- @cli
- Scenario: Keeping the queue item as not imported while importing non existent product model from queue
- Given the store operates on a single channel
- And the store is also available in "it_IT"
- And there is one item to import with identifier "NOT_EXISTS" for the "Product" importer in the Akeneo queue
- When I import all items in queue
- Then the product "NOT_EXISTS" should not exists
- And the queue item with identifier "NOT_EXISTS" for the "Product" importer has not been marked as imported
- And the queue item with identifier "NOT_EXISTS" for the "Product" importer has an error message
-
- @cli
- Scenario: Going on with subsequent product imports when any fail
- Given the store operates on a single channel
- And the store is also available in "it_IT"
- And there is one item to import with identifier "NOT_EXISTS" for the "Product" importer in the Akeneo queue
- And there is one item to import with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- When I import all items in queue
- Then the product "NOT_EXISTS" should not exists
- And the product variant "braided-hat-m" of product "model-braided-hat" should exists with the right data
- And the queue item with identifier "braided-hat-m" for the "Product" importer has been marked as imported
- And the queue item with identifier "NOT_EXISTS" for the "Product" importer has not been marked as imported
-
- @cli
- Scenario: Importing products with images should not leave temporary files in temporary files directory
- Given the store operates on a single channel
- And the store is also available in "it_IT"
- And there is one item to import with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And there is one item to import with identifier "braided-hat-l" for the "Product" importer in the Akeneo queue
- When I import all items in queue
- Then there should not be any temporary file in the temporary files directory
diff --git a/features/managing_queue_items/browsing_queue_items.feature b/features/managing_queue_items/browsing_queue_items.feature
deleted file mode 100644
index e746e623..00000000
--- a/features/managing_queue_items/browsing_queue_items.feature
+++ /dev/null
@@ -1,44 +0,0 @@
-@managing_queue_items
-Feature: Browsing queue items
- In order to see the status of imported and not imported items from Akeneo
- As an Administrator
- I want to browse the Akeneo items queue
-
- Background:
- Given I am logged in as an administrator
- And there is a not imported item with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And there is a not imported item with identifier "braided-hat-l" for the "ProductAssociations" importer in the Akeneo queue
- And there is an already imported item with identifier "braided-hat-s" for the "Product" importer in the Akeneo queue
-
- @ui
- Scenario: Browsing all items
- When I browse Akeneo queue items
- Then I should see 3 queue items in the list
-
- @ui
- Scenario: Browsing not imported items
- When I browse Akeneo queue items
- And I choose "No" as an imported filter
- And I filter
- Then I should see 2, not imported, queue items in the list
-
- @ui
- Scenario: Browsing imported items
- When I browse Akeneo queue items
- And I choose "Yes" as an imported filter
- And I filter
- Then I should see 1, imported, queue item in the list
-
- @ui
- Scenario: Filtering items by importer
- When I browse Akeneo queue items
- And I specify "Associations" as an importer filter
- And I filter
- Then I should see 1 queue item in the list
-
- @ui
- Scenario: Filtering items by identifier
- When I browse Akeneo queue items
- And I specify "hat-l" as an identifier filter
- And I filter
- Then I should see 1 queue item in the list
diff --git a/features/managing_queue_items/deleting_queue_items.feature b/features/managing_queue_items/deleting_queue_items.feature
deleted file mode 100644
index 6e04523e..00000000
--- a/features/managing_queue_items/deleting_queue_items.feature
+++ /dev/null
@@ -1,29 +0,0 @@
-@managing_queue_items
-Feature: Deleting queue items
- In order to keep the Akeneo import queue clean
- As an Administrator
- I want to delete queue items that I know that will never be imported
-
- Background:
- Given I am logged in as an administrator
-
- @ui
- Scenario: Deleting single queue item
- Given there is a not imported item with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And I browse Akeneo queue items
- When I delete the "braided-hat-m" queue item
- Then I should be notified that it has been successfully deleted
- And this queue item should no longer exist in the queue
-
- @ui @javascript
- Scenario: Deleting multiple queue items at once
- Given there is a not imported item with identifier "braided-hat-l" for the "Product" importer in the Akeneo queue
- And there is a not imported item with identifier "braided-hat-m" for the "Product" importer in the Akeneo queue
- And there is a not imported item with identifier "braided-hat-s" for the "Product" importer in the Akeneo queue
- When I browse Akeneo queue items
- And I check the "braided-hat-m" queue item
- And I check also the "braided-hat-s" queue item
- And I delete them
- Then I should be notified that they have been successfully deleted
- And I should see a single queue item in the list
- And I should see the "braided-hat-l" queue item in the list
diff --git a/spec/ValueHandler/FileAttributeValueHandlerSpec.php b/spec/ValueHandler/FileAttributeValueHandlerSpec.php
index b5925d1c..c52e68d6 100644
--- a/spec/ValueHandler/FileAttributeValueHandlerSpec.php
+++ b/spec/ValueHandler/FileAttributeValueHandlerSpec.php
@@ -17,6 +17,7 @@
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Symfony\Component\Filesystem\Filesystem;
+use Webgriffe\SyliusAkeneoPlugin\TemporaryFilesManagerInterface;
use Webgriffe\SyliusAkeneoPlugin\ValueHandler\FileAttributeValueHandler;
use Webgriffe\SyliusAkeneoPlugin\ValueHandlerInterface;
use Webmozart\Assert\InvalidArgumentException;
@@ -31,7 +32,8 @@ public function let(
MediaFileApiInterface $productMediaFileApi,
Filesystem $filesystem,
ProductVariantInterface $productVariant,
- ProductInterface $product
+ ProductInterface $product,
+ TemporaryFilesManagerInterface $temporaryFilesManager,
): void {
$commerceChannel = new Channel();
$commerceChannel->setCode('ecommerce');
@@ -43,7 +45,8 @@ public function let(
$apiClient->getProductMediaFileApi()->willReturn($productMediaFileApi);
$productMediaFileApi->download(Argument::type('string'))->willReturn(new Response(200, [], '__FILE_CONTENT__'));
$attributeApi->get('allegato_1')->willReturn(['type' => 'pim_catalog_file']);
- $this->beConstructedWith($apiClient, $filesystem, 'allegato_1', 'public/media/attachment/product/');
+ $temporaryFilesManager->generateTemporaryFilePath()->willReturn('tempfile');
+ $this->beConstructedWith($apiClient, $filesystem, $temporaryFilesManager, 'allegato_1', 'public/media/attachment/product/');
}
public function it_is_initializable(): void
diff --git a/spec/ValueHandler/ImageValueHandlerSpec.php b/spec/ValueHandler/ImageValueHandlerSpec.php
index 587556d8..437e0303 100644
--- a/spec/ValueHandler/ImageValueHandlerSpec.php
+++ b/spec/ValueHandler/ImageValueHandlerSpec.php
@@ -19,6 +19,7 @@
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Webgriffe\SyliusAkeneoPlugin\ApiClientInterface;
+use Webgriffe\SyliusAkeneoPlugin\TemporaryFilesManagerInterface;
use Webgriffe\SyliusAkeneoPlugin\ValueHandler\ImageValueHandler;
class ImageValueHandlerSpec extends ObjectBehavior
@@ -45,7 +46,8 @@ public function let(
ResponseInterface $downloadResponse,
StreamInterface $responseBody,
ProductVariantInterface $productVariant,
- ProductInterface $product
+ ProductInterface $product,
+ TemporaryFilesManagerInterface $temporaryFilesManager,
): void {
$productImageFactory->createNew()->willReturn($productImage);
$apiClient->getProductMediaFileApi()->willReturn($productMediaFileApi);
@@ -66,10 +68,12 @@ public function let(
$productImageRepository
->findBy(['owner' => $product, 'type' => self::SYLIUS_IMAGE_TYPE])
->willReturn(new ArrayCollection([]));
+ $temporaryFilesManager->generateTemporaryFilePath()->willReturn('tempfile');
$this->beConstructedWith(
$productImageFactory,
$productImageRepository,
$apiClient,
+ $temporaryFilesManager,
self::AKENEO_ATTRIBUTE_CODE,
self::SYLIUS_IMAGE_TYPE
);
diff --git a/src/Command/ConsumeCommand.php b/src/Command/ConsumeCommand.php
deleted file mode 100644
index 7cbb49c7..00000000
--- a/src/Command/ConsumeCommand.php
+++ /dev/null
@@ -1,104 +0,0 @@
-setDescription('Process the Queue by calling the proper importer for each item');
- }
-
- /**
- * @throws \Throwable
- */
- protected function execute(InputInterface $input, OutputInterface $output): int
- {
- if (!$this->lock()) {
- $output->writeln('The command is already running in another process.');
-
- return 0;
- }
-
- $queueItems = $this->queueItemRepository->findAllToImport();
- foreach ($queueItems as $queueItem) {
- $akeneoIdentifier = $queueItem->getAkeneoIdentifier();
-
- try {
- $importer = $this->resolveImporter($queueItem->getAkeneoEntity());
- $importer->import($akeneoIdentifier);
- $queueItem->setImportedAt(new \DateTime());
- $queueItem->setErrorMessage(null);
- } catch (\Throwable $t) {
- /** @var EntityManagerInterface $objectManager */
- $objectManager = $this->managerRegistry->getManager();
- if (!$objectManager->isOpen()) {
- $this->release();
-
- throw $t;
- }
- $queueItem->setErrorMessage($t->getMessage() . \PHP_EOL . $t->getTraceAsString());
- $output->writeln(
- sprintf(
- 'There has been an error importing %s entity with identifier %s. ' .
- 'The error was: %s.',
- $queueItem->getAkeneoEntity(),
- $akeneoIdentifier,
- $t->getMessage(),
- ),
- );
- if ($output->isVeryVerbose()) {
- $output->writeln((string) $t);
- }
- }
-
- $this->queueItemRepository->add($queueItem);
- $output->writeln(
- sprintf(
- '%s entity with identifier %s has been imported.',
- $queueItem->getAkeneoEntity(),
- $akeneoIdentifier,
- ),
- );
- }
-
- $this->release();
-
- return 0;
- }
-
- private function resolveImporter(string $akeneoEntity): ImporterInterface
- {
- foreach ($this->importerRegistry->all() as $importer) {
- if ($importer->getAkeneoEntity() === $akeneoEntity) {
- return $importer;
- }
- }
-
- throw new \RuntimeException(sprintf('Cannot find suitable importer for entity "%s".', $akeneoEntity));
- }
-}
diff --git a/src/Command/EnqueueCommand.php b/src/Command/ImportCommand.php
similarity index 71%
rename from src/Command/EnqueueCommand.php
rename to src/Command/ImportCommand.php
index 76894567..792f220a 100644
--- a/src/Command/EnqueueCommand.php
+++ b/src/Command/ImportCommand.php
@@ -4,20 +4,22 @@
namespace Webgriffe\SyliusAkeneoPlugin\Command;
-use Sylius\Component\Resource\Factory\FactoryInterface;
+use DateTime;
+use InvalidArgumentException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Messenger\MessageBusInterface;
+use Throwable;
use Webgriffe\SyliusAkeneoPlugin\DateTimeBuilderInterface;
-use Webgriffe\SyliusAkeneoPlugin\Entity\QueueItemInterface;
use Webgriffe\SyliusAkeneoPlugin\ImporterInterface;
use Webgriffe\SyliusAkeneoPlugin\ImporterRegistryInterface;
-use Webgriffe\SyliusAkeneoPlugin\Repository\QueueItemRepositoryInterface;
+use Webgriffe\SyliusAkeneoPlugin\Message\ItemImport;
use Webmozart\Assert\Assert;
-final class EnqueueCommand extends Command
+final class ImportCommand extends Command
{
use LockableTrait;
@@ -29,13 +31,12 @@ final class EnqueueCommand extends Command
private const IMPORTER_OPTION_NAME = 'importer';
- protected static $defaultName = 'webgriffe:akeneo:enqueue';
+ protected static $defaultName = 'webgriffe:akeneo:import';
public function __construct(
- private QueueItemRepositoryInterface $queueItemRepository,
- private FactoryInterface $queueItemFactory,
private DateTimeBuilderInterface $dateTimeBuilder,
private ImporterRegistryInterface $importerRegistry,
+ private MessageBusInterface $messageBus,
) {
parent::__construct();
}
@@ -43,7 +44,7 @@ public function __construct(
protected function configure(): void
{
$this->setDescription(
- 'Populate the Queue with Akeneo\'s entities that has been modified since a specified date/datetime',
+ 'Import Akeneo\'s entities that has been modified since a specified date/datetime',
);
$this->addOption(
self::SINCE_OPTION_NAME,
@@ -61,13 +62,13 @@ protected function configure(): void
self::ALL_OPTION_NAME,
'a',
InputOption::VALUE_NONE,
- 'Enqueue all identifiers regardless their last modified date.',
+ 'Import all identifiers regardless their last modified date.',
);
$this->addOption(
self::IMPORTER_OPTION_NAME,
'i',
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
- 'Enqueue items only for specified importers',
+ 'Import items only for specified importers',
);
}
@@ -76,18 +77,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$sinceFilePath = null;
if ('' !== $sinceOptionValue = (string) $input->getOption(self::SINCE_OPTION_NAME)) {
try {
- $sinceDate = new \DateTime($sinceOptionValue);
- } catch (\Throwable) {
- throw new \InvalidArgumentException(
+ $sinceDate = new DateTime($sinceOptionValue);
+ } catch (Throwable) {
+ throw new InvalidArgumentException(
sprintf('The "%s" argument must be a valid date', self::SINCE_OPTION_NAME),
);
}
} elseif ('' !== $sinceFilePath = (string) $input->getOption(self::SINCE_FILE_OPTION_NAME)) {
$sinceDate = $this->getSinceDateByFile($sinceFilePath);
} elseif ($input->getOption(self::ALL_OPTION_NAME) === true) {
- $sinceDate = (new \DateTime())->setTimestamp(0);
+ $sinceDate = (new DateTime())->setTimestamp(0);
} else {
- throw new \InvalidArgumentException(
+ throw new InvalidArgumentException(
sprintf(
'One of "--%s", "--%s" or "--%s" option must be specified',
self::SINCE_OPTION_NAME,
@@ -118,18 +119,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
continue;
}
foreach ($identifiers as $identifier) {
- if ($this->isEntityAlreadyQueuedToImport($importer->getAkeneoEntity(), $identifier)) {
- continue;
- }
- $queueItem = $this->queueItemFactory->createNew();
- Assert::isInstanceOf($queueItem, QueueItemInterface::class);
- $queueItem->setAkeneoEntity($importer->getAkeneoEntity());
- $queueItem->setAkeneoIdentifier($identifier);
- $queueItem->setCreatedAt(new \DateTime());
- $this->queueItemRepository->add($queueItem);
+ $itemImport = new ItemImport(
+ $importer->getAkeneoEntity(),
+ $identifier,
+ );
+ $this->messageBus->dispatch($itemImport);
$output->writeln(
sprintf(
- '%s entity with identifier %s enqueued.',
+ '%s entity with identifier %s imported.',
$importer->getAkeneoEntity(),
$identifier,
),
@@ -146,20 +143,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return 0;
}
- private function getSinceDateByFile(string $filepath): \DateTime
+ private function getSinceDateByFile(string $filepath): DateTime
{
if (!file_exists($filepath)) {
- throw new \InvalidArgumentException(
+ throw new InvalidArgumentException(
sprintf('The file "%s" does not exists', $filepath),
);
}
if (!is_readable($filepath)) {
- throw new \InvalidArgumentException(
+ throw new InvalidArgumentException(
sprintf('The file "%s" is not readable', $filepath),
);
}
if (!is_writable($filepath)) {
- throw new \InvalidArgumentException(
+ throw new InvalidArgumentException(
sprintf('The file "%s" is not writable', $filepath),
);
}
@@ -167,29 +164,19 @@ private function getSinceDateByFile(string $filepath): \DateTime
try {
$content = file_get_contents($filepath);
Assert::string($content);
- $sinceDate = new \DateTime(trim($content));
- } catch (\Throwable $t) {
+ $sinceDate = new DateTime(trim($content));
+ } catch (Throwable $t) {
throw new \RuntimeException(sprintf('The file "%s" must contain a valid datetime', $filepath), 0, $t);
}
return $sinceDate;
}
- private function writeSinceDateFile(string $filepath, \DateTime $runDate): void
+ private function writeSinceDateFile(string $filepath, DateTime $runDate): void
{
file_put_contents($filepath, $runDate->format('c'));
}
- private function isEntityAlreadyQueuedToImport(string $akeneoEntity, string $akeneoIdentifier): bool
- {
- $queueItem = $this->queueItemRepository->findOneToImport($akeneoEntity, $akeneoIdentifier);
- if ($queueItem !== null) {
- return true;
- }
-
- return false;
- }
-
/**
* @return ImporterInterface[]
*/
@@ -220,7 +207,7 @@ private function getImporters(InputInterface $input): array
$importers = [];
foreach ($importersToUse as $importerToUse) {
if (!array_key_exists($importerToUse, $allImporters)) {
- throw new \InvalidArgumentException(sprintf('Importer "%s" does not exists.', $importerToUse));
+ throw new InvalidArgumentException(sprintf('Importer "%s" does not exists.', $importerToUse));
}
$importers[] = $allImporters[$importerToUse];
}
diff --git a/src/Command/QueueCleanupCommand.php b/src/Command/QueueCleanupCommand.php
deleted file mode 100644
index fb22cf14..00000000
--- a/src/Command/QueueCleanupCommand.php
+++ /dev/null
@@ -1,97 +0,0 @@
-setDescription('Clean the Akeneo\'s queue of items older than N days.')
- ->setHelp('This command allows you to clean the Akeneo\'s queue of item older than a specificed numbers of days.')
- ->addArgument(
- self::DAYS_ARGUMENT_NAME,
- InputArgument::OPTIONAL,
- 'Number of days from which to purge the queue of previous items',
- (string) (self::DEFAULT_DAYS),
- )
- ;
- }
-
- protected function execute(InputInterface $input, OutputInterface $output): int
- {
- $numberOfDays = self::DEFAULT_DAYS;
- // get the number of days from user
- $numberOfDaysEntered = $input->getArgument(self::DAYS_ARGUMENT_NAME);
- if ($numberOfDaysEntered !== null) {
- if (!is_string($numberOfDaysEntered) || (int) $numberOfDaysEntered < 0) {
- $output->writeln('Sorry, the number of days entered is not valid!');
-
- return self::FAILURE;
- }
- $numberOfDays = (int) $numberOfDaysEntered;
- }
-
- // get the beginning date
- $dateToDelete = $this->getPreviousDateNDays($numberOfDays);
-
- $queueItems = $this->queueItemRepository->findToCleanup($dateToDelete);
-
- if (count($queueItems) === 0) {
- $output->writeln('There are no items to clean');
-
- return self::SUCCESS;
- }
-
- /** @var QueueItem $queueItem */
- foreach ($queueItems as $queueItem) {
- $this->queueItemRepository->remove($queueItem);
- }
-
- $output->writeln(sprintf('%s items imported before %s has been deleted.', count($queueItems), $dateToDelete->format('Y-m-d H:i:s')));
-
- return self::SUCCESS;
- }
-
- /**
- * @throws \Exception
- */
- private function getPreviousDateNDays(int $numberOfDays): DateTime
- {
- $dtBuilder = new DateTimeBuilder();
- $today = $dtBuilder->build();
-
- return $today->sub(new DateInterval(sprintf('P%dD', $numberOfDays)));
- }
-}
diff --git a/src/Controller/ProductEnqueueController.php b/src/Controller/ProductImportController.php
similarity index 51%
rename from src/Controller/ProductEnqueueController.php
rename to src/Controller/ProductImportController.php
index 69375a19..057f416b 100644
--- a/src/Controller/ProductEnqueueController.php
+++ b/src/Controller/ProductImportController.php
@@ -9,23 +9,21 @@
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
-use Webgriffe\SyliusAkeneoPlugin\Entity\QueueItem;
-use Webgriffe\SyliusAkeneoPlugin\Repository\QueueItemRepositoryInterface;
+use Webgriffe\SyliusAkeneoPlugin\Message\ItemImport;
use Webmozart\Assert\Assert;
-final class ProductEnqueueController extends AbstractController
+final class ProductImportController extends AbstractController
{
public function __construct(
- private QueueItemRepositoryInterface $queueItemRepository,
private ProductRepositoryInterface $productRepository,
- private UrlGeneratorInterface $urlGenerator,
+ private MessageBusInterface $messageBus,
private TranslatorInterface $translator,
) {
}
- public function enqueueAction(int $productId): Response
+ public function importAction(int $productId): Response
{
/** @var ProductInterface|null $product */
$product = $this->productRepository->find($productId);
@@ -33,38 +31,20 @@ public function enqueueAction(int $productId): Response
throw new NotFoundHttpException('Product not found');
}
- $alreadyEnqueued = [];
$enqueued = [];
foreach ($product->getVariants() as $productVariant) {
$productVariantCode = $productVariant->getCode();
Assert::notNull($productVariantCode);
- $productEnqueued = $this->queueItemRepository->findBy([
- 'akeneoIdentifier' => $productVariantCode,
- 'akeneoEntity' => 'Product',
- 'importedAt' => null,
- ]);
- if (count($productEnqueued) > 0) {
- $alreadyEnqueued[] = $productVariantCode;
-
- continue;
- }
-
- $queueItem = new QueueItem();
- $queueItem->setAkeneoEntity('Product');
- $queueItem->setAkeneoIdentifier($productVariantCode);
- $queueItem->setCreatedAt(new \DateTime());
- $this->queueItemRepository->add($queueItem);
+ $queueItem = new ItemImport(
+ 'Product',
+ $productVariantCode,
+ );
+ $this->messageBus->dispatch($queueItem);
$enqueued[] = $productVariantCode;
}
- foreach ($alreadyEnqueued as $code) {
- $this->addFlash(
- 'error',
- $this->translator->trans('webgriffe_sylius_akeneo.ui.product_already_enqueued', ['code' => $code]), // @phpstan-ignore-line
- );
- }
foreach ($enqueued as $code) {
$this->addFlash(
'success',
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index f4e653c3..6b16a2d4 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -4,13 +4,8 @@
namespace Webgriffe\SyliusAkeneoPlugin\DependencyInjection;
-use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
-use Sylius\Component\Resource\Factory\Factory;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
-use Webgriffe\SyliusAkeneoPlugin\Doctrine\ORM\QueueItemRepository;
-use Webgriffe\SyliusAkeneoPlugin\Entity\QueueItem;
-use Webgriffe\SyliusAkeneoPlugin\Entity\QueueItemInterface;
final class Configuration implements ConfigurationInterface
{
@@ -56,25 +51,6 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->end()
- ->arrayNode('resources')->addDefaultsIfNotSet()
- ->children()
- ->arrayNode('queue_item')->addDefaultsIfNotSet()
- ->children()
- ->variableNode('options')->end()
- ->arrayNode('classes')->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('model')->defaultValue(QueueItem::class)->cannotBeEmpty()->end()
- ->scalarNode('interface')->defaultValue(QueueItemInterface::class)->cannotBeEmpty()->end()
- ->scalarNode('controller')->defaultValue(ResourceController::class)->cannotBeEmpty()->end()
- ->scalarNode('factory')->defaultValue(Factory::class)->cannotBeEmpty()->end()
- ->scalarNode('repository')->defaultValue(QueueItemRepository::class)->cannotBeEmpty()->end()
- ->end()
- ->end()
- ->end()
- ->end()
- ->end()
- ->end()
-
->end()
;
diff --git a/src/DependencyInjection/WebgriffeSyliusAkeneoExtension.php b/src/DependencyInjection/WebgriffeSyliusAkeneoExtension.php
index 886d954a..52494efd 100644
--- a/src/DependencyInjection/WebgriffeSyliusAkeneoExtension.php
+++ b/src/DependencyInjection/WebgriffeSyliusAkeneoExtension.php
@@ -53,6 +53,7 @@ final class WebgriffeSyliusAkeneoExtension extends AbstractResourceExtension imp
'$productImageFactory' => 'sylius.factory.product_image',
'$productImageRepository' => 'sylius.repository.product_image',
'$apiClient' => 'webgriffe_sylius_akeneo.api_client',
+ '$temporaryFilesManager' => 'webgriffe_sylius_akeneo.temporary_file_manager',
],
],
'immutable_slug' => [
@@ -99,6 +100,7 @@ final class WebgriffeSyliusAkeneoExtension extends AbstractResourceExtension imp
'arguments' => [
'$apiClient' => 'webgriffe_sylius_akeneo.api_client',
'$filesystem' => 'filesystem',
+ '$temporaryFilesManager' => 'webgriffe_sylius_akeneo.temporary_file_manager',
],
],
'metric_property' => [
@@ -118,9 +120,6 @@ public function load(array $config, ContainerBuilder $container): void
$config = $this->processConfiguration($this->getConfiguration([], $container), $config);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
- Assert::isArray($config['resources']);
-
- $this->registerResources('webgriffe_sylius_akeneo', 'doctrine/orm', $config['resources'], $container);
$this->registerApiClientParameters($config['api_client'], $container);
$loader->load('services.xml');
diff --git a/src/Doctrine/ORM/QueueItemRepository.php b/src/Doctrine/ORM/QueueItemRepository.php
deleted file mode 100644
index 89fe9210..00000000
--- a/src/Doctrine/ORM/QueueItemRepository.php
+++ /dev/null
@@ -1,50 +0,0 @@
-createQueryBuilder('o')
- ->andWhere('o.importedAt IS NULL')
- ->getQuery()
- ->getResult()
- ;
- }
-
- public function findOneToImport(string $akeneoEntity, string $akeneoIdentifier): ?QueueItemInterface
- {
- return $this->createQueryBuilder('o')
- ->andWhere('o.importedAt IS NULL')
- ->andWhere('o.akeneoEntity = :akeneoEntity')
- ->andWhere('o.akeneoIdentifier = :akeneoIdentifier')
- ->setParameter('akeneoEntity', $akeneoEntity)
- ->setParameter('akeneoIdentifier', $akeneoIdentifier)
- ->getQuery()
- ->getOneOrNullResult()
- ;
- }
-
- public function findToCleanup(DateTime $dateLimit): array
- {
- return $this->createQueryBuilder('o')
- ->where('o.importedAt IS NOT NULL')
- ->andWhere('o.importedAt <= :dateLimit')
- ->setParameter('dateLimit', $dateLimit)
- ->getQuery()
- ->getResult()
- ;
- }
-}
diff --git a/src/Entity/QueueItem.php b/src/Entity/QueueItem.php
deleted file mode 100644
index 6da0e483..00000000
--- a/src/Entity/QueueItem.php
+++ /dev/null
@@ -1,80 +0,0 @@
-id;
- }
-
- public function getAkeneoEntity(): string
- {
- return $this->akeneoEntity;
- }
-
- public function getAkeneoIdentifier(): string
- {
- return $this->akeneoIdentifier;
- }
-
- public function getErrorMessage(): ?string
- {
- return $this->errorMessage;
- }
-
- public function getCreatedAt(): DateTimeInterface
- {
- return $this->createdAt;
- }
-
- public function getImportedAt(): ?DateTimeInterface
- {
- return $this->importedAt;
- }
-
- public function setAkeneoIdentifier(string $identifier): void
- {
- $this->akeneoIdentifier = $identifier;
- }
-
- public function setAkeneoEntity(string $entity): void
- {
- $this->akeneoEntity = $entity;
- }
-
- public function setErrorMessage(?string $errorMessage): void
- {
- $this->errorMessage = $errorMessage;
- }
-
- public function setCreatedAt(DateTimeInterface $createdAt): void
- {
- $this->createdAt = $createdAt;
- }
-
- public function setImportedAt(?DateTimeInterface $importedAt): void
- {
- $this->importedAt = $importedAt;
- }
-}
diff --git a/src/Entity/QueueItemInterface.php b/src/Entity/QueueItemInterface.php
deleted file mode 100644
index 15239675..00000000
--- a/src/Entity/QueueItemInterface.php
+++ /dev/null
@@ -1,30 +0,0 @@
- ['onTerminateCommand']];
- }
-
- public function onTerminateCommand(ConsoleTerminateEvent $event): void
- {
- $command = $event->getCommand();
-
- if ($command !== null && $command->getName() === 'webgriffe:akeneo:consume') {
- $this->temporaryFilesManager->deleteAllTemporaryFiles();
- }
- }
-}
diff --git a/src/EventSubscriber/ProductEventSubscriber.php b/src/EventSubscriber/ProductEventSubscriber.php
new file mode 100644
index 00000000..15c9d636
--- /dev/null
+++ b/src/EventSubscriber/ProductEventSubscriber.php
@@ -0,0 +1,38 @@
+ ['removeImagesFileProperty', -50],
+ 'sylius.product.pre_update' => ['removeImagesFileProperty', -50],
+ ];
+ }
+
+ /**
+ * When more than two variants with different images are handled by the same instance of Messenger
+ * the file property should be removed after having uploaded with the Sylius\Bundle\CoreBundle\EventListener\ImagesUploadListener.
+ * Otherwise, the next pre create/update product event will throw an error by getting content from the first image that was removed by the TemporaryFilesManager.
+ * See features/importing_products_from_queue.feature for having a real case.
+ */
+ public function removeImagesFileProperty(GenericEvent $event): void
+ {
+ /** @var ImagesAwareInterface|mixed $subject */
+ $subject = $event->getSubject();
+ Assert::isInstanceOf($subject, ImagesAwareInterface::class);
+
+ foreach ($subject->getImages() as $image) {
+ $image->setFile(null);
+ }
+ }
+}
diff --git a/src/Menu/AdminMenuListener.php b/src/Menu/AdminMenuListener.php
deleted file mode 100644
index 96c8814e..00000000
--- a/src/Menu/AdminMenuListener.php
+++ /dev/null
@@ -1,25 +0,0 @@
-getMenu();
- $catalogMenu = $menu->getChild('catalog');
- if ($catalogMenu === null) {
- return;
- }
-
- $catalogMenu
- ->addChild('webgriffe_sylius_akeneo.queue_item', ['route' => 'webgriffe_sylius_akeneo_admin_queue_item_index'])
- ->setLabel('webgriffe_sylius_akeneo.ui.queue_items')
- ->setLabelAttribute('icon', 'cloud download')
- ;
- }
-}
diff --git a/src/Message/ItemImport.php b/src/Message/ItemImport.php
new file mode 100644
index 00000000..aa19a29e
--- /dev/null
+++ b/src/Message/ItemImport.php
@@ -0,0 +1,24 @@
+akeneoEntity;
+ }
+
+ public function getAkeneoIdentifier(): string
+ {
+ return $this->akeneoIdentifier;
+ }
+}
diff --git a/src/MessageHandler/ItemImportHandler.php b/src/MessageHandler/ItemImportHandler.php
new file mode 100644
index 00000000..feea55ba
--- /dev/null
+++ b/src/MessageHandler/ItemImportHandler.php
@@ -0,0 +1,44 @@
+getAkeneoIdentifier();
+ $importer = $this->resolveImporter($message->getAkeneoEntity());
+ $importer->import($akeneoIdentifier);
+
+ $this->entityManager->flush();
+
+ $this->temporaryFilesManager->deleteAllTemporaryFiles();
+ }
+
+ private function resolveImporter(string $akeneoEntity): ImporterInterface
+ {
+ foreach ($this->importerRegistry->all() as $importer) {
+ if ($importer->getAkeneoEntity() === $akeneoEntity) {
+ return $importer;
+ }
+ }
+
+ throw new RuntimeException(sprintf('Cannot find suitable importer for entity "%s".', $akeneoEntity));
+ }
+}
diff --git a/src/Product/Importer.php b/src/Product/Importer.php
index 991d1c64..0b88d1f3 100644
--- a/src/Product/Importer.php
+++ b/src/Product/Importer.php
@@ -104,8 +104,11 @@ public function getIdentifiersModifiedSince(DateTime $sinceDate): array
$products = $this->apiClient->getProductApi()->all(50, ['search' => $searchBuilder->getFilters()]);
$identifiers = [];
foreach ($products as $product) {
- Assert::string($product['identifier']);
- $identifiers[] = $product['identifier'];
+ Assert::isArray($product);
+ Assert::keyExists($product, 'identifier');
+ $productIdentifier = (string) $product['identifier'];
+ Assert::stringNotEmpty($productIdentifier);
+ $identifiers[] = $productIdentifier;
}
return $identifiers;
diff --git a/src/ProductAssociations/Importer.php b/src/ProductAssociations/Importer.php
index bfdd9200..ba1ff52c 100644
--- a/src/ProductAssociations/Importer.php
+++ b/src/ProductAssociations/Importer.php
@@ -131,7 +131,11 @@ public function getIdentifiersModifiedSince(DateTime $sinceDate): array
$products = $this->apiClient->getProductApi()->all(50, ['search' => $searchBuilder->getFilters()]);
$identifiers = [];
foreach ($products as $product) {
- $identifiers[] = $product['identifier'];
+ Assert::isArray($product);
+ Assert::keyExists($product, 'identifier');
+ $productIdentifier = (string) $product['identifier'];
+ Assert::stringNotEmpty($productIdentifier);
+ $identifiers[] = $productIdentifier;
}
return $identifiers;
diff --git a/src/Repository/CleanableQueueItemRepositoryInterface.php b/src/Repository/CleanableQueueItemRepositoryInterface.php
deleted file mode 100644
index 85e48287..00000000
--- a/src/Repository/CleanableQueueItemRepositoryInterface.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index 89adc2c3..a9436850 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -6,35 +6,11 @@
-
-
-
-
-
-
- Webgriffe\SyliusAkeneoPlugin\Entity\QueueItem
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
@@ -70,11 +46,10 @@
-
+
-
-
+
@@ -90,15 +65,10 @@
%webgriffe_sylius_akeneo.temporary_files_prefix%
-
-
+
-
-
@@ -164,5 +134,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml
index 01e1ad25..22a20d40 100644
--- a/src/Resources/translations/messages.en.yaml
+++ b/src/Resources/translations/messages.en.yaml
@@ -8,7 +8,7 @@ webgriffe_sylius_akeneo:
imported_yes: Yes, at %date%
imported_no: No
error_message: Error message
- enqueue: Schedule Akeneo PIM import
+ import: Schedule Akeneo PIM import
enqueued_success: Akeneo PIM import for product "{code}" has been successfully scheduled
product_not_exist: Product not found
product_already_enqueued: Akeneo PIM import for product "{code}" has been already scheduled before
diff --git a/src/Resources/translations/messages.it.yaml b/src/Resources/translations/messages.it.yaml
index 2df00806..4c2d9ee6 100644
--- a/src/Resources/translations/messages.it.yaml
+++ b/src/Resources/translations/messages.it.yaml
@@ -8,7 +8,7 @@ webgriffe_sylius_akeneo:
imported_yes: Si, il %date%
imported_no: No
error_message: Messaggio d'errore
- enqueue: Programma importazione da Akeneo PIM
+ import: Programma importazione da Akeneo PIM
enqueued_success: L'importazione del prodotto "{code}" da Akeneo PIM è stata correttamente programmata
product_not_exist: Prodotto non trovato
product_already_enqueued: L'importazione del prodotto "{code}" da Akeneo PIM è già stata programmata precedentemente
diff --git a/src/Resources/views/Product/Grid/Action/enqueue.html.twig b/src/Resources/views/Product/Grid/Action/import.html.twig
similarity index 100%
rename from src/Resources/views/Product/Grid/Action/enqueue.html.twig
rename to src/Resources/views/Product/Grid/Action/import.html.twig
diff --git a/src/Resources/views/QueueItem/Grid/importedAt.html.twig b/src/Resources/views/QueueItem/Grid/importedAt.html.twig
deleted file mode 100644
index 66a2cd92..00000000
--- a/src/Resources/views/QueueItem/Grid/importedAt.html.twig
+++ /dev/null
@@ -1,11 +0,0 @@
-{% if data %}
-
-
- {{ 'webgriffe_sylius_akeneo.ui.imported_yes'|trans({'%date%': data|date('Y-m-d H:i:s')}) }}
-
-{% else %}
-
-
- {{ 'webgriffe_sylius_akeneo.ui.imported_no'|trans }}
-
-{% endif %}
diff --git a/src/ValueHandler/FileAttributeValueHandler.php b/src/ValueHandler/FileAttributeValueHandler.php
index a10beb8e..4a659e6c 100644
--- a/src/ValueHandler/FileAttributeValueHandler.php
+++ b/src/ValueHandler/FileAttributeValueHandler.php
@@ -7,6 +7,7 @@
use Akeneo\Pim\ApiClient\AkeneoPimClientInterface;
use Akeneo\Pim\ApiClient\Exception\HttpException;
use InvalidArgumentException;
+use const JSON_THROW_ON_ERROR;
use SplFileInfo;
use Sylius\Component\Channel\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
@@ -14,6 +15,7 @@
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpKernel\Exception\HttpException as SymfonyHttpException;
+use Webgriffe\SyliusAkeneoPlugin\TemporaryFilesManagerInterface;
use Webgriffe\SyliusAkeneoPlugin\ValueHandlerInterface;
use Webmozart\Assert\Assert;
@@ -24,6 +26,7 @@ final class FileAttributeValueHandler implements ValueHandlerInterface
public function __construct(
private AkeneoPimClientInterface $apiClient,
private Filesystem $filesystem,
+ private TemporaryFilesManagerInterface $temporaryFilesManager,
private string $akeneoAttributeCode,
private string $downloadPath,
) {
@@ -137,14 +140,18 @@ private function downloadFile(string $mediaCode): SplFileInfo
$bodyContents = $response->getBody()->getContents();
if ($statusClass !== 2) {
/** @var array $responseResult */
- $responseResult = json_decode($bodyContents, true, 512, \JSON_THROW_ON_ERROR);
+ $responseResult = json_decode($bodyContents, true, 512, JSON_THROW_ON_ERROR);
throw new SymfonyHttpException((int) $responseResult['code'], (string) $responseResult['message']);
}
- $tempName = tempnam(sys_get_temp_dir(), 'akeneo-');
- Assert::string($tempName);
+ $tempName = $this->generateTempFilePath();
file_put_contents($tempName, $bodyContents);
return new File($tempName);
}
+
+ private function generateTempFilePath(): string
+ {
+ return $this->temporaryFilesManager->generateTemporaryFilePath();
+ }
}
diff --git a/src/ValueHandler/ImageValueHandler.php b/src/ValueHandler/ImageValueHandler.php
index b70a4412..fc2c360b 100644
--- a/src/ValueHandler/ImageValueHandler.php
+++ b/src/ValueHandler/ImageValueHandler.php
@@ -5,6 +5,7 @@
namespace Webgriffe\SyliusAkeneoPlugin\ValueHandler;
use Akeneo\Pim\ApiClient\AkeneoPimClientInterface;
+use InvalidArgumentException;
use SplFileInfo;
use Sylius\Component\Channel\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductImageInterface;
@@ -14,6 +15,7 @@
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpKernel\Exception\HttpException;
+use Webgriffe\SyliusAkeneoPlugin\TemporaryFilesManagerInterface;
use Webgriffe\SyliusAkeneoPlugin\ValueHandlerInterface;
use Webmozart\Assert\Assert;
@@ -23,6 +25,7 @@ public function __construct(
private FactoryInterface $productImageFactory,
private RepositoryInterface $productImageRepository,
private AkeneoPimClientInterface $apiClient,
+ private TemporaryFilesManagerInterface $temporaryFilesManager,
private string $akeneoAttributeCode,
private string $syliusImageType,
) {
@@ -42,7 +45,7 @@ public function supports($subject, string $attribute, array $value): bool
public function handle($subject, string $attribute, array $value): void
{
if (!$subject instanceof ProductVariantInterface) {
- throw new \InvalidArgumentException(
+ throw new InvalidArgumentException(
sprintf(
'This image value handler only supports instances of %s, %s given.',
ProductVariantInterface::class,
@@ -137,7 +140,7 @@ private function getValue(array $value, ProductInterface $product): ?string
$productChannelCodes = array_map(static fn (ChannelInterface $channel): ?string => $channel->getCode(), $product->getChannels()->toArray());
foreach ($value as $valueData) {
if (!is_array($valueData)) {
- throw new \InvalidArgumentException(sprintf('Invalid Akeneo value data: expected an array, "%s" given.', gettype($valueData)));
+ throw new InvalidArgumentException(sprintf('Invalid Akeneo value data: expected an array, "%s" given.', gettype($valueData)));
}
// todo: we should throw here? it seeme that API won't never return an empty array
if (!array_key_exists('data', $valueData)) {
@@ -145,7 +148,7 @@ private function getValue(array $value, ProductInterface $product): ?string
}
if (!array_key_exists('scope', $valueData)) {
- throw new \InvalidArgumentException('Invalid Akeneo value data: required "scope" information was not found.');
+ throw new InvalidArgumentException('Invalid Akeneo value data: required "scope" information was not found.');
}
if ($valueData['scope'] !== null && !in_array($valueData['scope'], $productChannelCodes, true)) {
continue;
@@ -154,13 +157,13 @@ private function getValue(array $value, ProductInterface $product): ?string
/** @psalm-suppress MixedAssignment */
$data = $valueData['data'];
if (!is_string($data) && null !== $data) {
- throw new \InvalidArgumentException(sprintf('Invalid Akeneo value data: expected a string or null value, got "%s".', gettype($data)));
+ throw new InvalidArgumentException(sprintf('Invalid Akeneo value data: expected a string or null value, got "%s".', gettype($data)));
}
return $data;
}
- throw new \InvalidArgumentException('Invalid Akeneo value data: cannot find the media code.');
+ throw new InvalidArgumentException('Invalid Akeneo value data: cannot find the media code.');
}
private function downloadFile(string $mediaCode): SplFileInfo
@@ -174,10 +177,14 @@ private function downloadFile(string $mediaCode): SplFileInfo
throw new HttpException((int) $responseResult['code'], (string) $responseResult['message']);
}
- $tempName = tempnam(sys_get_temp_dir(), 'akeneo-');
- Assert::string($tempName);
+ $tempName = $this->generateTempFilePath();
file_put_contents($tempName, $bodyContents);
return new File($tempName);
}
+
+ private function generateTempFilePath(): string
+ {
+ return $this->temporaryFilesManager->generateTemporaryFilePath();
+ }
}
diff --git a/tests/Application/config/packages/test/messenger.yaml b/tests/Application/config/packages/test/messenger.yaml
new file mode 100644
index 00000000..561f725d
--- /dev/null
+++ b/tests/Application/config/packages/test/messenger.yaml
@@ -0,0 +1,4 @@
+framework:
+ messenger:
+ transports:
+ main: 'sync://'
diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/Product/_showInShopButton.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/Product/_showInShopButton.html.twig
index 491033e8..6a443f0c 100644
--- a/tests/Application/templates/bundles/SyliusAdminBundle/Product/_showInShopButton.html.twig
+++ b/tests/Application/templates/bundles/SyliusAdminBundle/Product/_showInShopButton.html.twig
@@ -36,7 +36,7 @@
{% endif %}
{% endif %}
-
+
- {{ 'webgriffe_sylius_akeneo.ui.enqueue'|trans }}
+ {{ 'webgriffe_sylius_akeneo.ui.import'|trans }}
diff --git a/tests/Behat/Context/Cli/ConsumeCommandContext.php b/tests/Behat/Context/Cli/ConsumeCommandContext.php
index 3d0fb005..e69de29b 100644
--- a/tests/Behat/Context/Cli/ConsumeCommandContext.php
+++ b/tests/Behat/Context/Cli/ConsumeCommandContext.php
@@ -1,30 +0,0 @@
-kernel);
- $application->setAutoExit(false);
- $application->add($this->consumeCommand);
- $applicationTester = new ApplicationTester($application);
- $applicationTester->run(['command' => 'webgriffe:akeneo:consume']);
- }
-}
diff --git a/tests/Behat/Context/Cli/EnqueueCommandContext.php b/tests/Behat/Context/Cli/ImportCommandContext.php
similarity index 62%
rename from tests/Behat/Context/Cli/EnqueueCommandContext.php
rename to tests/Behat/Context/Cli/ImportCommandContext.php
index 556b93ef..a5a2ead3 100644
--- a/tests/Behat/Context/Cli/EnqueueCommandContext.php
+++ b/tests/Behat/Context/Cli/ImportCommandContext.php
@@ -5,53 +5,57 @@
namespace Tests\Webgriffe\SyliusAkeneoPlugin\Behat\Context\Cli;
use Behat\Behat\Context\Context;
+use DateTime;
use org\bovigo\vfs\vfsStream;
use Sylius\Behat\Service\SharedStorageInterface;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\HttpKernel\KernelInterface;
use Throwable;
-use Webgriffe\SyliusAkeneoPlugin\Command\EnqueueCommand;
+use Webgriffe\SyliusAkeneoPlugin\Command\ImportCommand;
use Webmozart\Assert\Assert;
-final class EnqueueCommandContext implements Context
+final class ImportCommandContext implements Context
{
- public function __construct(private KernelInterface $kernel, private EnqueueCommand $enqueueCommand, private SharedStorageInterface $sharedStorage)
- {
+ public function __construct(
+ private KernelInterface $kernel,
+ private ImportCommand $importCommand,
+ private SharedStorageInterface $sharedStorage,
+ ) {
}
/**
- * @When /^I enqueue items for all importers modified since date "([^"]+)"$/
+ * @When I import items for all importers modified since date :date
*/
- public function iRunEnqueueCommandWithSinceDate(string $date): void
+ public function iImportItemsForAllImportersModifiedSinceDate(DateTime $date): void
{
$commandTester = $this->getCommandTester();
try {
- $commandTester->execute(['command' => 'webgriffe:akeneo:enqueue', '--since' => $date]);
+ $commandTester->execute(['command' => 'webgriffe:akeneo:import', '--since' => $date->format('Y-m-d H:i:s')]);
} catch (Throwable $t) {
$this->sharedStorage->set('command_exception', $t);
}
}
/**
- * @When I enqueue items for all importers with no since date
+ * @When I import items for all importers with no since date
*/
- public function iRunEnqueueCommandWithNoSinceDate(): void
+ public function iImportItemsForAllImportersWithNoSinceDate(): void
{
$commandTester = $this->getCommandTester();
try {
- $commandTester->execute(['command' => 'webgriffe:akeneo:enqueue']);
+ $commandTester->execute(['command' => 'webgriffe:akeneo:import']);
} catch (Throwable $t) {
$this->sharedStorage->set('command_exception', $t);
}
}
/**
- * @Then /^I should be notified that a since date is required$/
+ * @Then I should be notified that a since date is required
*/
- public function theCommandShouldHaveThrownExceptionWithMessageContaining(): void
+ public function iShouldBeNotifiedThatASinceDateIsRequired(): void
{
/** @var Throwable|mixed $throwable */
$throwable = $this->sharedStorage->get('command_exception');
@@ -63,21 +67,21 @@ public function theCommandShouldHaveThrownExceptionWithMessageContaining(): void
}
/**
- * @When /^I enqueue items for all importers with invalid since date$/
+ * @When I import items for all importers with invalid since date
*/
- public function iEnqueueItemsForAllImportersWithInvalidSinceDate(): void
+ public function iImportItemsForAllImportersWithInvalidSinceDate(): void
{
$commandTester = $this->getCommandTester();
try {
- $commandTester->execute(['command' => 'webgriffe:akeneo:enqueue', '--since' => 'bad date']);
+ $commandTester->execute(['command' => 'webgriffe:akeneo:import', '--since' => 'bad date']);
} catch (Throwable $t) {
$this->sharedStorage->set('command_exception', $t);
}
}
/**
- * @Then /^I should be notified that the since date must be a valid date$/
+ * @Then I should be notified that the since date must be a valid date
*/
public function iShouldBeNotifiedThatTheSinceDateMustBeAValidDate(): void
{
@@ -88,22 +92,22 @@ public function iShouldBeNotifiedThatTheSinceDateMustBeAValidDate(): void
}
/**
- * @When /^I enqueue items with since date specified from a not existent file$/
+ * @When I import items with since date specified from a not existent file
*/
- public function iEnqueueItemsWithSinceDateSpecifiedFromANotExistentFile(): void
+ public function iImportItemsWithSinceDateSpecifiedFromANotExistentFile(): void
{
$commandTester = $this->getCommandTester();
$filepath = vfsStream::url('root/not-existent-file.txt');
try {
- $commandTester->execute(['command' => 'webgriffe:akeneo:enqueue', '--since-file' => $filepath]);
+ $commandTester->execute(['command' => 'webgriffe:akeneo:import', '--since-file' => $filepath]);
} catch (Throwable $t) {
$this->sharedStorage->set('command_exception', $t);
}
}
/**
- * @Then /^I should be notified that the since date file does not exists$/
+ * @Then I should be notified that the since date file does not exists
*/
public function iShouldBeNotifiedThatTheSinceDateFileDoesNotExists(): void
{
@@ -114,52 +118,53 @@ public function iShouldBeNotifiedThatTheSinceDateFileDoesNotExists(): void
}
/**
- * @When /^I enqueue items for all importers modified since date specified from file "([^"]+)"$/
+ * @When I import items for all importers modified since date specified from file :file
*/
- public function iEnqueueItemsWithSinceDateSpecifiedFromFile(string $file): void
+ public function iImportItemsForAllImportersModifiedSinceDateSpecifiedFromFile(string $file): void
{
$commandTester = $this->getCommandTester();
$filepath = vfsStream::url('root/' . $file);
try {
- $commandTester->execute(['command' => 'webgriffe:akeneo:enqueue', '--since-file' => $filepath]);
+ $commandTester->execute(['command' => 'webgriffe:akeneo:import', '--since-file' => $filepath]);
} catch (Throwable $t) {
$this->sharedStorage->set('command_exception', $t);
}
}
/**
- * @When /^I enqueue all items for all importers$/
+ * @When I import all items for all importers
+ * @When I import all from Akeneo
*/
- public function iEnqueueAllItemsForAllImporters(): void
+ public function iImportAllItemsForAllImporters(): void
{
$commandTester = $this->getCommandTester();
- $commandTester->execute(['command' => 'webgriffe:akeneo:enqueue', '--all' => true]);
+ $commandTester->execute(['command' => 'webgriffe:akeneo:import', '--all' => true]);
}
/**
- * @When /^I enqueue all items for the "([^"]+)" importer$/
+ * @When I import all items for the :importer importer
*/
- public function iEnqueueItemsModifiedSinceDateForTheImporter(string $importer): void
+ public function iImportAllItemsForTheImporter(string $importer): void
{
$commandTester = $this->getCommandTester();
$commandTester->execute(
- ['command' => 'webgriffe:akeneo:enqueue', '--all' => true, '--importer' => [$importer]],
+ ['command' => 'webgriffe:akeneo:import', '--all' => true, '--importer' => [$importer]],
);
}
/**
- * @When /^I enqueue all items for a not existent importer$/
+ * @When I import all items for a not existent importer
*/
- public function iEnqueueAllItemsForANotExistentImporter(): void
+ public function iImportAllItemsForANotExistentImporter(): void
{
$commandTester = $this->getCommandTester();
try {
$commandTester->execute(
- ['command' => 'webgriffe:akeneo:enqueue', '--all' => true, '--importer' => ['not_existent']],
+ ['command' => 'webgriffe:akeneo:import', '--all' => true, '--importer' => ['not_existent']],
);
} catch (Throwable $t) {
$this->sharedStorage->set('command_exception', $t);
@@ -167,7 +172,7 @@ public function iEnqueueAllItemsForANotExistentImporter(): void
}
/**
- * @Then /^I should be notified that the importer does not exists$/
+ * @Then I should be notified that the importer does not exists
*/
public function iShouldBeNotifiedThatTheImporterDoesNotExists(): void
{
@@ -180,8 +185,8 @@ public function iShouldBeNotifiedThatTheImporterDoesNotExists(): void
private function getCommandTester(): CommandTester
{
$application = new Application($this->kernel);
- $application->add($this->enqueueCommand);
- $command = $application->find('webgriffe:akeneo:enqueue');
+ $application->add($this->importCommand);
+ $command = $application->find('webgriffe:akeneo:import');
return new CommandTester($command);
}
diff --git a/tests/Behat/Context/Cli/QueueCleanupCommandContext.php b/tests/Behat/Context/Cli/QueueCleanupCommandContext.php
index b15dd247..e69de29b 100644
--- a/tests/Behat/Context/Cli/QueueCleanupCommandContext.php
+++ b/tests/Behat/Context/Cli/QueueCleanupCommandContext.php
@@ -1,73 +0,0 @@
-sharedStorage->set('command_input_days', $days);
- $commandTester = $this->getCommandTester();
-
- $input = ['command' => 'webgriffe:akeneo:cleanup-queue'];
- if ($days !== null) {
- $input['days'] = (string) $days;
- }
- $commandTester->execute($input);
- $this->sharedStorage->set('command_display', $commandTester->getDisplay());
- }
-
- /**
- * @Then I should be notified that there are no items to clean
- */
- public function iShouldBeNotifiedThatThereAreNoItemsToClean(): void
- {
- $output = $this->sharedStorage->get('command_display');
- Assert::contains($output, 'There are no items to clean');
- }
-
- /**
- * @Then /^I should be notified that (\d+) item[s]? (has|have) been deleted$/
- */
- public function iShouldBeNotifiedThatItemHasBeenDeleted(int $count): void
- {
- $output = $this->sharedStorage->get('command_display');
- Assert::regex($output, "/$count items imported before \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} has been deleted/");
- }
-
- /**
- * @Then /^there shouldn\'t be any more item[s]? to clean$/
- */
- public function thereShouldntBeAnyMoreItemToClean(): void
- {
- $this->iCleanTheQueue($this->sharedStorage->has('command_input_days') ? $this->sharedStorage->get('command_input_days') : null);
- $this->iShouldBeNotifiedThatThereAreNoItemsToClean();
- }
-
- private function getCommandTester(): CommandTester
- {
- $application = new Application($this->kernel);
- $application->add($this->queueCleanupCommand);
- $command = $application->find('webgriffe:akeneo:cleanup-queue');
-
- return new CommandTester($command);
- }
-}
diff --git a/tests/Behat/Context/Cli/ReconcileCommandContext.php b/tests/Behat/Context/Cli/ReconcileCommandContext.php
index b91b7713..fd50ef97 100644
--- a/tests/Behat/Context/Cli/ReconcileCommandContext.php
+++ b/tests/Behat/Context/Cli/ReconcileCommandContext.php
@@ -12,12 +12,14 @@
final class ReconcileCommandContext implements Context
{
- public function __construct(private KernelInterface $kernel, private ReconcileCommand $reconcileCommand)
- {
+ public function __construct(
+ private KernelInterface $kernel,
+ private ReconcileCommand $reconcileCommand,
+ ) {
}
/**
- * @When /^I reconcile items$/
+ * @When I reconcile items
*/
public function iReconcileItems(): void
{
diff --git a/tests/Behat/Context/Db/ProductContext.php b/tests/Behat/Context/Db/ProductContext.php
index df4dbf7c..1d2ab02e 100644
--- a/tests/Behat/Context/Db/ProductContext.php
+++ b/tests/Behat/Context/Db/ProductContext.php
@@ -40,7 +40,7 @@ public function theProductVariantShouldExistsWithTheRightData(string $code, stri
}
/**
- * @Then /^the product "([^"]*)" should not exists$/
+ * @Then the product :code should not exists
*/
public function theProductShouldNotExists(string $code): void
{
diff --git a/tests/Behat/Context/Db/QueueContext.php b/tests/Behat/Context/Db/QueueContext.php
deleted file mode 100644
index 0033613d..00000000
--- a/tests/Behat/Context/Db/QueueContext.php
+++ /dev/null
@@ -1,130 +0,0 @@
-getQueueItemByImporterAndIdentifier($importer, $identifier);
- Assert::notNull($queueItem->getImportedAt());
- }
-
- /**
- * @Given /^the queue item with identifier "([^"]*)" for the "([^"]*)" importer has not been marked as imported$/
- */
- public function theQueueItemForProductWithIdentifierHasNotBeenMarkedAsImported(string $identifier, string $importer): void
- {
- $queueItem = $this->getQueueItemByImporterAndIdentifier($importer, $identifier);
- Assert::null($queueItem->getImportedAt());
- }
-
- /**
- * @Given /^the queue item with identifier "([^"]*)" for the "([^"]*)" importer has an error message$/
- */
- public function theQueueItemHasAnErrorMessage(string $identifier, string $importer): void
- {
- $queueItem = $this->getQueueItemByImporterAndIdentifier($importer, $identifier);
- Assert::notNull($queueItem->getErrorMessage());
- }
-
- /**
- * @Given /^the queue item with identifier "([^"]*)" for the "([^"]*)" importer has an error message containing "([^"]*)"$/
- */
- public function theQueueItemHasAnErrorMessageContaining(string $identifier, string $importer, string $message): void
- {
- $queueItem = $this->getQueueItemByImporterAndIdentifier($importer, $identifier);
- Assert::contains((string) $queueItem->getErrorMessage(), $message);
- }
-
- /**
- * @Then /^the queue item with identifier "([^"]*)" for the "([^"]*)" importer should not be in the Akeneo queue$/
- */
- public function theProductShouldNotBeInTheAkeneoQueue(string $identifier, string $importer): void
- {
- Assert::null(
- $this->queueItemRepository->findOneBy(['akeneoEntity' => $importer, 'akeneoIdentifier' => $identifier]),
- );
- }
-
- /**
- * @Then /^the queue item with identifier "([^"]*)" for the "([^"]*)" importer should be in the Akeneo queue$/
- */
- public function theProductShouldBeInTheAkeneoQueue(string $identifier, string $importer): void
- {
- Assert::isInstanceOf(
- $this->queueItemRepository->findOneBy(
- ['akeneoEntity' => $importer, 'akeneoIdentifier' => $identifier],
- ),
- QueueItemInterface::class,
- );
- }
-
- /**
- * @Then /^there should be no item in the queue for the "([^"]*)" importer/
- */
- public function thereShouldBeNoProductInTheAkeneoQueue(string $importer): void
- {
- Assert::isEmpty($this->queueItemRepository->findBy(['akeneoEntity' => $importer]));
- }
-
- /**
- * @Then /^there should be no item in the Akeneo queue$/
- */
- public function thereShouldBeNoItemInTheAkeneoQueue(): void
- {
- Assert::isEmpty($this->queueItemRepository->findAll());
- }
-
- /**
- * @Then /^there should be only one queue item with identifier "([^"]*)" for the "([^"]*)" importer in the Akeneo queue$/
- */
- public function thereShouldBeOnlyOneProductQueueItemForInTheAkeneoQueue(string $identifier, string $importer): void
- {
- $items = $this->queueItemRepository->findBy(
- ['akeneoEntity' => $importer, 'akeneoIdentifier' => $identifier],
- );
- Assert::count($items, 1);
- }
-
- /**
- * @Then /^there should be (\d+) items for the "([^"]*)" importer in the Akeneo queue$/
- */
- public function thereShouldBeItemsForTheImporterInTheAkeneoQueue(int $count, string $importer): void
- {
- $items = $this->queueItemRepository->findBy(['akeneoEntity' => $importer]);
- Assert::count($items, $count);
- }
-
- /**
- * @Then /^there should be items for the "([^"]*)" importer only in the Akeneo queue$/
- */
- public function thereShouldBeItemsForTheImporterOnlyInTheAkeneoQueue(string $importer): void
- {
- $importerItems = $this->queueItemRepository->findBy(['akeneoEntity' => $importer]);
- Assert::count($this->queueItemRepository->findAll(), count($importerItems));
- }
-
- private function getQueueItemByImporterAndIdentifier(string $importer, string $identifier): QueueItemInterface
- {
- /** @var QueueItemInterface|null $item */
- $item = $this->queueItemRepository->findOneBy(['akeneoEntity' => $importer, 'akeneoIdentifier' => $identifier]);
- Assert::isInstanceOf($item, QueueItemInterface::class);
-
- return $item;
- }
-}
diff --git a/tests/Behat/Context/Setup/AkeneoContext.php b/tests/Behat/Context/Setup/AkeneoContext.php
index 1fc47103..b53a9d02 100644
--- a/tests/Behat/Context/Setup/AkeneoContext.php
+++ b/tests/Behat/Context/Setup/AkeneoContext.php
@@ -21,12 +21,13 @@ public function __construct(
}
/**
+ * @Given there is a product :identifier on Akeneo
* @Given there is a product :identifier updated at :date on Akeneo
*/
- public function thereIsAProductUpdatedAtOnAkeneo(string $identifier, DateTime $date): void
+ public function thereIsAProductUpdatedAtOnAkeneo(string $identifier, DateTime $date = null): void
{
Assert::isInstanceOf($this->apiClient, ApiClientMock::class);
- $this->apiClient->addProductUpdatedAt($identifier, $date);
+ $this->apiClient->addProductUpdatedAt($identifier, $date ?? new DateTime());
}
/**
diff --git a/tests/Behat/Context/Setup/QueueContext.php b/tests/Behat/Context/Setup/QueueContext.php
index 5afbe59b..43bb0442 100644
--- a/tests/Behat/Context/Setup/QueueContext.php
+++ b/tests/Behat/Context/Setup/QueueContext.php
@@ -6,75 +6,37 @@
use Behat\Behat\Context\Context;
use Sylius\Behat\Service\SharedStorageInterface;
-use Sylius\Component\Resource\Factory\FactoryInterface;
-use Webgriffe\SyliusAkeneoPlugin\Entity\QueueItemInterface;
-use Webgriffe\SyliusAkeneoPlugin\Repository\QueueItemRepositoryInterface;
+use Symfony\Component\Messenger\MessageBusInterface;
+use Webgriffe\SyliusAkeneoPlugin\Message\ItemImport;
final class QueueContext implements Context
{
- public function __construct(private FactoryInterface $queueItemFactory, private QueueItemRepositoryInterface $queueItemRepository, private SharedStorageInterface $sharedStorage)
- {
+ public function __construct(
+ private SharedStorageInterface $sharedStorage,
+ private MessageBusInterface $messageBus,
+ ) {
}
/**
- * @Given /^there is one item to import with identifier "([^"]*)" for the "([^"]*)" importer in the Akeneo queue$/
- * @Given /^there is a not imported item with identifier "([^"]*)" for the "([^"]*)" importer in the Akeneo queue$/
+ * @Given there is one item to import with identifier :identifier for the :importer importer in the Akeneo queue
+ * @Given there is a not imported item with identifier :identifier for the :importer importer in the Akeneo queue
*/
public function thereIsOneProductToImportWithIdentifierInTheAkeneoQueue(string $identifier, string $importer): void
{
- /** @var QueueItemInterface $queueItem */
- $queueItem = $this->queueItemFactory->createNew();
- $queueItem->setAkeneoEntity($importer);
- $queueItem->setAkeneoIdentifier($identifier);
- $queueItem->setCreatedAt(new \DateTime());
- $this->queueItemRepository->add($queueItem);
- $this->sharedStorage->set('item', $queueItem);
- }
-
- /**
- * @Given /^there is one product associations to import with identifier "([^"]*)" in the Akeneo queue$/
- */
- public function thereIsOneProductAssociationsToImportWithIdentifierInTheAkeneoQueue(string $identifier): void
- {
- /** @var QueueItemInterface $queueItem */
- $queueItem = $this->queueItemFactory->createNew();
- $queueItem->setAkeneoEntity('ProductAssociations');
- $queueItem->setAkeneoIdentifier($identifier);
- $queueItem->setCreatedAt(new \DateTime());
- $this->queueItemRepository->add($queueItem);
- $this->sharedStorage->set('item', $queueItem);
- }
+ $itemImport = new ItemImport($importer, $identifier);
+ $this->messageBus->dispatch($itemImport);
- /**
- * @Given /^there is an already imported item with identifier "([^"]*)" for the "([^"]*)" importer in the Akeneo queue$/
- */
- public function thereIsAnAlreadyImportedItemWithIdentifierForTheImporterInTheAkeneoQueue(string $identifier, string $importer): void
- {
- /** @var QueueItemInterface $queueItem */
- $queueItem = $this->queueItemFactory->createNew();
- $queueItem->setAkeneoEntity($importer);
- $queueItem->setAkeneoIdentifier($identifier);
- $queueItem->setCreatedAt(new \DateTime());
- $queueItem->setImportedAt(new \DateTime());
- $this->queueItemRepository->add($queueItem);
- $this->sharedStorage->set('item', $queueItem);
+ $this->sharedStorage->set('item_import', $itemImport);
}
/**
- * @Given /^(this item) has been imported (\d+) days ago$/
+ * @Given there is one product associations to import with identifier :identifier in the Akeneo queue
*/
- public function thisItemHasBeenImportedDaysAgo(QueueItemInterface $queueItem, int $days): void
+ public function thereIsOneProductAssociationsToImportWithIdentifierInTheAkeneoQueue(string $identifier): void
{
- $queueItem->setImportedAt(new \DateTime("$days days ago"));
- $this->queueItemRepository->add($queueItem);
- }
+ $itemImport = new ItemImport('ProductAssociations', $identifier);
+ $this->messageBus->dispatch($itemImport);
- /**
- * @Given /^(this item) has been imported now$/
- */
- public function thisItemHasBeenImportedNow(QueueItemInterface $queueItem): void
- {
- $queueItem->setImportedAt(new \DateTime());
- $this->queueItemRepository->add($queueItem);
+ $this->sharedStorage->set('item', $itemImport);
}
}
diff --git a/tests/Behat/Context/System/FilesystemContext.php b/tests/Behat/Context/System/FilesystemContext.php
index 6c4d9bf4..e99137de 100644
--- a/tests/Behat/Context/System/FilesystemContext.php
+++ b/tests/Behat/Context/System/FilesystemContext.php
@@ -45,7 +45,7 @@ public function thereIsAFileWithNameThatContains(string $filename, string $conte
}
/**
- * @Then /^there should not be any temporary file in the temporary files directory$/
+ * @Then there should not be any temporary file in the temporary files directory
*/
public function thereShouldNotBeAnyTemporaryFileInTheTemporaryFilesDirectory(): void
{
diff --git a/tests/Behat/Context/Transform/QueueItemContext.php b/tests/Behat/Context/Transform/QueueItemContext.php
deleted file mode 100644
index 5e844713..00000000
--- a/tests/Behat/Context/Transform/QueueItemContext.php
+++ /dev/null
@@ -1,33 +0,0 @@
-queueItemRepository->findBy(['akeneoIdentifier' => $akeneoIdentifier]);
-
- Assert::count(
- $queueItems,
- 1,
- sprintf('%d queue items has been found with identifier "%s".', count($queueItems), $akeneoIdentifier),
- );
-
- return $queueItems[0];
- }
-}
diff --git a/tests/Behat/Context/Ui/Admin/ManagingProductsContext.php b/tests/Behat/Context/Ui/Admin/ManagingProductsContext.php
index 75907d9a..edd70750 100644
--- a/tests/Behat/Context/Ui/Admin/ManagingProductsContext.php
+++ b/tests/Behat/Context/Ui/Admin/ManagingProductsContext.php
@@ -8,21 +8,25 @@
use Behat\Mink\Element\NodeElement;
use Sylius\Behat\NotificationType;
use Sylius\Behat\Page\Admin\Product\IndexPageInterface;
+use Sylius\Behat\Page\Admin\Product\UpdateSimpleProductPageInterface;
use Sylius\Behat\Service\Helper\JavaScriptTestHelperInterface;
use Sylius\Behat\Service\NotificationCheckerInterface;
use Sylius\Component\Core\Model\ProductInterface;
-use Tests\Webgriffe\SyliusAkeneoPlugin\Behat\Page\Admin\QueueItem\IndexPageInterface as QueueItemsIndexPageInterface;
+use Sylius\Component\Core\Repository\ProductRepositoryInterface;
+use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
use Webmozart\Assert\Assert;
final class ManagingProductsContext implements Context
{
private const SCHEDULE_AKENEO_PIM_IMPORT = 'Schedule Akeneo PIM import';
- /**
- * ProductItems constructor.
- */
- public function __construct(private IndexPageInterface $indexPage, private JavaScriptTestHelperInterface $testHelper, private NotificationCheckerInterface $notificationChecker, private QueueItemsIndexPageInterface $queueItemsIndexPage)
- {
+ public function __construct(
+ private IndexPageInterface $indexPage,
+ private JavaScriptTestHelperInterface $testHelper,
+ private NotificationCheckerInterface $notificationChecker,
+ private UpdateSimpleProductPageInterface $updateSimpleProductPage,
+ private ProductRepositoryInterface $productRepository,
+ ) {
}
/**
@@ -49,26 +53,46 @@ public function iShouldBeNotifiedThatItHasBeenSuccessfullyEnqueued(): void
}
/**
- * @Given /^I should be notified that it has been already enqueued$/
+ * @Then the product with code :code should have an association :productAssociationType with product :productName
*/
- public function iShouldBeNotifiedThatItHasBeenAlreadyEnqueued(): void
- {
- $this->testHelper->waitUntilNotificationPopups(
- $this->notificationChecker,
- NotificationType::success(),
- 'Akeneo PIM import for this product has been already scheduled before',
- );
+ public function theProductShouldHaveAnAssociationWithProducts(
+ string $code,
+ ProductAssociationTypeInterface $productAssociationType,
+ string ...$productsNames,
+ ): void {
+ $product = $this->productRepository->findOneByCode($code);
+ Assert::isInstanceOf($product, ProductInterface::class);
+ $this->updateSimpleProductPage->open(['id' => $product->getId()]);
+ foreach ($productsNames as $productName) {
+ Assert::true(
+ $this->updateSimpleProductPage->hasAssociatedProduct($productName, $productAssociationType),
+ sprintf(
+ 'This product should have an association %s with product %s.',
+ $productAssociationType->getName(),
+ $productName,
+ ),
+ );
+ }
}
/**
- * @Then /^I should see (\d+), not imported, items? in the Akeneo queue items list$/
+ * @Then the product with code :code should not have an association :productAssociationType with product :productName
*/
- public function iShouldSeeNotImportedItemInTheAkeneoQueueItemsList(int $numberOfItems): void
- {
- $this->queueItemsIndexPage->open();
- Assert::same($this->queueItemsIndexPage->countItems(), $numberOfItems);
- foreach ($this->indexPage->getColumnFields('importedAt') as $columnField) {
- Assert::eq($columnField, 'No');
- }
+ public function theProductShouldNotHaveAnAssociationWithProduct(
+ string $code,
+ ProductAssociationTypeInterface $productAssociationType,
+ string $productName,
+ ): void {
+ $product = $this->productRepository->findOneByCode($code);
+ Assert::isInstanceOf($product, ProductInterface::class);
+ $this->updateSimpleProductPage->open(['id' => $product->getId()]);
+ Assert::false(
+ $this->updateSimpleProductPage->hasAssociatedProduct($productName, $productAssociationType),
+ sprintf(
+ 'This product should have an association %s with product %s.',
+ $productAssociationType->getName(),
+ $productName,
+ ),
+ );
}
}
diff --git a/tests/Behat/Context/Ui/Admin/ManagingQueueItems.php b/tests/Behat/Context/Ui/Admin/ManagingQueueItems.php
deleted file mode 100644
index 0ab7fb9f..00000000
--- a/tests/Behat/Context/Ui/Admin/ManagingQueueItems.php
+++ /dev/null
@@ -1,146 +0,0 @@
-indexPage->open();
- }
-
- /**
- * @Then /^I should see (\d+), not imported, queue items in the list$/
- */
- public function iShouldSeeQueueItemsInTheList(int $numberOfItems): void
- {
- Assert::same($this->indexPage->countItems(), $numberOfItems);
- foreach ($this->indexPage->getColumnFields('importedAt') as $columnField) {
- Assert::eq($columnField, 'No');
- }
- }
-
- /**
- * @Given /^I choose "([^"]*)" as an imported filter$/
- */
- public function iChooseAsAnImportedFilter(string $imported): void
- {
- $this->indexPage->chooseImportedFilter($imported);
- }
-
- /**
- * @When /^I filter$/
- */
- public function iFilter(): void
- {
- $this->indexPage->filter();
- }
-
- /**
- * @Then /^I should see (\d+), imported, queue items? in the list$/
- */
- public function iShouldSeeImportedQueueItemInTheList(int $numberOfItems): void
- {
- Assert::same($this->indexPage->countItems(), $numberOfItems);
- foreach ($this->indexPage->getColumnFields('importedAt') as $columnField) {
- Assert::contains($columnField, 'Yes');
- }
- }
-
- /**
- * @When /^I specify "([^"]*)" as an importer filter$/
- */
- public function iSpecifyAsAnImporterFilter(string $importer): void
- {
- $this->indexPage->specifyImporterFilter($importer);
- }
-
- /**
- * @Then /^I should see (\d+) queue items? in the list$/
- */
- public function iShouldSeeQueueItemInTheList(int $numberOfItems): void
- {
- Assert::same($this->indexPage->countItems(), $numberOfItems);
- }
-
- /**
- * @Given /^I specify "([^"]*)" as an identifier filter$/
- */
- public function iSpecifyAsAnIdentifierFilter(string $identifier): void
- {
- $this->indexPage->specifyIdentifierFilter($identifier);
- }
-
- /**
- * @When /^I delete the ("([^"]*)" queue item)$/
- */
- public function iDeleteTheQueueItem(QueueItemInterface $queueItem): void
- {
- $this->indexPage->deleteResourceOnPage(['akeneoIdentifier' => $queueItem->getAkeneoIdentifier()]);
-
- $this->sharedStorage->set('queue_item', $queueItem);
- }
-
- /**
- * @Given /^(this queue item) should no longer exist in the queue$/
- */
- public function thisQueueItemShouldNoLongerExistInTheQueue(QueueItemInterface $queueItem): void
- {
- Assert::false(
- $this->indexPage->isSingleResourceOnPage(
- [
- 'akeneoIdentifier' => $queueItem->getAkeneoIdentifier(),
- 'akeneoEntity' => $queueItem->getAkeneoEntity(),
- ],
- ),
- );
- }
-
- /**
- * @Given /^I check the ("([^"]*)" queue item)$/
- * @Given /^I check also the ("([^"]*)" queue item)$/
- */
- public function iCheckAlsoTheQueueItem(QueueItemInterface $queueItem): void
- {
- $this->indexPage->checkResourceOnPage(['akeneoIdentifier' => $queueItem->getAkeneoIdentifier()]);
- }
-
- /**
- * @When I delete them
- */
- public function iDeleteThem(): void
- {
- $this->indexPage->bulkDelete();
- }
-
- /**
- * @Given /^I should see a single queue item in the list$/
- */
- public function iShouldSeeASingleQueueItemInTheList(): void
- {
- Assert::eq($this->indexPage->countItems(), 1);
- }
-
- /**
- * @Given /^I should see the ("([^"]*)" queue item) in the list$/
- */
- public function iShouldSeeTheQueueItemInTheList(QueueItemInterface $queueItem): void
- {
- Assert::true($this->indexPage->isSingleResourceOnPage(['akeneoIdentifier' => $queueItem->getAkeneoIdentifier()]));
- }
-}
diff --git a/tests/Behat/Page/Admin/QueueItem/IndexPage.php b/tests/Behat/Page/Admin/QueueItem/IndexPage.php
index 07d7e4f6..e69de29b 100644
--- a/tests/Behat/Page/Admin/QueueItem/IndexPage.php
+++ b/tests/Behat/Page/Admin/QueueItem/IndexPage.php
@@ -1,37 +0,0 @@
-getElement('filter_imported')->selectOption($imported);
- }
-
- public function specifyImporterFilter(string $importer): void
- {
- $this->getElement('filter_importer')->setValue($importer);
- }
-
- public function specifyIdentifierFilter(string $identifier): void
- {
- $this->getElement('filter_identifier')->setValue($identifier);
- }
-
- protected function getDefinedElements(): array
- {
- return array_merge(
- parent::getDefinedElements(),
- [
- 'filter_imported' => '#criteria_imported',
- 'filter_importer' => '#criteria_akeneoEntity_value',
- 'filter_identifier' => '#criteria_akeneoIdentifier_value',
- ],
- );
- }
-}
diff --git a/tests/Behat/Page/Admin/QueueItem/IndexPageInterface.php b/tests/Behat/Page/Admin/QueueItem/IndexPageInterface.php
deleted file mode 100644
index bb625e15..00000000
--- a/tests/Behat/Page/Admin/QueueItem/IndexPageInterface.php
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
@@ -47,10 +31,6 @@
-
-
-
-
%webgriffe_sylius_akeneo.temporary_directory%
%webgriffe_sylius_akeneo.temporary_files_prefix%
@@ -58,20 +38,12 @@
-
-
-
-
-
-
-
-
-
- webgriffe_sylius_akeneo_admin_queue_item_index
+
+
diff --git a/tests/Behat/Resources/suites.yml b/tests/Behat/Resources/suites.yml
index 43b9c88a..7652b896 100644
--- a/tests/Behat/Resources/suites.yml
+++ b/tests/Behat/Resources/suites.yml
@@ -8,106 +8,75 @@ default:
- sylius.behat.context.setup.channel
- sylius.behat.context.setup.locale
- webgriffe_sylius_akeneo.behat.context.setup.queue
-
- - webgriffe_sylius_akeneo.behat.context.cli.consume_command
+ - webgriffe_sylius_akeneo.behat.context.setup.akeneo
- webgriffe_sylius_akeneo.behat.context.db.product
- - webgriffe_sylius_akeneo.behat.context.db.queue
+ - webgriffe_sylius_akeneo.behat.context.cli.import_command
- webgriffe_sylius_akeneo.behat.context.system.filesystem
filters:
tags: "@importing_products && @cli"
- cli_importing_product_associations:
+ ui_importing_products:
contexts:
- sylius.behat.context.hook.doctrine_orm
- - sylius.behat.context.setup.product
- - sylius.behat.context.setup.product_association
+ - sylius.behat.context.transform.shared_storage
+ - sylius.behat.context.transform.product
+
- sylius.behat.context.setup.channel
+ - sylius.behat.context.setup.admin_security
+ - sylius.behat.context.setup.product
+ - webgriffe_sylius_akeneo.behat.context.setup.akeneo
- webgriffe_sylius_akeneo.behat.context.setup.queue
- - webgriffe_sylius_akeneo.behat.context.cli.consume_command
-
- webgriffe_sylius_akeneo.behat.context.db.product
- - webgriffe_sylius_akeneo.behat.context.db.queue
+
+ - sylius.behat.context.ui.admin.managing_products
+ - webgriffe_sylius_akeneo.behat.context.ui.admin.managing_products
filters:
- tags: "@importing_product_associations && @cli"
+ tags: "@importing_products && @ui"
- cli_enqueuing_generic_items:
+ cli_importing_product_associations:
contexts:
- sylius.behat.context.hook.doctrine_orm
- - sylius.behat.context.transform.date_time
-
- - webgriffe_sylius_akeneo.behat.context.setup.akeneo
+ - sylius.behat.context.setup.product
+ - sylius.behat.context.setup.product_association
+ - sylius.behat.context.setup.channel
- webgriffe_sylius_akeneo.behat.context.setup.queue
+ - webgriffe_sylius_akeneo.behat.context.setup.akeneo
- - webgriffe_sylius_akeneo.behat.context.cli.enqueue_command
-
- - webgriffe_sylius_akeneo.behat.context.db.queue
+ - webgriffe_sylius_akeneo.behat.context.db.product
- - webgriffe_sylius_akeneo.behat.context.system.filesystem
- - webgriffe_sylius_akeneo.behat.context.system.datetime
+ - webgriffe_sylius_akeneo.behat.context.cli.import_command
filters:
- tags: "@enqueuing_generic_items && @cli"
+ tags: "@importing_product_associations && @cli"
- cli_enqueuing_products:
+ cli_ui_importing_generic_items:
contexts:
- sylius.behat.context.hook.doctrine_orm
- sylius.behat.context.transform.date_time
+ - sylius.behat.context.transform.product_association_type
+ - sylius.behat.context.setup.admin_security
+ - sylius.behat.context.setup.product_association
- webgriffe_sylius_akeneo.behat.context.setup.akeneo
- webgriffe_sylius_akeneo.behat.context.setup.queue
- - webgriffe_sylius_akeneo.behat.context.cli.enqueue_command
-
- - webgriffe_sylius_akeneo.behat.context.db.queue
-
- - webgriffe_sylius_akeneo.behat.context.system.filesystem
- - webgriffe_sylius_akeneo.behat.context.system.datetime
-
- filters:
- tags: "@enqueuing_products && @cli"
-
- ui_enqueuing_products:
- contexts:
- - sylius.behat.context.hook.doctrine_orm
-
- - sylius.behat.context.transform.shared_storage
- - sylius.behat.context.transform.product
-
- - sylius.behat.context.setup.channel
- - sylius.behat.context.setup.admin_security
- - sylius.behat.context.setup.product
- - webgriffe_sylius_akeneo.behat.context.setup.queue
+ - webgriffe_sylius_akeneo.behat.context.cli.import_command
- sylius.behat.context.ui.admin.managing_products
- webgriffe_sylius_akeneo.behat.context.ui.admin.managing_products
- filters:
- tags: "@enqueuing_products && @ui"
-
- cli_enqueuing_products_associations:
- contexts:
- - sylius.behat.context.hook.doctrine_orm
-
- - sylius.behat.context.transform.date_time
-
- - webgriffe_sylius_akeneo.behat.context.setup.akeneo
- - webgriffe_sylius_akeneo.behat.context.setup.queue
-
- - webgriffe_sylius_akeneo.behat.context.cli.enqueue_command
-
- - webgriffe_sylius_akeneo.behat.context.db.queue
- webgriffe_sylius_akeneo.behat.context.system.filesystem
- webgriffe_sylius_akeneo.behat.context.system.datetime
filters:
- tags: "@enqueuing_products_associations && @cli"
+ tags: "@importing_generic_items && @cli && @ui"
cli_reconcile_products:
contexts:
@@ -128,32 +97,3 @@ default:
- webgriffe_sylius_akeneo.behat.context.cli.reconcile_command
filters:
tags: "@reconcile_products && @cli"
-
- ui_managing_queue_items:
- contexts:
- - sylius.behat.context.hook.doctrine_orm
-
- - sylius.behat.context.transform.shared_storage
- - webgriffe_sylius_akeneo.behat.context.transform.queue_item
-
- - sylius.behat.context.setup.admin_security
- - webgriffe_sylius_akeneo.behat.context.setup.queue
-
- - webgriffe_sylius_akeneo.behat.context.ui.admin.managing_queue_items
- - sylius.behat.context.ui.admin.notification
-
- filters:
- tags: "@managing_queue_items && @ui"
-
- cli_cleaning_queue:
- contexts:
- - sylius.behat.context.hook.doctrine_orm
-
- - sylius.behat.context.transform.shared_storage
-
- - webgriffe_sylius_akeneo.behat.context.setup.queue
-
- - webgriffe_sylius_akeneo.behat.context.cli.queue_cleanup_command
-
- filters:
- tags: "@cleaning_queue && @cli"
diff --git a/tests/Integration/DataFixtures/ApiClientMock/Product/10597353.json b/tests/Integration/DataFixtures/ApiClientMock/Product/10597353.json
new file mode 100644
index 00000000..0b986ea8
--- /dev/null
+++ b/tests/Integration/DataFixtures/ApiClientMock/Product/10597353.json
@@ -0,0 +1,82 @@
+{
+ "identifier": "10597353",
+ "enabled": true,
+ "family": "loudspeakers",
+ "categories": [
+ "audio_video_sales",
+ "loudspeakers",
+ "nec"
+ ],
+ "groups": [],
+ "parent": null,
+ "values": {
+ "picture": [
+ {
+ "locale": null,
+ "scope": null,
+ "data": "6/5/8/8/65887ee600d9d66e829a75beedf374533b1ff8bc_10597353_1104.jpg",
+ "_links": {
+ "download": {
+ "href": "http://127.0.0.1:8081/api/rest/v1/media-files/6/5/8/8/65887ee600d9d66e829a75beedf374533b1ff8bc_10597353_1104.jpg/download"
+ }
+ }
+ }
+ ],
+ "name": [
+ {
+ "locale": null,
+ "scope": null,
+ "data": "NEC SP-4046PV"
+ }
+ ],
+ "description": [
+ {
+ "locale": "de_DE",
+ "scope": "print",
+ "data": "Dem edlen Design der Displays angepasst und mit wenigen Handgriffen montiert bzw. demontiert."
+ },
+ {
+ "locale": "en_US",
+ "scope": "print",
+ "data": "Enhance your Large-Screen Display Speakers without breaking your budget with NEC's SP-4046PV."
+ },
+ {
+ "locale": "fr_FR",
+ "scope": "print",
+ "data": "Adapté au design des moniteurs LCD NEC Public Display, montage et démontage faciles."
+ }
+ ],
+ "release_date": [
+ {
+ "locale": null,
+ "scope": "ecommerce",
+ "data": "2011-08-07T00:00:00+00:00"
+ }
+ ]
+ },
+ "created": "2022-04-14T13:14:05+00:00",
+ "updated": "2022-04-14T13:14:05+00:00",
+ "associations": {
+ "PACK": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "UPSELL": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "X_SELL": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "SUBSTITUTION": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ }
+ },
+ "quantified_associations": {}
+}
diff --git a/tests/Integration/DataFixtures/ApiClientMock/Product/11164822.json b/tests/Integration/DataFixtures/ApiClientMock/Product/11164822.json
new file mode 100644
index 00000000..97b29406
--- /dev/null
+++ b/tests/Integration/DataFixtures/ApiClientMock/Product/11164822.json
@@ -0,0 +1,84 @@
+{
+ "identifier": "11164822",
+ "enabled": true,
+ "family": "loudspeakers",
+ "categories": [
+ "audio_video_sales",
+ "loudspeakers",
+ "philips"
+ ],
+ "groups": [],
+ "parent": null,
+ "values": {
+ "picture": [
+ {
+ "locale": null,
+ "scope": null,
+ "data": "7/3/6/b/736bbc43fd1e384f4badbeababd84389b31159f8_11164822_Philips.jpg",
+ "_links": {
+ "download": {
+ "href": "http://127.0.0.1:8081/api/rest/v1/media-files/7/3/6/b/736bbc43fd1e384f4badbeababd84389b31159f8_11164822_Philips.jpg/download"
+ }
+ }
+ }
+ ],
+ "name": [
+ {
+ "locale": null,
+ "scope": null,
+ "data": "Philips AD7000W"
+ }
+ ],
+ "description": [
+ {
+ "locale": "de_DE",
+ "scope": "print",
+ "data": "Eleganz und erstklassige Audio-Qualität, kabellos dank AirPlay\\nBegeistert von Sound\\n\\nDieser kabellose Philips Fidelio-Lautsprecher ermöglicht es Ihnen, Titel direkt von Ihrem iPod/iPhone/iPad und über iTunes auf Ihrem Computer abzuspielen, und das ganze kabellos dank AirPlay. Dieser elegante und kompakte Lautsprecher erfüllt Ihr Zuhause mit großartiger Musik ganz ohne Kabelgewirr.\\n\\nKristallklarer Klang\\n- SoundAvia für eine ausgewogene Klangleistung\\n- 10 W RMS Gesamtausgangsleistung\\n\\nElegant und kompakt\\n- Kompaktes Design mit minimalem Platzbedarf für jeden Lebensstil\\n\\nNoch vielseitiger\\n- Musikübertragung mit kabelloser AirPlay-Technologie\\n- Gleichzeitiges Wiedergeben und Aufladen Ihres iPods/iPhones/iPads\\n- AUX-Eingang für einfaches Anschließen an nahezu jedes elektronische Gerät\\n- Entdecken Sie Musik und weitere Funktionen, und teilen Sie diese über die kostenlose Fidelio\\nApp"
+ },
+ {
+ "locale": "en_US",
+ "scope": "print",
+ "data": "Elegance and superb audio, wirelessly with AirPlay\\nObsessed with sound\\n\\nThis Philips Fidelio wireless speaker gives you the freedom to play songs directly from\\nyour iPod/iPhone/iPad, and from your computer’s iTunes - wirelessly via AirPlay. Elegant\\nand compact, it fills your home with great music, not clutter.\\n\\nCrystal clear sound\\n- SoundAvia for well-balanced sound performance\\n- 10 W RMS total output power\\n\\nElegant and compact\\n- Compact design for any space, any lifestyle\\n\\nAdvanced versatility\\n- Stream music with AirPlay wireless technology\\n- Play and charge your iPod/iPhone/iPad simultaneously\\n- AUX-in for easy connection to almost any electronic device\\n- Discover, share music and more features via free Fidelio app"
+ },
+ {
+ "locale": "fr_FR",
+ "scope": "print",
+ "data": "Élégance et qualité audio exceptionnelle, sans fil avec AirPlay\\nL'obsession du son\\n\\nCette enceinte sans fil Philips Fidelio vous laisse la liberté d'écouter des morceaux directement à partir de votre iPod/iPhone/iPad ou depuis iTunes sur votre ordinateur, tout cela sans fil grâce à AirPlay. Élégante et compacte, elle emplit votre maison d'un son haute qualité, sans l'encombrer inutilement.\\n\\nSon limpide\\n- SoundAvia pour des performances sonores équilibrées\\n- Puissance de sortie totale de 10 W RMS\\n\\nÉlégante et compacte\\n- Design compact pour tous les intérieurs et tous les modes de vie\\n\\nPolyvalence accrue\\n- Technologie de diffusion de la musique sans fil AirPlay\\n- Écoutez et chargez simultanément votre iPod/iPhone/iPad\\n- Entrée AUX, pour une connexion facile à la plupart des périphériques électroniques\\n- Découvrez et partagez de la musique et bien plus via l'appli Fidelio gratuite"
+ }
+ ],
+ "release_date": [
+ {
+ "locale": null,
+ "scope": "ecommerce",
+ "data": "2011-10-09T00:00:00+00:00"
+ }
+ ]
+ },
+ "created": "2022-04-14T13:14:01+00:00",
+ "updated": "2022-04-14T13:14:01+00:00",
+ "associations": {
+ "PACK": {
+ "products": [
+ "10597353"
+ ],
+ "product_models": [],
+ "groups": []
+ },
+ "UPSELL": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "X_SELL": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "SUBSTITUTION": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ }
+ },
+ "quantified_associations": {}
+}
diff --git a/tests/Integration/DataFixtures/ApiClientMock/Product/1314976.json b/tests/Integration/DataFixtures/ApiClientMock/Product/1314976.json
new file mode 100644
index 00000000..07d2baf9
--- /dev/null
+++ b/tests/Integration/DataFixtures/ApiClientMock/Product/1314976.json
@@ -0,0 +1,72 @@
+{
+ "identifier": "1314976",
+ "enabled": true,
+ "family": "loudspeakers",
+ "categories": [
+ "audio_video_sales",
+ "loudspeakers",
+ "sony"
+ ],
+ "groups": [],
+ "parent": null,
+ "values": {
+ "picture": [
+ {
+ "locale": null,
+ "scope": null,
+ "data": "8/e/2/d/8e2d8254e599201a0e6e91d0c512bc37c8780c21_1314976_5566.jpg",
+ "_links": {
+ "download": {
+ "href": "http://127.0.0.1:8081/api/rest/v1/media-files/8/e/2/d/8e2d8254e599201a0e6e91d0c512bc37c8780c21_1314976_5566.jpg/download"
+ }
+ }
+ }
+ ],
+ "name": [
+ {
+ "locale": null,
+ "scope": null,
+ "data": "Sony SS-SP32FWB"
+ }
+ ],
+ "description": [
+ {
+ "locale": "en_US",
+ "scope": "print",
+ "data": "When it comes to creating high-quality Hi-Fi sound in your home, selecting the proper speakers is even more important. Sony makes it easy with an extremely wide range of different speakers. Whether you're listening to a refined string quartet or watching a powerful action-packed movie, Sony's speakers are designed to deliver an intensive acoustic experience that is both powerful and emotional."
+ }
+ ],
+ "release_date": [
+ {
+ "locale": null,
+ "scope": "ecommerce",
+ "data": "2007-10-13T00:00:00+00:00"
+ }
+ ]
+ },
+ "created": "2022-04-14T13:14:11+00:00",
+ "updated": "2022-04-14T13:14:11+00:00",
+ "associations": {
+ "PACK": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "UPSELL": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "X_SELL": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ },
+ "SUBSTITUTION": {
+ "products": [],
+ "product_models": [],
+ "groups": []
+ }
+ },
+ "quantified_associations": {}
+}
diff --git a/tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-l.json b/tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_L.json
similarity index 97%
rename from tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-l.json
rename to tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_L.json
index 2728e686..e2d5ae52 100644
--- a/tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-l.json
+++ b/tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_L.json
@@ -1,5 +1,5 @@
{
- "identifier": "braided-hat-l",
+ "identifier": "BRAIDED_HAT_L",
"enabled": true,
"family": "accessories",
"categories": [
@@ -7,7 +7,7 @@
"master_accessories_hats"
],
"groups": [],
- "parent": "model-braided-hat",
+ "parent": "MODEL_BRAIDED_HAT",
"values": {
"size": [
{
diff --git a/tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-m.json b/tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_M.json
similarity index 98%
rename from tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-m.json
rename to tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_M.json
index 1e5d188a..a0b069e8 100644
--- a/tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-m.json
+++ b/tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_M.json
@@ -1,5 +1,5 @@
{
- "identifier": "braided-hat-m",
+ "identifier": "BRAIDED_HAT_M",
"enabled": true,
"family": "accessories",
"categories": [
@@ -7,7 +7,7 @@
"master_accessories_hats"
],
"groups": [],
- "parent": "model-braided-hat",
+ "parent": "MODEL_BRAIDED_HAT",
"values": {
"size": [
{
diff --git a/tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-s.json b/tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_S.json
similarity index 97%
rename from tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-s.json
rename to tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_S.json
index 41afc02e..5dfbc5ec 100644
--- a/tests/Integration/DataFixtures/ApiClientMock/Product/braided-hat-s.json
+++ b/tests/Integration/DataFixtures/ApiClientMock/Product/BRAIDED_HAT_S.json
@@ -1,5 +1,5 @@
{
- "identifier": "braided-hat-s",
+ "identifier": "BRAIDED_HAT_S",
"enabled": false,
"family": "accessories",
"categories": [
@@ -7,7 +7,7 @@
"master_accessories_hats"
],
"groups": [],
- "parent": "model-braided-hat",
+ "parent": "MODEL_BRAIDED_HAT",
"values": {
"size": [
{
diff --git a/tests/Integration/DataFixtures/ApiClientMock/ProductModel/model-braided-hat.json b/tests/Integration/DataFixtures/ApiClientMock/ProductModel/MODEL_BRAIDED_HAT.json
similarity index 100%
rename from tests/Integration/DataFixtures/ApiClientMock/ProductModel/model-braided-hat.json
rename to tests/Integration/DataFixtures/ApiClientMock/ProductModel/MODEL_BRAIDED_HAT.json
diff --git a/tests/Integration/DataFixtures/ApiClientMock/media-files/6/5/8/8/65887ee600d9d66e829a75beedf374533b1ff8bc_10597353_1104.jpg b/tests/Integration/DataFixtures/ApiClientMock/media-files/6/5/8/8/65887ee600d9d66e829a75beedf374533b1ff8bc_10597353_1104.jpg
new file mode 100644
index 00000000..350bc04c
Binary files /dev/null and b/tests/Integration/DataFixtures/ApiClientMock/media-files/6/5/8/8/65887ee600d9d66e829a75beedf374533b1ff8bc_10597353_1104.jpg differ
diff --git a/tests/Integration/DataFixtures/ApiClientMock/media-files/7/3/6/b/736bbc43fd1e384f4badbeababd84389b31159f8_11164822_Philips.jpg b/tests/Integration/DataFixtures/ApiClientMock/media-files/7/3/6/b/736bbc43fd1e384f4badbeababd84389b31159f8_11164822_Philips.jpg
new file mode 100644
index 00000000..ff7eb269
Binary files /dev/null and b/tests/Integration/DataFixtures/ApiClientMock/media-files/7/3/6/b/736bbc43fd1e384f4badbeababd84389b31159f8_11164822_Philips.jpg differ
diff --git a/tests/Integration/DataFixtures/ApiClientMock/media-files/8/e/2/d/8e2d8254e599201a0e6e91d0c512bc37c8780c21_1314976_5566.jpg b/tests/Integration/DataFixtures/ApiClientMock/media-files/8/e/2/d/8e2d8254e599201a0e6e91d0c512bc37c8780c21_1314976_5566.jpg
new file mode 100644
index 00000000..2c6238f4
Binary files /dev/null and b/tests/Integration/DataFixtures/ApiClientMock/media-files/8/e/2/d/8e2d8254e599201a0e6e91d0c512bc37c8780c21_1314976_5566.jpg differ
diff --git a/tests/Integration/DataFixtures/ORM/resources/Product/model-braided-hat-with-variation-image.yaml b/tests/Integration/DataFixtures/ORM/resources/Product/model-braided-hat-with-variation-image.yaml
index 9c6fd159..6f1ddbfb 100644
--- a/tests/Integration/DataFixtures/ORM/resources/Product/model-braided-hat-with-variation-image.yaml
+++ b/tests/Integration/DataFixtures/ORM/resources/Product/model-braided-hat-with-variation-image.yaml
@@ -29,7 +29,7 @@ Sylius\Component\Core\Model\Product:
model-braided-hat:
fallbackLocale: "en_US"
currentLocale: "en_US"
- code: "model-braided-hat"
+ code: "MODEL_BRAIDED_HAT"
translations:
- "@model-braided-hat_en_US"
- "@model-braided-hat_it_IT"
diff --git a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-l.yaml b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-l.yaml
index a8f2aa1a..cc9aef91 100644
--- a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-l.yaml
+++ b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-l.yaml
@@ -1,6 +1,6 @@
Sylius\Component\Core\Model\ProductVariant:
braided-hat-l:
- code: 'braided-hat-l'
+ code: 'BRAIDED_HAT_L'
product: '@model-braided-hat'
optionValues:
- '@size_l'
diff --git a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m.yaml b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m.yaml
index 24d3be9e..8593b557 100644
--- a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m.yaml
+++ b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m.yaml
@@ -1,6 +1,6 @@
Sylius\Component\Core\Model\ProductVariant:
braided-hat-m:
- code: 'braided-hat-m'
+ code: 'BRAIDED_HAT_M'
product: '@model-braided-hat'
optionValues:
- '@size_m'
diff --git a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/with-channel-pricings.yaml b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/with-channel-pricings.yaml
index bb83521c..c44a65e4 100644
--- a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/with-channel-pricings.yaml
+++ b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/with-channel-pricings.yaml
@@ -11,7 +11,7 @@ Sylius\Component\Core\Model\ChannelPricing:
Sylius\Component\Core\Model\ProductVariant:
braided-hat-m:
- code: 'braided-hat-m'
+ code: 'BRAIDED_HAT_M'
product: '@model-braided-hat'
optionValues:
- '@size_m'
diff --git a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/without-option-values.yaml b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/without-option-values.yaml
index b1380c26..be71bf80 100644
--- a/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/without-option-values.yaml
+++ b/tests/Integration/DataFixtures/ORM/resources/ProductVariant/braided-hat-m/without-option-values.yaml
@@ -1,4 +1,4 @@
Sylius\Component\Core\Model\ProductVariant:
braided-hat-m:
- code: 'braided-hat-m'
+ code: 'BRAIDED_HAT_M'
product: '@model-braided-hat'
diff --git a/tests/Integration/Product/ImporterTest.php b/tests/Integration/Product/ImporterTest.php
index 90b76438..7e3b1832 100644
--- a/tests/Integration/Product/ImporterTest.php
+++ b/tests/Integration/Product/ImporterTest.php
@@ -57,14 +57,14 @@ public function it_creates_new_product_variant_and_its_product_when_importing_va
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductVariantInterface[] $allVariants */
$allVariants = $this->productVariantRepository->findAll();
$this->assertCount(1, $allVariants);
$this->assertInstanceOf(ProductVariantInterface::class, $allVariants[0]);
$this->assertInstanceOf(ProductInterface::class, $allVariants[0]->getProduct());
- $this->assertEquals('model-braided-hat', $allVariants[0]->getProduct()->getCode());
+ $this->assertEquals('MODEL_BRAIDED_HAT', $allVariants[0]->getProduct()->getCode());
}
/**
@@ -83,7 +83,7 @@ public function it_creates_proper_product_option_value_with_translations_if_miss
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductVariantInterface $variant */
$variant = $this->productVariantRepository->findAll()[0];
@@ -114,7 +114,7 @@ public function it_updates_alredy_existent_product_option_value()
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductVariantInterface $variant */
$variant = $this->productVariantRepository->findAll()[0];
@@ -143,7 +143,7 @@ public function it_creates_missing_translations_while_updating_alredy_existent_p
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductVariantInterface $variant */
$variant = $this->productVariantRepository->findAll()[0];
@@ -171,7 +171,7 @@ public function it_creates_missing_option_value_while_updating_alredy_existent_p
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductVariantInterface $variant */
$variant = $this->productVariantRepository->findAll()[0];
@@ -259,7 +259,7 @@ public function it_sets_channel_price_value_on_product_variant_according_to_chan
/** @var ChannelInterface $europeChannel */
$europeChannel = $this->channelRepository->findOneByCode('europe');
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductVariantInterface $variant */
$variant = $this->productVariantRepository->findAll()[0];
@@ -303,7 +303,7 @@ public function it_updates_channel_price_value_on_product_variant_according_chan
/** @var ChannelInterface $europeChannel */
$europeChannel = $this->channelRepository->findOneByCode('europe');
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductVariantInterface $variant */
$variant = $this->productVariantRepository->findAll()[0];
@@ -338,7 +338,7 @@ public function it_sets_all_channels_to_imported_products()
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductInterface $product */
$product = $this->productRepository->findAll()[0];
@@ -359,8 +359,8 @@ public function it_imports_all_product_images_when_importing_variants_of_configu
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
- $this->importer->import('braided-hat-l');
+ $this->importer->import('BRAIDED_HAT_M');
+ $this->importer->import('BRAIDED_HAT_L');
/** @var ProductVariantInterface[] $allVariants */
$allVariants = $this->productVariantRepository->findAll();
@@ -368,7 +368,7 @@ public function it_imports_all_product_images_when_importing_variants_of_configu
$this->assertInstanceOf(ProductVariantInterface::class, $allVariants[0]);
$product = $allVariants[0]->getProduct();
$this->assertInstanceOf(ProductInterface::class, $product);
- $this->assertEquals('model-braided-hat', $product->getCode());
+ $this->assertEquals('MODEL_BRAIDED_HAT', $product->getCode());
$this->assertCount(2, $product->getImages());
/** @var ProductImageInterface $image */
foreach ($product->getImages() as $image) {
@@ -511,9 +511,9 @@ public function it_imports_product_as_enabled_even_if_is_disabled_on_akeneo_but_
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-s');
+ $this->importer->import('BRAIDED_HAT_S');
- $product = $this->productRepository->findOneByCode('model-braided-hat');
+ $product = $this->productRepository->findOneByCode('MODEL_BRAIDED_HAT');
$this->assertTrue($product->isEnabled());
}
@@ -534,9 +534,9 @@ public function it_imports_variant_of_a_configurable_product_as_disabled_if_it_i
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-s');
+ $this->importer->import('BRAIDED_HAT_S');
- $productVariant = $this->productVariantRepository->findOneByCode('braided-hat-s');
+ $productVariant = $this->productVariantRepository->findOneByCode('BRAIDED_HAT_S');
$this->assertFalse($productVariant->isEnabled());
}
@@ -556,10 +556,10 @@ public function it_updates_existing_product_attribute_value()
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductInterface $product */
- $product = $this->productRepository->findOneByCode('model-braided-hat');
+ $product = $this->productRepository->findOneByCode('MODEL_BRAIDED_HAT');
$this->assertEquals('cotton', $product->getAttributeByCodeAndLocale('material', 'en_US')->getValue());
$this->assertEquals('cotone', $product->getAttributeByCodeAndLocale('material', 'it_IT')->getValue());
}
@@ -580,7 +580,7 @@ public function it_downloads_file_from_akeneo()
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
$this->assertTrue(
$this->filesystem->exists(
self::$container->getParameter(
@@ -636,9 +636,9 @@ public function it_removes_product_images_removed_on_akeneo()
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
- $product = $this->productRepository->findOneByCode('model-braided-hat');
+ $product = $this->productRepository->findOneByCode('MODEL_BRAIDED_HAT');
$this->assertCount(1, $product->getImages());
}
@@ -662,9 +662,9 @@ public function it_does_not_remove_product_images_of_other_variants_removed_on_a
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-l');
+ $this->importer->import('BRAIDED_HAT_L');
- $product = $this->productRepository->findOneByCode('model-braided-hat');
+ $product = $this->productRepository->findOneByCode('MODEL_BRAIDED_HAT');
$this->assertCount(2, $product->getImages());
}
@@ -708,10 +708,10 @@ public function it_removes_existing_product_attributes_values_if_they_are_empty_
PurgeMode::createDeleteMode(),
);
- $this->importer->import('braided-hat-m');
+ $this->importer->import('BRAIDED_HAT_M');
/** @var ProductInterface $product */
- $product = $this->productRepository->findOneByCode('model-braided-hat');
+ $product = $this->productRepository->findOneByCode('MODEL_BRAIDED_HAT');
$this->assertFalse($product->hasAttributeByCodeAndLocale('supplier', 'it_IT'));
$this->assertFalse($product->hasAttributeByCodeAndLocale('supplier', 'en_US'));
}
diff --git a/tests/Integration/TemporaryFilesManagerTest.php b/tests/Integration/TemporaryFilesManagerTest.php
index a700ed26..89c56150 100644
--- a/tests/Integration/TemporaryFilesManagerTest.php
+++ b/tests/Integration/TemporaryFilesManagerTest.php
@@ -12,7 +12,7 @@
final class TemporaryFilesManagerTest extends TestCase
{
- private $temporaryFileManager;
+ private TemporaryFilesManager $temporaryFileManager;
protected function setUp(): void
{
@@ -25,10 +25,8 @@ protected function setUp(): void
);
}
- /**
- * @test
- */
- public function it_generates_temporary_file_path()
+ /** @test */
+ public function it_generates_temporary_file_path(): void
{
$this->assertMatchesRegularExpression(
'|' . vfsStream::url('root') . '/akeneo-.*|',
@@ -36,10 +34,8 @@ public function it_generates_temporary_file_path()
);
}
- /**
- * @test
- */
- public function it_deletes_all_temporary_files()
+ /** @test */
+ public function it_deletes_all_temporary_files(): void
{
touch(vfsStream::url('root') . '/akeneo-temp1');
touch(vfsStream::url('root') . '/akeneo-temp2');
@@ -52,10 +48,8 @@ public function it_deletes_all_temporary_files()
$this->assertFileDoesNotExist(vfsStream::url('root') . '/akeneo-temp3');
}
- /**
- * @test
- */
- public function it_does_not_delete_not_managed_temporary_files()
+ /** @test */
+ public function it_does_not_delete_not_managed_temporary_files(): void
{
touch(vfsStream::url('root') . '/not-managed-temp-file');