From 9a7f3e6c567b1b83d920655be75176daaa66b4c8 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Thu, 11 Oct 2018 22:47:36 +0200 Subject: [PATCH 001/247] allows to define argument shareable state --- .../layout/adminhtml_notification_block.xml | 2 +- .../adminhtml/layout/catalog_search_block.xml | 2 +- .../layout/adminhtml_cache_block.xml | 2 +- .../adminhtml_system_design_grid_block.xml | 2 +- .../adminhtml_system_store_grid_block.xml | 2 +- .../adminhtml/layout/backup_index_block.xml | 2 +- .../layout/catalog_product_set_block.xml | 2 +- .../catalog_rule_promo_catalog_block.xml | 2 +- .../adminhtml_email_template_grid_block.xml | 2 +- .../layout/groupedproduct_popup_grid.xml | 2 +- .../layout/adminhtml_history_grid_block.xml | 2 +- .../layout/indexer_indexer_list_grid.xml | 2 +- .../adminhtml_integration_grid_block.xml | 2 +- .../layout/newsletter_problem_block.xml | 2 +- .../layout/newsletter_queue_grid_block.xml | 2 +- .../layout/newsletter_subscriber_block.xml | 2 +- .../layout/adminhtml_paypal_reports_block.xml | 2 +- .../paypal_billing_agreement_ordersgrid.xml | 2 +- .../layout/paypal_billing_agreement_view.xml | 2 +- .../reports_report_customer_accounts_grid.xml | 2 +- .../reports_report_customer_orders_grid.xml | 2 +- .../reports_report_customer_totals_grid.xml | 2 +- .../adminhtml/layout/reports_report_grid.xml | 2 +- .../reports_report_product_lowstock_grid.xml | 2 +- .../reports_report_product_sold_grid.xml | 2 +- .../reports_report_review_customer_grid.xml | 2 +- .../reports_report_review_product_grid.xml | 2 +- .../reports_report_statistics_index.xml | 2 +- .../view/adminhtml/layout/rating_block.xml | 2 +- .../sales_order_create_customer_block.xml | 2 +- .../sales_order_creditmemo_grid_block.xml | 2 +- .../layout/sales_order_invoice_grid_block.xml | 2 +- .../sales_order_shipment_grid_block.xml | 2 +- .../layout/sales_order_status_index.xml | 2 +- .../sales_order_transactions_grid_block.xml | 2 +- .../layout/sales_transaction_child_block.xml | 2 +- .../layout/sales_transactions_grid_block.xml | 2 +- .../layout/sales_rule_promo_quote_index.xml | 2 +- .../adminhtml/layout/search_term_block.xml | 2 +- .../layout/search_term_grid_block.xml | 2 +- .../layout/search_term_report_block.xml | 2 +- .../adminhtml_sitemap_index_grid_block.xml | 2 +- .../view/adminhtml/layout/tax_rate_block.xml | 2 +- .../view/adminhtml/layout/tax_rule_block.xml | 2 +- .../adminhtml_system_design_theme_block.xml | 2 +- .../layout/adminhtml_url_rewrite_index.xml | 2 +- .../layout/adminhtml_locks_block.xml | 2 +- .../layout/adminhtml_user_grid_block.xml | 2 +- .../layout/adminhtml_user_role_grid_block.xml | 2 +- .../adminhtml_system_variable_grid_block.xml | 2 +- .../adminhtml_widget_instance_block.xml | 2 +- .../layout/customer_index_wishlist.xml | 2 +- .../Argument/Interpreter/DataObject.php | 30 +++++-- .../Framework/View/Layout/etc/elements.xsd | 1 + .../Argument/Interpreter/ObjectTest.php | 86 ++++++++++++++++++- 55 files changed, 160 insertions(+), 61 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/layout/adminhtml_notification_block.xml b/app/code/Magento/AdminNotification/view/adminhtml/layout/adminhtml_notification_block.xml index c68313211c2e..06fd380cb2a4 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/layout/adminhtml_notification_block.xml +++ b/app/code/Magento/AdminNotification/view/adminhtml/layout/adminhtml_notification_block.xml @@ -11,7 +11,7 @@ notificationGrid - Magento\AdminNotification\Model\ResourceModel\Grid\Collection + Magento\AdminNotification\Model\ResourceModel\Grid\Collection DESC date_added 1 diff --git a/app/code/Magento/AdvancedSearch/view/adminhtml/layout/catalog_search_block.xml b/app/code/Magento/AdvancedSearch/view/adminhtml/layout/catalog_search_block.xml index b6ef596281e5..f3544863348e 100644 --- a/app/code/Magento/AdvancedSearch/view/adminhtml/layout/catalog_search_block.xml +++ b/app/code/Magento/AdvancedSearch/view/adminhtml/layout/catalog_search_block.xml @@ -11,7 +11,7 @@ catalog_search_grid - Magento\AdvancedSearch\Model\ResourceModel\Search\Grid\Collection + Magento\AdvancedSearch\Model\ResourceModel\Search\Grid\Collection name ASC 1 diff --git a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_cache_block.xml b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_cache_block.xml index 50d210f71025..6d2ecd8d36a9 100644 --- a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_cache_block.xml +++ b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_cache_block.xml @@ -11,7 +11,7 @@ cache_grid - Magento\Backend\Model\Cache\ResourceModel\Grid\Collection + Magento\Backend\Model\Cache\ResourceModel\Grid\Collection 0 diff --git a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_design_grid_block.xml b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_design_grid_block.xml index b96614f4bd8d..41bfe6e78a2a 100644 --- a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_design_grid_block.xml +++ b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_design_grid_block.xml @@ -11,7 +11,7 @@ designGrid - Magento\Theme\Model\ResourceModel\Design\Collection + Magento\Theme\Model\ResourceModel\Design\Collection 1 1 diff --git a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_store_grid_block.xml b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_store_grid_block.xml index 126de5eb4084..d0c0d8fcbf69 100644 --- a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_store_grid_block.xml +++ b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_store_grid_block.xml @@ -12,7 +12,7 @@ storeGrid 1 - Magento\Store\Model\ResourceModel\Website\Grid\Collection + Magento\Store\Model\ResourceModel\Website\Grid\Collection diff --git a/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml b/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml index e17618b97e21..e3e984d933f2 100644 --- a/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml +++ b/app/code/Magento/Backup/view/adminhtml/layout/backup_index_block.xml @@ -11,7 +11,7 @@ backupsGrid - Magento\Backup\Model\Fs\Collection + Magento\Backup\Model\Fs\Collection time desc diff --git a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_set_block.xml b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_set_block.xml index 44884897461a..4e7396608826 100644 --- a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_set_block.xml +++ b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_set_block.xml @@ -11,7 +11,7 @@ setGrid - Magento\Eav\Model\ResourceModel\Entity\Attribute\Grid\Collection + Magento\Eav\Model\ResourceModel\Entity\Attribute\Grid\Collection set_name ASC 1 diff --git a/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_block.xml b/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_block.xml index 99d64ed7a635..f38f6e0fcd85 100644 --- a/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_block.xml +++ b/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_block.xml @@ -11,7 +11,7 @@ promo_catalog_grid - Magento\CatalogRule\Model\ResourceModel\Grid\Collection + Magento\CatalogRule\Model\ResourceModel\Grid\Collection name ASC 1 diff --git a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_grid_block.xml b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_grid_block.xml index fa15560817dd..87da146d8ce5 100644 --- a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_grid_block.xml +++ b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_grid_block.xml @@ -11,7 +11,7 @@ systemEmailTemplateGrid - Magento\Email\Model\ResourceModel\Template\Collection + Magento\Email\Model\ResourceModel\Template\Collection 1 1 diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/layout/groupedproduct_popup_grid.xml b/app/code/Magento/GroupedProduct/view/adminhtml/layout/groupedproduct_popup_grid.xml index 503404c6cb3c..fab7851df5bc 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/layout/groupedproduct_popup_grid.xml +++ b/app/code/Magento/GroupedProduct/view/adminhtml/layout/groupedproduct_popup_grid.xml @@ -11,7 +11,7 @@ grouped_grid_popup - Magento\GroupedProduct\Model\ResourceModel\Product\Type\Grouped\AssociatedProductsCollection + Magento\GroupedProduct\Model\ResourceModel\Product\Type\Grouped\AssociatedProductsCollection 1 id ASC diff --git a/app/code/Magento/ImportExport/view/adminhtml/layout/adminhtml_history_grid_block.xml b/app/code/Magento/ImportExport/view/adminhtml/layout/adminhtml_history_grid_block.xml index 02fc198cb0ad..51e5827c8ab9 100644 --- a/app/code/Magento/ImportExport/view/adminhtml/layout/adminhtml_history_grid_block.xml +++ b/app/code/Magento/ImportExport/view/adminhtml/layout/adminhtml_history_grid_block.xml @@ -11,7 +11,7 @@ importHistoryGrid - Magento\ImportExport\Model\ResourceModel\History\Collection + Magento\ImportExport\Model\ResourceModel\History\Collection history_id desc diff --git a/app/code/Magento/Indexer/view/adminhtml/layout/indexer_indexer_list_grid.xml b/app/code/Magento/Indexer/view/adminhtml/layout/indexer_indexer_list_grid.xml index bf6b2351f75f..f1099c4133bc 100644 --- a/app/code/Magento/Indexer/view/adminhtml/layout/indexer_indexer_list_grid.xml +++ b/app/code/Magento/Indexer/view/adminhtml/layout/indexer_indexer_list_grid.xml @@ -13,7 +13,7 @@ 0 0 gridIndexer - Magento\Indexer\Ui\DataProvider\Indexer\DataCollection + Magento\Indexer\Ui\DataProvider\Indexer\DataCollection diff --git a/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_grid_block.xml b/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_grid_block.xml index 506f836f9951..43b67d6904f1 100644 --- a/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_grid_block.xml +++ b/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_grid_block.xml @@ -13,7 +13,7 @@ integrationGrid - Magento\Integration\Model\ResourceModel\Integration\Collection + Magento\Integration\Model\ResourceModel\Integration\Collection 1 integration_id asc diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_problem_block.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_problem_block.xml index 3eb7de194d24..008cb9c003e5 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_problem_block.xml +++ b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_problem_block.xml @@ -11,7 +11,7 @@ problemGrid - Magento\Newsletter\Model\ResourceModel\Grid\Collection + Magento\Newsletter\Model\ResourceModel\Grid\Collection true true 1 diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_grid_block.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_grid_block.xml index 3bfb52157bb9..8a2c891c68f8 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_grid_block.xml +++ b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_grid_block.xml @@ -11,7 +11,7 @@ queueGrid - Magento\Newsletter\Model\ResourceModel\Queue\Grid\Collection + Magento\Newsletter\Model\ResourceModel\Queue\Grid\Collection start_at DESC 1 diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_subscriber_block.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_subscriber_block.xml index 9de1807af18e..e8600c2d49d7 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_subscriber_block.xml +++ b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_subscriber_block.xml @@ -11,7 +11,7 @@ subscriberGrid - Magento\Newsletter\Model\ResourceModel\Subscriber\Grid\Collection + Magento\Newsletter\Model\ResourceModel\Subscriber\Grid\Collection subscriber_id desc 1 diff --git a/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_paypal_reports_block.xml b/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_paypal_reports_block.xml index 12dcc46e3ece..596381a4b114 100644 --- a/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_paypal_reports_block.xml +++ b/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_paypal_reports_block.xml @@ -11,7 +11,7 @@ settlementGrid - Magento\Paypal\Model\ResourceModel\Report\Settlement\Row\Collection + Magento\Paypal\Model\ResourceModel\Report\Settlement\Row\Collection row_id DESC 1 diff --git a/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_ordersgrid.xml b/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_ordersgrid.xml index 76a105f5abcd..0510011a6a55 100644 --- a/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_ordersgrid.xml +++ b/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_ordersgrid.xml @@ -9,7 +9,7 @@ - + Magento\Paypal\Model\Billing\Agreement\OrdersUpdater diff --git a/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_view.xml b/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_view.xml index c76539f5cb20..d9c376701db3 100644 --- a/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_view.xml +++ b/app/code/Magento/Paypal/view/adminhtml/layout/paypal_billing_agreement_view.xml @@ -12,7 +12,7 @@ - + Magento\Paypal\Model\Billing\Agreement\OrdersUpdater diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_accounts_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_accounts_grid.xml index 900dc08d571d..55ca286ad3d4 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_accounts_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_accounts_grid.xml @@ -11,7 +11,7 @@ gridAccounts - Magento\Reports\Model\ResourceModel\Accounts\Collection\Initial + Magento\Reports\Model\ResourceModel\Accounts\Collection\Initial diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_orders_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_orders_grid.xml index d886e5724cb0..f97bec3c1525 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_orders_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_orders_grid.xml @@ -11,7 +11,7 @@ gridOrdersCustomer - Magento\Reports\Model\ResourceModel\Customer\Orders\Collection\Initial + Magento\Reports\Model\ResourceModel\Customer\Orders\Collection\Initial diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_totals_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_totals_grid.xml index 4914829cf6eb..e1df04237c2a 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_totals_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_customer_totals_grid.xml @@ -11,7 +11,7 @@ gridTotalsCustomer - Magento\Reports\Model\ResourceModel\Customer\Totals\Collection\Initial + Magento\Reports\Model\ResourceModel\Customer\Totals\Collection\Initial diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_grid.xml index 82aa475807a2..0f6fbabb6a55 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_grid.xml @@ -24,7 +24,7 @@ 0 0 gridReport - Magento\Reports\Model\ResourceModel\Report\Collection + Magento\Reports\Model\ResourceModel\Report\Collection diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_lowstock_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_lowstock_grid.xml index 070c39259aab..62916fe1c1d7 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_lowstock_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_lowstock_grid.xml @@ -12,7 +12,7 @@ gridLowstock 0 - Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection + Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_sold_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_sold_grid.xml index a1b01aeeb526..22c66352b32e 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_sold_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_product_sold_grid.xml @@ -11,7 +11,7 @@ gridProductsSold - Magento\Reports\Model\ResourceModel\Product\Sold\Collection\Initial + Magento\Reports\Model\ResourceModel\Product\Sold\Collection\Initial diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_customer_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_customer_grid.xml index f941ca52eef5..a728f471e4de 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_customer_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_customer_grid.xml @@ -13,7 +13,7 @@ customers_grid review_cnt desc - Magento\Reports\Model\ResourceModel\Review\Customer\Collection + Magento\Reports\Model\ResourceModel\Review\Customer\Collection diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml index 1275e761ade3..26d0e8b13659 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml @@ -13,7 +13,7 @@ gridProducts review_cnt desc - Magento\Reports\Model\ResourceModel\Review\Product\Collection + Magento\Reports\Model\ResourceModel\Review\Product\Collection diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_statistics_index.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_statistics_index.xml index 4ec984ef9fc1..649dc7ceeb06 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_statistics_index.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_statistics_index.xml @@ -15,7 +15,7 @@ 0 0 0 - Magento\Reports\Model\ResourceModel\Refresh\Collection + Magento\Reports\Model\ResourceModel\Refresh\Collection diff --git a/app/code/Magento/Review/view/adminhtml/layout/rating_block.xml b/app/code/Magento/Review/view/adminhtml/layout/rating_block.xml index b439bcb1c271..414cec14c3be 100644 --- a/app/code/Magento/Review/view/adminhtml/layout/rating_block.xml +++ b/app/code/Magento/Review/view/adminhtml/layout/rating_block.xml @@ -11,7 +11,7 @@ ratingsGrid - Magento\Review\Model\ResourceModel\Rating\Grid\Collection + Magento\Review\Model\ResourceModel\Rating\Grid\Collection rating_code ASC 1 diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_customer_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_customer_block.xml index c321bee460e4..e11a5887beb6 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_customer_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_customer_block.xml @@ -13,7 +13,7 @@ sales_order_create_customer_grid 1 entity_id - Magento\Sales\Model\ResourceModel\Order\Customer\Collection + Magento\Sales\Model\ResourceModel\Order\Customer\Collection 1 customer_grid diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_grid_block.xml index 7f14ff3728a4..318416a777f3 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_grid_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_creditmemo_grid_block.xml @@ -11,7 +11,7 @@ order_creditmemos - Magento\Sales\Model\ResourceModel\Order\Creditmemo\Order\Grid\Collection + Magento\Sales\Model\ResourceModel\Order\Creditmemo\Order\Grid\Collection true created_at DESC diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_grid_block.xml index 941696f0ce89..d69ed4267710 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_grid_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_invoice_grid_block.xml @@ -11,7 +11,7 @@ order_invoices - Magento\Sales\Model\ResourceModel\Order\Invoice\Orders\Grid\Collection + Magento\Sales\Model\ResourceModel\Order\Invoice\Orders\Grid\Collection true created_at DESC diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_shipment_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_shipment_grid_block.xml index 0180efd29d2f..21b5d3b06c16 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_shipment_grid_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_shipment_grid_block.xml @@ -11,7 +11,7 @@ order_shipments - Magento\Sales\Model\ResourceModel\Order\Shipment\Order\Grid\Collection + Magento\Sales\Model\ResourceModel\Order\Shipment\Order\Grid\Collection true created_at DESC diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml index 87d7644a4b00..6854d3bb7bc3 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml @@ -12,7 +12,7 @@ sales_order_status_grid - Magento\Sales\Model\ResourceModel\Status\Collection + Magento\Sales\Model\ResourceModel\Status\Collection state desc 1 diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml index c2f553285720..adb722f6d0f5 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_transactions_grid_block.xml @@ -13,7 +13,7 @@ order_transactions - + Magento\Sales\Model\Grid\CollectionUpdater true diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_transaction_child_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_transaction_child_block.xml index aa8672a68bc6..5bdad85ebc16 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_transaction_child_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_transaction_child_block.xml @@ -11,7 +11,7 @@ transactionChildGrid - + Magento\Sales\Model\Grid\Child\CollectionUpdater false diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_grid_block.xml index 9f3b7f23ba20..37b319b94352 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_grid_block.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_transactions_grid_block.xml @@ -11,7 +11,7 @@ sales_transactions_grid - Magento\Sales\Model\ResourceModel\Transaction\Grid\Collection + Magento\Sales\Model\ResourceModel\Transaction\Grid\Collection true created_at DESC diff --git a/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_index.xml b/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_index.xml index 21ce8bfc3eaa..7796f280efcb 100644 --- a/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_index.xml +++ b/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_index.xml @@ -12,7 +12,7 @@ promo_quote_grid - Magento\SalesRule\Model\ResourceModel\Rule\Quote\Collection + Magento\SalesRule\Model\ResourceModel\Rule\Quote\Collection sort_order ASC 1 diff --git a/app/code/Magento/Search/view/adminhtml/layout/search_term_block.xml b/app/code/Magento/Search/view/adminhtml/layout/search_term_block.xml index cc2e1509e441..9dc60bde1131 100644 --- a/app/code/Magento/Search/view/adminhtml/layout/search_term_block.xml +++ b/app/code/Magento/Search/view/adminhtml/layout/search_term_block.xml @@ -11,7 +11,7 @@ searchReportGrid - Magento\Search\Model\ResourceModel\Query\Collection + Magento\Search\Model\ResourceModel\Query\Collection query_id DESC diff --git a/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml b/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml index 7330ac1f9271..38c6fa52455b 100644 --- a/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml +++ b/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml @@ -11,7 +11,7 @@ search_term_grid - Magento\Search\Model\ResourceModel\Query\Collection + Magento\Search\Model\ResourceModel\Query\Collection name ASC 1 diff --git a/app/code/Magento/Search/view/adminhtml/layout/search_term_report_block.xml b/app/code/Magento/Search/view/adminhtml/layout/search_term_report_block.xml index b6b1455cf27c..f4c5d1ab85a0 100644 --- a/app/code/Magento/Search/view/adminhtml/layout/search_term_report_block.xml +++ b/app/code/Magento/Search/view/adminhtml/layout/search_term_report_block.xml @@ -12,7 +12,7 @@ searchReportGrid - Magento\Search\Model\ResourceModel\Query\Collection + Magento\Search\Model\ResourceModel\Query\Collection query_id DESC diff --git a/app/code/Magento/Sitemap/view/adminhtml/layout/adminhtml_sitemap_index_grid_block.xml b/app/code/Magento/Sitemap/view/adminhtml/layout/adminhtml_sitemap_index_grid_block.xml index cdaa6575d559..632768e4a5f0 100644 --- a/app/code/Magento/Sitemap/view/adminhtml/layout/adminhtml_sitemap_index_grid_block.xml +++ b/app/code/Magento/Sitemap/view/adminhtml/layout/adminhtml_sitemap_index_grid_block.xml @@ -11,7 +11,7 @@ sitemapGrid - Magento\Sitemap\Model\ResourceModel\Sitemap\Collection + Magento\Sitemap\Model\ResourceModel\Sitemap\Collection sitemap_id diff --git a/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml b/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml index 463994262b7d..5c50b306411e 100644 --- a/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml +++ b/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml @@ -11,7 +11,7 @@ tax_rate_grid - Magento\Tax\Model\TaxRateCollection + Magento\Tax\Model\TaxRateCollection region_name ASC 1 diff --git a/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml b/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml index 5e42b835c035..07afd05e63f8 100644 --- a/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml +++ b/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml @@ -11,7 +11,7 @@ taxRuleGrid - Magento\Tax\Model\TaxRuleCollection + Magento\Tax\Model\TaxRuleCollection tax_rule_id ASC 1 diff --git a/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_block.xml b/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_block.xml index bb8fbd44629c..e19460d56a89 100644 --- a/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_block.xml +++ b/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_block.xml @@ -11,7 +11,7 @@ theme_grid - Magento\Theme\Model\ResourceModel\Theme\Grid\Collection + Magento\Theme\Model\ResourceModel\Theme\Grid\Collection 1 1 diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml b/app/code/Magento/UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml index 7d8151d27030..8b4910b62532 100644 --- a/app/code/Magento/UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml +++ b/app/code/Magento/UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml @@ -12,7 +12,7 @@ urlrewriteGrid - Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection + Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection url_rewrite_id diff --git a/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_block.xml b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_block.xml index 13cfbfe85933..d195ac93c16e 100644 --- a/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_block.xml +++ b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_block.xml @@ -12,7 +12,7 @@ lockedAdminsGrid - Magento\User\Model\ResourceModel\User\Locked\Collection + Magento\User\Model\ResourceModel\User\Locked\Collection user_id 1 diff --git a/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml b/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml index a4bc9aa5ed48..9099028ce9bf 100644 --- a/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml +++ b/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml @@ -11,7 +11,7 @@ permissionsUserGrid - Magento\User\Model\ResourceModel\User\Collection + Magento\User\Model\ResourceModel\User\Collection 1 username asc diff --git a/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_role_grid_block.xml b/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_role_grid_block.xml index 6d7ce67e2352..f2d699b6cc08 100644 --- a/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_role_grid_block.xml +++ b/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_role_grid_block.xml @@ -11,7 +11,7 @@ roleGrid - Magento\Authorization\Model\ResourceModel\Role\Grid\Collection + Magento\Authorization\Model\ResourceModel\Role\Grid\Collection 1 role_id asc diff --git a/app/code/Magento/Variable/view/adminhtml/layout/adminhtml_system_variable_grid_block.xml b/app/code/Magento/Variable/view/adminhtml/layout/adminhtml_system_variable_grid_block.xml index d934e46117fb..edee7fcca822 100644 --- a/app/code/Magento/Variable/view/adminhtml/layout/adminhtml_system_variable_grid_block.xml +++ b/app/code/Magento/Variable/view/adminhtml/layout/adminhtml_system_variable_grid_block.xml @@ -11,7 +11,7 @@ customVariablesGrid - Magento\Variable\Model\ResourceModel\Variable\Collection + Magento\Variable\Model\ResourceModel\Variable\Collection variable_id ASC diff --git a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml index 934b0ca1a85b..8ca3fab413b2 100644 --- a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml +++ b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml @@ -13,7 +13,7 @@ widgetInstanceGrid instance_id ASC - Magento\Widget\Model\ResourceModel\Widget\Instance\Collection + Magento\Widget\Model\ResourceModel\Widget\Instance\Collection diff --git a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml index 95b786603390..e364087405ed 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml +++ b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml @@ -9,7 +9,7 @@ - Magento\Wishlist\Model\ResourceModel\Item\Collection\Grid + Magento\Wishlist\Model\ResourceModel\Item\Collection\Grid wishlistGrid true added_at diff --git a/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php b/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php index ea9fef369e31..fb528a0fd1c9 100644 --- a/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php +++ b/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php @@ -3,10 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\View\Layout\Argument\Interpreter; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Data\Argument\InterpreterInterface; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Stdlib\BooleanUtils; /** * Interpreter that instantiates object by a class name @@ -14,23 +18,33 @@ class DataObject implements InterpreterInterface { /** - * @var ObjectManagerInterface + * @var \Magento\Framework\ObjectManagerInterface */ private $objectManager; + /** + * @var \Magento\Framework\Stdlib\BooleanUtils + */ + private $booleanUtils; + /** * @var string|null */ private $expectedClass; /** - * @param ObjectManagerInterface $objectManager + * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param string|null $expectedClass + * @param \Magento\Framework\Stdlib\BooleanUtils|null $booleanUtils */ - public function __construct(ObjectManagerInterface $objectManager, $expectedClass = null) - { + public function __construct( + ObjectManagerInterface $objectManager, + ?string $expectedClass = null, + ?BooleanUtils $booleanUtils = null + ) { $this->objectManager = $objectManager; $this->expectedClass = $expectedClass; + $this->booleanUtils = $booleanUtils ?? ObjectManager::getInstance()->get(BooleanUtils::class); } /** @@ -44,13 +58,17 @@ public function evaluate(array $data) if (!isset($data['value'])) { throw new \InvalidArgumentException('Object class name is missing.'); } + + $shared = isset($data['shared']) ? $this->booleanUtils->toBoolean($data['shared']) : true; $className = $data['value']; - $result = $this->objectManager->create($className); + $result = $shared ? $this->objectManager->get($className) : $this->objectManager->create($className); + if ($this->expectedClass && !$result instanceof $this->expectedClass) { throw new \UnexpectedValueException( - sprintf("Instance of %s is expected, got %s instead.", $this->expectedClass, get_class($result)) + \sprintf('Instance of %s is expected, got %s instead.', $this->expectedClass, \get_class($result)) ); } + return $result; } } diff --git a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd index 39cdec05a65e..f3967bb2fca4 100755 --- a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd +++ b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd @@ -14,6 +14,7 @@ + diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php index 7cc280a930d9..180888bcc1d3 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Framework\View\Test\Unit\Layout\Argument\Interpreter; -use \Magento\Framework\View\Layout\Argument\Interpreter\DataObject; +use Magento\Framework\View\Layout\Argument\Interpreter\DataObject; class ObjectTest extends \PHPUnit\Framework\TestCase { @@ -22,19 +22,55 @@ class ObjectTest extends \PHPUnit\Framework\TestCase protected $_interpreter; /** - * @var DataObject + * @var \Magento\Framework\Stdlib\BooleanUtils + */ + protected $_booleanUtils; + + /** + * @var \Magento\Framework\View\Layout\Argument\Interpreter\DataObject */ protected $_model; protected function setUp() { $this->_objectManager = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $this->_model = new DataObject($this->_objectManager, self::EXPECTED_CLASS); + $this->_booleanUtils = $this->createMock(\Magento\Framework\Stdlib\BooleanUtils::class); + $this->_model = new DataObject($this->_objectManager, self::EXPECTED_CLASS, $this->_booleanUtils); } public function testEvaluate() { $input = ['name' => 'dataSource', 'value' => self::EXPECTED_CLASS]; + $this->_objectManager->expects($this->once()) + ->method('get') + ->with(self::EXPECTED_CLASS) + ->willReturn($this); + + $actual = $this->_model->evaluate($input); + $this->assertSame($this, $actual); + } + + public function textEvaluateShareEnabled() + { + $input = ['name' => 'dataSource', 'value' => self::EXPECTED_CLASS, 'shared' => true]; + $this->_booleanUtils->expects($this->once()) + ->method('toBoolean') + ->willReturn(true); + $this->_objectManager->expects($this->once()) + ->method('get') + ->with(self::EXPECTED_CLASS) + ->willReturn($this); + + $actual = $this->_model->evaluate($input); + $this->assertSame($this, $actual); + } + + public function textEvaluateShareDisabled() + { + $input = ['name' => 'dataSource', 'value' => self::EXPECTED_CLASS, 'shared' => false]; + $this->_booleanUtils->expects($this->once()) + ->method('toBoolean') + ->willReturn(false); $this->_objectManager->expects($this->once()) ->method('create') ->with(self::EXPECTED_CLASS) @@ -52,12 +88,56 @@ public function testEvaluateWrongClass($input, $expectedException, $expectedExce $this->expectException($expectedException); $this->expectExceptionMessage($expectedExceptionMessage); $self = $this; + $this->_objectManager->expects($this->any())->method('get')->willReturnCallback( + function ($className) use ($self) { + return $self->createMock($className); + } + ); + + $this->_model->evaluate($input); + } + + /** + * @dataProvider evaluateWrongClassDataProvider + */ + public function testEvaluateShareEnabledWrongClass($input, $expectedException, $expectedExceptionMessage) + { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $self = $this; + $this->_booleanUtils->expects($this->any()) + ->method('toBoolean') + ->willReturn(true); + $this->_objectManager->expects($this->any())->method('get')->willReturnCallback( + function ($className) use ($self) { + return $self->createMock($className); + } + ); + + $input['shared'] = true; + + $this->_model->evaluate($input); + } + + /** + * @dataProvider evaluateWrongClassDataProvider + */ + public function testEvaluateShareDisabledWrongClass($input, $expectedException, $expectedExceptionMessage) + { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $self = $this; + $this->_booleanUtils->expects($this->any()) + ->method('toBoolean') + ->willReturn(false); $this->_objectManager->expects($this->any())->method('create')->willReturnCallback( function ($className) use ($self) { return $self->createMock($className); } ); + $input['shared'] = false; + $this->_model->evaluate($input); } From 415288f8b8bfc4dd3b700e25442b074c260ba30e Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Thu, 20 Dec 2018 13:48:59 +0200 Subject: [PATCH 002/247] Fix static and integration test. --- .../Magento/Test/Integrity/Modular/LayoutFilesTest.php | 5 ++--- .../View/Layout/Argument/Interpreter/DataObject.php | 5 +---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php index a11cd4b73b5c..32a58e285d76 100644 --- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php +++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php @@ -77,9 +77,8 @@ public function layoutArgumentsDataProvider() */ protected function isSkippedArgument(array $argumentData) { - // Do not take into account argument name and parameters - unset($argumentData['name']); - unset($argumentData['param']); + // Do not take into account argument name, shared and parameters + unset($argumentData['name'], $argumentData['param'], $argumentData['shared']); $isUpdater = isset($argumentData['updater']); unset($argumentData['updater']); diff --git a/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php b/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php index fb528a0fd1c9..bf607672cae0 100644 --- a/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php +++ b/lib/internal/Magento/Framework/View/Layout/Argument/Interpreter/DataObject.php @@ -48,10 +48,7 @@ public function __construct( } /** - * {@inheritdoc} - * @return object - * @throws \InvalidArgumentException - * @throws \UnexpectedValueException + * @inheritdoc */ public function evaluate(array $data) { From 5abd3308539fd0449d9ffe22a2d826e1909cc074 Mon Sep 17 00:00:00 2001 From: Julian Wundrak Date: Thu, 20 Dec 2018 22:30:00 +0100 Subject: [PATCH 003/247] [#19908] locale in rest calls is always default locale --- .../Webapi/Controller/PathProcessor.php | 15 ++++++- .../Unit/Controller/PathProcessorTest.php | 44 +++++++++++++------ .../Webapi/Controller/PathProcessorTest.php | 22 ++++++++++ 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Webapi/Controller/PathProcessor.php b/app/code/Magento/Webapi/Controller/PathProcessor.php index c5748cc6e848..20f1f02e3826 100644 --- a/app/code/Magento/Webapi/Controller/PathProcessor.php +++ b/app/code/Magento/Webapi/Controller/PathProcessor.php @@ -21,12 +21,21 @@ class PathProcessor */ private $storeManager; + /** + * @var \Magento\Framework\Locale\ResolverInterface + */ + private $localeResolver; + /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param \Magento\Framework\Locale\ResolverInterface $localeResolver */ - public function __construct(\Magento\Store\Model\StoreManagerInterface $storeManager) - { + public function __construct( + \Magento\Store\Model\StoreManagerInterface $storeManager, + \Magento\Framework\Locale\ResolverInterface $localeResolver + ) { $this->storeManager = $storeManager; + $this->localeResolver = $localeResolver; } /** @@ -57,9 +66,11 @@ public function process($pathInfo) $stores = $this->storeManager->getStores(false, true); if (isset($stores[$storeCode])) { $this->storeManager->setCurrentStore($storeCode); + $this->localeResolver->emulate($this->storeManager->getStore()->getId()); $path = '/' . (isset($pathParts[1]) ? $pathParts[1] : ''); } elseif ($storeCode === self::ALL_STORE_CODE) { $this->storeManager->setCurrentStore(\Magento\Store\Model\Store::ADMIN_CODE); + $this->localeResolver->emulate($this->storeManager->getStore()->getId()); $path = '/' . (isset($pathParts[1]) ? $pathParts[1] : ''); } else { $path = '/' . implode('/', $pathParts); diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php index c213c72b5185..9a1eb249cd9b 100644 --- a/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php @@ -13,6 +13,9 @@ class PathProcessorTest extends \PHPUnit\Framework\TestCase /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Store\Model\StoreManagerInterface */ private $storeManagerMock; + /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Locale\ResolverInterface */ + private $localeResolverMock; + /** @var \Magento\Webapi\Controller\PathProcessor */ private $model; @@ -24,13 +27,22 @@ class PathProcessorTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->storeManagerMock->expects($this->once()) - ->method('getStores') - ->willReturn([$this->arbitraryStoreCode => 'store object', 'default' => 'default store object']); - $this->model = new \Magento\Webapi\Controller\PathProcessor($this->storeManagerMock); + $store = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class); + $store->method('getId')->willReturn(2); + + $this->storeManagerMock = $this->createConfiguredMock( + \Magento\Store\Model\StoreManagerInterface::class, + [ + 'getStores' => [$this->arbitraryStoreCode => 'store object', 'default' => 'default store object'], + 'getStore' => $store, + ] + ); + $this->storeManagerMock->expects($this->once())->method('getStores'); + + $this->localeResolverMock = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class); + $this->localeResolverMock->method('emulate')->with(2); + + $this->model = new \Magento\Webapi\Controller\PathProcessor($this->storeManagerMock, $this->localeResolverMock); } /** @@ -38,15 +50,19 @@ protected function setUp() * * @param string $storeCodeInPath * @param string $storeCodeSet - * @param int $setCurrentStoreCallCtr + * @param int $setCurrentStoreCallCtr */ public function testAllStoreCode($storeCodeInPath, $storeCodeSet, $setCurrentStoreCallCtr = 1) { - $storeCodeInPath = !$storeCodeInPath ?: '/' . $storeCodeInPath; // add leading slash if store code not empty - $inPath = 'rest' . $storeCodeInPath . $this->endpointPath; + $storeCodeInPath = !$storeCodeInPath ? : '/' . $storeCodeInPath; // add leading slash if store code not empty + $inPath = 'rest' . $storeCodeInPath . $this->endpointPath; $this->storeManagerMock->expects($this->exactly($setCurrentStoreCallCtr)) ->method('setCurrentStore') ->with($storeCodeSet); + if($setCurrentStoreCallCtr > 0) { + $this->localeResolverMock->expects($this->once()) + ->method('emulate'); + } $result = $this->model->process($inPath); $this->assertSame($this->endpointPath, $result); } @@ -57,10 +73,10 @@ public function testAllStoreCode($storeCodeInPath, $storeCodeSet, $setCurrentSto public function processPathDataProvider() { return [ - 'All store code' => ['all', Store::ADMIN_CODE], - 'Default store code' => ['', 'default', 0], - 'Arbitrary store code' => [$this->arbitraryStoreCode, $this->arbitraryStoreCode], - 'Explicit default store code' => ['default', 'default'] + 'All store code' => ['all', Store::ADMIN_CODE], + 'Default store code' => ['', 'default', 0], + 'Arbitrary store code' => [$this->arbitraryStoreCode, $this->arbitraryStoreCode], + 'Explicit default store code' => ['default', 'default'], ]; } } diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php index 932ad03d691e..4b8bfd32b4f7 100644 --- a/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php +++ b/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php @@ -15,6 +15,11 @@ class PathProcessorTest extends \PHPUnit\Framework\TestCase */ protected $storeManager; + /** + * @var \Magento\Framework\Locale\ResolverInterface::class + */ + protected $localeResolver; + /** * @var \Magento\Webapi\Controller\PathProcessor */ @@ -25,6 +30,7 @@ protected function setUp() $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $this->storeManager = $objectManager->get(\Magento\Store\Model\StoreManagerInterface::class); $this->storeManager->reinitStores(); + $this->localeResolver = $objectManager->get(\Magento\Framework\Locale\ResolverInterface::class); $this->pathProcessor = $objectManager->get(\Magento\Webapi\Controller\PathProcessor::class); } @@ -59,4 +65,20 @@ public function testProcessWithoutStoreCode() $this->assertEquals($path, $result); $this->assertEquals('default', $this->storeManager->getStore()->getCode()); } + + /** + * @magentoDataFixture Magento/Store/_files/core_fixturestore.php + * @magentoConfigFixture default_store general/locale/code en_US + * @magentoConfigFixture fixturestore_store general/locale/code de_DE + */ + public function testProcessWithValidStoreCodeApplyLocale() + { + $locale = 'de_DE'; + $storeCode = 'fixturestore'; + $basePath = "rest/{$storeCode}"; + $path = $basePath . '/V1/customerAccounts/createCustomer'; + $this->pathProcessor->process($path); + $this->assertEquals($locale, $this->localeResolver->getLocale()); + $this->assertNotEquals('en_US', $this->localeResolver->getLocale()); + } } From ef724a622b5a45cb8dbeb9ca5f5d5039af4affcf Mon Sep 17 00:00:00 2001 From: Julian Wundrak Date: Sat, 22 Dec 2018 11:36:34 +0100 Subject: [PATCH 004/247] [#19908] add requested code style changes --- app/code/Magento/Webapi/Controller/PathProcessor.php | 7 +++++-- .../Webapi/Test/Unit/Controller/PathProcessorTest.php | 10 +++++----- .../Magento/Webapi/Controller/PathProcessorTest.php | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Webapi/Controller/PathProcessor.php b/app/code/Magento/Webapi/Controller/PathProcessor.php index 20f1f02e3826..b5f0be97de2f 100644 --- a/app/code/Magento/Webapi/Controller/PathProcessor.php +++ b/app/code/Magento/Webapi/Controller/PathProcessor.php @@ -6,6 +6,7 @@ */ namespace Magento\Webapi\Controller; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\NoSuchEntityException; /** @@ -32,10 +33,12 @@ class PathProcessor */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Locale\ResolverInterface $localeResolver + \Magento\Framework\Locale\ResolverInterface $localeResolver = null ) { $this->storeManager = $storeManager; - $this->localeResolver = $localeResolver; + $this->localeResolver = $localeResolver ?: ObjectManager::getInstance()->get( + \Magento\Framework\Locale\ResolverInterface::class + ); } /** diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php index 9a1eb249cd9b..e53d47d4b723 100644 --- a/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php @@ -54,8 +54,8 @@ protected function setUp() */ public function testAllStoreCode($storeCodeInPath, $storeCodeSet, $setCurrentStoreCallCtr = 1) { - $storeCodeInPath = !$storeCodeInPath ? : '/' . $storeCodeInPath; // add leading slash if store code not empty - $inPath = 'rest' . $storeCodeInPath . $this->endpointPath; + $storeCodeInPath = !$storeCodeInPath ?: '/' . $storeCodeInPath; // add leading slash if store code not empty + $inPath = 'rest' . $storeCodeInPath . $this->endpointPath; $this->storeManagerMock->expects($this->exactly($setCurrentStoreCallCtr)) ->method('setCurrentStore') ->with($storeCodeSet); @@ -73,9 +73,9 @@ public function testAllStoreCode($storeCodeInPath, $storeCodeSet, $setCurrentSto public function processPathDataProvider() { return [ - 'All store code' => ['all', Store::ADMIN_CODE], - 'Default store code' => ['', 'default', 0], - 'Arbitrary store code' => [$this->arbitraryStoreCode, $this->arbitraryStoreCode], + 'All store code' => ['all', Store::ADMIN_CODE], + 'Default store code' => ['', 'default', 0], + 'Arbitrary store code' => [$this->arbitraryStoreCode, $this->arbitraryStoreCode], 'Explicit default store code' => ['default', 'default'], ]; } diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php index 4b8bfd32b4f7..43aa788dea3a 100644 --- a/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php +++ b/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php @@ -18,7 +18,7 @@ class PathProcessorTest extends \PHPUnit\Framework\TestCase /** * @var \Magento\Framework\Locale\ResolverInterface::class */ - protected $localeResolver; + private $localeResolver; /** * @var \Magento\Webapi\Controller\PathProcessor From 29b4b3920d413c2571ef2d8fd2fb1dba55f63d43 Mon Sep 17 00:00:00 2001 From: Julian Wundrak Date: Thu, 27 Dec 2018 10:12:18 +0100 Subject: [PATCH 005/247] [#19908] Fix WebapiAyncTest --- .../Unit/Controller/PathProcessorTest.php | 2 +- .../Unit/Controller/PathProcessorTest.php | 29 ++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php index e53d47d4b723..513e0cbafcbb 100644 --- a/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Controller/PathProcessorTest.php @@ -50,7 +50,7 @@ protected function setUp() * * @param string $storeCodeInPath * @param string $storeCodeSet - * @param int $setCurrentStoreCallCtr + * @param int $setCurrentStoreCallCtr */ public function testAllStoreCode($storeCodeInPath, $storeCodeSet, $setCurrentStoreCallCtr = 1) { diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php index e5453f757454..cea7a4168ea4 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php @@ -15,6 +15,9 @@ class PathProcessorTest extends \PHPUnit\Framework\TestCase /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Store\Model\StoreManagerInterface */ private $storeManagerMock; + /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Locale\ResolverInterface */ + private $localeResolverMock; + /** @var \Magento\Webapi\Controller\PathProcessor */ private $model; @@ -26,16 +29,22 @@ class PathProcessorTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->storeManagerMock->expects($this->once()) - ->method('getStores') - ->willReturn([ - $this->arbitraryStoreCode => 'store object', - 'default' => 'default store object', - ]); - $this->model = new \Magento\Webapi\Controller\PathProcessor($this->storeManagerMock); + $store = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class); + $store->method('getId')->willReturn(2); + + $this->storeManagerMock = $this->createConfiguredMock( + \Magento\Store\Model\StoreManagerInterface::class, + [ + 'getStores' => [$this->arbitraryStoreCode => 'store object', 'default' => 'default store object'], + 'getStore' => $store, + ] + ); + $this->storeManagerMock->expects($this->once())->method('getStores'); + + $this->localeResolverMock = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class); + $this->localeResolverMock->method('emulate')->with(2); + + $this->model = new \Magento\Webapi\Controller\PathProcessor($this->storeManagerMock, $this->localeResolverMock); } /** From 334d71368b2d7ad8b060051b7009c730825f9c4f Mon Sep 17 00:00:00 2001 From: Khodu Vaishnav Date: Sat, 8 Dec 2018 16:50:22 +0530 Subject: [PATCH 006/247] patch-9155 : set default qty for add to cart from wishlist. patch-9155 : set default qty for add to cart from wishlist. patch-9155 : set default qty for add to cart in wishlist. --- .../Customer/Wishlist/Item/Column/Cart.php | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php index fe0683a52fe9..3e0a611b2e7c 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php @@ -16,6 +16,28 @@ */ class Cart extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column { + /** + * @var \Magento\Catalog\Block\Product\View + */ + protected $productView; + + /** + * + * @param \Magento\Catalog\Block\Product\Context $context + * @param \Magento\Framework\App\Http\Context $httpContext + * @param array $data + * @param \Magento\Catalog\Block\Product\View $productView + */ + public function __construct( + \Magento\Catalog\Block\Product\Context $context, + \Magento\Framework\App\Http\Context $httpContext, + \Magento\Catalog\Block\Product\View $productView = null, + array $data = [] + ) { + $this->productView = $productView ?: + \Magento\Framework\App\ObjectManager::getInstance()->get(\Magento\Catalog\Block\Product\View::class); + parent::__construct($context, $httpContext, $data); + } /** * Returns qty to show visually to user * @@ -25,6 +47,8 @@ class Cart extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column public function getAddToCartQty(\Magento\Wishlist\Model\Item $item) { $qty = $item->getQty(); + $qty = $qty < $this->productView->getProductDefaultQty($this->getProductItem()) + ? $this->productView->getProductDefaultQty($this->getProductItem()) : $qty ; return $qty ? $qty : 1; } From 9dc3a19d2cb37f4d0a4cddbab7334d0c579c45b9 Mon Sep 17 00:00:00 2001 From: Iaroslav Gyryn Date: Thu, 31 Jan 2019 09:42:59 +0200 Subject: [PATCH 007/247] magento/magento2#20481 REST products update category_ids cannot be removed --- .../Catalog/Model/ProductRepository.php | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index d124bf5e4263..217454b2eb72 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -11,6 +11,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap; use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Catalog\Api\CategoryLinkManagementInterface; use Magento\Eav\Model\Entity\Attribute\Exception as AttributeException; use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\Api\Data\ImageContentInterfaceFactory; @@ -161,6 +162,16 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa */ private $readExtensions; + /** + * @var CategoryLinkManagementInterface + */ + private $categoryLinkManagement; + + /** + * @var AssignProductToCategories + */ + private $assignProductToCategories = false; + /** * ProductRepository constructor. * @param ProductFactory $productFactory @@ -187,6 +198,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer * @param int $cacheLimit [optional] * @param ReadExtensions|null $readExtensions + * @param Magento\Catalog\Api\CategoryLinkManagementInterface|null $categoryLinkManagement * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -214,7 +226,8 @@ public function __construct( CollectionProcessorInterface $collectionProcessor = null, \Magento\Framework\Serialize\Serializer\Json $serializer = null, $cacheLimit = 1000, - ReadExtensions $readExtensions = null + ReadExtensions $readExtensions = null, + CategoryLinkManagementInterface $categoryLinkManagement = null ) { $this->productFactory = $productFactory; $this->collectionFactory = $collectionFactory; @@ -239,6 +252,8 @@ public function __construct( $this->cacheLimit = (int)$cacheLimit; $this->readExtensions = $readExtensions ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(ReadExtensions::class); + $this->categoryLinkManagement = $categoryLinkManagement ?:\Magento\Framework\App\ObjectManager::getInstance() + ->get(CategoryLinkManagementInterface::class); } /** @@ -589,6 +604,7 @@ public function save(ProductInterface $product, $saveOptions = false) $extensionAttributes = $product->getExtensionAttributes(); if (empty($extensionAttributes->__toArray())) { $product->setExtensionAttributes($existingProduct->getExtensionAttributes()); + $this->assignProductToCategories = true; } } catch (NoSuchEntityException $e) { $existingProduct = null; @@ -626,6 +642,12 @@ public function save(ProductInterface $product, $saveOptions = false) } $this->saveProduct($product); + if ($this->assignProductToCategories === true) { + $this->categoryLinkManagement->assignProductToCategories( + $product->getSku(), + $product->getCategoryIds() + ); + } $this->removeProductFromLocalCache($product->getSku()); unset($this->instancesById[$product->getId()]); From b6020677c4fd3e99d59c67b953bfa53d70bed165 Mon Sep 17 00:00:00 2001 From: Iaroslav Gyryn Date: Thu, 31 Jan 2019 16:56:44 +0200 Subject: [PATCH 008/247] magento/magento2#20481 REST products update category_ids cannot be removed Code review --- .../Catalog/Model/ProductRepository.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 217454b2eb72..518a17ff3f10 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -165,12 +165,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa /** * @var CategoryLinkManagementInterface */ - private $categoryLinkManagement; - - /** - * @var AssignProductToCategories - */ - private $assignProductToCategories = false; + private $linkManagement; /** * ProductRepository constructor. @@ -227,7 +222,7 @@ public function __construct( \Magento\Framework\Serialize\Serializer\Json $serializer = null, $cacheLimit = 1000, ReadExtensions $readExtensions = null, - CategoryLinkManagementInterface $categoryLinkManagement = null + CategoryLinkManagementInterface $linkManagement = null ) { $this->productFactory = $productFactory; $this->collectionFactory = $collectionFactory; @@ -252,7 +247,7 @@ public function __construct( $this->cacheLimit = (int)$cacheLimit; $this->readExtensions = $readExtensions ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(ReadExtensions::class); - $this->categoryLinkManagement = $categoryLinkManagement ?:\Magento\Framework\App\ObjectManager::getInstance() + $this->linkManagement = $linkManagement ?:\Magento\Framework\App\ObjectManager::getInstance() ->get(CategoryLinkManagementInterface::class); } @@ -587,6 +582,7 @@ protected function processMediaGallery(ProductInterface $product, $mediaGalleryE */ public function save(ProductInterface $product, $saveOptions = false) { + $assignToCategories = false; $tierPrices = $product->getData('tier_price'); try { @@ -604,7 +600,7 @@ public function save(ProductInterface $product, $saveOptions = false) $extensionAttributes = $product->getExtensionAttributes(); if (empty($extensionAttributes->__toArray())) { $product->setExtensionAttributes($existingProduct->getExtensionAttributes()); - $this->assignProductToCategories = true; + $assignToCategories = true; } } catch (NoSuchEntityException $e) { $existingProduct = null; @@ -642,8 +638,8 @@ public function save(ProductInterface $product, $saveOptions = false) } $this->saveProduct($product); - if ($this->assignProductToCategories === true) { - $this->categoryLinkManagement->assignProductToCategories( + if ($assignToCategories === true) { + $this->linkManagement->assignProductToCategories( $product->getSku(), $product->getCategoryIds() ); From 73859cd565ddf112ba003953efb523688acdfea2 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Wed, 30 Jan 2019 11:47:02 +0200 Subject: [PATCH 009/247] ENGCOM-3715: Static test fix. --- .../Customer/Wishlist/Item/Column/Cart.php | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php index 3e0a611b2e7c..d2871efc1aab 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php @@ -6,7 +6,11 @@ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; +use Magento\Catalog\Block\Product\View; use Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter; +use Magento\Catalog\Model\Product\Image\UrlBuilder; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\View\ConfigInterface; /** * Wishlist block customer item cart column @@ -17,27 +21,30 @@ class Cart extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column { /** - * @var \Magento\Catalog\Block\Product\View + * @var View */ protected $productView; /** - * * @param \Magento\Catalog\Block\Product\Context $context * @param \Magento\Framework\App\Http\Context $httpContext * @param array $data - * @param \Magento\Catalog\Block\Product\View $productView + * @param ConfigInterface|null $config + * @param UrlBuilder|null $urlBuilder + * @param View|null $productView */ public function __construct( \Magento\Catalog\Block\Product\Context $context, \Magento\Framework\App\Http\Context $httpContext, - \Magento\Catalog\Block\Product\View $productView = null, - array $data = [] + array $data = [], + ?ConfigInterface $config = null, + ?UrlBuilder $urlBuilder = null, + ?View $productView = null ) { - $this->productView = $productView ?: - \Magento\Framework\App\ObjectManager::getInstance()->get(\Magento\Catalog\Block\Product\View::class); - parent::__construct($context, $httpContext, $data); + $this->productView = $productView ?: ObjectManager::getInstance()->get(View::class); + parent::__construct($context, $httpContext, $data, $config, $urlBuilder); } + /** * Returns qty to show visually to user * @@ -48,8 +55,8 @@ public function getAddToCartQty(\Magento\Wishlist\Model\Item $item) { $qty = $item->getQty(); $qty = $qty < $this->productView->getProductDefaultQty($this->getProductItem()) - ? $this->productView->getProductDefaultQty($this->getProductItem()) : $qty ; - return $qty ? $qty : 1; + ? $this->productView->getProductDefaultQty($this->getProductItem()) : $qty; + return $qty ?: 1; } /** From d1b7097bc38e87669607cfac094d312d76ce7ab3 Mon Sep 17 00:00:00 2001 From: Iaroslav Gyryn Date: Thu, 7 Feb 2019 14:00:33 +0200 Subject: [PATCH 010/247] magento/magento2#20481 REST products update category_ids cannot be removed Code review, updated unit tests --- app/code/Magento/Catalog/Model/ProductRepository.php | 4 ++-- .../Test/Unit/Model/ProductRepositoryTest.php | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 518a17ff3f10..d78d1ca2f216 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -193,7 +193,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer * @param int $cacheLimit [optional] * @param ReadExtensions|null $readExtensions - * @param Magento\Catalog\Api\CategoryLinkManagementInterface|null $categoryLinkManagement + * @param Magento\Catalog\Api\CategoryLinkManagementInterface|null $linkManagement * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -638,7 +638,7 @@ public function save(ProductInterface $product, $saveOptions = false) } $this->saveProduct($product); - if ($assignToCategories === true) { + if ($assignToCategories === true && $product->getCategoryIds()) { $this->linkManagement->assignProductToCategories( $product->getSku(), $product->getCategoryIds() diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index c729a0c58e1e..6d3b4713b830 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -200,7 +200,8 @@ protected function setUp() 'setData', 'getStoreId', 'getMediaGalleryEntries', - 'getExtensionAttributes' + 'getExtensionAttributes', + 'getCategoryIds' ] ); @@ -220,7 +221,8 @@ protected function setUp() 'validate', 'save', 'getMediaGalleryEntries', - 'getExtensionAttributes' + 'getExtensionAttributes', + 'getCategoryIds' ] ); $this->initializedProduct->expects($this->any()) @@ -269,6 +271,12 @@ protected function setUp() $this->initializedProduct ->method('getExtensionAttributes') ->willReturn($this->productExtension); + $this->product + ->method('getCategoryIds') + ->willReturn([1, 2, 3, 4]); + $this->initializedProduct + ->method('getCategoryIds') + ->willReturn([1, 2, 3, 4]); $storeMock = $this->getMockBuilder(StoreInterface::class) ->disableOriginalConstructor() ->setMethods([]) From 814947905ba35e2bbaca4f4124d1e0ac19225ce5 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Thu, 7 Feb 2019 21:25:07 +0200 Subject: [PATCH 011/247] Minor code style fixes --- app/code/Magento/Catalog/Model/ProductRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index d78d1ca2f216..57584b116a3a 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -7,11 +7,11 @@ namespace Magento\Catalog\Model; +use Magento\Catalog\Api\CategoryLinkManagementInterface; use Magento\Catalog\Api\Data\ProductExtension; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product\Gallery\MimeTypeExtensionMap; use Magento\Catalog\Model\ResourceModel\Product\Collection; -use Magento\Catalog\Api\CategoryLinkManagementInterface; use Magento\Eav\Model\Entity\Attribute\Exception as AttributeException; use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\Api\Data\ImageContentInterfaceFactory; @@ -247,7 +247,7 @@ public function __construct( $this->cacheLimit = (int)$cacheLimit; $this->readExtensions = $readExtensions ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(ReadExtensions::class); - $this->linkManagement = $linkManagement ?:\Magento\Framework\App\ObjectManager::getInstance() + $this->linkManagement = $linkManagement ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(CategoryLinkManagementInterface::class); } From 0510379aa8668ae6b52e1c46f8acd9b17e291c18 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 26 Feb 2019 13:17:41 -0600 Subject: [PATCH 012/247] MC-15033: Configurable product gallery does not prepend images with multiple attributes - add functional test --- .../Catalog/Test/Mftf/Data/ProductData.xml | 9 ++++ .../AdminAddDefaultImageSimpleProductTest.xml | 4 +- .../AdminConfigurableProductActionGroup.xml | 16 +++++++ ...reateProductConfigurationsPanelSection.xml | 6 +++ .../StorefrontProductInfoMainSection.xml | 2 +- .../StorefrontFilterByImageSwatchTest.xml | 43 +++++++++++++++++-- 6 files changed, 74 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index d136661e917c..10f70a7094fb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -222,6 +222,15 @@ magento-again jpg + + magento-adobe + 1.00 + Upload File + Yes + adobe-base.jpg + adobe-base + jpg + 霁产品 simple diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml index 88a39a9087bb..117f094ee060 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml @@ -43,7 +43,9 @@ - + + + diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml index d2abfc797751..503a8ffd4e1d 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml @@ -131,6 +131,22 @@ + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml index 9b4798c95ec7..242eb3b4ca79 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml @@ -26,6 +26,12 @@ + + + + + + diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/StorefrontProductInfoMainSection.xml index e40a04080285..4290ddbbd8dd 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/StorefrontProductInfoMainSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/StorefrontProductInfoMainSection.xml @@ -9,7 +9,7 @@
- + diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml index e4c96ab3a2ba..5347a1a1f870 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml @@ -79,16 +79,25 @@ - + + + + + + + + + - + - + + @@ -111,7 +120,33 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3a772bc0fba518ab0328cd6a881955ac719aef16 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 26 Feb 2019 13:36:53 -0600 Subject: [PATCH 013/247] MC-15033: Configurable product gallery does not prepend images with multiple attributes - add after clicks --- .../Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml index 503a8ffd4e1d..c7af58212b5f 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml @@ -143,8 +143,8 @@ - - + + From ce441c69dd37859fc4ddbd400ab7209ac021b6f2 Mon Sep 17 00:00:00 2001 From: Danny Verkade Date: Wed, 27 Feb 2019 20:04:26 +0100 Subject: [PATCH 014/247] Fix for issue #21477 sets CURRENT_TIMESTAMP and updated_at fields in the DB Schema. --- app/code/Magento/Integration/etc/db_schema.xml | 2 +- app/code/Magento/Quote/etc/db_schema.xml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Integration/etc/db_schema.xml b/app/code/Magento/Integration/etc/db_schema.xml index f1824fadb97f..cbf43d79b2cf 100644 --- a/app/code/Magento/Integration/etc/db_schema.xml +++ b/app/code/Magento/Integration/etc/db_schema.xml @@ -107,7 +107,7 @@ comment="Oauth consumer"/> - diff --git a/app/code/Magento/Quote/etc/db_schema.xml b/app/code/Magento/Quote/etc/db_schema.xml index 6f9f81ba6b3f..82d468547c47 100644 --- a/app/code/Magento/Quote/etc/db_schema.xml +++ b/app/code/Magento/Quote/etc/db_schema.xml @@ -108,7 +108,7 @@ default="0" comment="Quote Id"/> - @@ -218,7 +218,7 @@ default="0" comment="Quote Id"/> - @@ -322,7 +322,7 @@ default="0" comment="Quote Item Id"/> - @@ -434,7 +434,7 @@ default="0" comment="Quote Id"/> - @@ -470,7 +470,7 @@ default="0" comment="Address Id"/> - From b57dab0c754144cb94584523747bf2b40148d4c0 Mon Sep 17 00:00:00 2001 From: David Alger Date: Fri, 1 Mar 2019 15:43:20 -0600 Subject: [PATCH 015/247] Fixed curl adapter to properly set http version as passed in arguments to prevent failure when requesting from http2 capable endpoint --- lib/internal/Magento/Framework/HTTP/Adapter/Curl.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php index bc833bf3bb2d..96af9be49f34 100644 --- a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php @@ -183,6 +183,12 @@ public function write($method, $url, $http_ver = '1.1', $headers = [], $body = ' curl_setopt($this->_getResource(), CURLOPT_CUSTOMREQUEST, 'GET'); } + if ($http_ver === \Zend_Http_Client::HTTP_1) { + curl_setopt($this->_getResource(), CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + } elseif ($http_ver === \Zend_Http_Client::HTTP_0) { + curl_setopt($this->_getResource(), CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + } + if (is_array($headers)) { curl_setopt($this->_getResource(), CURLOPT_HTTPHEADER, $headers); } From bc8f90993c35b5c232a923ef126ba97d046a35c0 Mon Sep 17 00:00:00 2001 From: Matthew Muscat Date: Thu, 19 Jul 2018 22:46:18 +1000 Subject: [PATCH 016/247] Resolve incorrect scope code selection when the requested scopeCode is null - resolves an issue whereby the incorrect scope could be returned when attempting to resolve a scope with a requested scopeCode of null - simplify the scope resolver logic to a avoid multiple if conditional checks - move scope interface class to an alias of the class - update docblock on the expected values available for scopeCode Signed-off-by: Matthew Muscat --- .../Framework/App/Config/ScopeCodeResolver.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php b/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php index 321997afdba9..8876f751f7c3 100644 --- a/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php +++ b/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php @@ -5,6 +5,7 @@ */ namespace Magento\Framework\App\Config; +use Magento\Framework\App\ScopeInterface; use Magento\Framework\App\ScopeResolverPool; /** @@ -34,7 +35,7 @@ public function __construct(ScopeResolverPool $scopeResolverPool) * Resolve scope code * * @param string $scopeType - * @param string $scopeCode + * @param string|null $scopeCode * @return string */ public function resolve($scopeType, $scopeCode) @@ -42,20 +43,25 @@ public function resolve($scopeType, $scopeCode) if (isset($this->resolvedScopeCodes[$scopeType][$scopeCode])) { return $this->resolvedScopeCodes[$scopeType][$scopeCode]; } - if (($scopeCode === null || is_numeric($scopeCode)) - && $scopeType !== ScopeConfigInterface::SCOPE_TYPE_DEFAULT - ) { + + if ($scopeType !== ScopeConfigInterface::SCOPE_TYPE_DEFAULT) { $scopeResolver = $this->scopeResolverPool->get($scopeType); $resolverScopeCode = $scopeResolver->getScope($scopeCode); - } else { + } + else { $resolverScopeCode = $scopeCode; } - if ($resolverScopeCode instanceof \Magento\Framework\App\ScopeInterface) { + if ($resolverScopeCode instanceof ScopeInterface) { $resolverScopeCode = $resolverScopeCode->getCode(); } + if ($scopeCode == null) { + $scopeCode = $resolverScopeCode; + } + $this->resolvedScopeCodes[$scopeType][$scopeCode] = $resolverScopeCode; + return $resolverScopeCode; } From ca168091922bc4d34e2347304abb12e9f08a81f9 Mon Sep 17 00:00:00 2001 From: Matthew Muscat Date: Fri, 20 Jul 2018 11:56:16 +1000 Subject: [PATCH 017/247] update travis-ci for phpcs static test --- .../Magento/Framework/App/Config/ScopeCodeResolver.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php b/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php index 8876f751f7c3..ea26b736eca9 100644 --- a/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php +++ b/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php @@ -47,8 +47,7 @@ public function resolve($scopeType, $scopeCode) if ($scopeType !== ScopeConfigInterface::SCOPE_TYPE_DEFAULT) { $scopeResolver = $this->scopeResolverPool->get($scopeType); $resolverScopeCode = $scopeResolver->getScope($scopeCode); - } - else { + } else { $resolverScopeCode = $scopeCode; } From 9e5fdbbb0edbaceea6d5a17607dea1a21205286c Mon Sep 17 00:00:00 2001 From: Matthew Muscat Date: Fri, 20 Jul 2018 18:49:11 +1000 Subject: [PATCH 018/247] Update null conditional check --- lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php b/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php index ea26b736eca9..681af3594469 100644 --- a/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php +++ b/lib/internal/Magento/Framework/App/Config/ScopeCodeResolver.php @@ -55,7 +55,7 @@ public function resolve($scopeType, $scopeCode) $resolverScopeCode = $resolverScopeCode->getCode(); } - if ($scopeCode == null) { + if ($scopeCode === null) { $scopeCode = $resolverScopeCode; } From 6ce9ee7dbd13bbce08372482c3a4fcd7dcd08499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20M=C3=BCnch?= Date: Sat, 16 Mar 2019 11:27:48 +0200 Subject: [PATCH 019/247] Issue #7227: "x_forwarded_for" value is always empty in Order object --- .../Magento/Quote/Model/QuoteManagement.php | 28 ++++++- .../Test/Unit/Model/QuoteManagementTest.php | 78 +++++++++++++++---- 2 files changed, 88 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index 8f216b64aa9b..4c37e22898de 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -146,6 +146,16 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface */ private $addressesToSync = []; + /** + * @var \Magento\Framework\App\RequestInterface + */ + private $request; + + /** + * @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress + */ + private $remoteAddress; + /** * @param EventManager $eventManager * @param QuoteValidator $quoteValidator @@ -169,6 +179,8 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface * @param QuoteFactory $quoteFactory * @param \Magento\Quote\Model\QuoteIdMaskFactory|null $quoteIdMaskFactory * @param \Magento\Customer\Api\AddressRepositoryInterface|null $addressRepository + * @param \Magento\Framework\App\RequestInterface|null $request + * @param \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -193,7 +205,9 @@ public function __construct( \Magento\Customer\Api\AccountManagementInterface $accountManagement, \Magento\Quote\Model\QuoteFactory $quoteFactory, \Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory = null, - \Magento\Customer\Api\AddressRepositoryInterface $addressRepository = null + \Magento\Customer\Api\AddressRepositoryInterface $addressRepository = null, + \Magento\Framework\App\RequestInterface $request = null, + \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress = null ) { $this->eventManager = $eventManager; $this->quoteValidator = $quoteValidator; @@ -219,6 +233,10 @@ public function __construct( ->get(\Magento\Quote\Model\QuoteIdMaskFactory::class); $this->addressRepository = $addressRepository ?: ObjectManager::getInstance() ->get(\Magento\Customer\Api\AddressRepositoryInterface::class); + $this->request = $request ?: ObjectManager::getInstance() + ->get(\Magento\Framework\App\RequestInterface::class); + $this->remoteAddress = $remoteAddress ?: ObjectManager::getInstance() + ->get(\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress::class); } /** @@ -368,6 +386,14 @@ public function placeOrder($cartId, PaymentInterface $paymentMethod = null) $quote->setCustomerGroupId(\Magento\Customer\Api\Data\GroupInterface::NOT_LOGGED_IN_ID); } + $remoteAddress = $this->remoteAddress->getRemoteAddress(); + if ($remoteAddress !== false) { + $quote->setRemoteIp($remoteAddress); + $quote->setXForwardedFor( + $this->request->getServer('HTTP_X_FORWARDED_FOR') + ); + } + $this->eventManager->dispatch('checkout_submit_before', ['quote' => $quote]); $order = $this->submit($quote); diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php index b61f95b4eee6..8d8200cd6ef6 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php @@ -6,9 +6,12 @@ namespace Magento\Quote\Test\Unit\Model; +use Magento\Framework\App\RequestInterface; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress; use Magento\Quote\Model\CustomerManagement; +use Magento\Quote\Model\QuoteIdMaskFactory; use Magento\Sales\Api\Data\OrderAddressInterface; /** @@ -137,6 +140,21 @@ class QuoteManagementTest extends \PHPUnit\Framework\TestCase */ private $quoteFactoryMock; + /** + * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; + + /** + * @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress|\PHPUnit_Framework_MockObject_MockObject + */ + private $remoteAddressMock; + + /** + * @var \Magento\Quote\Model\QuoteIdMaskFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $quoteIdMaskFactoryMock; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -178,18 +196,20 @@ protected function setUp() ); $this->quoteMock = $this->createPartialMock(\Magento\Quote\Model\Quote::class, [ - 'getId', - 'getCheckoutMethod', - 'setCheckoutMethod', - 'setCustomerId', - 'setCustomerEmail', - 'getBillingAddress', - 'setCustomerIsGuest', - 'setCustomerGroupId', - 'assignCustomer', - 'getPayment', - 'collectTotals' - ]); + 'assignCustomer', + 'collectTotals', + 'getBillingAddress', + 'getCheckoutMethod', + 'getPayment', + 'setCheckoutMethod', + 'setCustomerEmail', + 'setCustomerGroupId', + 'setCustomerId', + 'setCustomerIsGuest', + 'setRemoteIp', + 'setXForwardedFor', + 'getId', + ]); $this->quoteAddressFactory = $this->createPartialMock( \Magento\Quote\Model\Quote\AddressFactory::class, @@ -237,8 +257,11 @@ protected function setUp() // Set the new dependency $this->quoteIdMock = $this->createMock(\Magento\Quote\Model\QuoteIdMask::class); - $quoteIdFactoryMock = $this->createPartialMock(\Magento\Quote\Model\QuoteIdMaskFactory::class, ['create']); - $this->setPropertyValue($this->model, 'quoteIdMaskFactory', $quoteIdFactoryMock); + $this->quoteIdMaskFactoryMock = $this->createPartialMock(QuoteIdMaskFactory::class, ['create']); + $this->setPropertyValue($this->model, 'quoteIdMaskFactory', $this->quoteIdMaskFactoryMock); + + $this->requestMock = $this->createPartialMockForAbstractClass(RequestInterface::class, ['getServer']); + $this->remoteAddressMock = $this->createMock(RemoteAddress::class); } public function testCreateEmptyCartAnonymous() @@ -676,7 +699,11 @@ public function testPlaceOrderIfCustomerIsGuest() 'checkoutSession' => $this->checkoutSessionMock, 'customerSession' => $this->customerSessionMock, 'accountManagement' => $this->accountManagementMock, - 'quoteFactory' => $this->quoteFactoryMock + 'quoteFactory' => $this->quoteFactoryMock, + 'quoteIdMaskFactory' => $this->quoteIdMaskFactoryMock, + 'addressRepository' => $this->addressRepositoryMock, + 'request' => $this->requestMock, + 'remoteAddress' => $this->remoteAddressMock, ] ) ->getMock(); @@ -709,13 +736,15 @@ public function testPlaceOrder() $orderId = 332; $orderIncrementId = 100003332; $orderStatus = 'status1'; + $remoteAddress = '192.168.1.10'; + $forwardedForIp = '192.168.1.11'; /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Quote\Model\QuoteManagement $service */ $service = $this->getMockBuilder(\Magento\Quote\Model\QuoteManagement::class) ->setMethods(['submit']) ->setConstructorArgs( [ - 'eventManager' => $this->eventManager, + 'eventManager' => $this->eventManager, 'quoteValidator' => $this->quoteValidator, 'orderFactory' => $this->orderFactory, 'orderManagement' => $this->orderManagement, @@ -734,7 +763,11 @@ public function testPlaceOrder() 'checkoutSession' => $this->checkoutSessionMock, 'customerSession' => $this->customerSessionMock, 'accountManagement' => $this->accountManagementMock, - 'quoteFactory' => $this->quoteFactoryMock + 'quoteFactory' => $this->quoteFactoryMock, + 'quoteIdMaskFactory' => $this->quoteIdMaskFactoryMock, + 'addressRepository' => $this->addressRepositoryMock, + 'request' => $this->requestMock, + 'remoteAddress' => $this->remoteAddressMock, ] ) ->getMock(); @@ -762,6 +795,17 @@ public function testPlaceOrder() ->method('setCustomerIsGuest') ->with(true); + $this->remoteAddressMock + ->method('getRemoteAddress') + ->willReturn($remoteAddress); + + $this->requestMock + ->method('getServer') + ->willReturn($forwardedForIp); + + $this->quoteMock->expects($this->once())->method('setRemoteIp')->with($remoteAddress); + $this->quoteMock->expects($this->once())->method('setXForwardedFor')->with($forwardedForIp); + $service->expects($this->once())->method('submit')->willReturn($orderMock); $this->quoteMock->expects($this->atLeastOnce())->method('getId')->willReturn($cartId); From c90d75ed9e34445a78ecc651c79d8bb99f455199 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Tue, 19 Mar 2019 12:17:17 +0200 Subject: [PATCH 020/247] ENGCOM-3715: Health Index fix. --- .../Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php index 7078cc0a502a..5625dd5aabb7 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php @@ -23,7 +23,7 @@ class Cart extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column /** * @var View */ - protected $productView; + private $productView; /** * @param \Magento\Catalog\Block\Product\Context $context From 7d0d01e327a54b460d334165e7a68fcae7456f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= Date: Wed, 20 Mar 2019 00:30:02 +0100 Subject: [PATCH 021/247] 21842 - do not cache absolute file paths Github issue: https://github.com/magento/magento2/issues/21842 In customer and customer_address validation context the validator factory no longer caches absolute file paths for the validation.xml files (currently two file) as the file content is evaluated later in the filesystem directly and the file paths may not be correct in a multi server setup with shared cache (id_prefix) --- lib/internal/Magento/Framework/Validator/Factory.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/internal/Magento/Framework/Validator/Factory.php b/lib/internal/Magento/Framework/Validator/Factory.php index f2089c662e95..4e82c8972046 100644 --- a/lib/internal/Magento/Framework/Validator/Factory.php +++ b/lib/internal/Magento/Framework/Validator/Factory.php @@ -75,17 +75,7 @@ public function __construct( protected function _initializeConfigList() { if (!$this->_configFiles) { - $this->_configFiles = $this->cache->load(self::CACHE_KEY); - if (!$this->_configFiles) { - $this->_configFiles = $this->moduleReader->getConfigurationFiles('validation.xml'); - $this->cache->save( - $this->getSerializer()->serialize($this->_configFiles->toArray()), - self::CACHE_KEY - ); - } else { - $filesArray = $this->getSerializer()->unserialize($this->_configFiles); - $this->_configFiles = $this->getFileIteratorFactory()->create(array_keys($filesArray)); - } + $this->_configFiles = $this->moduleReader->getConfigurationFiles('validation.xml'); } } From e266d9af43a01fce13d98001b335bf69b4219eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= Date: Wed, 20 Mar 2019 11:46:41 +0100 Subject: [PATCH 022/247] clean up Validator Factory - adapt unit test --- .../Magento/Framework/Validator/Factory.php | 90 +++++-------------- .../Validator/Test/Unit/FactoryTest.php | 76 +--------------- 2 files changed, 24 insertions(+), 142 deletions(-) diff --git a/lib/internal/Magento/Framework/Validator/Factory.php b/lib/internal/Magento/Framework/Validator/Factory.php index 4e82c8972046..7a9eacac6ddb 100644 --- a/lib/internal/Magento/Framework/Validator/Factory.php +++ b/lib/internal/Magento/Framework/Validator/Factory.php @@ -6,24 +6,26 @@ namespace Magento\Framework\Validator; -use Magento\Framework\Cache\FrontendInterface; +use Magento\Framework\Module\Dir\Reader; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Validator; +/** + * Factory for \Magento\Framework\Validator and \Magento\Framework\Validator\Builder. + */ class Factory { - /** cache key */ - const CACHE_KEY = __CLASS__; - /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ protected $_objectManager; /** * Validator config files * - * @var array|null + * @var iterable|null */ - protected $_configFiles = null; + protected $_configFiles; /** * @var bool @@ -31,40 +33,22 @@ class Factory private $isDefaultTranslatorInitialized = false; /** - * @var \Magento\Framework\Module\Dir\Reader + * @var Reader */ private $moduleReader; - /** - * @var FrontendInterface - */ - private $cache; - - /** - * @var \Magento\Framework\Serialize\SerializerInterface - */ - private $serializer; - - /** - * @var \Magento\Framework\Config\FileIteratorFactory - */ - private $fileIteratorFactory; - /** * Initialize dependencies * - * @param \Magento\Framework\ObjectManagerInterface $objectManager - * @param \Magento\Framework\Module\Dir\Reader $moduleReader - * @param FrontendInterface $cache + * @param ObjectManagerInterface $objectManager + * @param Reader $moduleReader */ public function __construct( - \Magento\Framework\ObjectManagerInterface $objectManager, - \Magento\Framework\Module\Dir\Reader $moduleReader, - FrontendInterface $cache + ObjectManagerInterface $objectManager, + Reader $moduleReader ) { $this->_objectManager = $objectManager; $this->moduleReader = $moduleReader; - $this->cache = $cache; } /** @@ -83,6 +67,7 @@ protected function _initializeConfigList() * Create and set default translator to \Magento\Framework\Validator\AbstractValidator. * * @return void + * @throws \Zend_Translate_Exception */ protected function _initializeDefaultTranslator() { @@ -95,7 +80,7 @@ protected function _initializeDefaultTranslator() /** @var \Magento\Framework\Translate\Adapter $translator */ $translator = $this->_objectManager->create(\Magento\Framework\Translate\Adapter::class); $translator->setOptions(['translator' => $translatorCallback]); - \Magento\Framework\Validator\AbstractValidator::setDefaultTranslator($translator); + AbstractValidator::setDefaultTranslator($translator); $this->isDefaultTranslatorInitialized = true; } } @@ -105,14 +90,15 @@ protected function _initializeDefaultTranslator() * * Will instantiate \Magento\Framework\Validator\Config * - * @return \Magento\Framework\Validator\Config + * @return Config + * @throws \Zend_Translate_Exception */ public function getValidatorConfig() { $this->_initializeConfigList(); $this->_initializeDefaultTranslator(); return $this->_objectManager->create( - \Magento\Framework\Validator\Config::class, + Config::class, ['configFiles' => $this->_configFiles] ); } @@ -123,7 +109,8 @@ public function getValidatorConfig() * @param string $entityName * @param string $groupName * @param array|null $builderConfig - * @return \Magento\Framework\Validator\Builder + * @return Builder + * @throws \Zend_Translate_Exception */ public function createValidatorBuilder($entityName, $groupName, array $builderConfig = null) { @@ -137,43 +124,12 @@ public function createValidatorBuilder($entityName, $groupName, array $builderCo * @param string $entityName * @param string $groupName * @param array|null $builderConfig - * @return \Magento\Framework\Validator + * @return Validator + * @throws \Zend_Translate_Exception */ public function createValidator($entityName, $groupName, array $builderConfig = null) { $this->_initializeDefaultTranslator(); return $this->getValidatorConfig()->createValidator($entityName, $groupName, $builderConfig); } - - /** - * Get serializer - * - * @return \Magento\Framework\Serialize\SerializerInterface - * @deprecated 100.2.0 - */ - private function getSerializer() - { - if ($this->serializer === null) { - $this->serializer = $this->_objectManager->get( - \Magento\Framework\Serialize\SerializerInterface::class - ); - } - return $this->serializer; - } - - /** - * Get file iterator factory - * - * @return \Magento\Framework\Config\FileIteratorFactory - * @deprecated 100.2.0 - */ - private function getFileIteratorFactory() - { - if ($this->fileIteratorFactory === null) { - $this->fileIteratorFactory = $this->_objectManager->get( - \Magento\Framework\Config\FileIteratorFactory::class - ); - } - return $this->fileIteratorFactory; - } } diff --git a/lib/internal/Magento/Framework/Validator/Test/Unit/FactoryTest.php b/lib/internal/Magento/Framework/Validator/Test/Unit/FactoryTest.php index 5511627c6dcc..73a8c95c9a2f 100644 --- a/lib/internal/Magento/Framework/Validator/Test/Unit/FactoryTest.php +++ b/lib/internal/Magento/Framework/Validator/Test/Unit/FactoryTest.php @@ -25,21 +25,6 @@ class FactoryTest extends \PHPUnit\Framework\TestCase */ private $validatorConfigMock; - /** - * @var \Magento\Framework\Cache\FrontendInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $cacheMock; - - /** - * @var \Magento\Framework\Serialize\SerializerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $serializerMock; - - /** - * @var \Magento\Framework\Config\FileIteratorFactory|\PHPUnit_Framework_MockObject_MockObject - */ - private $fileIteratorFactoryMock; - /** * @var \Magento\Framework\Config\FileIterator|\PHPUnit_Framework_MockObject_MockObject */ @@ -55,11 +40,6 @@ class FactoryTest extends \PHPUnit\Framework\TestCase */ private $factory; - /** - * @var string - */ - private $jsonString = '["\/tmp\/moduleOne\/etc\/validation.xml"]'; - /** * @var array */ @@ -99,23 +79,9 @@ protected function setUp() \Magento\Framework\Validator\Factory::class, [ 'objectManager' => $this->objectManagerMock, - 'moduleReader' => $this->readerMock, - 'cache' => $this->cacheMock + 'moduleReader' => $this->readerMock ] ); - - $this->serializerMock = $this->createMock(\Magento\Framework\Serialize\SerializerInterface::class); - $this->fileIteratorFactoryMock = $this->createMock(\Magento\Framework\Config\FileIteratorFactory::class); - $objectManager->setBackwardCompatibleProperty( - $this->factory, - 'serializer', - $this->serializerMock - ); - $objectManager->setBackwardCompatibleProperty( - $this->factory, - 'fileIteratorFactory', - $this->fileIteratorFactoryMock - ); } /** @@ -147,46 +113,6 @@ public function testGetValidatorConfig() ); } - public function testGetValidatorConfigCacheNotExist() - { - $this->cacheMock->expects($this->once()) - ->method('load') - ->willReturn(false); - $this->readerMock->expects($this->once()) - ->method('getConfigurationFiles') - ->willReturn($this->fileIteratorMock); - $this->fileIteratorMock->method('toArray') - ->willReturn($this->data); - $this->cacheMock->expects($this->once()) - ->method('save') - ->with($this->jsonString); - $this->serializerMock->expects($this->once()) - ->method('serialize') - ->with($this->data) - ->willReturn($this->jsonString); - $this->factory->getValidatorConfig(); - $this->factory->getValidatorConfig(); - } - - public function testGetValidatorConfigCacheExist() - { - $this->cacheMock->expects($this->once()) - ->method('load') - ->willReturn($this->jsonString); - $this->readerMock->expects($this->never()) - ->method('getConfigurationFiles'); - $this->cacheMock->expects($this->never()) - ->method('save'); - $this->serializerMock->expects($this->once()) - ->method('unserialize') - ->with($this->jsonString) - ->willReturn($this->data); - $this->fileIteratorFactoryMock->method('create') - ->willReturn($this->fileIteratorMock); - $this->factory->getValidatorConfig(); - $this->factory->getValidatorConfig(); - } - public function testCreateValidatorBuilder() { $this->readerMock->method('getConfigurationFiles') From 83b34b89b5caffb1b2eef74423090e7f343b0e18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= Date: Wed, 20 Mar 2019 14:48:40 +0100 Subject: [PATCH 023/247] untouch static method call to prevent codacy fail - refactoring of static method use should be in a separate pull request --- lib/internal/Magento/Framework/Validator/Factory.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Validator/Factory.php b/lib/internal/Magento/Framework/Validator/Factory.php index 7a9eacac6ddb..198f4fb6730f 100644 --- a/lib/internal/Magento/Framework/Validator/Factory.php +++ b/lib/internal/Magento/Framework/Validator/Factory.php @@ -8,6 +8,7 @@ use Magento\Framework\Module\Dir\Reader; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Phrase; use Magento\Framework\Validator; /** @@ -75,12 +76,12 @@ protected function _initializeDefaultTranslator() // Pass translations to \Magento\Framework\TranslateInterface from validators $translatorCallback = function () { $argc = func_get_args(); - return (string)new \Magento\Framework\Phrase(array_shift($argc), $argc); + return (string)new Phrase(array_shift($argc), $argc); }; /** @var \Magento\Framework\Translate\Adapter $translator */ $translator = $this->_objectManager->create(\Magento\Framework\Translate\Adapter::class); $translator->setOptions(['translator' => $translatorCallback]); - AbstractValidator::setDefaultTranslator($translator); + \Magento\Framework\Validator\AbstractValidator::setDefaultTranslator($translator); $this->isDefaultTranslatorInitialized = true; } } From b78aa2aa72dd4cee72389f6c568130299e3fd5bd Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun Date: Fri, 22 Mar 2019 16:19:56 +0200 Subject: [PATCH 024/247] Cannot return null for non-nullable field AvailableShippingMethod.method_code when no shipping methods are available --- .../ShippingAddress/AvailableShippingMethods.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/AvailableShippingMethods.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/AvailableShippingMethods.php index a9e0ba59d15d..d0bded279bee 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/AvailableShippingMethods.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/AvailableShippingMethods.php @@ -10,6 +10,7 @@ use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\Data\ShippingMethodInterface; @@ -65,13 +66,19 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $shippingRates = $address->getGroupedAllShippingRates(); foreach ($shippingRates as $carrierRates) { foreach ($carrierRates as $rate) { - $methods[] = $this->dataObjectConverter->toFlatArray( + $method = $this->dataObjectConverter->toFlatArray( $this->shippingMethodConverter->modelToDataObject($rate, $cart->getQuoteCurrencyCode()), [], ShippingMethodInterface::class ); + if ($method['available'] && $method['error_message'] === "") { + $methods[] = $method; + } } } + if (count($methods) === 0) { + throw new GraphQlNoSuchEntityException(__(' This shipping method is not available. To use this shipping method, please contact us.')); + } return $methods; } } From 9a15895df01989478ce5fc004d3157cf247cbc14 Mon Sep 17 00:00:00 2001 From: Alex Paliarush Date: Tue, 9 Oct 2018 18:26:46 -0500 Subject: [PATCH 025/247] Added caching of GraphQL GET requests with Varnish (no invalidation yet) --- .../Controller/GraphQl/Plugin.php | 30 +++++++++++++++++++ app/code/Magento/GraphQlCache/composer.json | 21 +++++++++++++ .../Magento/GraphQlCache/etc/graphql/di.xml | 12 ++++++++ app/code/Magento/GraphQlCache/etc/module.xml | 14 +++++++++ .../Magento/GraphQlCache/registration.php | 9 ++++++ 5 files changed, 86 insertions(+) create mode 100644 app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php create mode 100644 app/code/Magento/GraphQlCache/composer.json create mode 100644 app/code/Magento/GraphQlCache/etc/graphql/di.xml create mode 100644 app/code/Magento/GraphQlCache/etc/module.xml create mode 100644 app/code/Magento/GraphQlCache/registration.php diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php new file mode 100644 index 000000000000..9e095a320159 --- /dev/null +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -0,0 +1,30 @@ +isGet()) { + $response->setHeader('Pragma', 'cache', true); + // TODO: Take from configuration + $response->setHeader('Cache-Control', 'max-age=86400, public, s-maxage=86400', true); + } + return $response; + } +} diff --git a/app/code/Magento/GraphQlCache/composer.json b/app/code/Magento/GraphQlCache/composer.json new file mode 100644 index 000000000000..7b5e6137895f --- /dev/null +++ b/app/code/Magento/GraphQlCache/composer.json @@ -0,0 +1,21 @@ +{ + "name": "magento/module-graph-ql-cache", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\GraphQlCache\\": "" + } + } +} diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml new file mode 100644 index 000000000000..a6480d04d549 --- /dev/null +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/app/code/Magento/GraphQlCache/etc/module.xml b/app/code/Magento/GraphQlCache/etc/module.xml new file mode 100644 index 000000000000..d7f08c552933 --- /dev/null +++ b/app/code/Magento/GraphQlCache/etc/module.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/app/code/Magento/GraphQlCache/registration.php b/app/code/Magento/GraphQlCache/registration.php new file mode 100644 index 000000000000..2dfe717003a0 --- /dev/null +++ b/app/code/Magento/GraphQlCache/registration.php @@ -0,0 +1,9 @@ + Date: Wed, 10 Oct 2018 21:02:12 -0500 Subject: [PATCH 026/247] Added prototype of Varnish cache invalidation for GraphQL --- .../CatalogGraphQl/etc/schema.graphqls | 2 +- .../Controller/GraphQl/Plugin.php | 19 ++++- .../Magento/GraphQlCache/Model/CacheTags.php | 36 +++++++++ .../GraphQlCache/Query/Resolver/Plugin.php | 74 +++++++++++++++++++ .../Magento/GraphQlCache/etc/graphql/di.xml | 5 +- 5 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/GraphQlCache/Model/CacheTags.php create mode 100644 app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 778d0783305b..f86ecea9e075 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -9,7 +9,7 @@ type Query { currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @cache(tag: "cat_p") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") category ( id: Int @doc(description: "Id of the category") ): CategoryTree diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index 9e095a320159..e1109da0ea9b 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -10,9 +10,23 @@ use Magento\Framework\App\FrontControllerInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; +use Magento\GraphQlCache\Model\CacheTags; class Plugin { + /** + * @var CacheTags + */ + private $cacheTags; + + /** + * @param CacheTags $cacheTags + */ + public function __construct(CacheTags $cacheTags) + { + $this->cacheTags = $cacheTags; + } + public function afterDispatch( FrontControllerInterface $subject, ResponseInterface $response, @@ -20,10 +34,13 @@ public function afterDispatch( ) { /** @var \Magento\Framework\App\Request\Http $request */ /** @var \Magento\Framework\Webapi\Response $response */ - if ($request->isGet()) { + $cacheTags = $this->cacheTags->getCacheTags(); + if ($request->isGet() && count($cacheTags)) { + // assume that response should be cacheable if it contains cache tags $response->setHeader('Pragma', 'cache', true); // TODO: Take from configuration $response->setHeader('Cache-Control', 'max-age=86400, public, s-maxage=86400', true); + $response->setHeader('X-Magento-Tags', implode(',', $cacheTags), true); } return $response; } diff --git a/app/code/Magento/GraphQlCache/Model/CacheTags.php b/app/code/Magento/GraphQlCache/Model/CacheTags.php new file mode 100644 index 000000000000..6889a873a3f0 --- /dev/null +++ b/app/code/Magento/GraphQlCache/Model/CacheTags.php @@ -0,0 +1,36 @@ +cacheTags; + } + + /** + * @param string[] $tags + * @return void + */ + public function addCacheTags(array $cacheTags): void + { + $this->cacheTags = array_merge($this->cacheTags, $cacheTags); + } +} diff --git a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php new file mode 100644 index 000000000000..65b05bf71da0 --- /dev/null +++ b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php @@ -0,0 +1,74 @@ +cacheTags = $cacheTags; + } + + public function afterResolve( + ResolverInterface $subject, + $resolvedValue, + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if ($field->getName() == 'products') { + // TODO: Read cache tag value from the GraphQL schema and make it accessible via $field + $cacheTag = 'cat_p'; + } + // TODO: Can be optimized to avoid tags calculation for POST requests + if (!empty($cacheTag)) { + $cacheTags = [$cacheTag]; + // Resolved value must have cache IDs defined + $resolvedItemsIds = $this->extractResolvedItemsIds($resolvedValue); + foreach ($resolvedItemsIds as $itemId) { + $cacheTags[] = $cacheTag . '_' . $itemId; + } + $this->cacheTags->addCacheTags($cacheTags); + } + return $resolvedValue; + } + + private function extractResolvedItemsIds($resolvedValue) + { + // TODO: Implement safety checks and think about additional places which can hold items IDs + if (isset($resolvedValue['ids']) && is_array($resolvedValue['ids'])) { + return $resolvedValue['ids']; + } + if (isset($resolvedValue['items']) && is_array($resolvedValue['items'])) { + return array_keys($resolvedValue['items']); + } + $ids = []; + if (is_array($resolvedValue)) { + foreach ($resolvedValue as $item) { + if (isset($item['id'])) { + $ids[] = $item['id']; + } + } + } + } +} diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml index a6480d04d549..7dbc54fd0673 100644 --- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -7,6 +7,9 @@ --> - + + + + From 12674368b0ae77c3a0e4b72e4ee0fa91fa028395 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Mon, 25 Mar 2019 16:14:17 +0200 Subject: [PATCH 027/247] magento/graphql-ce#530: [Cart Operations] Update Cart Items validation messages --- .../Model/Resolver/UpdateCartItems.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php index 78a07506556c..50d16360dd55 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php @@ -111,6 +111,25 @@ private function processCartItems(Quote $cart, array $items): void $this->cartItemRepository->deleteById((int)$cart->getId(), $itemId); } else { $cartItem->setQty($qty); + + if ($cartItem->getHasError()) { + $errors = []; + foreach ($cartItem->getMessage(false) as $message) { + if (!in_array($message, $errors)) { + $errors[] = $message; + } + } + + if (!empty($errors)) { + throw new GraphQlInputException( + __( + 'Could not update the product with SKU %sku: %message', + ['sku' => $cartItem->getSku(), 'message' => __(implode("\n", $errors))] + ) + ); + } + } + $this->cartItemRepository->save($cartItem); } } From 43bb3211265fd71b663c00c37dd2942763fadb62 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 25 Mar 2019 17:46:35 -0500 Subject: [PATCH 028/247] Issue-230: implementing cache --- .../Controller/GraphQl/Plugin.php | 15 +++++- .../Model/App/CacheIdentifierPlugin.php | 52 +++++++++++++++++++ .../Magento/GraphQlCache/etc/graphql/di.xml | 4 ++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index e1109da0ea9b..582fa93e5532 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -11,6 +11,7 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; use Magento\GraphQlCache\Model\CacheTags; +use Magento\Framework\App\State as AppState; class Plugin { @@ -19,12 +20,19 @@ class Plugin */ private $cacheTags; + /** + * @var AppState + */ + private $state; + /** * @param CacheTags $cacheTags + * @param AppState $state */ - public function __construct(CacheTags $cacheTags) + public function __construct(CacheTags $cacheTags, AppState $state) { $this->cacheTags = $cacheTags; + $this->state = $state; } public function afterDispatch( @@ -42,6 +50,11 @@ public function afterDispatch( $response->setHeader('Cache-Control', 'max-age=86400, public, s-maxage=86400', true); $response->setHeader('X-Magento-Tags', implode(',', $cacheTags), true); } + + if ($request->isGet() && $this->state->getMode() == AppState::MODE_DEVELOPER) { + $response->setHeader('X-Magento-Debug', 1); + } + return $response; } } diff --git a/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php b/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php new file mode 100644 index 000000000000..e279395e43d4 --- /dev/null +++ b/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php @@ -0,0 +1,52 @@ +request = $request; + $this->config = $config; + } + + /** + * Adds a unique key identifier for graphql specific query and variables + * + * @param \Magento\Framework\App\PageCache\Identifier $identifier + * @param string $result + * @return string + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterGetValue(\Magento\Framework\App\PageCache\Identifier $identifier, $result) + { + //If full page cache is enabled + if ($this->config->isEnabled()) { + //we need to compute unique query identifier from the 3 variables and removing whitespaces + $data = [ + $this->request->isSecure(), + $this->request->getUriString(), + $this->request->get(\Magento\Framework\App\Response\Http::COOKIE_VARY_STRING) + ?: $this->context->getVaryString() + ]; + $result = sha1($this->serializer->serialize($data)); + } + return $result; + } +} diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml index 7dbc54fd0673..6007bdd173aa 100644 --- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -12,4 +12,8 @@ + + + From ca2ba261576ac2729b8220267d77bafac6864a01 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 26 Mar 2019 15:41:44 -0500 Subject: [PATCH 029/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- app/code/Magento/Authorization/Model/Role.php | 14 +- .../Magento/Backend/Model/Auth/Session.php | 197 ++++++++++++- .../Backend/Model/Auth/SessionAclHydrator.php | 36 +++ .../Model/Auth/SessionUserHydrator.php | 54 ++++ .../Spi/SessionAclHydratorInterface.php | 34 +++ .../Spi/SessionUserHydratorInterface.php | 34 +++ .../Test/Unit/Model/Auth/SessionTest.php | 273 ------------------ .../Model/Authorization/RoleLocatorTest.php | 36 --- .../Test/Unit/Model/Locale/ManagerTest.php | 127 -------- app/code/Magento/Backend/composer.json | 1 + app/code/Magento/Backend/etc/di.xml | 4 + .../Model/ResourceModel/Eav/Attribute.php | 10 + .../Config/Model/Config/Backend/Encrypted.php | 12 + .../Product/Type/Configurable/Attribute.php | 49 ++-- .../Configurable/Attribute/Collection.php | 14 + app/code/Magento/Customer/Model/Attribute.php | 10 + .../Magento/Eav/Model/Entity/Attribute.php | 14 +- .../Entity/Attribute/AbstractAttribute.php | 10 + .../Model/ResourceModel/Entity/Attribute.php | 10 + .../System/Config/Fieldset/GroupTest.php | 107 ------- .../Condition/CanViewNotificationTest.php | 16 +- app/code/Magento/Store/Model/Store.php | 10 + app/code/Magento/User/Model/User.php | 14 + .../AdminSessionUserContextTest.php | 89 ------ .../Magento/User/Test/Unit/Model/UserTest.php | 25 -- .../Backend/Model/Auth/SessionTest.php | 39 ++- .../Backend/Model/Locale/ResolverTest.php | 15 +- .../Spi/SessionAclHydratorInterfaceTest.php | 55 ++++ .../Spi/SessionUserHydratorInterfaceTest.php | 58 ++++ .../Rule/Design/SerializationAware.php | 34 +++ .../resources/rulesets/design.xml | 25 ++ .../Magento/Test/Php/_files/phpmd/ruleset.xml | 1 + .../Magento/Framework/App/AreaList/Proxy.php | 18 +- .../Magento/Framework/App/Response/Http.php | 23 +- .../App/Route/ConfigInterface/Proxy.php | 12 + .../App/Test/Unit/Response/HttpTest.php | 39 --- lib/internal/Magento/Framework/DB/Select.php | 22 +- .../Framework/DB/Select/RendererProxy.php | 14 +- .../Magento/Framework/Data/Collection.php | 10 + .../Framework/Data/Collection/AbstractDb.php | 10 + .../DataObject/Copy/Config/Data/Proxy.php | 18 +- .../Framework/Interception/Interceptor.php | 10 + .../Model/AbstractExtensibleModel.php | 18 +- .../Magento/Framework/Model/AbstractModel.php | 10 + .../Model/ResourceModel/Db/AbstractDb.php | 23 +- .../Db/Collection/AbstractCollection.php | 10 + .../Framework/Mview/Config/Data/Proxy.php | 16 +- .../Framework/Translate/Inline/Proxy.php | 12 + .../Magento/Framework/View/Layout/Proxy.php | 128 ++++---- 49 files changed, 994 insertions(+), 826 deletions(-) create mode 100644 app/code/Magento/Backend/Model/Auth/SessionAclHydrator.php create mode 100644 app/code/Magento/Backend/Model/Auth/SessionUserHydrator.php create mode 100644 app/code/Magento/Backend/Spi/SessionAclHydratorInterface.php create mode 100644 app/code/Magento/Backend/Spi/SessionUserHydratorInterface.php delete mode 100644 app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php delete mode 100644 app/code/Magento/Backend/Test/Unit/Model/Authorization/RoleLocatorTest.php delete mode 100644 app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php delete mode 100644 app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/System/Config/Fieldset/GroupTest.php delete mode 100644 app/code/Magento/User/Test/Unit/Model/Authorization/AdminSessionUserContextTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Backend/Spi/SessionUserHydratorInterfaceTest.php create mode 100644 dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/SerializationAware.php diff --git a/app/code/Magento/Authorization/Model/Role.php b/app/code/Magento/Authorization/Model/Role.php index 2546df86d09d..dcc46ee77ee1 100644 --- a/app/code/Magento/Authorization/Model/Role.php +++ b/app/code/Magento/Authorization/Model/Role.php @@ -51,19 +51,29 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritDoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = parent::__sleep(); return array_diff($properties, ['_resource', '_resourceCollection']); } /** - * {@inheritdoc} + * @inheritDoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_resource = $objectManager->get(\Magento\Authorization\Model\ResourceModel\Role::class); diff --git a/app/code/Magento/Backend/Model/Auth/Session.php b/app/code/Magento/Backend/Model/Auth/Session.php index 593b4219d45f..01f762de83de 100644 --- a/app/code/Magento/Backend/Model/Auth/Session.php +++ b/app/code/Magento/Backend/Model/Auth/Session.php @@ -5,17 +5,20 @@ */ namespace Magento\Backend\Model\Auth; +use Magento\Framework\Acl; +use Magento\Framework\AclFactory; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory; use Magento\Framework\Stdlib\CookieManagerInterface; +use Magento\Backend\Spi\SessionUserHydratorInterface; +use Magento\Backend\Spi\SessionAclHydratorInterface; +use Magento\User\Model\User; +use Magento\User\Model\UserFactory; /** * Backend Auth session model * * @api - * @method \Magento\User\Model\User|null getUser() - * @method \Magento\Backend\Model\Auth\Session setUser(\Magento\User\Model\User $value) - * @method \Magento\Framework\Acl|null getAcl() - * @method \Magento\Backend\Model\Auth\Session setAcl(\Magento\Framework\Acl $value) * @method int getUpdatedAt() * @method \Magento\Backend\Model\Auth\Session setUpdatedAt(int $value) * @@ -55,6 +58,36 @@ class Session extends \Magento\Framework\Session\SessionManager implements \Mage */ protected $_config; + /** + * @var SessionUserHydratorInterface + */ + private $userHydrator; + + /** + * @var SessionAclHydratorInterface + */ + private $aclHydrator; + + /** + * @var UserFactory + */ + private $userFactory; + + /** + * @var AclFactory + */ + private $aclFactory; + + /** + * @var User|null + */ + private $user; + + /** + * @var Acl|null + */ + private $acl; + /** * @param \Magento\Framework\App\Request\Http $request * @param \Magento\Framework\Session\SidResolverInterface $sidResolver @@ -69,6 +102,10 @@ class Session extends \Magento\Framework\Session\SessionManager implements \Mage * @param \Magento\Backend\Model\UrlInterface $backendUrl * @param \Magento\Backend\App\ConfigInterface $config * @throws \Magento\Framework\Exception\SessionException + * @param SessionUserHydratorInterface|null $userHydrator + * @param SessionAclHydratorInterface|null $aclHydrator + * @param UserFactory|null $userFactory + * @param AclFactory|null $aclFactory * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -83,11 +120,19 @@ public function __construct( \Magento\Framework\App\State $appState, \Magento\Framework\Acl\Builder $aclBuilder, \Magento\Backend\Model\UrlInterface $backendUrl, - \Magento\Backend\App\ConfigInterface $config + \Magento\Backend\App\ConfigInterface $config, + ?SessionUserHydratorInterface $userHydrator = null, + ?SessionAclHydratorInterface $aclHydrator = null, + ?UserFactory $userFactory = null, + ?AclFactory $aclFactory = null ) { $this->_config = $config; $this->_aclBuilder = $aclBuilder; $this->_backendUrl = $backendUrl; + $this->userHydrator = $userHydrator ?? ObjectManager::getInstance()->get(SessionUserHydratorInterface::class); + $this->aclHydrator = $aclHydrator ?? ObjectManager::getInstance()->get(SessionAclHydratorInterface::class); + $this->userFactory = $userFactory ?? ObjectManager::getInstance()->get(UserFactory::class); + $this->aclFactory = $aclFactory ?? ObjectManager::getInstance()->get(AclFactory::class); parent::__construct( $request, $sidResolver, @@ -230,6 +275,16 @@ public function processLogin() return $this; } + /** + * @inheritDoc + */ + public function destroy(array $options = null) + { + $this->user = null; + $this->acl = null; + parent::destroy($options); + } + /** * Process of configuring of current auth storage when logout was performed * @@ -253,4 +308,136 @@ public function isValidForPath($path) { return true; } + + /** + * Logged-in user. + * + * @return User|null + */ + public function getUser(): ?User + { + if (!$this->user) { + $userData = $this->getUserData(); + if ($userData) { + /** @var User $user */ + $user = $this->userFactory->create(); + $this->userHydrator->hydrate($user, $userData); + $this->user = $user; + } + } + + return $this->user; + } + + /** + * Set logged-in user instance. + * + * @param User|null $user + * @return Session + */ + public function setUser(?User $user): self + { + $this->setUserData(null); + if ($user) { + $this->setUserData($this->userHydrator->extract($user)); + } + $this->user = $user; + + return $this; + } + + /** + * Is user logged in? + * + * @return bool + */ + public function hasUser(): bool + { + return $this->user || $this->hasUserData(); + } + + /** + * Remove logged-in user. + * + * @return Session + */ + public function unsUser(): self + { + $this->user = null; + $this->unsUserData(); + } + + /** + * Logged-in user's ACL data. + * + * @return Acl|null + */ + public function getAcl(): ?Acl + { + if (!$this->acl) { + $aclData = $this->getUserAclData(); + if ($aclData) { + /** @var Acl $acl */ + $acl = $this->aclFactory->create(); + $this->aclHydrator->hydrate($acl, $aclData); + $this->acl = $acl; + } + } + + return $this->acl; + } + + /** + * Set logged-in user's ACL data instance. + * + * @param Acl|null $acl + * @return Session + */ + public function setAcl(?Acl $acl): self + { + $this->setUserAclData(null); + if ($acl) { + $this->setUserAclData($this->aclHydrator->extract($acl)); + } + $this->acl = $acl; + + return $this; + } + + /** + * Whether ACL data is present. + * + * @return bool + */ + public function hasAcl(): bool + { + return $this->acl || $this->hasUserAclData(); + } + + /** + * Remove ACL data. + * + * @return Session + */ + public function unsAcl(): self + { + $this->acl = null; + $this->unsUserAclData(); + } + + /** + * @inheritDoc + */ + public function writeClose() + { + //Updating data in session in case these objects has been changed. + if ($this->user) { + $this->setUser($this->user); + } + if ($this->acl) { + $this->setAcl($this->acl); + } + + parent::writeClose(); + } } diff --git a/app/code/Magento/Backend/Model/Auth/SessionAclHydrator.php b/app/code/Magento/Backend/Model/Auth/SessionAclHydrator.php new file mode 100644 index 000000000000..34e01be69667 --- /dev/null +++ b/app/code/Magento/Backend/Model/Auth/SessionAclHydrator.php @@ -0,0 +1,36 @@ + $acl->_rules, 'resources' => $acl->_resources, 'roles' => $acl->_roleRegistry]; + } + + /** + * @inheritDoc + */ + public function hydrate(Acl $target, array $data): void + { + $target->_rules = $data['rules']; + $target->_resources = $data['resources']; + $target->_roleRegistry = $data['roles']; + } +} diff --git a/app/code/Magento/Backend/Model/Auth/SessionUserHydrator.php b/app/code/Magento/Backend/Model/Auth/SessionUserHydrator.php new file mode 100644 index 000000000000..6dee8b7b302c --- /dev/null +++ b/app/code/Magento/Backend/Model/Auth/SessionUserHydrator.php @@ -0,0 +1,54 @@ +roleFactory = $roleFactory; + } + + /** + * @inheritDoc + */ + public function extract(User $user): array + { + return ['data' => $user->getData(), 'role_data' => $user->getRole()->getData()]; + } + + /** + * @inheritDoc + */ + public function hydrate(User $target, array $data): void + { + $target->setData($data['data']); + /** @var Role $role */ + $role = $this->roleFactory->create(); + $role->setData($data['role_data']); + $target->setData('extracted_role', $role); + $target->getRole(); + } +} diff --git a/app/code/Magento/Backend/Spi/SessionAclHydratorInterface.php b/app/code/Magento/Backend/Spi/SessionAclHydratorInterface.php new file mode 100644 index 000000000000..7227cc92fcc8 --- /dev/null +++ b/app/code/Magento/Backend/Spi/SessionAclHydratorInterface.php @@ -0,0 +1,34 @@ +cookieMetadataFactory = $this->createPartialMock( - \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory::class, - ['createPublicCookieMetadata'] - ); - - $this->config = $this->createPartialMock(\Magento\Backend\App\Config::class, ['getValue']); - $this->cookieManager = $this->createPartialMock( - \Magento\Framework\Stdlib\Cookie\PhpCookieManager::class, - ['getCookie', 'setPublicCookie'] - ); - $this->storage = $this->createPartialMock( - \Magento\Framework\Session\Storage::class, - ['getUser', 'getAcl', 'setAcl'] - ); - $this->sessionConfig = $this->createPartialMock( - \Magento\Framework\Session\Config::class, - ['getCookiePath', 'getCookieDomain', 'getCookieSecure', 'getCookieHttpOnly'] - ); - $this->aclBuilder = $this->getMockBuilder(\Magento\Framework\Acl\Builder::class) - ->disableOriginalConstructor() - ->getMock(); - $objectManager = new ObjectManager($this); - $this->session = $objectManager->getObject( - \Magento\Backend\Model\Auth\Session::class, - [ - 'config' => $this->config, - 'sessionConfig' => $this->sessionConfig, - 'cookieManager' => $this->cookieManager, - 'cookieMetadataFactory' => $this->cookieMetadataFactory, - 'storage' => $this->storage, - 'aclBuilder' => $this->aclBuilder - ] - ); - } - - protected function tearDown() - { - $this->config = null; - $this->sessionConfig = null; - $this->session = null; - } - - /** - * @dataProvider refreshAclDataProvider - * @param $isUserPassedViaParams - */ - public function testRefreshAcl($isUserPassedViaParams) - { - $aclMock = $this->getMockBuilder(\Magento\Framework\Acl::class)->disableOriginalConstructor()->getMock(); - $this->aclBuilder->expects($this->any())->method('getAcl')->willReturn($aclMock); - $userMock = $this->getMockBuilder(\Magento\User\Model\User::class) - ->setMethods(['getReloadAclFlag', 'setReloadAclFlag', 'unsetData', 'save']) - ->disableOriginalConstructor() - ->getMock(); - $userMock->expects($this->any())->method('getReloadAclFlag')->willReturn(true); - $userMock->expects($this->once())->method('setReloadAclFlag')->with('0')->willReturnSelf(); - $userMock->expects($this->once())->method('save'); - $this->storage->expects($this->once())->method('setAcl')->with($aclMock); - $this->storage->expects($this->any())->method('getAcl')->willReturn($aclMock); - if ($isUserPassedViaParams) { - $this->session->refreshAcl($userMock); - } else { - $this->storage->expects($this->once())->method('getUser')->willReturn($userMock); - $this->session->refreshAcl(); - } - $this->assertSame($aclMock, $this->session->getAcl()); - } - - /** - * @return array - */ - public function refreshAclDataProvider() - { - return [ - 'User set via params' => [true], - 'User set to session object' => [false] - ]; - } - - public function testIsLoggedInPositive() - { - $user = $this->createPartialMock(\Magento\User\Model\User::class, ['getId', '__wakeup']); - $user->expects($this->once()) - ->method('getId') - ->will($this->returnValue(1)); - - $this->storage->expects($this->any()) - ->method('getUser') - ->will($this->returnValue($user)); - - $this->assertTrue($this->session->isLoggedIn()); - } - - public function testProlong() - { - $name = session_name(); - $cookie = 'cookie'; - $lifetime = 900; - $path = '/'; - $domain = 'magento2'; - $secure = true; - $httpOnly = true; - - $this->config->expects($this->once()) - ->method('getValue') - ->with(\Magento\Backend\Model\Auth\Session::XML_PATH_SESSION_LIFETIME) - ->willReturn($lifetime); - $cookieMetadata = $this->createMock(\Magento\Framework\Stdlib\Cookie\PublicCookieMetadata::class); - $cookieMetadata->expects($this->once()) - ->method('setDuration') - ->with($lifetime) - ->will($this->returnSelf()); - $cookieMetadata->expects($this->once()) - ->method('setPath') - ->with($path) - ->will($this->returnSelf()); - $cookieMetadata->expects($this->once()) - ->method('setDomain') - ->with($domain) - ->will($this->returnSelf()); - $cookieMetadata->expects($this->once()) - ->method('setSecure') - ->with($secure) - ->will($this->returnSelf()); - $cookieMetadata->expects($this->once()) - ->method('setHttpOnly') - ->with($httpOnly) - ->will($this->returnSelf()); - - $this->cookieMetadataFactory->expects($this->once()) - ->method('createPublicCookieMetadata') - ->will($this->returnValue($cookieMetadata)); - - $this->cookieManager->expects($this->once()) - ->method('getCookie') - ->with($name) - ->will($this->returnValue($cookie)); - $this->cookieManager->expects($this->once()) - ->method('setPublicCookie') - ->with($name, $cookie, $cookieMetadata); - - $this->sessionConfig->expects($this->once()) - ->method('getCookiePath') - ->will($this->returnValue($path)); - $this->sessionConfig->expects($this->once()) - ->method('getCookieDomain') - ->will($this->returnValue($domain)); - $this->sessionConfig->expects($this->once()) - ->method('getCookieSecure') - ->will($this->returnValue($secure)); - $this->sessionConfig->expects($this->once()) - ->method('getCookieHttpOnly') - ->will($this->returnValue($httpOnly)); - - $this->session->prolong(); - - $this->assertLessThanOrEqual(time(), $this->session->getUpdatedAt()); - } - - /** - * @dataProvider isAllowedDataProvider - * @param bool $isUserDefined - * @param bool $isAclDefined - * @param bool $isAllowed - * @param true $expectedResult - */ - public function testIsAllowed($isUserDefined, $isAclDefined, $isAllowed, $expectedResult) - { - $userAclRole = 'userAclRole'; - if ($isAclDefined) { - $aclMock = $this->getMockBuilder(\Magento\Framework\Acl::class)->disableOriginalConstructor()->getMock(); - $this->storage->expects($this->any())->method('getAcl')->willReturn($aclMock); - } - if ($isUserDefined) { - $userMock = $this->getMockBuilder(\Magento\User\Model\User::class)->disableOriginalConstructor()->getMock(); - $this->storage->expects($this->once())->method('getUser')->willReturn($userMock); - } - if ($isAclDefined && $isUserDefined) { - $userMock->expects($this->any())->method('getAclRole')->willReturn($userAclRole); - $aclMock->expects($this->once())->method('isAllowed')->with($userAclRole)->willReturn($isAllowed); - } - - $this->assertEquals($expectedResult, $this->session->isAllowed('resource')); - } - - /** - * @return array - */ - public function isAllowedDataProvider() - { - return [ - "Negative: User not defined" => [false, true, true, false], - "Negative: Acl not defined" => [true, false, true, false], - "Negative: Permission denied" => [true, true, false, false], - "Positive: Permission granted" => [true, true, false, false], - ]; - } - - /** - * @dataProvider firstPageAfterLoginDataProvider - * @param bool $isFirstPageAfterLogin - */ - public function testFirstPageAfterLogin($isFirstPageAfterLogin) - { - $this->session->setIsFirstPageAfterLogin($isFirstPageAfterLogin); - $this->assertEquals($isFirstPageAfterLogin, $this->session->isFirstPageAfterLogin()); - } - - /** - * @return array - */ - public function firstPageAfterLoginDataProvider() - { - return [ - 'First page after login' => [true], - 'Not first page after login' => [false], - ]; - } -} diff --git a/app/code/Magento/Backend/Test/Unit/Model/Authorization/RoleLocatorTest.php b/app/code/Magento/Backend/Test/Unit/Model/Authorization/RoleLocatorTest.php deleted file mode 100644 index 5b3910e9445f..000000000000 --- a/app/code/Magento/Backend/Test/Unit/Model/Authorization/RoleLocatorTest.php +++ /dev/null @@ -1,36 +0,0 @@ -_sessionMock = $this->createPartialMock( - \Magento\Backend\Model\Auth\Session::class, - ['getUser', 'getAclRole', 'hasUser'] - ); - $this->_model = new \Magento\Backend\Model\Authorization\RoleLocator($this->_sessionMock); - } - - public function testGetAclRoleIdReturnsCurrentUserAclRoleId() - { - $this->_sessionMock->expects($this->once())->method('hasUser')->will($this->returnValue(true)); - $this->_sessionMock->expects($this->once())->method('getUser')->will($this->returnSelf()); - $this->_sessionMock->expects($this->once())->method('getAclRole')->will($this->returnValue('some_role')); - $this->assertEquals('some_role', $this->_model->getAclRoleId()); - } -} diff --git a/app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php b/app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php deleted file mode 100644 index 77eb7cdb34d1..000000000000 --- a/app/code/Magento/Backend/Test/Unit/Model/Locale/ManagerTest.php +++ /dev/null @@ -1,127 +0,0 @@ -_session = $this->createMock(\Magento\Backend\Model\Session::class); - - $this->_authSession = $this->createPartialMock(\Magento\Backend\Model\Auth\Session::class, ['getUser']); - - $this->_backendConfig = $this->getMockForAbstractClass( - \Magento\Backend\App\ConfigInterface::class, - [], - '', - false - ); - - $userMock = new \Magento\Framework\DataObject(); - - $this->_authSession->expects($this->any())->method('getUser')->will($this->returnValue($userMock)); - - $this->_translator = $this->getMockBuilder(\Magento\Framework\TranslateInterface::class) - ->setMethods(['init', 'setLocale']) - ->getMockForAbstractClass(); - - $this->_translator->expects($this->any())->method('setLocale')->will($this->returnValue($this->_translator)); - - $this->_translator->expects($this->any())->method('init')->will($this->returnValue(false)); - - $this->_model = new \Magento\Backend\Model\Locale\Manager( - $this->_session, - $this->_authSession, - $this->_translator, - $this->_backendConfig - ); - } - - /** - * @return array - */ - public function switchBackendInterfaceLocaleDataProvider() - { - return ['case1' => ['locale' => 'de_DE'], 'case2' => ['locale' => 'en_US']]; - } - - /** - * @param string $locale - * @dataProvider switchBackendInterfaceLocaleDataProvider - * @covers \Magento\Backend\Model\Locale\Manager::switchBackendInterfaceLocale - */ - public function testSwitchBackendInterfaceLocale($locale) - { - $this->_model->switchBackendInterfaceLocale($locale); - - $userInterfaceLocale = $this->_authSession->getUser()->getInterfaceLocale(); - $this->assertEquals($userInterfaceLocale, $locale); - - $sessionLocale = $this->_session->getSessionLocale(); - $this->assertEquals($sessionLocale, null); - } - - /** - * @covers \Magento\Backend\Model\Locale\Manager::getUserInterfaceLocale - */ - public function testGetUserInterfaceLocaleDefault() - { - $locale = $this->_model->getUserInterfaceLocale(); - - $this->assertEquals($locale, Resolver::DEFAULT_LOCALE); - } - - /** - * @covers \Magento\Backend\Model\Locale\Manager::getUserInterfaceLocale - */ - public function testGetUserInterfaceLocale() - { - $this->_model->switchBackendInterfaceLocale('de_DE'); - $locale = $this->_model->getUserInterfaceLocale(); - - $this->assertEquals($locale, 'de_DE'); - } - - /** - * @covers \Magento\Backend\Model\Locale\Manager::getUserInterfaceLocale - */ - public function testGetUserInterfaceGeneralLocale() - { - $this->_backendConfig->expects($this->any()) - ->method('getValue') - ->with('general/locale/code') - ->willReturn('test_locale'); - $locale = $this->_model->getUserInterfaceLocale(); - $this->assertEquals($locale, 'test_locale'); - } -} diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index f9408768136b..e54bd136b349 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -22,6 +22,7 @@ "magento/module-store": "*", "magento/module-translation": "*", "magento/module-ui": "*", + "magento/module-authorization": "*", "magento/module-user": "*" }, "suggest": { diff --git a/app/code/Magento/Backend/etc/di.xml b/app/code/Magento/Backend/etc/di.xml index c526703da997..41db85b9323a 100644 --- a/app/code/Magento/Backend/etc/di.xml +++ b/app/code/Magento/Backend/etc/di.xml @@ -198,4 +198,8 @@ Magento\Backend\Block\AnchorRenderer + + diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php index 23f612582f42..d56cc40ad0fc 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php @@ -845,9 +845,14 @@ public function afterDelete() /** * @inheritdoc * @since 100.0.9 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->unsetData('entity_type'); return array_diff( parent::__sleep(), @@ -858,9 +863,14 @@ public function __sleep() /** * @inheritdoc * @since 100.0.9 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_indexerEavProcessor = $objectManager->get(\Magento\Catalog\Model\Indexer\Product\Flat\Processor::class); diff --git a/app/code/Magento/Config/Model/Config/Backend/Encrypted.php b/app/code/Magento/Config/Model/Config/Backend/Encrypted.php index 1a91e403a679..ea3b1d4c74a5 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Encrypted.php +++ b/app/code/Magento/Config/Model/Config/Backend/Encrypted.php @@ -9,6 +9,8 @@ namespace Magento\Config\Model\Config\Backend; /** + * Backend model for encrypted values. + * * @api * @since 100.0.2 */ @@ -48,9 +50,14 @@ public function __construct( * Magic method called during class serialization * * @return string[] + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = parent::__sleep(); return array_diff($properties, ['_encryptor']); } @@ -59,9 +66,14 @@ public function __sleep() * Magic method called during class un-serialization * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $this->_encryptor = \Magento\Framework\App\ObjectManager::getInstance()->get( \Magento\Framework\Encryption\EncryptorInterface::class diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php index 7306942c3c49..4ead9ffe0fe7 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php @@ -12,6 +12,8 @@ use Magento\Framework\EntityManager\MetadataPool; /** + * Configurable product attribute model. + * * @method Attribute setProductAttribute(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute $value) * @method \Magento\Eav\Model\Entity\Attribute\AbstractAttribute getProductAttribute() */ @@ -86,7 +88,7 @@ public function getOptions() } /** - * {@inheritdoc} + * @inheritdoc */ public function getLabel() { @@ -112,10 +114,10 @@ public function afterSave() } /** - * Load configurable attribute by product and product's attribute + * Load configurable attribute by product and product's attribute. * * @param \Magento\Catalog\Model\Product $product - * @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute + * @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute * @return void */ public function loadByProductAndAttribute($product, $attribute) @@ -144,7 +146,7 @@ public function deleteByProduct($product) } /** - * {@inheritdoc} + * @inheritdoc * @codeCoverageIgnore */ public function getAttributeId() @@ -153,7 +155,7 @@ public function getAttributeId() } /** - * {@inheritdoc} + * @inheritdoc * @codeCoverageIgnore */ public function getPosition() @@ -162,7 +164,7 @@ public function getPosition() } /** - * {@inheritdoc} + * @inheritdoc * @codeCoverageIgnore */ public function getIsUseDefault() @@ -171,7 +173,7 @@ public function getIsUseDefault() } /** - * {@inheritdoc} + * @inheritdoc * @codeCoverageIgnore */ public function getValues() @@ -182,8 +184,7 @@ public function getValues() //@codeCoverageIgnoreStart /** - * @param string $attributeId - * @return $this + * @inheritdoc */ public function setAttributeId($attributeId) { @@ -191,8 +192,7 @@ public function setAttributeId($attributeId) } /** - * @param string $label - * @return $this + * @inheritdoc */ public function setLabel($label) { @@ -200,8 +200,7 @@ public function setLabel($label) } /** - * @param int $position - * @return $this + * @inheritdoc */ public function setPosition($position) { @@ -209,8 +208,7 @@ public function setPosition($position) } /** - * @param bool $isUseDefault - * @return $this + * @inheritdoc */ public function setIsUseDefault($isUseDefault) { @@ -218,8 +216,7 @@ public function setIsUseDefault($isUseDefault) } /** - * @param \Magento\ConfigurableProduct\Api\Data\OptionValueInterface[] $values - * @return $this + * @inheritdoc */ public function setValues(array $values = null) { @@ -227,7 +224,7 @@ public function setValues(array $values = null) } /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface|null */ @@ -237,7 +234,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface $extensionAttributes * @return $this @@ -249,7 +246,7 @@ public function setExtensionAttributes( } /** - * {@inheritdoc} + * @inheritdoc */ public function getProductId() { @@ -257,7 +254,7 @@ public function getProductId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setProductId($value) { @@ -268,9 +265,14 @@ public function setProductId($value) /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return array_diff( parent::__sleep(), ['metadataPool'] @@ -279,9 +281,14 @@ public function __sleep() /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->metadataPool = $objectManager->get(MetadataPool::class); diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php index 3c40d326be77..81cbbd06c523 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php @@ -18,6 +18,8 @@ use Magento\Catalog\Api\Data\ProductInterface; /** + * Collection of configurable product attributes. + * * @api * @SuppressWarnings(PHPMD.LongVariable) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -302,6 +304,8 @@ protected function _loadLabels() } /** + * Load related options' data. + * * @return void */ protected function loadOptions() @@ -354,9 +358,14 @@ protected function getIncludedOptions(array $usedProducts, AbstractAttribute $pr /** * @inheritdoc * @since 100.0.6 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return array_diff( parent::__sleep(), [ @@ -373,9 +382,14 @@ public function __sleep() /** * @inheritdoc * @since 100.0.6 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = ObjectManager::getInstance(); $this->_storeManager = $objectManager->get(\Magento\Store\Model\StoreManagerInterface::class); diff --git a/app/code/Magento/Customer/Model/Attribute.php b/app/code/Magento/Customer/Model/Attribute.php index 98a97872f15f..ae714f993082 100644 --- a/app/code/Magento/Customer/Model/Attribute.php +++ b/app/code/Magento/Customer/Model/Attribute.php @@ -202,9 +202,14 @@ public function canBeFilterableInGrid() /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->unsetData('entity_type'); return array_diff( parent::__sleep(), @@ -214,9 +219,14 @@ public function __sleep() /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->indexerRegistry = $objectManager->get(\Magento\Framework\Indexer\IndexerRegistry::class); diff --git a/app/code/Magento/Eav/Model/Entity/Attribute.php b/app/code/Magento/Eav/Model/Entity/Attribute.php index 06a4abb98580..e820f14090f7 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute.php @@ -310,9 +310,9 @@ public function beforeSave() } /** - * Save additional data + * @inheritdoc * - * @return $this + * Save additional data. */ public function afterSave() { @@ -496,9 +496,14 @@ public function getIdentities() /** * @inheritdoc * @since 100.0.7 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->unsetData('attribute_set_info'); return array_diff( parent::__sleep(), @@ -509,9 +514,14 @@ public function __sleep() /** * @inheritdoc * @since 100.0.7 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_localeDate = $objectManager->get(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class); diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php index 7ed455eccf4e..9ed4ac529368 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php @@ -1404,9 +1404,14 @@ public function setExtensionAttributes(\Magento\Eav\Api\Data\AttributeExtensionI /** * @inheritdoc * @since 100.0.7 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return array_diff( parent::__sleep(), [ @@ -1429,9 +1434,14 @@ public function __sleep() /** * @inheritdoc * @since 100.0.7 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_eavConfig = $objectManager->get(\Magento\Eav\Model\Config::class); diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php index 0e7a46125d87..5e7226e7a36d 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php @@ -725,9 +725,14 @@ public function getValidAttributeIds($attributeIds) * * @return array * @since 100.0.7 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = parent::__sleep(); $properties = array_diff($properties, ['_storeManager']); return $properties; @@ -738,9 +743,14 @@ public function __sleep() * * @return void * @since 100.0.7 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $this->_storeManager = \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Store\Model\StoreManagerInterface::class); diff --git a/app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/System/Config/Fieldset/GroupTest.php b/app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/System/Config/Fieldset/GroupTest.php deleted file mode 100644 index cfdfe17b1e00..000000000000 --- a/app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/System/Config/Fieldset/GroupTest.php +++ /dev/null @@ -1,107 +0,0 @@ -_group = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Group::class); - $this->_element = $this->getMockForAbstractClass( - \Magento\Framework\Data\Form\Element\AbstractElement::class, - [], - '', - false, - true, - true, - ['getHtmlId', 'getElementHtml', 'getName', 'getElements', 'getId'] - ); - $this->_element->expects($this->any()) - ->method('getHtmlId') - ->will($this->returnValue('html id')); - $this->_element->expects($this->any()) - ->method('getElementHtml') - ->will($this->returnValue('element html')); - $this->_element->expects($this->any()) - ->method('getName') - ->will($this->returnValue('name')); - $this->_element->expects($this->any()) - ->method('getElements') - ->will($this->returnValue([])); - $this->_element->expects($this->any()) - ->method('getId') - ->will($this->returnValue('id')); - $this->_user = $this->createMock(\Magento\User\Model\User::class); - $this->_authSession = $this->createMock(\Magento\Backend\Model\Auth\Session::class); - $this->_authSession->expects($this->any()) - ->method('__call') - ->with('getUser') - ->will($this->returnValue($this->_user)); - $this->_model = $helper->getObject( - \Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group::class, - ['authSession' => $this->_authSession] - ); - $this->_model->setGroup($this->_group); - } - - /** - * @param mixed $expanded - * @param int $expected - * @dataProvider isCollapseStateDataProvider - */ - public function testIsCollapseState($expanded, $expected) - { - $this->_user->setExtra(['configState' => []]); - $this->_element->setGroup(isset($expanded) ? ['expanded' => $expanded] : []); - $html = $this->_model->render($this->_element); - $this->assertContains( - '', - $html - ); - } - - /** - * @return array - */ - public function isCollapseStateDataProvider() - { - return [ - [null, 0], - [false, 0], - ['', 0], - [1, 1], - ['1', 1], - ]; - } -} diff --git a/app/code/Magento/ReleaseNotification/Test/Unit/Model/Condition/CanViewNotificationTest.php b/app/code/Magento/ReleaseNotification/Test/Unit/Model/Condition/CanViewNotificationTest.php index 55f448730a50..b86f8dff2b3b 100644 --- a/app/code/Magento/ReleaseNotification/Test/Unit/Model/Condition/CanViewNotificationTest.php +++ b/app/code/Magento/ReleaseNotification/Test/Unit/Model/Condition/CanViewNotificationTest.php @@ -12,6 +12,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Backend\Model\Auth\Session; use Magento\Framework\App\CacheInterface; +use Magento\User\Model\User; class CanViewNotificationTest extends \PHPUnit\Framework\TestCase { @@ -33,6 +34,11 @@ class CanViewNotificationTest extends \PHPUnit\Framework\TestCase /** @var $cacheStorageMock \PHPUnit_Framework_MockObject_MockObject|CacheInterface */ private $cacheStorageMock; + /** + * @var User|\PHPUnit_Framework_MockObject_MockObject + */ + private $userMock; + public function setUp() { $this->cacheStorageMock = $this->getMockBuilder(CacheInterface::class) @@ -41,7 +47,6 @@ public function setUp() ->getMock(); $this->sessionMock = $this->getMockBuilder(Session::class) ->disableOriginalConstructor() - ->setMethods(['getUser', 'getId']) ->getMock(); $this->viewerLoggerMock = $this->getMockBuilder(Logger::class) ->disableOriginalConstructor() @@ -49,6 +54,7 @@ public function setUp() $this->productMetadataMock = $this->getMockBuilder(ProductMetadataInterface::class) ->disableOriginalConstructor() ->getMock(); + $this->userMock = $this->createMock(User::class); $objectManager = new ObjectManager($this); $this->canViewNotification = $objectManager->getObject( CanViewNotification::class, @@ -65,8 +71,8 @@ public function testIsVisibleLoadDataFromCache() { $this->sessionMock->expects($this->once()) ->method('getUser') - ->willReturn($this->sessionMock); - $this->sessionMock->expects($this->once()) + ->willReturn($this->userMock); + $this->userMock->expects($this->once()) ->method('getId') ->willReturn(1); $this->cacheStorageMock->expects($this->once()) @@ -90,8 +96,8 @@ public function testIsVisible($expected, $version, $lastViewVersion) ->willReturn(false); $this->sessionMock->expects($this->once()) ->method('getUser') - ->willReturn($this->sessionMock); - $this->sessionMock->expects($this->once()) + ->willReturn($this->userMock); + $this->userMock->expects($this->once()) ->method('getId') ->willReturn(1); $this->productMetadataMock->expects($this->once()) diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index b2a515b198b1..21dea880bb43 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -423,9 +423,14 @@ public function __construct( /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = parent::__sleep(); $properties = array_diff($properties, ['_coreFileStorageDatabase', '_config']); return $properties; @@ -435,9 +440,14 @@ public function __sleep() * Init not serializable fields * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $this->_coreFileStorageDatabase = ObjectManager::getInstance() ->get(\Magento\MediaStorage\Helper\File\Storage\Database::class); diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php index 2994ac351fc7..d8040b0bbaaa 100644 --- a/app/code/Magento/User/Model/User.php +++ b/app/code/Magento/User/Model/User.php @@ -212,9 +212,14 @@ protected function _construct() * Removing dependencies and leaving only entity's properties. * * @return string[] + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = parent::__sleep(); return array_diff( $properties, @@ -240,9 +245,14 @@ public function __sleep() * Restoring required objects after serialization. * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->serializer = $objectManager->get(Json::class); @@ -406,6 +416,10 @@ public function getRoles() */ public function getRole() { + if ($this->getData('extracted_role')) { + $this->_role = $this->getData('extracted_role'); + $this->unsetData('extracted_role'); + } if (null === $this->_role) { $this->_role = $this->_roleFactory->create(); $roles = $this->getRoles(); diff --git a/app/code/Magento/User/Test/Unit/Model/Authorization/AdminSessionUserContextTest.php b/app/code/Magento/User/Test/Unit/Model/Authorization/AdminSessionUserContextTest.php deleted file mode 100644 index 23681c4b8da2..000000000000 --- a/app/code/Magento/User/Test/Unit/Model/Authorization/AdminSessionUserContextTest.php +++ /dev/null @@ -1,89 +0,0 @@ -objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->adminSession = $this->getMockBuilder(\Magento\Backend\Model\Auth\Session::class) - ->disableOriginalConstructor() - ->setMethods(['hasUser', 'getUser', 'getId']) - ->getMock(); - - $this->adminSessionUserContext = $this->objectManager->getObject( - \Magento\User\Model\Authorization\AdminSessionUserContext::class, - ['adminSession' => $this->adminSession] - ); - } - - public function testGetUserIdExist() - { - $userId = 1; - - $this->setupUserId($userId); - - $this->assertEquals($userId, $this->adminSessionUserContext->getUserId()); - } - - public function testGetUserIdDoesNotExist() - { - $userId = null; - - $this->setupUserId($userId); - - $this->assertEquals($userId, $this->adminSessionUserContext->getUserId()); - } - - public function testGetUserType() - { - $this->assertEquals(UserContextInterface::USER_TYPE_ADMIN, $this->adminSessionUserContext->getUserType()); - } - - /** - * @param int|null $userId - * @return void - */ - public function setupUserId($userId) - { - $this->adminSession->expects($this->once()) - ->method('hasUser') - ->will($this->returnValue($userId)); - - if ($userId) { - $this->adminSession->expects($this->once()) - ->method('getUser') - ->will($this->returnSelf()); - - $this->adminSession->expects($this->once()) - ->method('getId') - ->will($this->returnValue($userId)); - } - } -} diff --git a/app/code/Magento/User/Test/Unit/Model/UserTest.php b/app/code/Magento/User/Test/Unit/Model/UserTest.php index 670316c2500f..ab06c8754b2f 100644 --- a/app/code/Magento/User/Test/Unit/Model/UserTest.php +++ b/app/code/Magento/User/Test/Unit/Model/UserTest.php @@ -44,31 +44,6 @@ protected function setUp() ); } - /** - * @return void - */ - public function testSleep() - { - $excludedProperties = [ - '_eventManager', - '_cacheManager', - '_registry', - '_appState', - '_userData', - '_config', - '_validatorObject', - '_roleFactory', - '_encryptor', - '_transportBuilder', - '_storeManager', - '_validatorBeforeSave' - ]; - $actualResult = $this->model->__sleep(); - $this->assertNotEmpty($actualResult); - $expectedResult = array_intersect($actualResult, $excludedProperties); - $this->assertEmpty($expectedResult); - } - /** * @return void */ diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Auth/SessionTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Auth/SessionTest.php index 5ca2bf1f7317..f1e7a1073760 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Model/Auth/SessionTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Auth/SessionTest.php @@ -3,8 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Backend\Model\Auth; +use Magento\TestFramework\Bootstrap as TestHelper; +use Magento\TestFramework\Helper\Bootstrap; + /** * @magentoAppArea adminhtml * @magentoAppIsolation enabled @@ -18,10 +22,15 @@ class SessionTest extends \PHPUnit\Framework\TestCase private $auth; /** - * @var \Magento\Backend\Model\Auth\Session + * @var Session */ private $authSession; + /** + * @var SessionFactory + */ + private $authSessionFactory; + /** * @var \Magento\Framework\ObjectManagerInterface */ @@ -30,11 +39,12 @@ class SessionTest extends \PHPUnit\Framework\TestCase protected function setUp() { parent::setUp(); - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->objectManager = Bootstrap::getObjectManager(); $this->objectManager->get(\Magento\Framework\Config\ScopeInterface::class) ->setCurrentScope(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE); $this->auth = $this->objectManager->create(\Magento\Backend\Model\Auth::class); - $this->authSession = $this->objectManager->create(\Magento\Backend\Model\Auth\Session::class); + $this->authSession = $this->objectManager->create(Session::class); + $this->authSessionFactory = $this->objectManager->get(SessionFactory::class); $this->auth->setAuthStorage($this->authSession); $this->auth->logout(); } @@ -52,8 +62,8 @@ public function testIsLoggedIn($loggedIn) { if ($loggedIn) { $this->auth->login( - \Magento\TestFramework\Bootstrap::ADMIN_NAME, - \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD + TestHelper::ADMIN_NAME, + TestHelper::ADMIN_PASSWORD ); } $this->assertEquals($loggedIn, $this->authSession->isLoggedIn()); @@ -63,4 +73,23 @@ public function loginDataProvider() { return [[false], [true]]; } + + /** + * Check that persisting user data is working. + */ + public function testStorage() + { + $this->auth->login(TestHelper::ADMIN_NAME, TestHelper::ADMIN_PASSWORD); + $user = $this->authSession->getUser(); + $acl = $this->authSession->getAcl(); + /** @var Session $session */ + $session = $this->authSessionFactory->create(); + $persistedUser = $session->getUser(); + $persistedAcl = $session->getAcl(); + + $this->assertEquals($user->getData(), $persistedUser->getData()); + $this->assertEquals($user->getAclRole(), $persistedUser->getAclRole()); + $this->assertEquals($acl->getRoles(), $persistedAcl->getRoles()); + $this->assertEquals($acl->getResources(), $persistedAcl->getResources()); + } } diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php index d1252be2c4b5..88662a65c742 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php @@ -3,9 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Backend\Model\Locale; use Magento\Framework\Locale\Resolver; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\User\Model\User; /** * @magentoAppArea adminhtml @@ -20,7 +23,7 @@ class ResolverTest extends \PHPUnit\Framework\TestCase protected function setUp() { parent::setUp(); - $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + $this->_model = Bootstrap::getObjectManager()->create( \Magento\Backend\Model\Locale\Resolver::class ); } @@ -38,12 +41,12 @@ public function testSetLocaleWithDefaultLocale() */ public function testSetLocaleWithBaseInterfaceLocale() { - $user = new \Magento\Framework\DataObject(); - $session = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + $user = Bootstrap::getObjectManager()->create(User::class); + $session = Bootstrap::getObjectManager()->get( \Magento\Backend\Model\Auth\Session::class ); $session->setUser($user); - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + Bootstrap::getObjectManager()->get( \Magento\Backend\Model\Auth\Session::class )->getUser()->setInterfaceLocale( 'fr_FR' @@ -56,7 +59,7 @@ public function testSetLocaleWithBaseInterfaceLocale() */ public function testSetLocaleWithSessionLocale() { - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + Bootstrap::getObjectManager()->get( \Magento\Backend\Model\Session::class )->setSessionLocale( 'es_ES' @@ -69,7 +72,7 @@ public function testSetLocaleWithSessionLocale() */ public function testSetLocaleWithRequestLocale() { - $request = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + $request = Bootstrap::getObjectManager() ->get(\Magento\Framework\App\RequestInterface::class); $request->setPostValue(['locale' => 'de_DE']); $this->_checkSetLocale('de_DE'); diff --git a/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php new file mode 100644 index 000000000000..eaa93887fee9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php @@ -0,0 +1,55 @@ +hydrator = $objectManager->get(SessionAclHydratorInterface::class); + $this->aclBuilder = $objectManager->get(AclBuilder::class); + $this->aclFactory = $objectManager->get(AclFactory::class); + } + + /** + * Test that ACL data is preserved. + */ + public function testHydrate() + { + $acl = $this->aclBuilder->getAcl(); + $data = $this->hydrator->extract($acl); + $this->hydrator->hydrate($built = $this->aclFactory->create(), $data); + $this->assertEquals($acl->getRoles(), $built->getRoles()); + $this->assertEquals($acl->getResources(), $built->getResources()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionUserHydratorInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionUserHydratorInterfaceTest.php new file mode 100644 index 000000000000..e076a4fe1c38 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionUserHydratorInterfaceTest.php @@ -0,0 +1,58 @@ +hydrator = $objectManager->get(SessionUserHydratorInterface::class); + $this->userFactory = $objectManager->get(UserFactory::class); + } + + /** + * Make sure users' data is preserved during extract/hydrate. + */ + public function testHydrate() + { + /** @var User $user */ + $user = $this->userFactory->create(); + $user->loadByUsername(TestHelper::ADMIN_NAME); + + $userData = $this->hydrator->extract($user); + /** @var User $newUser */ + $newUser = $this->userFactory->create(); + $this->hydrator->hydrate($newUser, $userData); + $this->assertEquals($user->getData(), $newUser->getData()); + $this->assertEquals($user->getRole()->getId(), $newUser->getRole()->getId()); + } +} diff --git a/dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/SerializationAware.php b/dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/SerializationAware.php new file mode 100644 index 000000000000..e38fba8558ba --- /dev/null +++ b/dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/SerializationAware.php @@ -0,0 +1,34 @@ +getName() === '__wakeup' || $method->getName() === '__sleep') { + $this->addViolation($method, [$method->getName(), $method->getParent()->getFullQualifiedName()]); + } + } +} diff --git a/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml b/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml index 73354c46d76b..56b8036a11ef 100644 --- a/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml +++ b/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml @@ -83,6 +83,31 @@ class OrderProcessor $currentOrder = $this->session->get('current_order'); ... } +} + ]]> + + + + + + + 2 + + + diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml index 7a402818eb0b..67b195e2f8f0 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml @@ -49,5 +49,6 @@ + diff --git a/lib/internal/Magento/Framework/App/AreaList/Proxy.php b/lib/internal/Magento/Framework/App/AreaList/Proxy.php index d3b26ee9a419..09115add5719 100644 --- a/lib/internal/Magento/Framework/App/AreaList/Proxy.php +++ b/lib/internal/Magento/Framework/App/AreaList/Proxy.php @@ -1,12 +1,14 @@ _objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/App/Response/Http.php b/lib/internal/Magento/Framework/App/Response/Http.php index 62ff94e7043f..a152b655e42a 100644 --- a/lib/internal/Magento/Framework/App/Response/Http.php +++ b/lib/internal/Magento/Framework/App/Response/Http.php @@ -1,10 +1,9 @@ cookieManager = $objectManager->create(\Magento\Framework\Stdlib\CookieManagerInterface::class); $this->cookieMetadataFactory = $objectManager->get( diff --git a/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php b/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php index fd37590bb778..5e79315238f7 100644 --- a/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php +++ b/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php @@ -60,10 +60,17 @@ public function __construct( } /** + * Remove links to other objects. + * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return ['_subject', '_isShared']; } @@ -71,9 +78,14 @@ public function __sleep() * Retrieve ObjectManager from global scope * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php index efb35b7321c3..9be68b379900 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php @@ -290,45 +290,6 @@ public function testRepresentJson() $this->assertEquals('json_string', $this->model->getBody('default')); } - /** - * - * @expectedException \RuntimeException - * @expectedExceptionMessage ObjectManager isn't initialized - */ - public function testWakeUpWithException() - { - /* ensure that the test preconditions are met */ - $objectManagerClass = new \ReflectionClass(\Magento\Framework\App\ObjectManager::class); - $instanceProperty = $objectManagerClass->getProperty('_instance'); - $instanceProperty->setAccessible(true); - $instanceProperty->setValue(null); - - $this->model->__wakeup(); - $this->assertNull($this->cookieMetadataFactoryMock); - $this->assertNull($this->cookieManagerMock); - } - - /** - * Test for the magic method __wakeup - * - * @covers \Magento\Framework\App\Response\Http::__wakeup - */ - public function testWakeUpWith() - { - $objectManagerMock = $this->createMock(\Magento\Framework\App\ObjectManager::class); - $objectManagerMock->expects($this->once()) - ->method('create') - ->with(\Magento\Framework\Stdlib\CookieManagerInterface::class) - ->will($this->returnValue($this->cookieManagerMock)); - $objectManagerMock->expects($this->at(1)) - ->method('get') - ->with(\Magento\Framework\Stdlib\Cookie\CookieMetadataFactory::class) - ->will($this->returnValue($this->cookieMetadataFactoryMock)); - - \Magento\Framework\App\ObjectManager::setInstance($objectManagerMock); - $this->model->__wakeup(); - } - public function testSetXFrameOptions() { $value = 'DENY'; diff --git a/lib/internal/Magento/Framework/DB/Select.php b/lib/internal/Magento/Framework/DB/Select.php index 4d178b81af6d..f33aaea7d0e6 100644 --- a/lib/internal/Magento/Framework/DB/Select.php +++ b/lib/internal/Magento/Framework/DB/Select.php @@ -400,7 +400,7 @@ public function useStraightJoin($flag = true) /** * Render STRAIGHT_JOIN clause * - * @param string $sql SQL query + * @param string $sql SQL query * @return string */ protected function _renderStraightjoin($sql) @@ -452,7 +452,7 @@ public function orderRand($field = null) /** * Render FOR UPDATE clause * - * @param string $sql SQL query + * @param string $sql SQL query * @return string */ protected function _renderForupdate($sql) @@ -467,9 +467,9 @@ protected function _renderForupdate($sql) /** * Add EXISTS clause * - * @param Select $select - * @param string $joinCondition - * @param bool $isExists + * @param Select $select + * @param string $joinCondition + * @param bool $isExists * @return $this */ public function exists($select, $joinCondition, $isExists = true) @@ -509,11 +509,18 @@ public function assemble() } /** + * Remove links to other objects. + * * @return string[] * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = array_keys(get_object_vars($this)); $properties = array_diff( $properties, @@ -530,9 +537,14 @@ public function __sleep() * * @return void * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_adapter = $objectManager->get(ResourceConnection::class)->getConnection(); $this->selectRenderer = $objectManager->get(\Magento\Framework\DB\Select\SelectRenderer::class); diff --git a/lib/internal/Magento/Framework/DB/Select/RendererProxy.php b/lib/internal/Magento/Framework/DB/Select/RendererProxy.php index 3626f6a07fa1..dc69b96b7905 100644 --- a/lib/internal/Magento/Framework/DB/Select/RendererProxy.php +++ b/lib/internal/Magento/Framework/DB/Select/RendererProxy.php @@ -56,10 +56,17 @@ public function __construct( } /** + * Remove links to other objects. + * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return ['_subject', '_isShared']; } @@ -67,9 +74,14 @@ public function __sleep() * Retrieve ObjectManager from global scope * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } @@ -99,7 +111,7 @@ protected function _getSubject() } /** - * {@inheritdoc} + * @inheritdoc */ public function render(\Magento\Framework\DB\Select $select, $sql = '') { diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index 9c789e81913c..5477b58d4e86 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -886,9 +886,14 @@ public function hasFlag($flag) * * @return string[] * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = array_keys(get_object_vars($this)); $properties = array_diff( $properties, @@ -904,9 +909,14 @@ public function __sleep() * * @return void * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_entityFactory = $objectManager->get(EntityFactoryInterface::class); } diff --git a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php index 308f2a12f506..1b28e367dcc3 100644 --- a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php +++ b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php @@ -890,9 +890,14 @@ private function getMainTableAlias() /** * @inheritdoc * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return array_diff( parent::__sleep(), ['_fetchStrategy', '_logger', '_conn', 'extensionAttributesJoinProcessor'] @@ -902,9 +907,14 @@ public function __sleep() /** * @inheritdoc * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_logger = $objectManager->get(Logger::class); diff --git a/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php b/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php index 880da5db771e..b0f5742afef1 100644 --- a/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php +++ b/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php @@ -57,10 +57,17 @@ public function __construct( } /** + * Remove links to other objects. + * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return ['_subject', '_isShared']; } @@ -68,9 +75,14 @@ public function __sleep() * Retrieve ObjectManager from global scope * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } @@ -100,7 +112,7 @@ protected function _getSubject() } /** - * {@inheritdoc} + * @inheritdoc */ public function merge(array $config) { @@ -108,7 +120,7 @@ public function merge(array $config) } /** - * {@inheritdoc} + * @inheritdoc */ public function get($path = null, $default = null) { @@ -116,7 +128,7 @@ public function get($path = null, $default = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function reset() { diff --git a/lib/internal/Magento/Framework/Interception/Interceptor.php b/lib/internal/Magento/Framework/Interception/Interceptor.php index 07600c516818..df1b68023422 100644 --- a/lib/internal/Magento/Framework/Interception/Interceptor.php +++ b/lib/internal/Magento/Framework/Interception/Interceptor.php @@ -62,9 +62,14 @@ public function ___callParent($method, array $arguments) * Calls parent class sleep if defined, otherwise provides own implementation * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + if (method_exists(get_parent_class($this), '__sleep')) { $properties = parent::__sleep(); } else { @@ -78,9 +83,14 @@ public function __sleep() * Causes Interceptor to be initialized * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + if (method_exists(get_parent_class($this), '__wakeup')) { parent::__wakeup(); } diff --git a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php index 1cffba2543b0..e1f6c792c9c3 100644 --- a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php @@ -158,7 +158,7 @@ public function getCustomAttribute($attributeCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomAttributes(array $attributes) { @@ -166,7 +166,7 @@ public function setCustomAttributes(array $attributes) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomAttribute($attributeCode, $attributeValue) { @@ -182,7 +182,7 @@ public function setCustomAttribute($attributeCode, $attributeValue) } /** - * {@inheritdoc} + * @inheritdoc * * Added custom attributes support. */ @@ -200,7 +200,7 @@ public function setData($key, $value = null) } /** - * {@inheritdoc} + * @inheritdoc * * Unset customAttributesChanged flag */ @@ -359,17 +359,27 @@ private function populateExtensionAttributes(array $extensionAttributesData = [] /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return array_diff(parent::__sleep(), ['extensionAttributesFactory', 'customAttributeFactory']); } /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->extensionAttributesFactory = $objectManager->get(ExtensionAttributesFactory::class); diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php index 567d174938b1..f5095dbb6e87 100644 --- a/lib/internal/Magento/Framework/Model/AbstractModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractModel.php @@ -219,9 +219,14 @@ protected function _init($resourceModel) * Remove unneeded properties from serialization * * @return string[] + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = array_keys(get_object_vars($this)); $properties = array_diff( $properties, @@ -243,9 +248,14 @@ public function __sleep() * Init not serializable fields * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_registry = $objectManager->get(\Magento\Framework\Registry::class); diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php index 1eaed75bcbfd..0cadb10aaafe 100644 --- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php +++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php @@ -156,9 +156,14 @@ public function __construct( * Provide variables to serialize * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $properties = array_keys(get_object_vars($this)); $properties = array_diff($properties, ['_resources', '_connections']); return $properties; @@ -168,9 +173,14 @@ public function __sleep() * Restore global dependencies * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->_resources = \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Framework\App\ResourceConnection::class); } @@ -219,8 +229,10 @@ protected function _setResource($connections, $tables = null) } /** - * Set main entity table name and primary key field name - * If field name is omitted {table_name}_id will be used + * Main table setter. + * + * Set main entity table name and primary key field name. + * If field name is omitted {table_name}_id will be used. * * @param string $mainTable * @param string|null $idFieldName @@ -253,8 +265,10 @@ public function getIdFieldName() } /** + * Main table getter. + * * Returns main table name - extracted from "module/table" style and - * validated by db adapter + * validated by db adapter. * * @throws LocalizedException * @return string @@ -542,8 +556,7 @@ protected function _prepareDataForSave(\Magento\Framework\Model\AbstractModel $o } /** - * Check that model data fields that can be saved - * has really changed comparing with origData + * Check that model data fields that can be saved has really changed comparing with origData. * * @param \Magento\Framework\Model\AbstractModel $object * @return bool diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php index 8ec47ed97e11..bc2187f47491 100644 --- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php +++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php @@ -606,9 +606,14 @@ public function save() /** * @inheritdoc * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return array_diff( parent::__sleep(), ['_resource', '_eventManager'] @@ -618,9 +623,14 @@ public function __sleep() /** * @inheritdoc * @since 100.0.11 + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_eventManager = $objectManager->get(\Magento\Framework\Event\ManagerInterface::class); diff --git a/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php b/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php index a83e9507bda0..d67c38020755 100644 --- a/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php +++ b/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php @@ -55,10 +55,17 @@ public function __construct( } /** + * Remove links to objects. + * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return ['subject', 'isShared']; } @@ -66,9 +73,14 @@ public function __sleep() * Retrieve ObjectManager from global scope * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } @@ -100,7 +112,7 @@ protected function _getSubject() } /** - * {@inheritdoc} + * @inheritdoc */ public function merge(array $config) { @@ -108,7 +120,7 @@ public function merge(array $config) } /** - * {@inheritdoc} + * @inheritdoc */ public function get($path = null, $default = null) { diff --git a/lib/internal/Magento/Framework/Translate/Inline/Proxy.php b/lib/internal/Magento/Framework/Translate/Inline/Proxy.php index 370a88d6d9a4..e6d6cc57c2b0 100644 --- a/lib/internal/Magento/Framework/Translate/Inline/Proxy.php +++ b/lib/internal/Magento/Framework/Translate/Inline/Proxy.php @@ -55,10 +55,17 @@ public function __construct( } /** + * Remove links to other objects. + * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return ['subject', 'isShared']; } @@ -66,9 +73,14 @@ public function __sleep() * Retrieve ObjectManager from global scope * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/View/Layout/Proxy.php b/lib/internal/Magento/Framework/View/Layout/Proxy.php index 03020307c538..a3d89c6ec7a8 100644 --- a/lib/internal/Magento/Framework/View/Layout/Proxy.php +++ b/lib/internal/Magento/Framework/View/Layout/Proxy.php @@ -57,10 +57,17 @@ public function __construct( } /** + * Remove links to objects. + * * @return array + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __sleep() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + return ['_subject', '_isShared']; } @@ -68,9 +75,14 @@ public function __sleep() * Retrieve ObjectManager from global scope * * @return void + * + * @SuppressWarnings(PHPMD.SerializationAware) + * @deprecated Do not use PHP serialization. */ public function __wakeup() { + trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } @@ -100,7 +112,7 @@ protected function _getSubject() } /** - * {@inheritdoc} + * @inheritdoc */ public function setGeneratorPool(\Magento\Framework\View\Layout\GeneratorPool $generatorPool) { @@ -108,7 +120,7 @@ public function setGeneratorPool(\Magento\Framework\View\Layout\GeneratorPool $g } /** - * {@inheritdoc} + * @inheritdoc */ public function setBuilder(\Magento\Framework\View\Layout\BuilderInterface $builder) { @@ -116,7 +128,7 @@ public function setBuilder(\Magento\Framework\View\Layout\BuilderInterface $buil } /** - * {@inheritdoc} + * @inheritdoc */ public function publicBuild() { @@ -124,7 +136,7 @@ public function publicBuild() } /** - * {@inheritdoc} + * @inheritdoc */ public function getUpdate() { @@ -132,7 +144,7 @@ public function getUpdate() } /** - * {@inheritdoc} + * @inheritdoc */ public function generateXml() { @@ -140,7 +152,7 @@ public function generateXml() } /** - * {@inheritdoc} + * @inheritdoc */ public function generateElements() { @@ -148,7 +160,7 @@ public function generateElements() } /** - * {@inheritdoc} + * @inheritdoc */ public function getChildBlock($parentName, $alias) { @@ -156,7 +168,7 @@ public function getChildBlock($parentName, $alias) } /** - * {@inheritdoc} + * @inheritdoc */ public function setChild($parentName, $elementName, $alias) { @@ -164,7 +176,7 @@ public function setChild($parentName, $elementName, $alias) } /** - * {@inheritdoc} + * @inheritdoc */ public function reorderChild($parentName, $childName, $offsetOrSibling, $after = true) { @@ -172,7 +184,7 @@ public function reorderChild($parentName, $childName, $offsetOrSibling, $after = } /** - * {@inheritdoc} + * @inheritdoc */ public function unsetChild($parentName, $alias) { @@ -180,7 +192,7 @@ public function unsetChild($parentName, $alias) } /** - * {@inheritdoc} + * @inheritdoc */ public function getChildNames($parentName) { @@ -188,7 +200,7 @@ public function getChildNames($parentName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getChildBlocks($parentName) { @@ -196,7 +208,7 @@ public function getChildBlocks($parentName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getChildName($parentName, $alias) { @@ -204,7 +216,7 @@ public function getChildName($parentName, $alias) } /** - * {@inheritdoc} + * @inheritdoc */ public function renderElement($name, $useCache = true) { @@ -212,7 +224,7 @@ public function renderElement($name, $useCache = true) } /** - * {@inheritdoc} + * @inheritdoc */ public function renderNonCachedElement($name) { @@ -220,7 +232,7 @@ public function renderNonCachedElement($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function addToParentGroup($blockName, $parentGroupName) { @@ -228,7 +240,7 @@ public function addToParentGroup($blockName, $parentGroupName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getGroupChildNames($blockName, $groupName) { @@ -236,7 +248,7 @@ public function getGroupChildNames($blockName, $groupName) } /** - * {@inheritdoc} + * @inheritdoc */ public function hasElement($name) { @@ -244,7 +256,7 @@ public function hasElement($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function getElementProperty($name, $attribute) { @@ -252,7 +264,7 @@ public function getElementProperty($name, $attribute) } /** - * {@inheritdoc} + * @inheritdoc */ public function isBlock($name) { @@ -260,7 +272,7 @@ public function isBlock($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function isUiComponent($name) { @@ -268,7 +280,7 @@ public function isUiComponent($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function isContainer($name) { @@ -276,7 +288,7 @@ public function isContainer($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function isManipulationAllowed($name) { @@ -284,7 +296,7 @@ public function isManipulationAllowed($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBlock($name, $block) { @@ -292,7 +304,7 @@ public function setBlock($name, $block) } /** - * {@inheritdoc} + * @inheritdoc */ public function unsetElement($name) { @@ -300,7 +312,7 @@ public function unsetElement($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function createBlock($type, $name = '', array $arguments = []) { @@ -308,7 +320,7 @@ public function createBlock($type, $name = '', array $arguments = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function addBlock($block, $name = '', $parent = '', $alias = '') { @@ -316,7 +328,7 @@ public function addBlock($block, $name = '', $parent = '', $alias = '') } /** - * {@inheritdoc} + * @inheritdoc */ public function addContainer($name, $label, array $options = [], $parent = '', $alias = '') { @@ -324,7 +336,7 @@ public function addContainer($name, $label, array $options = [], $parent = '', $ } /** - * {@inheritdoc} + * @inheritdoc */ public function renameElement($oldName, $newName) { @@ -332,7 +344,7 @@ public function renameElement($oldName, $newName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAllBlocks() { @@ -340,7 +352,7 @@ public function getAllBlocks() } /** - * {@inheritdoc} + * @inheritdoc */ public function getBlock($name) { @@ -348,7 +360,7 @@ public function getBlock($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function getUiComponent($name) { @@ -356,7 +368,7 @@ public function getUiComponent($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function getParentName($childName) { @@ -364,7 +376,7 @@ public function getParentName($childName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getElementAlias($name) { @@ -372,7 +384,7 @@ public function getElementAlias($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function addOutputElement($name) { @@ -380,7 +392,7 @@ public function addOutputElement($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function removeOutputElement($name) { @@ -388,7 +400,7 @@ public function removeOutputElement($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function getOutput() { @@ -396,7 +408,7 @@ public function getOutput() } /** - * {@inheritdoc} + * @inheritdoc */ public function getMessagesBlock() { @@ -404,7 +416,7 @@ public function getMessagesBlock() } /** - * {@inheritdoc} + * @inheritdoc */ public function getBlockSingleton($type) { @@ -412,7 +424,7 @@ public function getBlockSingleton($type) } /** - * {@inheritdoc} + * @inheritdoc */ public function addAdjustableRenderer($namespace, $staticType, $dynamicType, $type, $template, $data = []) { @@ -427,7 +439,7 @@ public function addAdjustableRenderer($namespace, $staticType, $dynamicType, $ty } /** - * {@inheritdoc} + * @inheritdoc */ public function getRendererOptions($namespace, $staticType, $dynamicType) { @@ -435,7 +447,7 @@ public function getRendererOptions($namespace, $staticType, $dynamicType) } /** - * {@inheritdoc} + * @inheritdoc */ public function executeRenderer($namespace, $staticType, $dynamicType, $data = []) { @@ -443,7 +455,7 @@ public function executeRenderer($namespace, $staticType, $dynamicType, $data = [ } /** - * {@inheritdoc} + * @inheritdoc */ public function initMessages($messageGroups = []) { @@ -451,7 +463,7 @@ public function initMessages($messageGroups = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function isCacheable() { @@ -459,7 +471,7 @@ public function isCacheable() } /** - * {@inheritdoc} + * @inheritdoc */ public function isPrivate() { @@ -467,7 +479,7 @@ public function isPrivate() } /** - * {@inheritdoc} + * @inheritdoc */ public function setIsPrivate($isPrivate = true) { @@ -475,7 +487,7 @@ public function setIsPrivate($isPrivate = true) } /** - * {@inheritdoc} + * @inheritdoc */ public function getReaderContext() { @@ -483,7 +495,7 @@ public function getReaderContext() } /** - * {@inheritdoc} + * @inheritdoc */ public function setXml(\Magento\Framework\Simplexml\Element $node) { @@ -491,7 +503,7 @@ public function setXml(\Magento\Framework\Simplexml\Element $node) } /** - * {@inheritdoc} + * @inheritdoc */ public function getNode($path = null) { @@ -499,7 +511,7 @@ public function getNode($path = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function getXpath($xpath) { @@ -507,7 +519,7 @@ public function getXpath($xpath) } /** - * {@inheritdoc} + * @inheritdoc */ public function getXmlString() { @@ -515,7 +527,7 @@ public function getXmlString() } /** - * {@inheritdoc} + * @inheritdoc */ public function loadFile($filePath) { @@ -523,7 +535,7 @@ public function loadFile($filePath) } /** - * {@inheritdoc} + * @inheritdoc */ public function loadString($string) { @@ -531,7 +543,7 @@ public function loadString($string) } /** - * {@inheritdoc} + * @inheritdoc */ public function loadDom(\DOMNode $dom) { @@ -539,7 +551,7 @@ public function loadDom(\DOMNode $dom) } /** - * {@inheritdoc} + * @inheritdoc */ public function setNode($path, $value, $overwrite = true) { @@ -547,7 +559,7 @@ public function setNode($path, $value, $overwrite = true) } /** - * {@inheritdoc} + * @inheritdoc */ public function applyExtends() { @@ -555,7 +567,7 @@ public function applyExtends() } /** - * {@inheritdoc} + * @inheritdoc */ public function processFileData($text) { @@ -563,7 +575,7 @@ public function processFileData($text) } /** - * {@inheritdoc} + * @inheritdoc */ public function extend(\Magento\Framework\Simplexml\Config $config, $overwrite = true) { From e627992e01baf5e19b8fae76ed2b23f12fc8d5b2 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky Date: Wed, 27 Mar 2019 01:03:00 +0200 Subject: [PATCH 030/247] 530 - [Cart Operations] Update Cart Items validation messages 1. Add necessary tests --- .../CatalogInventory/AddProductToCartTest.php | 21 ++++++++++++++++++- .../Quote/AddSimpleProductToCartTest.php | 21 ++++++++++++++++++- .../Quote/Customer/UpdateCartItemsTest.php | 21 +++++++++++++++++++ .../Quote/Guest/UpdateCartItemsTest.php | 21 +++++++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/AddProductToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/AddProductToCartTest.php index 17c2af8dc59d..e41c6b4dfe3b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/AddProductToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/AddProductToCartTest.php @@ -78,6 +78,25 @@ public function testAddMoreProductsThatAllowed() self::fail('Should be "The most you may purchase is 5." error message.'); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/products.php + * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php + */ + public function testAddProductIfQuantityIsDecimal() + { + $sku = 'simple'; + $qty = 0.2; + + $maskedQuoteId = $this->getMaskedQuoteId(); + $query = $this->getAddSimpleProductQuery($maskedQuoteId, $sku, $qty); + + $this->expectExceptionMessage( + "Could not add the product with SKU {$sku} to the shopping cart: The fewest you may purchase is 1." + ); + + $this->graphQlQuery($query); + } + /** * @return string */ @@ -95,7 +114,7 @@ public function getMaskedQuoteId() : string * @param int $qty * @return string */ - public function getAddSimpleProductQuery(string $maskedQuoteId, string $sku, int $qty) : string + public function getAddSimpleProductQuery(string $maskedQuoteId, string $sku, float $qty) : string { return <<getMaskedQuoteId(); + + $query = $this->getAddSimpleProductQuery($maskedQuoteId, $sku, $qty); + + $this->expectExceptionMessage( + "Could not add the product with SKU {$sku} to the shopping cart: The fewest you may purchase is 1." + ); + + $this->graphQlQuery($query); + } + /** * @return string */ @@ -76,7 +95,7 @@ public function getMaskedQuoteId() : string * @param int $qty * @return string */ - public function getAddSimpleProductQuery(string $maskedQuoteId, string $sku, int $qty): string + public function getAddSimpleProductQuery(string $maskedQuoteId, string $sku, float $qty): string { return <<assertEquals($qty, $item['qty']); } + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testUpdateCartItemDecimalQty() + { + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, 'test_order_1', 'reserved_order_id'); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quote->getId()); + $product = $this->productRepository->get('simple'); + + $itemId = (int)$quote->getItemByProduct($product)->getId(); + $qty = 0.5; + + $this->expectExceptionMessage( + "Could not update the product with SKU " . $product->getSku() . ": The fewest you may purchase is 1." + ); + + $query = $this->getQuery($maskedQuoteId, $itemId, $qty); + $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + } + /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php */ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php index fca7a4287620..254d2560f899 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php @@ -72,6 +72,27 @@ public function testUpdateCartItemQty() $this->assertEquals($qty, $item['qty']); } + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testUpdateCartItemDecimalQty() + { + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, 'test_order_with_simple_product_without_address', 'reserved_order_id'); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quote->getId()); + $product = $this->productRepository->get('simple'); + + $itemId = (int)$quote->getItemByProduct($product)->getId(); + $qty = 0.5; + + $this->expectExceptionMessage( + "Could not update the product with SKU " . $product->getSku() . ": The fewest you may purchase is 1." + ); + + $query = $this->getQuery($maskedQuoteId, $itemId, $qty); + $this->graphQlQuery($query); + } + /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php */ From eec7473b6c774d72ab2d3e86495b43082face6f5 Mon Sep 17 00:00:00 2001 From: Vishal Sutariya Date: Wed, 27 Mar 2019 15:10:47 +0530 Subject: [PATCH 031/247] Fixed shipping method block alignment issue --- .../backend/Magento_Sales/web/css/source/module/_order.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less index fa1ae2562898..480fc57c1149 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less @@ -64,6 +64,7 @@ } .order-shipping-address, + .order-shipping-method, .order-totals, .order-view-account-information .order-account-information { float: right; From a1661a5effb01e5fcd3cdf846d3052d8ec8e642f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bajsarowicz?= Date: Sat, 30 Mar 2019 13:47:29 +0100 Subject: [PATCH 032/247] #22047 Add Transaction name to NewRelic based on Command name --- .../Model/NewRelicWrapper.php | 15 ++++++- .../Plugin/CommandPlugin.php | 44 +++++++++++++++++++ app/code/Magento/NewRelicReporting/etc/di.xml | 3 ++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php diff --git a/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php b/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php index 9882a1ce9b0b..c37d3bcd2bba 100644 --- a/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php +++ b/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php @@ -49,7 +49,7 @@ public function reportError($exception) */ public function setAppName(string $appName) { - if (extension_loaded('newrelic')) { + if ($this->isExtensionInstalled()) { newrelic_set_appname($appName); } } @@ -66,4 +66,17 @@ public function isExtensionInstalled() } return false; } + + /** + * Wrapper for 'newrelic_name_transaction' + * + * @param string $transactionName + * @return void + */ + public function setTransactionName(string $transactionName): void + { + if ($this->isExtensionInstalled()) { + newrelic_name_transaction($transactionName); + } + } } diff --git a/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php b/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php new file mode 100644 index 000000000000..1d24ed609bef --- /dev/null +++ b/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php @@ -0,0 +1,44 @@ +config = $config; + $this->newRelicWrapper = $newRelicWrapper; + } + + public function beforeRun(\Symfony\Component\Console\Command\Command $command, ...$args) + { + $this->newRelicWrapper->setTransactionName( + sprintf('CLI %s', $command->getName()) + ); + + return $args; + } +} diff --git a/app/code/Magento/NewRelicReporting/etc/di.xml b/app/code/Magento/NewRelicReporting/etc/di.xml index bab7d6611f14..15516f6df89b 100644 --- a/app/code/Magento/NewRelicReporting/etc/di.xml +++ b/app/code/Magento/NewRelicReporting/etc/di.xml @@ -40,4 +40,7 @@ + + + From 07f8a65073331732f511c61fb66954365e2ada11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bajsarowicz?= Date: Sat, 30 Mar 2019 13:47:54 +0100 Subject: [PATCH 033/247] Remove unused `use` section --- app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php b/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php index 1d24ed609bef..065455e2a27c 100644 --- a/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php +++ b/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php @@ -5,7 +5,6 @@ */ namespace Magento\NewRelicReporting\Plugin; -use Magento\Framework\Exception\LocalizedException; use Magento\NewRelicReporting\Model\Config; use Magento\NewRelicReporting\Model\NewRelicWrapper; From 638b73a514788822c19d8506763f79c0ac5a70b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bajsarowicz?= Date: Sat, 30 Mar 2019 13:50:23 +0100 Subject: [PATCH 034/247] Cleanup for Wrapper --- .../Model/NewRelicWrapper.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php b/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php index c37d3bcd2bba..bce42b4e9007 100644 --- a/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php +++ b/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php @@ -21,7 +21,7 @@ class NewRelicWrapper */ public function addCustomParameter($param, $value) { - if (extension_loaded('newrelic')) { + if ($this->isExtensionInstalled()) { newrelic_add_custom_parameter($param, $value); return true; } @@ -36,7 +36,7 @@ public function addCustomParameter($param, $value) */ public function reportError($exception) { - if (extension_loaded('newrelic')) { + if ($this->isExtensionInstalled()) { newrelic_notice_error($exception->getMessage(), $exception); } } @@ -55,28 +55,28 @@ public function setAppName(string $appName) } /** - * Checks whether newrelic-php5 agent is installed + * Wrapper for 'newrelic_name_transaction' * - * @return bool + * @param string $transactionName + * @return void */ - public function isExtensionInstalled() + public function setTransactionName(string $transactionName): void { - if (extension_loaded('newrelic')) { - return true; + if ($this->isExtensionInstalled()) { + newrelic_name_transaction($transactionName); } - return false; } /** - * Wrapper for 'newrelic_name_transaction' + * Checks whether newrelic-php5 agent is installed * - * @param string $transactionName - * @return void + * @return bool */ - public function setTransactionName(string $transactionName): void + public function isExtensionInstalled() { - if ($this->isExtensionInstalled()) { - newrelic_name_transaction($transactionName); + if (extension_loaded('newrelic')) { + return true; } + return false; } } From f3d4d9611fdbbec3c4eddca917e86e3fae272f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= Date: Mon, 1 Apr 2019 10:27:38 +0200 Subject: [PATCH 035/247] changes due to backword compatiblity constraints --- .../Magento/Framework/Validator/Factory.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Validator/Factory.php b/lib/internal/Magento/Framework/Validator/Factory.php index 198f4fb6730f..87c29dd6681c 100644 --- a/lib/internal/Magento/Framework/Validator/Factory.php +++ b/lib/internal/Magento/Framework/Validator/Factory.php @@ -10,12 +10,20 @@ use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Phrase; use Magento\Framework\Validator; +use Magento\Framework\Cache\FrontendInterface; /** * Factory for \Magento\Framework\Validator and \Magento\Framework\Validator\Builder. */ class Factory { + /** + * cache key + * + * @deprecated + */ + const CACHE_KEY = __CLASS__; + /** * @var ObjectManagerInterface */ @@ -26,7 +34,7 @@ class Factory * * @var iterable|null */ - protected $_configFiles; + protected $_configFiles = null; /** * @var bool @@ -43,10 +51,12 @@ class Factory * * @param ObjectManagerInterface $objectManager * @param Reader $moduleReader + * @param FrontendInterface $cache @deprecated */ public function __construct( ObjectManagerInterface $objectManager, - Reader $moduleReader + Reader $moduleReader, + FrontendInterface $cache ) { $this->_objectManager = $objectManager; $this->moduleReader = $moduleReader; From 2784faa16967ce107e60ad08da367635475aad5d Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 1 Apr 2019 18:06:00 -0500 Subject: [PATCH 036/247] Issue-230: implementing builtin cache --- .htaccess | 2 +- .../Magento/GraphQl/Controller/GraphQl.php | 38 +++++++++---------- .../Controller/GraphQl/Plugin.php | 4 +- .../Magento/GraphQlCache/etc/graphql/di.xml | 15 ++++++-- .../Model/Controller/Result/BuiltinPlugin.php | 4 +- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/.htaccess b/.htaccess index d22b5a1395ca..ecf0ac778dfa 100644 --- a/.htaccess +++ b/.htaccess @@ -2,7 +2,7 @@ ## overrides deployment configuration mode value ## use command bin/magento deploy:mode:set to switch modes -# SetEnv MAGE_MODE developer + SetEnv MAGE_MODE developer ############################################ ## uncomment these lines for CGI mode diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index d28535e45ac0..f374c29e24a5 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -17,8 +17,9 @@ use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\SchemaGeneratorInterface; use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Webapi\Response; +use Magento\Framework\Controller\ResultInterface; use Magento\Framework\GraphQl\Query\Fields as QueryFields; +use Magento\Framework\Controller\Result\JsonFactory; /** * Front controller for web API GraphQL area. @@ -27,11 +28,6 @@ */ class GraphQl implements FrontControllerInterface { - /** - * @var Response - */ - private $response; - /** * @var SchemaGeneratorInterface */ @@ -68,7 +64,11 @@ class GraphQl implements FrontControllerInterface private $queryFields; /** - * @param Response $response + * @var JsonFactory + */ + private $jsonFactory; + + /** * @param SchemaGeneratorInterface $schemaGenerator * @param SerializerInterface $jsonSerializer * @param QueryProcessor $queryProcessor @@ -76,18 +76,18 @@ class GraphQl implements FrontControllerInterface * @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $resolverContext * @param HttpRequestProcessor $requestProcessor * @param QueryFields $queryFields + * @param JsonFactory $jsonFactory */ public function __construct( - Response $response, SchemaGeneratorInterface $schemaGenerator, SerializerInterface $jsonSerializer, QueryProcessor $queryProcessor, ExceptionFormatter $graphQlError, ContextInterface $resolverContext, HttpRequestProcessor $requestProcessor, - QueryFields $queryFields + QueryFields $queryFields, + JsonFactory $jsonFactory ) { - $this->response = $response; $this->schemaGenerator = $schemaGenerator; $this->jsonSerializer = $jsonSerializer; $this->queryProcessor = $queryProcessor; @@ -95,17 +95,19 @@ public function __construct( $this->resolverContext = $resolverContext; $this->requestProcessor = $requestProcessor; $this->queryFields = $queryFields; + $this->jsonFactory = $jsonFactory; } + /** * Handle GraphQL request * * @param RequestInterface $request - * @return ResponseInterface + * @return ResponseInterface|ResultInterface */ - public function dispatch(RequestInterface $request) : ResponseInterface + public function dispatch(RequestInterface $request) /* : ResponseInterface */ { - $statusCode = 200; + $jsonResult = $this->jsonFactory->create(); try { /** @var Http $request */ $this->requestProcessor->processHeaders($request); @@ -140,12 +142,10 @@ public function dispatch(RequestInterface $request) : ResponseInterface } catch (\Exception $error) { $result['errors'] = isset($result) && isset($result['errors']) ? $result['errors'] : []; $result['errors'][] = $this->graphQlError->create($error); - $statusCode = ExceptionFormatter::HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS; + $jsonResult->setHttpResponseCode(ExceptionFormatter::HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS); } - $this->response->setBody($this->jsonSerializer->serialize($result))->setHeader( - 'Content-Type', - 'application/json' - )->setHttpResponseCode($statusCode); - return $this->response; + + $jsonResult->setData($result); + return $jsonResult; } } diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index 582fa93e5532..a4832f262f55 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -37,11 +37,11 @@ public function __construct(CacheTags $cacheTags, AppState $state) public function afterDispatch( FrontControllerInterface $subject, - ResponseInterface $response, + /* \Magento\Framework\App\Response\Http */ $response, RequestInterface $request ) { /** @var \Magento\Framework\App\Request\Http $request */ - /** @var \Magento\Framework\Webapi\Response $response */ + /** @var \Magento\Framework\App\Response\Http $response */ $cacheTags = $this->cacheTags->getCacheTags(); if ($request->isGet() && count($cacheTags)) { // assume that response should be cacheable if it contains cache tags diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml index 6007bdd173aa..93ed92066aaf 100644 --- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -8,12 +8,21 @@ + + - - + + + + + + + + + + diff --git a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php index aadae97009ca..871bc511d290 100644 --- a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php +++ b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php @@ -87,8 +87,8 @@ public function afterRenderResult(ResultInterface $subject, ResultInterface $res $tags = []; if ($tagsHeader) { - $tags = explode(',', $tagsHeader->getFieldValue()); - $response->clearHeader('X-Magento-Tags'); + //$tags = explode(',', $tagsHeader->getFieldValue()); + //$response->clearHeader('X-Magento-Tags'); } $tags = array_unique(array_merge($tags, [CacheType::CACHE_TAG])); From 6ba9defd1a7d4789959ef07c88211bbe680bd33e Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 1 Apr 2019 18:07:36 -0500 Subject: [PATCH 037/247] Issue-230: reverting dev mode in htaccess --- .htaccess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index ecf0ac778dfa..d22b5a1395ca 100644 --- a/.htaccess +++ b/.htaccess @@ -2,7 +2,7 @@ ## overrides deployment configuration mode value ## use command bin/magento deploy:mode:set to switch modes - SetEnv MAGE_MODE developer +# SetEnv MAGE_MODE developer ############################################ ## uncomment these lines for CGI mode From 716e27cd100c70f76cc905eb62543692b79ddfe8 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 2 Apr 2019 11:25:51 -0500 Subject: [PATCH 038/247] Issue-230: adding varnish --- app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php | 2 +- app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php | 3 +++ app/code/Magento/GraphQlCache/etc/graphql/di.xml | 4 ++-- .../PageCache/Model/Controller/Result/BuiltinPlugin.php | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index a4832f262f55..fc7170619e79 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -43,7 +43,7 @@ public function afterDispatch( /** @var \Magento\Framework\App\Request\Http $request */ /** @var \Magento\Framework\App\Response\Http $response */ $cacheTags = $this->cacheTags->getCacheTags(); - if ($request->isGet() && count($cacheTags)) { + if (count($cacheTags)) { // assume that response should be cacheable if it contains cache tags $response->setHeader('Pragma', 'cache', true); // TODO: Take from configuration diff --git a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php index 65b05bf71da0..ba8b7ecf8b16 100644 --- a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php +++ b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php @@ -27,6 +27,9 @@ public function __construct(CacheTags $cacheTags) $this->cacheTags = $cacheTags; } + /** + * @inheritdoc + */ public function afterResolve( ResolverInterface $subject, $resolvedValue, diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml index 93ed92066aaf..ae403e0c56ba 100644 --- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -9,7 +9,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php index 871bc511d290..aadae97009ca 100644 --- a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php +++ b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php @@ -87,8 +87,8 @@ public function afterRenderResult(ResultInterface $subject, ResultInterface $res $tags = []; if ($tagsHeader) { - //$tags = explode(',', $tagsHeader->getFieldValue()); - //$response->clearHeader('X-Magento-Tags'); + $tags = explode(',', $tagsHeader->getFieldValue()); + $response->clearHeader('X-Magento-Tags'); } $tags = array_unique(array_merge($tags, [CacheType::CACHE_TAG])); From 0f4a75d7c7521bf51adcdacc2284c0f4ede5ff78 Mon Sep 17 00:00:00 2001 From: pganapat Date: Tue, 2 Apr 2019 11:45:27 -0500 Subject: [PATCH 039/247] 230: Implement cache tag generation for GraphQL queries - Modified schema stitcher to parse CacheTags from graphql schema - Modified Graphql plugin to gather resolved item ids - Validated the requests to be cached --- .../CatalogGraphQl/etc/schema.graphqls | 12 ++--- .../Controller/GraphQl/Plugin.php | 15 ++++++ .../GraphQlCache/Query/Resolver/Plugin.php | 47 ++++++++++++++++--- .../GraphQl/Config/Element/Field.php | 18 +++++++ .../GraphQl/Config/Element/FieldFactory.php | 10 +++- .../MetaReader/CacheTagReader.php | 34 ++++++++++++++ .../MetaReader/FieldMetaReader.php | 23 +++++++-- .../GraphQlReader/Reader/InputObjectType.php | 21 ++++++++- .../GraphQlReader/Reader/InterfaceType.php | 22 +++++++-- .../GraphQlReader/Reader/ObjectType.php | 19 +++++++- 10 files changed, 195 insertions(+), 26 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index f86ecea9e075..11e447621eba 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -9,11 +9,11 @@ type Query { currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @cache(tag: "cat_p") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The test products query searches for products that match the criteria specified in the search and filter attributes") @cacheable(cache_tag: "cat_p") category ( id: Int @doc(description: "Id of the category") ): CategoryTree - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The test products query searches for products that match the criteria specified in the search and filter attributes") @cacheable(cache_tag: "cat_c") } enum CurrencyEnum @doc(description: "The list of available currency codes") { @@ -244,7 +244,7 @@ type ProductTierPrices @doc(description: "The ProductTierPrices object defines a website_id: Float @doc(description: "The ID assigned to the website") } -interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "The ProductInterface contains attributes that are common to all types of products. Note that descriptions may not be available for custom and EAV attributes.") { +interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "The ProductInterface contains attributes that are common to all types of products. Note that descriptions may not be available for custom and EAV attributes.") @cacheable(cache_tag: "cat_p") { id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") @@ -378,9 +378,9 @@ interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGra options: [CustomizableOptionInterface] @doc(description: "An array of options for a customizable product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Options") } -interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CategoryInterfaceTypeResolver") @doc(description: "CategoryInterface contains the full set of attributes that can be returned in a category search") { +interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CategoryInterfaceTypeResolver") @cacheable(cache_tag: "cat_c") @doc(description: "CategoryInterface contains the full set of attributes that can be returned in a category search") { id: Int @doc(description: "An ID that uniquely identifies the category") - description: String @doc(description: "An optional description of the category") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryHtmlAttribute") + description: String @doc(description: "An optional description ofm the category") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryHtmlAttribute") name: String @doc(description: "The display name of the category") path: String @doc(description: "Category Path") path_in_store: String @doc(description: "Category path in store") @@ -396,7 +396,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + ): CategoryProducts @cacheable(cache_tag: "cat_p") @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index fc7170619e79..dc893322a609 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -13,6 +13,11 @@ use Magento\GraphQlCache\Model\CacheTags; use Magento\Framework\App\State as AppState; +/** + * Class Plugin + + * @package Magento\GraphQlCache\Controller\GraphQl + */ class Plugin { /** @@ -26,6 +31,8 @@ class Plugin private $state; /** + * Constructor + * * @param CacheTags $cacheTags * @param AppState $state */ @@ -35,6 +42,14 @@ public function __construct(CacheTags $cacheTags, AppState $state) $this->state = $state; } + /** + * Plugin for GraphQL Controller + * + * @param FrontControllerInterface $subject + * @param ResponseInterface $response + * @param RequestInterface $request + * @return ResponseInterface|\Magento\Framework\Webapi\Response + */ public function afterDispatch( FrontControllerInterface $subject, /* \Magento\Framework\App\Response\Http */ $response, diff --git a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php index ba8b7ecf8b16..c6a9ebb9180c 100644 --- a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php +++ b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php @@ -10,8 +10,15 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\GraphQl\Model\Query\Resolver\Context; use Magento\GraphQlCache\Model\CacheTags; +use Magento\Framework\App\RequestInterface; +/** + * Class Plugin + * + * @package Magento\GraphQlCache\Query\Resolver + */ class Plugin { /** @@ -20,15 +27,33 @@ class Plugin private $cacheTags; /** + * @var Request + */ + private $request; + + /** + * Constructor + * * @param CacheTags $cacheTags + * @param RequestInterface $request */ - public function __construct(CacheTags $cacheTags) + public function __construct(CacheTags $cacheTags, RequestInterface $request) { $this->cacheTags = $cacheTags; + $this->request = $request; } /** * @inheritdoc + * + * @param ResolverInterface $subject + * @param Object $resolvedValue + * @param Field $field + * @param Context $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @return mixed */ public function afterResolve( ResolverInterface $subject, @@ -39,12 +64,8 @@ public function afterResolve( array $value = null, array $args = null ) { - if ($field->getName() == 'products') { - // TODO: Read cache tag value from the GraphQL schema and make it accessible via $field - $cacheTag = 'cat_p'; - } - // TODO: Can be optimized to avoid tags calculation for POST requests - if (!empty($cacheTag)) { + $cacheTag = $field->getCacheTag(); + if (!empty($cacheTag) && $this->request->isGet()) { $cacheTags = [$cacheTag]; // Resolved value must have cache IDs defined $resolvedItemsIds = $this->extractResolvedItemsIds($resolvedValue); @@ -56,6 +77,12 @@ public function afterResolve( return $resolvedValue; } + /** + * Extract ids for resolved items + * + * @param Object $resolvedValue + * @return array + */ private function extractResolvedItemsIds($resolvedValue) { // TODO: Implement safety checks and think about additional places which can hold items IDs @@ -66,6 +93,11 @@ private function extractResolvedItemsIds($resolvedValue) return array_keys($resolvedValue['items']); } $ids = []; + if (isset($resolvedValue['id'])) { + $ids[] = $resolvedValue['id']; + return $ids; + } + if (is_array($resolvedValue)) { foreach ($resolvedValue as $item) { if (isset($item['id'])) { @@ -73,5 +105,6 @@ private function extractResolvedItemsIds($resolvedValue) } } } + return $ids; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php index 76cfa06f9c11..907b43424f08 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php @@ -48,6 +48,11 @@ class Field implements OutputFieldInterface */ private $description; + /** + * @var string + */ + private $cacheTag; + /** * @param string $name * @param string $type @@ -56,6 +61,7 @@ class Field implements OutputFieldInterface * @param string $itemType * @param string $resolver * @param string $description + * @param string $cacheTag * @param array $arguments */ public function __construct( @@ -66,6 +72,7 @@ public function __construct( string $itemType = '', string $resolver = '', string $description = '', + string $cacheTag = '', array $arguments = [] ) { $this->name = $name; @@ -75,6 +82,7 @@ public function __construct( $this->resolver = $resolver; $this->description = $description; $this->arguments = $arguments; + $this->cacheTag = $cacheTag; } /** @@ -146,4 +154,14 @@ public function getDescription() : string { return $this->description; } + + /** + * Return the cache tag for the field. + * + * @return string|null + */ + public function getCacheTag() : string + { + return $this->cacheTag; + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php index b9ec1dd87d12..70805f2b51ba 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php @@ -52,6 +52,13 @@ public function createFromConfigData( $fieldData['itemType'] = str_replace('[]', '', $fieldData['type']); } + if (isset($fieldData['description'])) { + if ($fieldData['description'] == "The list of products assigned to the category") { + $fieldType = $fieldData['type']; + } + } + + return $this->objectManager->create( Field::class, [ @@ -62,7 +69,8 @@ public function createFromConfigData( 'itemType' => isset($fieldData['itemType']) ? $fieldData['itemType'] : '', 'resolver' => isset($fieldData['resolver']) ? $fieldData['resolver'] : '', 'description' => isset($fieldData['description']) ? $fieldData['description'] : '', - 'arguments' => $arguments + 'cacheTag' => isset($fieldData['cacheable']) ? $fieldData['cacheable'] : false, + 'arguments' => $arguments, ] ); } diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php new file mode 100644 index 000000000000..b2141a7ec8b9 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php @@ -0,0 +1,34 @@ +name->value == 'cacheable') { + foreach ($directive->arguments as $directiveArgument) { + if ($directiveArgument->name->value == 'cache_tag') { + return $directiveArgument->value->value; + } + } + } + } + return ''; + } +} diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php index 736a94471100..e916aae5ddfc 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php @@ -7,8 +7,6 @@ namespace Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader; -use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\TypeMetaWrapperReader; - /** * Reads fields and possible arguments from a meta field */ @@ -25,13 +23,24 @@ class FieldMetaReader private $docReader; /** - * @param TypeMetaWrapperReader $typeMetaReader + * @var CacheTagReader + */ + private $cacheTagReader; + + /** + * FieldMetaReader constructor. + * @param \Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\TypeMetaWrapperReader $typeMetaReader * @param DocReader $docReader + * @param CacheTagReader $cacheTagReader */ - public function __construct(TypeMetaWrapperReader $typeMetaReader, DocReader $docReader) - { + public function __construct( + TypeMetaWrapperReader $typeMetaReader, + DocReader $docReader, + CacheTagReader $cacheTagReader + ) { $this->typeMetaReader = $typeMetaReader; $this->docReader = $docReader; + $this->cacheTagReader = $cacheTagReader; } /** @@ -63,6 +72,10 @@ public function read(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : arra $result['description'] = $this->docReader->read($fieldMeta->astNode->directives); } + if ($this->docReader->read($fieldMeta->astNode->directives)) { + $result['cacheable'] = $this->cacheTagReader->read($fieldMeta->astNode->directives); + } + $arguments = $fieldMeta->args; foreach ($arguments as $argumentMeta) { $argumentName = $argumentMeta->name; diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php index 3aea555e67f9..94326b894669 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php @@ -10,6 +10,8 @@ use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\TypeMetaReaderInterface; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\TypeMetaWrapperReader; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\CacheTagReader; + /** * Composite configuration reader to handle the input object type meta @@ -27,13 +29,24 @@ class InputObjectType implements TypeMetaReaderInterface private $docReader; /** + * @var CacheTagReader + */ + private $cacheTagReader; + + /** + * InputObjectType constructor. * @param TypeMetaWrapperReader $typeMetaReader * @param DocReader $docReader + * @param CacheTagReader $cacheTagReader */ - public function __construct(TypeMetaWrapperReader $typeMetaReader, DocReader $docReader) - { + public function __construct( + TypeMetaWrapperReader $typeMetaReader, + DocReader $docReader, + CacheTagReader $cacheTagReader + ) { $this->typeMetaReader = $typeMetaReader; $this->docReader = $docReader; + $this->cacheTagReader = $cacheTagReader; } /** @@ -56,6 +69,10 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array if ($this->docReader->read($typeMeta->astNode->directives)) { $result['description'] = $this->docReader->read($typeMeta->astNode->directives); } + + if ($this->docReader->read($typeMeta->astNode->directives)) { + $result['cacheable'] = $this->cacheTagReader->read($typeMeta->astNode->directives); + } return $result; } else { return []; diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php index dd934ffebc2c..bc1a65440ca0 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php @@ -10,6 +10,7 @@ use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\TypeMetaReaderInterface; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\FieldMetaReader; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\DocReader; +use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\CacheTagReader; /** * Composite configuration reader to handle the interface object type meta @@ -27,17 +28,28 @@ class InterfaceType implements TypeMetaReaderInterface private $docReader; /** + * @var CacheTagReader + */ + private $cacheTagReader; + + /** + * InterfaceType constructor. * @param FieldMetaReader $fieldMetaReader * @param DocReader $docReader + * @param CacheTagReader $cacheTagReader */ - public function __construct(FieldMetaReader $fieldMetaReader, DocReader $docReader) - { + public function __construct( + FieldMetaReader $fieldMetaReader, + DocReader $docReader, + CacheTagReader $cacheTagReader + ) { $this->fieldMetaReader = $fieldMetaReader; $this->docReader = $docReader; + $this->cacheTagReader = $cacheTagReader; } /** - * {@inheritdoc} + * @inheritdoc */ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array { @@ -63,6 +75,10 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array $result['description'] = $this->docReader->read($typeMeta->astNode->directives); } + if ($this->docReader->read($typeMeta->astNode->directives)) { + $result['cacheable'] = $this->cacheTagReader->read($typeMeta->astNode->directives); + } + return $result; } else { return []; diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php index fb015922087b..cf0545a21c4c 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php @@ -11,6 +11,8 @@ use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\FieldMetaReader; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\DocReader; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\ImplementsReader; +use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\CacheTagReader; + /** * Composite configuration reader to handle the object type meta @@ -33,22 +35,31 @@ class ObjectType implements TypeMetaReaderInterface private $implementsAnnotation; /** + * @var CacheTagReader + */ + private $cacheTagReader; + + /** + * ObjectType constructor. * @param FieldMetaReader $fieldMetaReader * @param DocReader $docReader * @param ImplementsReader $implementsAnnotation + * @param CacheTagReader $cacheTagReader */ public function __construct( FieldMetaReader $fieldMetaReader, DocReader $docReader, - ImplementsReader $implementsAnnotation + ImplementsReader $implementsAnnotation, + CacheTagReader $cacheTagReader ) { $this->fieldMetaReader = $fieldMetaReader; $this->docReader = $docReader; $this->implementsAnnotation = $implementsAnnotation; + $this->cacheTagReader = $cacheTagReader; } /** - * {@inheritdoc} + * @inheritdoc */ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array { @@ -77,6 +88,10 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array $result['description'] = $this->docReader->read($typeMeta->astNode->directives); } + if ($this->docReader->read($typeMeta->astNode->directives)) { + $result['cacheable'] = $this->cacheTagReader->read($typeMeta->astNode->directives); + } + return $result; } else { return []; From 0cf8e69f56fc1a43c50c3e64a177b0960969d221 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 2 Apr 2019 16:49:53 -0500 Subject: [PATCH 040/247] Issue-230: refactor builtin cache to support store context --- .../HttpHeaderProcessor/StoreProcessor.php | 32 ++++++++-- .../Controller/GraphQl/Plugin.php | 61 ++++++++++--------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index e92ff374eb35..3571a7588d11 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -11,6 +11,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpHeaderProcessorInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\App\Http\Context as HttpContext; /** * Process the "Store" header entry @@ -23,13 +24,20 @@ class StoreProcessor implements HttpHeaderProcessorInterface private $storeManager; /** - * StoreProcessor constructor. - * + * @var HttpContext + */ + private $httpContext; + + /** * @param StoreManagerInterface $storeManager + * @param HttpContext $httpContext */ - public function __construct(StoreManagerInterface $storeManager) - { + public function __construct( + StoreManagerInterface $storeManager, + HttpContext $httpContext + ) { $this->storeManager = $storeManager; + $this->httpContext = $httpContext; } /** @@ -45,6 +53,7 @@ public function processHeaderValue(string $headerValue, HttpRequestInterface $re $stores = $this->storeManager->getStores(false, true); if (isset($stores[$storeCode])) { $this->storeManager->setCurrentStore($storeCode); + $this->updateContext($storeCode); } elseif (strtolower($storeCode) !== 'default') { throw new GraphQlInputException( new \Magento\Framework\Phrase('Store code %1 does not exist', [$storeCode]) @@ -52,4 +61,19 @@ public function processHeaderValue(string $headerValue, HttpRequestInterface $re } } } + + /** + * Update context accordingly to the store code found. + * + * @param string $store + * @return void + */ + private function updateContext(string $storeCode) : void + { + $this->httpContext->setValue( + StoreManagerInterface::CONTEXT_STORE, + $storeCode, + $this->storeManager->getDefaultStoreView()->getCode() + ); + } } diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index dc893322a609..151e044c32be 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -10,13 +10,13 @@ use Magento\Framework\App\FrontControllerInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\Http as HttpResponse; +use Magento\Framework\Controller\ResultInterface; use Magento\GraphQlCache\Model\CacheTags; -use Magento\Framework\App\State as AppState; +use Magento\PageCache\Model\Config; /** * Class Plugin - - * @package Magento\GraphQlCache\Controller\GraphQl */ class Plugin { @@ -26,48 +26,53 @@ class Plugin private $cacheTags; /** - * @var AppState + * @var Config */ - private $state; + private $config; + + /** + * @var HttpResponse + */ + private $response; /** - * Constructor - * * @param CacheTags $cacheTags - * @param AppState $state + * @param Config $config + * @param HttpResponse $response */ - public function __construct(CacheTags $cacheTags, AppState $state) - { + public function __construct( + CacheTags $cacheTags, + Config $config, + HttpResponse $response + ) { $this->cacheTags = $cacheTags; - $this->state = $state; + $this->config = $config; + $this->response = $response; } /** - * Plugin for GraphQL Controller + * Plugin for GraphQL after dispatch to set tag and cache headers + * + * The $response doesn't have a set type because it's alternating between ResponseInterface and ResultInterface. * * @param FrontControllerInterface $subject - * @param ResponseInterface $response + * @param ResponseInterface | ResultInterface $response * @param RequestInterface $request - * @return ResponseInterface|\Magento\Framework\Webapi\Response + * @return ResponseInterface | ResultInterface + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterDispatch( FrontControllerInterface $subject, - /* \Magento\Framework\App\Response\Http */ $response, + $response, RequestInterface $request ) { - /** @var \Magento\Framework\App\Request\Http $request */ - /** @var \Magento\Framework\App\Response\Http $response */ - $cacheTags = $this->cacheTags->getCacheTags(); - if (count($cacheTags)) { - // assume that response should be cacheable if it contains cache tags - $response->setHeader('Pragma', 'cache', true); - // TODO: Take from configuration - $response->setHeader('Cache-Control', 'max-age=86400, public, s-maxage=86400', true); - $response->setHeader('X-Magento-Tags', implode(',', $cacheTags), true); - } - - if ($request->isGet() && $this->state->getMode() == AppState::MODE_DEVELOPER) { - $response->setHeader('X-Magento-Debug', 1); + if ($this->config->isEnabled()) { + $this->response->setPublicHeaders($this->config->getTtl()); + $cacheTags = $this->cacheTags->getCacheTags(); + if (!empty($cacheTags)) { + // assume that response should be cacheable if it contains cache tags + $this->response->setHeader('X-Magento-Tags', implode(',', $cacheTags), true); + } } return $response; From 2022307ea1cb8b0310ced73026ac2a10e4910bdc Mon Sep 17 00:00:00 2001 From: Yuriy Date: Wed, 3 Apr 2019 15:00:10 +0300 Subject: [PATCH 041/247] Error on design configuration save with imageUploader form element populated from gallery #21032 --- app/code/Magento/Theme/Model/Design/Backend/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Theme/Model/Design/Backend/File.php b/app/code/Magento/Theme/Model/Design/Backend/File.php index 511fe30f79dc..037434b1c526 100644 --- a/app/code/Magento/Theme/Model/Design/Backend/File.php +++ b/app/code/Magento/Theme/Model/Design/Backend/File.php @@ -237,7 +237,7 @@ private function getMime() */ private function getRelativeMediaPath(string $path): string { - return str_replace('/pub/media/', '', $path); + return preg_replace('/\/(pub\/)?media\//', '', $path); } /** From 887001d4b731f9cd1f326cfed056657df7e475ca Mon Sep 17 00:00:00 2001 From: Shikha Mishra Date: Thu, 4 Apr 2019 00:15:57 +0530 Subject: [PATCH 042/247] Added Confirmation field in customer form --- .../Customer/Model/Customer/DataProviderWithDefaultAddresses.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/Customer/DataProviderWithDefaultAddresses.php b/app/code/Magento/Customer/Model/Customer/DataProviderWithDefaultAddresses.php index 4d1bb2e6b9e9..07b8681df91a 100644 --- a/app/code/Magento/Customer/Model/Customer/DataProviderWithDefaultAddresses.php +++ b/app/code/Magento/Customer/Model/Customer/DataProviderWithDefaultAddresses.php @@ -39,7 +39,6 @@ class DataProviderWithDefaultAddresses extends \Magento\Ui\DataProvider\Abstract private static $forbiddenCustomerFields = [ 'password_hash', 'rp_token', - 'confirmation', ]; /** From 4c04f5513ce93072c4fca53ebd99d2dac94b28fd Mon Sep 17 00:00:00 2001 From: Shikha Mishra Date: Thu, 4 Apr 2019 00:18:19 +0530 Subject: [PATCH 043/247] Fixed #22052 Customer account confirmation is overwritten by backend customer save --- .../Customer/view/base/ui_component/customer_form.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml index 7e6b7bbe9cd0..e87997dbdb5e 100644 --- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -74,6 +74,17 @@ false + + + + customer + + + + text + false + + From 8d33059afbfe9cf2204722928c35320614b0c649 Mon Sep 17 00:00:00 2001 From: pganapat Date: Wed, 3 Apr 2019 14:00:38 -0500 Subject: [PATCH 044/247] 230: Implement cache tag generation for GraphQL queries - Used @cache to parse cache tags - Fetched ttl from config - Refactoring --- .../CatalogGraphQl/etc/schema.graphqls | 14 ++-- .../Controller/GraphQl/Plugin.php | 50 +++++++++----- .../Magento/GraphQlCache/Model/CacheInfo.php | 67 +++++++++++++++++++ .../Magento/GraphQlCache/Model/CacheTags.php | 36 ---------- .../GraphQlCache/Query/Resolver/Plugin.php | 33 ++++++--- .../GraphQl/Config/Element/Field.php | 16 ++--- .../GraphQl/Config/Element/FieldFactory.php | 2 +- .../MetaReader/CacheTagReader.php | 20 ++++-- .../MetaReader/FieldMetaReader.php | 2 +- .../GraphQlReader/Reader/InputObjectType.php | 2 +- .../GraphQlReader/Reader/InterfaceType.php | 2 +- .../GraphQlReader/Reader/ObjectType.php | 2 +- 12 files changed, 159 insertions(+), 87 deletions(-) create mode 100644 app/code/Magento/GraphQlCache/Model/CacheInfo.php delete mode 100644 app/code/Magento/GraphQlCache/Model/CacheTags.php diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 11e447621eba..8b74e5cc2cd7 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -9,11 +9,11 @@ type Query { currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The test products query searches for products that match the criteria specified in the search and filter attributes") @cacheable(cache_tag: "cat_p") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_p", cacheable: true) category ( id: Int @doc(description: "Id of the category") ): CategoryTree - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The test products query searches for products that match the criteria specified in the search and filter attributes") @cacheable(cache_tag: "cat_c") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_c", cacheable: true) } enum CurrencyEnum @doc(description: "The list of available currency codes") { @@ -244,7 +244,7 @@ type ProductTierPrices @doc(description: "The ProductTierPrices object defines a website_id: Float @doc(description: "The ID assigned to the website") } -interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "The ProductInterface contains attributes that are common to all types of products. Note that descriptions may not be available for custom and EAV attributes.") @cacheable(cache_tag: "cat_p") { +interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "The ProductInterface contains attributes that are common to all types of products. Note that descriptions may not be available for custom and EAV attributes.") { id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") @@ -275,7 +275,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") manufacturer: Int @doc(description: "A number representing the product's manufacturer") - categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") + categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @cache(cache_tag: "cat_c", cacheable: true) @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl") } @@ -378,9 +378,9 @@ interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGra options: [CustomizableOptionInterface] @doc(description: "An array of options for a customizable product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Options") } -interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CategoryInterfaceTypeResolver") @cacheable(cache_tag: "cat_c") @doc(description: "CategoryInterface contains the full set of attributes that can be returned in a category search") { +interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CategoryInterfaceTypeResolver") @doc(description: "CategoryInterface contains the full set of attributes that can be returned in a category search") { id: Int @doc(description: "An ID that uniquely identifies the category") - description: String @doc(description: "An optional description ofm the category") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryHtmlAttribute") + description: String @doc(description: "An optional description of the category") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryHtmlAttribute") name: String @doc(description: "The display name of the category") path: String @doc(description: "Category Path") path_in_store: String @doc(description: "Category path in store") @@ -396,7 +396,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @cacheable(cache_tag: "cat_p") @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + ): CategoryProducts @doc(description: "The list of products assigned to the category") @cache(cache_tag: "cat_p", cacheable: true) @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index dc893322a609..0770aead7289 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -10,20 +10,23 @@ use Magento\Framework\App\FrontControllerInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; -use Magento\GraphQlCache\Model\CacheTags; +use Magento\GraphQlCache\Model\CacheInfo; use Magento\Framework\App\State as AppState; +use \Magento\Framework\App\Config\ScopeConfigInterface; /** * Class Plugin - + * * @package Magento\GraphQlCache\Controller\GraphQl */ class Plugin { + const CACHE_TTL = 'system/full_page_cache/ttl'; + /** - * @var CacheTags + * @var CacheInfo */ - private $cacheTags; + private $cacheInfo; /** * @var AppState @@ -31,15 +34,21 @@ class Plugin private $state; /** - * Constructor - * - * @param CacheTags $cacheTags + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * Plugin constructor. + * @param CacheInfo $cacheInfo * @param AppState $state + * @param ScopeConfigInterface $scopeConfig */ - public function __construct(CacheTags $cacheTags, AppState $state) + public function __construct(CacheInfo $cacheInfo, AppState $state, ScopeConfigInterface $scopeConfig) { - $this->cacheTags = $cacheTags; + $this->cacheInfo = $cacheInfo; $this->state = $state; + $this->scopeConfig = $scopeConfig; } /** @@ -55,14 +64,13 @@ public function afterDispatch( /* \Magento\Framework\App\Response\Http */ $response, RequestInterface $request ) { - /** @var \Magento\Framework\App\Request\Http $request */ - /** @var \Magento\Framework\App\Response\Http $response */ - $cacheTags = $this->cacheTags->getCacheTags(); - if (count($cacheTags)) { - // assume that response should be cacheable if it contains cache tags + $cacheTags = $this->cacheInfo->getCacheTags(); + $isCacheValid = $this->cacheInfo->isCacheable(); + $ttl = $this->getTtl(); + + if (count($cacheTags) && $isCacheValid) { $response->setHeader('Pragma', 'cache', true); - // TODO: Take from configuration - $response->setHeader('Cache-Control', 'max-age=86400, public, s-maxage=86400', true); + $response->setHeader('Cache-Control', 'max-age='.$ttl.', public, s-maxage='.$ttl.'', true); $response->setHeader('X-Magento-Tags', implode(',', $cacheTags), true); } @@ -72,4 +80,14 @@ public function afterDispatch( return $response; } + + /** + * Return page lifetime + * + * @return int + */ + private function getTtl() + { + return $this->scopeConfig->getValue(self::CACHE_TTL); + } } diff --git a/app/code/Magento/GraphQlCache/Model/CacheInfo.php b/app/code/Magento/GraphQlCache/Model/CacheInfo.php new file mode 100644 index 000000000000..57c46f6c2139 --- /dev/null +++ b/app/code/Magento/GraphQlCache/Model/CacheInfo.php @@ -0,0 +1,67 @@ +cacheTags; + } + + /** + * Add Cache Tags + * + * @param array $cacheTags + * @return void + */ + public function addCacheTags(array $cacheTags): void + { + $this->cacheTags = array_merge($this->cacheTags, $cacheTags); + } + + /** + * Returns if its valid to cache the response + * + * @return bool + */ + public function isCacheable(): bool + { + return $this->cacheable; + } + + /** + * Sets cache validity + * + * @param bool $cacheable + */ + public function setCacheValidity(bool $cacheable): void + { + $this->cacheable = $cacheable; + } +} diff --git a/app/code/Magento/GraphQlCache/Model/CacheTags.php b/app/code/Magento/GraphQlCache/Model/CacheTags.php deleted file mode 100644 index 6889a873a3f0..000000000000 --- a/app/code/Magento/GraphQlCache/Model/CacheTags.php +++ /dev/null @@ -1,36 +0,0 @@ -cacheTags; - } - - /** - * @param string[] $tags - * @return void - */ - public function addCacheTags(array $cacheTags): void - { - $this->cacheTags = array_merge($this->cacheTags, $cacheTags); - } -} diff --git a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php index c6a9ebb9180c..2ff9c8a10b18 100644 --- a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php +++ b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php @@ -11,7 +11,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\GraphQl\Model\Query\Resolver\Context; -use Magento\GraphQlCache\Model\CacheTags; +use Magento\GraphQlCache\Model\CacheInfo; use Magento\Framework\App\RequestInterface; /** @@ -22,9 +22,9 @@ class Plugin { /** - * @var CacheTags + * @var CacheInfo */ - private $cacheTags; + private $cacheInfo; /** * @var Request @@ -34,12 +34,12 @@ class Plugin /** * Constructor * - * @param CacheTags $cacheTags + * @param CacheInfo $cacheInfo * @param RequestInterface $request */ - public function __construct(CacheTags $cacheTags, RequestInterface $request) + public function __construct(CacheInfo $cacheInfo, RequestInterface $request) { - $this->cacheTags = $cacheTags; + $this->cacheInfo = $cacheInfo; $this->request = $request; } @@ -64,16 +64,19 @@ public function afterResolve( array $value = null, array $args = null ) { - $cacheTag = $field->getCacheTag(); - if (!empty($cacheTag) && $this->request->isGet()) { + $cache = $field->getCache(); + $cacheTag = isset($cache['cache_tag']) ? $cache['cache_tag'] : []; + $cacheable = isset($cache['cacheable']) ? $cache['cacheable'] : true; + if (!empty($cacheTag) && $this->request->isGet() && $cacheable) { $cacheTags = [$cacheTag]; // Resolved value must have cache IDs defined $resolvedItemsIds = $this->extractResolvedItemsIds($resolvedValue); foreach ($resolvedItemsIds as $itemId) { $cacheTags[] = $cacheTag . '_' . $itemId; } - $this->cacheTags->addCacheTags($cacheTags); + $this->cacheInfo->addCacheTags($cacheTags); } + $this->setCacheValidity($cacheable); return $resolvedValue; } @@ -85,7 +88,6 @@ public function afterResolve( */ private function extractResolvedItemsIds($resolvedValue) { - // TODO: Implement safety checks and think about additional places which can hold items IDs if (isset($resolvedValue['ids']) && is_array($resolvedValue['ids'])) { return $resolvedValue['ids']; } @@ -107,4 +109,15 @@ private function extractResolvedItemsIds($resolvedValue) } return $ids; } + + /** + * Set cache validity for the graphql request + * + * @param bool $isValid + */ + private function setCacheValidity(bool $isValid): void + { + $cacheValidity = $this->cacheInfo->isCacheable() && $isValid; + $this->cacheInfo->setCacheValidity($cacheValidity); + } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php index 907b43424f08..dc59e490a020 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php @@ -49,9 +49,9 @@ class Field implements OutputFieldInterface private $description; /** - * @var string + * @var array */ - private $cacheTag; + private $cache; /** * @param string $name @@ -61,7 +61,7 @@ class Field implements OutputFieldInterface * @param string $itemType * @param string $resolver * @param string $description - * @param string $cacheTag + * @param array $cache * @param array $arguments */ public function __construct( @@ -72,7 +72,7 @@ public function __construct( string $itemType = '', string $resolver = '', string $description = '', - string $cacheTag = '', + array $cache = [], array $arguments = [] ) { $this->name = $name; @@ -82,7 +82,7 @@ public function __construct( $this->resolver = $resolver; $this->description = $description; $this->arguments = $arguments; - $this->cacheTag = $cacheTag; + $this->cache = $cache; } /** @@ -158,10 +158,10 @@ public function getDescription() : string /** * Return the cache tag for the field. * - * @return string|null + * @return array|null */ - public function getCacheTag() : string + public function getCache() : array { - return $this->cacheTag; + return $this->cache; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php index 70805f2b51ba..000fcc298708 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php @@ -69,7 +69,7 @@ public function createFromConfigData( 'itemType' => isset($fieldData['itemType']) ? $fieldData['itemType'] : '', 'resolver' => isset($fieldData['resolver']) ? $fieldData['resolver'] : '', 'description' => isset($fieldData['description']) ? $fieldData['description'] : '', - 'cacheTag' => isset($fieldData['cacheable']) ? $fieldData['cacheable'] : false, + 'cache' => isset($fieldData['cache']) ? $fieldData['cache'] : [], 'arguments' => $arguments, ] ); diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php index b2141a7ec8b9..6fa66b80a8c8 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php @@ -16,19 +16,29 @@ class CacheTagReader * Read documentation annotation for a specific node if exists * * @param \GraphQL\Language\AST\NodeList $directives - * @return string + * @return array */ - public function read(\GraphQL\Language\AST\NodeList $directives) : string + public function read(\GraphQL\Language\AST\NodeList $directives) : array { + $argMap = []; foreach ($directives as $directive) { - if ($directive->name->value == 'cacheable') { + if ($directive->name->value == 'cache') { foreach ($directive->arguments as $directiveArgument) { if ($directiveArgument->name->value == 'cache_tag') { - return $directiveArgument->value->value; + $argMap = array_merge( + $argMap, + ["cache_tag" => $directiveArgument->value->value] + ); + } + if ($directiveArgument->name->value == 'cacheable') { + $argMap = array_merge( + $argMap, + ["cacheable" => $directiveArgument->value->value] + ); } } } } - return ''; + return $argMap; } } diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php index e916aae5ddfc..97f169054a07 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php @@ -73,7 +73,7 @@ public function read(\GraphQL\Type\Definition\FieldDefinition $fieldMeta) : arra } if ($this->docReader->read($fieldMeta->astNode->directives)) { - $result['cacheable'] = $this->cacheTagReader->read($fieldMeta->astNode->directives); + $result['cache'] = $this->cacheTagReader->read($fieldMeta->astNode->directives); } $arguments = $fieldMeta->args; diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php index 94326b894669..e8c4f2721f65 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php @@ -71,7 +71,7 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array } if ($this->docReader->read($typeMeta->astNode->directives)) { - $result['cacheable'] = $this->cacheTagReader->read($typeMeta->astNode->directives); + $result['cache'] = $this->cacheTagReader->read($typeMeta->astNode->directives); } return $result; } else { diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php index bc1a65440ca0..2020f42dcaef 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php @@ -76,7 +76,7 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array } if ($this->docReader->read($typeMeta->astNode->directives)) { - $result['cacheable'] = $this->cacheTagReader->read($typeMeta->astNode->directives); + $result['cache'] = $this->cacheTagReader->read($typeMeta->astNode->directives); } return $result; diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php index cf0545a21c4c..5d38d1444e4f 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php @@ -89,7 +89,7 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array } if ($this->docReader->read($typeMeta->astNode->directives)) { - $result['cacheable'] = $this->cacheTagReader->read($typeMeta->astNode->directives); + $result['cache'] = $this->cacheTagReader->read($typeMeta->astNode->directives); } return $result; From 719ed40200caeedc87bd56545d4727afb889bed0 Mon Sep 17 00:00:00 2001 From: Vishal Sutariya Date: Thu, 4 Apr 2019 14:06:46 +0530 Subject: [PATCH 045/247] Fixed shipping & payment section design for create order layout --- .../templates/order/create/data.phtml | 18 ++++++++++-------- .../web/css/source/module/_order.less | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml index 170fea937348..fdbaae234739 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/data.phtml @@ -47,15 +47,17 @@
-
-
- getChildHtml('shipping_method') ?> +
+
+
-
- -
-
- getChildHtml('billing_method') ?> +
+
+ getChildHtml('billing_method') ?> +
+
+ getChildHtml('shipping_method') ?> +
diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less index 480fc57c1149..ffa5ee963952 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/_order.less @@ -55,6 +55,7 @@ } .order-billing-address, + .order-billing-method, .order-history, .order-information, .order-payment-method, From d661d613c17ba25304f2aa1f21e67bc97dff509d Mon Sep 17 00:00:00 2001 From: priti Date: Thu, 4 Apr 2019 16:26:05 +0530 Subject: [PATCH 046/247] Can't-scroll-in-modal-popup-on-iOS --- .../blank/web/css/source/components/_modals_extend.less | 3 +-- .../Magento/luma/web/css/source/components/_modals_extend.less | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/design/frontend/Magento/blank/web/css/source/components/_modals_extend.less b/app/design/frontend/Magento/blank/web/css/source/components/_modals_extend.less index 5cdb1444094e..2ab9f061c60c 100644 --- a/app/design/frontend/Magento/blank/web/css/source/components/_modals_extend.less +++ b/app/design/frontend/Magento/blank/web/css/source/components/_modals_extend.less @@ -148,10 +148,9 @@ } } } -} -.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { .modal-popup { + pointer-events: auto; &.modal-slide { .modal-inner-wrap[class] { .lib-css(background-color, @modal-slide-mobile__background-color); diff --git a/app/design/frontend/Magento/luma/web/css/source/components/_modals_extend.less b/app/design/frontend/Magento/luma/web/css/source/components/_modals_extend.less index 3814341efd05..48a8b0bc6b59 100644 --- a/app/design/frontend/Magento/luma/web/css/source/components/_modals_extend.less +++ b/app/design/frontend/Magento/luma/web/css/source/components/_modals_extend.less @@ -148,10 +148,9 @@ } } } -} -.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { .modal-popup { + pointer-events: auto; &.modal-slide { .modal-inner-wrap[class] { .lib-css(background-color, @modal-slide-mobile__background-color); From e5c1b94d1b254af46d06c162466b7137cb120a06 Mon Sep 17 00:00:00 2001 From: Shikha Mishra Date: Thu, 4 Apr 2019 20:54:04 +0530 Subject: [PATCH 047/247] Fixed Unit test failure --- .../Unit/Model/Customer/DataProviderWithDefaultAddressesTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderWithDefaultAddressesTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderWithDefaultAddressesTest.php index 2fc3cdb92772..d5eaecb3ef35 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderWithDefaultAddressesTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderWithDefaultAddressesTest.php @@ -339,7 +339,6 @@ public function testGetData(): void 'default_shipping' => 2, 'password_hash' => 'password_hash', 'rp_token' => 'rp_token', - 'confirmation' => 'confirmation', ]; $address = $this->getMockBuilder(\Magento\Customer\Model\Address::class) From aa44e8106948d52151485ae7520bcb94f8ae7e47 Mon Sep 17 00:00:00 2001 From: pganapat Date: Thu, 4 Apr 2019 12:05:00 -0500 Subject: [PATCH 048/247] 230: Implement cache tag generation for GraphQL queries - Configured vcl to consume store and currency as a part of header key. --- app/code/Magento/PageCache/etc/varnish4.vcl | 7 +++++++ app/code/Magento/PageCache/etc/varnish5.vcl | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/app/code/Magento/PageCache/etc/varnish4.vcl b/app/code/Magento/PageCache/etc/varnish4.vcl index 8068447e5ca9..35c43171cd9b 100644 --- a/app/code/Magento/PageCache/etc/varnish4.vcl +++ b/app/code/Magento/PageCache/etc/varnish4.vcl @@ -122,6 +122,13 @@ sub vcl_hash { hash_data(server.ip); } + if (req.http.store) { + hash_data(req.http.store); + } + if (req.http.Content-Currency) { + hash_data(req.http.Content-Currency); + } + # To make sure http users don't see ssl warning if (req.http./* {{ ssl_offloaded_header }} */) { hash_data(req.http./* {{ ssl_offloaded_header }} */); diff --git a/app/code/Magento/PageCache/etc/varnish5.vcl b/app/code/Magento/PageCache/etc/varnish5.vcl index 6c8414a5cb64..67f9786bd3cd 100644 --- a/app/code/Magento/PageCache/etc/varnish5.vcl +++ b/app/code/Magento/PageCache/etc/varnish5.vcl @@ -128,6 +128,13 @@ sub vcl_hash { hash_data(req.http./* {{ ssl_offloaded_header }} */); } /* {{ design_exceptions_code }} */ + + if (req.http.store) { + hash_data(req.http.store); + } + if (req.http.Content-Currency) { + hash_data(req.http.Content-Currency); + } } sub vcl_backend_response { From 9677f7370d914060b0e812bcc3bcfab5fbbf52ca Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 4 Apr 2019 14:36:57 -0500 Subject: [PATCH 049/247] Issue-230: implementing builtin cache - fix the builtin to work with store cookie - address headers processing - remove x magento vary cookie support --- .../HttpHeaderProcessor/CurrencyProcessor.php | 84 +++++++++++++++++++ .../DirectoryGraphQl/etc/graphql/di.xml | 16 ++++ .../Magento/GraphQl/Controller/GraphQl.php | 15 +--- .../ContentTypeProcessor.php | 4 +- app/code/Magento/GraphQl/composer.json | 1 - app/code/Magento/GraphQl/etc/graphql/di.xml | 1 - app/code/Magento/GraphQl/etc/module.xml | 1 - .../Controller/GraphQl/Plugin.php | 30 ++++++- .../Model/App/CacheIdentifierPlugin.php | 43 +++++++--- app/code/Magento/GraphQlCache/composer.json | 1 + .../Magento/GraphQlCache/etc/graphql/di.xml | 11 +-- .../HttpHeaderProcessor/StoreProcessor.php | 35 +++++++- app/code/Magento/StoreGraphQl/composer.json | 4 +- .../Magento/StoreGraphQl/etc/graphql/di.xml | 16 ++++ app/code/Magento/StoreGraphQl/etc/module.xml | 1 + 15 files changed, 219 insertions(+), 44 deletions(-) create mode 100644 app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php create mode 100644 app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml rename app/code/Magento/{GraphQl => StoreGraphQl}/Controller/HttpHeaderProcessor/StoreProcessor.php (66%) create mode 100644 app/code/Magento/StoreGraphQl/etc/graphql/di.xml diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php new file mode 100644 index 000000000000..23e1a2f1d4cf --- /dev/null +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php @@ -0,0 +1,84 @@ +storeManager = $storeManager; + $this->httpContext = $httpContext; + $this->session = $session; + } + + /** + * Handle the header 'Content-Currency' value. + * + * @inheritDoc + * @throws GraphQlInputException + */ + public function processHeaderValue(string $headerValue, HttpRequestInterface $request) : void + { + /** @var \Magento\Store\Model\Store $defaultStore */ + $defaultStore = $this->storeManager->getWebsite()->getDefaultStore(); + /** @var \Magento\Store\Model\Store $currentStore */ + $currentStore = $this->storeManager->getStore(); + + if (!empty($headerValue)) { + $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); + if (in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { + $currentStore->setCurrentCurrencyCode($headerCurrency); + } else { + throw new GraphQlInputException( + new \Magento\Framework\Phrase('Currency not allowed for store %1', [$currentStore->getStoreId()]) + ); + } + } else { + if ($this->session->getCurrencyCode()) { + $currentStore->setCurrentCurrencyCode($this->session->getCurrencyCode()); + } else { + $this->httpContext->setValue( + HttpContext::CONTEXT_CURRENCY, + $defaultStore->getCurrentCurrencyCode(), + $defaultStore->getDefaultCurrencyCode() + ); + } + } + } +} diff --git a/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml b/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml new file mode 100644 index 000000000000..515ffef4892c --- /dev/null +++ b/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml @@ -0,0 +1,16 @@ + + + + + + + Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor\CurrencyProcessor + + + + diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index f374c29e24a5..27836a5d2a02 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -8,7 +8,7 @@ namespace Magento\GraphQl\Controller; use Magento\Framework\App\FrontControllerInterface; -use Magento\Framework\App\Request\Http; +use Magento\Framework\App\Request\Http as HttpRequest; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; use Magento\Framework\Exception\LocalizedException; @@ -53,11 +53,6 @@ class GraphQl implements FrontControllerInterface */ private $resolverContext; - /** - * @var HttpRequestProcessor - */ - private $requestProcessor; - /** * @var QueryFields */ @@ -74,7 +69,6 @@ class GraphQl implements FrontControllerInterface * @param QueryProcessor $queryProcessor * @param \Magento\Framework\GraphQl\Exception\ExceptionFormatter $graphQlError * @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $resolverContext - * @param HttpRequestProcessor $requestProcessor * @param QueryFields $queryFields * @param JsonFactory $jsonFactory */ @@ -84,7 +78,6 @@ public function __construct( QueryProcessor $queryProcessor, ExceptionFormatter $graphQlError, ContextInterface $resolverContext, - HttpRequestProcessor $requestProcessor, QueryFields $queryFields, JsonFactory $jsonFactory ) { @@ -93,7 +86,6 @@ public function __construct( $this->queryProcessor = $queryProcessor; $this->graphQlError = $graphQlError; $this->resolverContext = $resolverContext; - $this->requestProcessor = $requestProcessor; $this->queryFields = $queryFields; $this->jsonFactory = $jsonFactory; } @@ -105,12 +97,11 @@ public function __construct( * @param RequestInterface $request * @return ResponseInterface|ResultInterface */ - public function dispatch(RequestInterface $request) /* : ResponseInterface */ + public function dispatch(RequestInterface $request) { $jsonResult = $this->jsonFactory->create(); try { - /** @var Http $request */ - $this->requestProcessor->processHeaders($request); + /** @var HttpRequest $request */ if ($request->isPost()) { $data = $this->jsonSerializer->unserialize($request->getContent()); } else { diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php index 69201f93ab4e..cff6cd3db619 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php +++ b/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/ContentTypeProcessor.php @@ -24,9 +24,7 @@ class ContentTypeProcessor implements HttpHeaderProcessorInterface */ public function processHeaderValue(string $headerValue, HttpRequestInterface $request) : void { - if ($request->isPost() - && (!$headerValue || strpos($headerValue, 'application/json') === false) - ) { + if ((empty($headerValue) || strpos($headerValue, 'application/json') === false)) { throw new LocalizedException( new \Magento\Framework\Phrase('Request content type must be application/json') ); diff --git a/app/code/Magento/GraphQl/composer.json b/app/code/Magento/GraphQl/composer.json index 3e821b090944..a81fb61984e0 100644 --- a/app/code/Magento/GraphQl/composer.json +++ b/app/code/Magento/GraphQl/composer.json @@ -5,7 +5,6 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/module-authorization": "*", - "magento/module-store": "*", "magento/module-eav": "*", "magento/framework": "*" }, diff --git a/app/code/Magento/GraphQl/etc/graphql/di.xml b/app/code/Magento/GraphQl/etc/graphql/di.xml index f4e6ca59364b..124a235f4fc2 100644 --- a/app/code/Magento/GraphQl/etc/graphql/di.xml +++ b/app/code/Magento/GraphQl/etc/graphql/di.xml @@ -29,7 +29,6 @@ Magento\GraphQl\Controller\HttpHeaderProcessor\ContentTypeProcessor - Magento\GraphQl\Controller\HttpHeaderProcessor\StoreProcessor diff --git a/app/code/Magento/GraphQl/etc/module.xml b/app/code/Magento/GraphQl/etc/module.xml index 4d8b2090a851..af0f5d06d3ba 100644 --- a/app/code/Magento/GraphQl/etc/module.xml +++ b/app/code/Magento/GraphQl/etc/module.xml @@ -9,7 +9,6 @@ - diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index 151e044c32be..ae501386aea5 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -14,6 +14,7 @@ use Magento\Framework\Controller\ResultInterface; use Magento\GraphQlCache\Model\CacheTags; use Magento\PageCache\Model\Config; +use Magento\GraphQl\Controller\HttpRequestProcessor; /** * Class Plugin @@ -35,25 +36,50 @@ class Plugin */ private $response; + /** + * @var HttpRequestProcessor + */ + private $requestProcessor; + /** * @param CacheTags $cacheTags * @param Config $config * @param HttpResponse $response + * @param HttpRequestProcessor $requestProcessor */ public function __construct( CacheTags $cacheTags, Config $config, - HttpResponse $response + HttpResponse $response, + HttpRequestProcessor $requestProcessor ) { $this->cacheTags = $cacheTags; $this->config = $config; $this->response = $response; + $this->requestProcessor = $requestProcessor; + } + + /** + * Process graphql headers + * + * @param FrontControllerInterface $subject + * @param RequestInterface $request + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeDispatch( + FrontControllerInterface $subject, + RequestInterface $request + ) { + /** @var \Magento\Framework\App\Request\Http $request */ + $this->requestProcessor->processHeaders($request); } /** * Plugin for GraphQL after dispatch to set tag and cache headers * - * The $response doesn't have a set type because it's alternating between ResponseInterface and ResultInterface. + * The $response doesn't have a set type because it's alternating between ResponseInterface and ResultInterface + * depending if it comes from builtin cache or the dispatch. * * @param FrontControllerInterface $subject * @param ResponseInterface | ResultInterface $response diff --git a/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php b/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php index e279395e43d4..9b70f4305fc7 100644 --- a/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php +++ b/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php @@ -6,6 +6,8 @@ namespace Magento\GraphQlCache\Model\App; +use Magento\Framework\Serialize\Serializer\Json; + /** * Class CachePlugin * Should add unique identifier for graphql query @@ -13,37 +15,58 @@ class CacheIdentifierPlugin { /** - * Constructor - * - * @param \Magento\Framework\App\RequestInterface $request + * @var \Magento\Framework\App\Request\Http + */ + private $request; + + /** + * @var \Magento\Framework\App\Http\Context + */ + private $context; + + /** + * @var \Magento\Framework\Serialize\Serializer\Json + */ + private $serializer; + + /** + * @var \Magento\PageCache\Model\Config + */ + private $config; + + /** + * @param \Magento\Framework\App\Request\Http $request + * @param \Magento\Framework\App\Http\Context $context + * @param \Magento\Framework\Serialize\Serializer\Json $serializer * @param \Magento\PageCache\Model\Config $config */ public function __construct( - \Magento\Framework\App\RequestInterface $request, + \Magento\Framework\App\Request\Http $request, + \Magento\Framework\App\Http\Context $context, + \Magento\Framework\Serialize\Serializer\Json $serializer, \Magento\PageCache\Model\Config $config ) { $this->request = $request; + $this->context = $context; + $this->serializer = $serializer; $this->config = $config; } /** - * Adds a unique key identifier for graphql specific query and variables + * Adds a unique key identifier for graphql specific query and variables that skips X-Magento-Vary cookie * * @param \Magento\Framework\App\PageCache\Identifier $identifier * @param string $result * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetValue(\Magento\Framework\App\PageCache\Identifier $identifier, $result) + public function afterGetValue(\Magento\Framework\App\PageCache\Identifier $identifier, string $result) { - //If full page cache is enabled if ($this->config->isEnabled()) { - //we need to compute unique query identifier from the 3 variables and removing whitespaces $data = [ $this->request->isSecure(), $this->request->getUriString(), - $this->request->get(\Magento\Framework\App\Response\Http::COOKIE_VARY_STRING) - ?: $this->context->getVaryString() + $this->context->getVaryString() ]; $result = sha1($this->serializer->serialize($data)); } diff --git a/app/code/Magento/GraphQlCache/composer.json b/app/code/Magento/GraphQlCache/composer.json index 7b5e6137895f..54e6573cb61c 100644 --- a/app/code/Magento/GraphQlCache/composer.json +++ b/app/code/Magento/GraphQlCache/composer.json @@ -5,6 +5,7 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/module-graph-ql": "*" + "magento/module-page-cache": "*" }, "license": [ "OSL-3.0", diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml index ae403e0c56ba..5c13dbb02e06 100644 --- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -14,15 +14,12 @@ - - - - + + + - - - diff --git a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php similarity index 66% rename from app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php rename to app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index 3571a7588d11..7036ac5f7594 100644 --- a/app/code/Magento/GraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -5,13 +5,14 @@ */ declare(strict_types=1); -namespace Magento\GraphQl\Controller\HttpHeaderProcessor; +namespace Magento\StoreGraphQl\Controller\HttpHeaderProcessor; use Magento\Framework\App\HttpRequestInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpHeaderProcessorInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Http\Context as HttpContext; +use Magento\Store\Api\StoreCookieManagerInterface; /** * Process the "Store" header entry @@ -28,27 +29,36 @@ class StoreProcessor implements HttpHeaderProcessorInterface */ private $httpContext; + /** + * @var StoreCookieManagerInterface + */ + private $storeCookieManager; + /** * @param StoreManagerInterface $storeManager * @param HttpContext $httpContext */ public function __construct( StoreManagerInterface $storeManager, - HttpContext $httpContext + HttpContext $httpContext, + StoreCookieManagerInterface $storeCookieManager ) { $this->storeManager = $storeManager; $this->httpContext = $httpContext; + $this->storeCookieManager = $storeCookieManager; } /** * Handle the value of the store and set the scope * - * @inheritDoc + * @see \Magento\Store\App\Action\Plugin\Context::beforeDispatch + * + * @inheritdoc * @throws GraphQlInputException */ public function processHeaderValue(string $headerValue, HttpRequestInterface $request) : void { - if ($headerValue) { + if (!empty($headerValue)) { $storeCode = ltrim(rtrim($headerValue)); $stores = $this->storeManager->getStores(false, true); if (isset($stores[$storeCode])) { @@ -59,6 +69,11 @@ public function processHeaderValue(string $headerValue, HttpRequestInterface $re new \Magento\Framework\Phrase('Store code %1 does not exist', [$storeCode]) ); } + } elseif (!$this->isAlreadySet()) { + $storeCode = $this->storeCookieManager->getStoreCodeFromCookie() + ?: $this->storeManager->getDefaultStoreView()->getCode(); + $this->storeManager->setCurrentStore($storeCode); + $this->updateContext($storeCode); } } @@ -76,4 +91,16 @@ private function updateContext(string $storeCode) : void $this->storeManager->getDefaultStoreView()->getCode() ); } + + /** + * Check if there is a need to find the current store. + * + * @return bool + */ + private function isAlreadySet(): bool + { + $storeKey = StoreManagerInterface::CONTEXT_STORE; + + return $this->httpContext->getValue($storeKey) !== null; + } } diff --git a/app/code/Magento/StoreGraphQl/composer.json b/app/code/Magento/StoreGraphQl/composer.json index d53ba9fbb002..aa36a4891343 100644 --- a/app/code/Magento/StoreGraphQl/composer.json +++ b/app/code/Magento/StoreGraphQl/composer.json @@ -5,9 +5,7 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", - "magento/module-store": "*" - }, - "suggest": { + "magento/module-store": "*", "magento/module-graph-ql": "*" }, "license": [ diff --git a/app/code/Magento/StoreGraphQl/etc/graphql/di.xml b/app/code/Magento/StoreGraphQl/etc/graphql/di.xml new file mode 100644 index 000000000000..973abc50a8aa --- /dev/null +++ b/app/code/Magento/StoreGraphQl/etc/graphql/di.xml @@ -0,0 +1,16 @@ + + + + + + + Magento\StoreGraphQl\Controller\HttpHeaderProcessor\StoreProcessor + + + + diff --git a/app/code/Magento/StoreGraphQl/etc/module.xml b/app/code/Magento/StoreGraphQl/etc/module.xml index f53379ac3bbf..bbec6a85a1a1 100644 --- a/app/code/Magento/StoreGraphQl/etc/module.xml +++ b/app/code/Magento/StoreGraphQl/etc/module.xml @@ -8,6 +8,7 @@ + From 0d94b0f51feddde21c683932f01c76c00c8ab2ef Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 4 Apr 2019 16:53:08 -0500 Subject: [PATCH 050/247] Issue-230: adding varnish - refactoring tags plugin and cache query class --- .../Controller/GraphQl/Plugin.php | 30 +++++++++++-------- .../{CacheInfo.php => CacheableQuery.php} | 22 ++++++++++---- .../GraphQlCache/Query/Resolver/Plugin.php | 20 ++++++------- 3 files changed, 43 insertions(+), 29 deletions(-) rename app/code/Magento/GraphQlCache/Model/{CacheInfo.php => CacheableQuery.php} (65%) diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index d1b14f96ae44..b5e4155a3382 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -10,7 +10,7 @@ use Magento\Framework\App\FrontControllerInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; -use Magento\GraphQlCache\Model\CacheInfo; +use Magento\GraphQlCache\Model\CacheableQuery; use Magento\Framework\App\Response\Http as HttpResponse; use Magento\Framework\Controller\ResultInterface; use Magento\PageCache\Model\Config; @@ -22,7 +22,7 @@ class Plugin { /** - * @var CacheInfo + * @var CacheableQuery */ private $cacheInfo; @@ -42,13 +42,13 @@ class Plugin private $requestProcessor; /** - * @param CacheInfo $cacheInfo + * @param CacheableQuery $cacheInfo * @param Config $config * @param HttpResponse $response * @param HttpRequestProcessor $requestProcessor */ public function __construct( - CacheInfo $cacheInfo, + CacheableQuery $cacheInfo, Config $config, HttpResponse $response, HttpRequestProcessor $requestProcessor @@ -92,14 +92,20 @@ public function afterDispatch( $response, RequestInterface $request ) { - $cacheTags = $this->cacheInfo->getCacheTags(); - $isCacheValid = $this->cacheInfo->isCacheable(); - if (!empty($cacheTags) - && $isCacheValid - && $this->config->isEnabled() - ) { - $this->response->setPublicHeaders($this->config->getTtl()); - $this->response->setHeader('X-Magento-Tags', implode(',', $cacheTags), true); + $sendNoCacheHeaders = false; + if ($this->config->isEnabled() && $request->isGet()) { + if ($this->cacheInfo->shouldPopulateCacheHeadersWithTags()) { + $this->response->setPublicHeaders($this->config->getTtl()); + $this->response->setHeader('X-Magento-Tags', implode(',', $this->cacheInfo->getCacheTags()), true); + } else { + $sendNoCacheHeaders = true; + } + } else { + $sendNoCacheHeaders = true; + } + + if ($sendNoCacheHeaders) { + $this->response->setNoCacheHeaders(); } return $response; diff --git a/app/code/Magento/GraphQlCache/Model/CacheInfo.php b/app/code/Magento/GraphQlCache/Model/CacheableQuery.php similarity index 65% rename from app/code/Magento/GraphQlCache/Model/CacheInfo.php rename to app/code/Magento/GraphQlCache/Model/CacheableQuery.php index 57c46f6c2139..3a7600b58f66 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheInfo.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQuery.php @@ -7,12 +7,10 @@ namespace Magento\GraphQlCache\Model; -use Magento\Eav\Model\Attribute\Data\Boolean; - /** - * CacheInfo object is a registry for collecting cache related info and tags of all entities. + * CacheableQuery object is a registry for collecting cache related info and tags of all entities. */ -class CacheInfo +class CacheableQuery { /** * @var string[] @@ -46,7 +44,7 @@ public function addCacheTags(array $cacheTags): void } /** - * Returns if its valid to cache the response + * Return if its valid to cache the response * * @return bool */ @@ -56,7 +54,7 @@ public function isCacheable(): bool } /** - * Sets cache validity + * Set cache validity * * @param bool $cacheable */ @@ -64,4 +62,16 @@ public function setCacheValidity(bool $cacheable): void { $this->cacheable = $cacheable; } + + /** + * Check if query is cacheable and we have a list of tags to populate + * + * @return bool + */ + public function shouldPopulateCacheHeadersWithTags() : bool + { + $cacheTags = $this->getCacheTags(); + $isQueryCaheable = $this->isCacheable(); + return !empty($cacheTags) && $isQueryCaheable; + } } diff --git a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php index 2ff9c8a10b18..029e29df3af2 100644 --- a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php +++ b/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php @@ -11,7 +11,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\GraphQl\Model\Query\Resolver\Context; -use Magento\GraphQlCache\Model\CacheInfo; +use Magento\GraphQlCache\Model\CacheableQuery; use Magento\Framework\App\RequestInterface; /** @@ -22,9 +22,9 @@ class Plugin { /** - * @var CacheInfo + * @var CacheableQuery */ - private $cacheInfo; + private $cacheableQuery; /** * @var Request @@ -32,14 +32,12 @@ class Plugin private $request; /** - * Constructor - * - * @param CacheInfo $cacheInfo + * @param CacheableQuery $cacheableQuery * @param RequestInterface $request */ - public function __construct(CacheInfo $cacheInfo, RequestInterface $request) + public function __construct(CacheableQuery $cacheableQuery, RequestInterface $request) { - $this->cacheInfo = $cacheInfo; + $this->cacheableQuery = $cacheableQuery; $this->request = $request; } @@ -74,7 +72,7 @@ public function afterResolve( foreach ($resolvedItemsIds as $itemId) { $cacheTags[] = $cacheTag . '_' . $itemId; } - $this->cacheInfo->addCacheTags($cacheTags); + $this->cacheableQuery->addCacheTags($cacheTags); } $this->setCacheValidity($cacheable); return $resolvedValue; @@ -117,7 +115,7 @@ private function extractResolvedItemsIds($resolvedValue) */ private function setCacheValidity(bool $isValid): void { - $cacheValidity = $this->cacheInfo->isCacheable() && $isValid; - $this->cacheInfo->setCacheValidity($cacheValidity); + $cacheValidity = $this->cacheableQuery->isCacheable() && $isValid; + $this->cacheableQuery->setCacheValidity($cacheValidity); } } From d75f99a54c927cbdbdd7ee31c72d9aca0eadc4d7 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 4 Apr 2019 17:28:55 -0500 Subject: [PATCH 051/247] Issue-230: adding varnish - removing header processor - adding dependency for store in graphql directory module --- app/code/Magento/DirectoryGraphQl/composer.json | 1 + app/code/Magento/GraphQl/Controller/GraphQl.php | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/DirectoryGraphQl/composer.json b/app/code/Magento/DirectoryGraphQl/composer.json index 0a81102a9276..ca1790c949d4 100644 --- a/app/code/Magento/DirectoryGraphQl/composer.json +++ b/app/code/Magento/DirectoryGraphQl/composer.json @@ -5,6 +5,7 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/module-directory": "*", + "magento/module-store": "*", "magento/framework": "*" }, "suggest": { diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index 6dfddf31c5e7..4620e5369f9b 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -104,7 +104,6 @@ public function dispatch(RequestInterface $request) try { /** @var HttpRequest $request */ if ($this->isHttpVerbValid($request)) { - $this->requestProcessor->processHeaders($request); $data = $this->getDataFromRequest($request); $query = isset($data['query']) ? $data['query'] : ''; $variables = isset($data['variables']) ? $data['variables'] : null; From 559431eba2f6276543eb05a76676b9cfb29a930c Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 4 Apr 2019 18:34:15 -0500 Subject: [PATCH 052/247] Issue-230: adding varnish - adding currency validator --- .../HttpHeaderProcessor/CurrencyProcessor.php | 11 ++-- .../HttpHeaderProcessor/CurrencyValidator.php | 63 +++++++++++++++++++ .../DirectoryGraphQl/etc/graphql/di.xml | 3 + .../HttpHeaderProcessor/StoreProcessor.php | 12 +--- 4 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php index b6bae362175a..972cb0b37648 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php @@ -7,11 +7,11 @@ namespace Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor; -use Magento\Framework\App\HttpRequestInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpHeaderProcessorInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Http\Context as HttpContext; +use Magento\Framework\Session\SessionManagerInterface; /** * Process the "Currency" header entry @@ -29,18 +29,19 @@ class CurrencyProcessor implements HttpHeaderProcessorInterface private $httpContext; /** - * @var \Magento\Framework\Session\SessionManagerInterface + * @var SessionManagerInterface */ private $session; /** * @param StoreManagerInterface $storeManager * @param HttpContext $httpContext + * @param SessionManagerInterface $session */ public function __construct( StoreManagerInterface $storeManager, HttpContext $httpContext, - \Magento\Framework\Session\SessionManagerInterface $session + SessionManagerInterface $session ) { $this->storeManager = $storeManager; $this->httpContext = $httpContext; @@ -65,10 +66,6 @@ public function processHeaderValue(string $headerValue) : void $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); if (in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { $currentStore->setCurrentCurrencyCode($headerCurrency); - } else { - throw new GraphQlInputException( - new \Magento\Framework\Phrase('Currency not allowed for store %1', [$currentStore->getStoreId()]) - ); } } else { if ($this->session->getCurrencyCode()) { diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php new file mode 100644 index 000000000000..6d28d712fdf9 --- /dev/null +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php @@ -0,0 +1,63 @@ +storeManager = $storeManager; + $this->httpContext = $httpContext; + } + + /** + * Validate the header 'Content-Currency' value. + * + * @param HttpRequestInterface $request + * @return void + */ + public function validate(HttpRequestInterface $request): void + { + /** @var \Magento\Store\Model\Store $currentStore */ + $currentStore = $this->storeManager->getStore(); + $headerValue = $request->getHeader('Content-Currency'); + if (!empty($headerValue)) { + $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); + if (!in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { + throw new GraphQlInputException( + new \Magento\Framework\Phrase('Currency not allowed for store %1', [$currentStore->getStoreId()]) + ); + } + } + } +} diff --git a/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml b/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml index 515ffef4892c..e9791654251c 100644 --- a/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml @@ -11,6 +11,9 @@ Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor\CurrencyProcessor + + Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor\CurrencyValidator + diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index 54ac3d4ae3bf..227665cbdd28 100644 --- a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -7,7 +7,6 @@ namespace Magento\StoreGraphQl\Controller\HttpHeaderProcessor; -use Magento\Framework\App\HttpRequestInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpHeaderProcessorInterface; use Magento\Store\Model\StoreManagerInterface; @@ -62,15 +61,8 @@ public function processHeaderValue(string $headerValue) : void { if (!empty($headerValue)) { $storeCode = ltrim(rtrim($headerValue)); - $stores = $this->storeManager->getStores(false, true); - if (isset($stores[$storeCode])) { - $this->storeManager->setCurrentStore($storeCode); - $this->updateContext($storeCode); - } elseif (strtolower($storeCode) !== 'default') { - throw new GraphQlInputException( - new \Magento\Framework\Phrase('Store code %1 does not exist', [$storeCode]) - ); - } + $this->storeManager->setCurrentStore($storeCode); + $this->updateContext($storeCode); } elseif (!$this->isAlreadySet()) { $storeCode = $this->storeCookieManager->getStoreCodeFromCookie() ?: $this->storeManager->getDefaultStoreView()->getCode(); From 934ce24c54a5764d007a920ac47278e417e730f8 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 4 Apr 2019 19:17:16 -0500 Subject: [PATCH 053/247] Issue-230: adding varnish - fixing validators vs processors --- .../HttpHeaderProcessor/CurrencyProcessor.php | 38 +++++----- .../HttpHeaderProcessor/CurrencyValidator.php | 25 ++++--- .../HttpHeaderProcessor/StoreValidator.php | 73 +++++++++++++++++++ .../Magento/StoreGraphQl/etc/graphql/di.xml | 3 + 4 files changed, 113 insertions(+), 26 deletions(-) create mode 100644 app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php index 972cb0b37648..8daa7750ddd3 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php @@ -57,26 +57,30 @@ public function __construct( */ public function processHeaderValue(string $headerValue) : void { - /** @var \Magento\Store\Model\Store $defaultStore */ - $defaultStore = $this->storeManager->getWebsite()->getDefaultStore(); - /** @var \Magento\Store\Model\Store $currentStore */ - $currentStore = $this->storeManager->getStore(); + try { + /** @var \Magento\Store\Model\Store $defaultStore */ + $defaultStore = $this->storeManager->getWebsite()->getDefaultStore(); + /** @var \Magento\Store\Model\Store $currentStore */ + $currentStore = $this->storeManager->getStore(); - if (!empty($headerValue)) { - $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); - if (in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { - $currentStore->setCurrentCurrencyCode($headerCurrency); - } - } else { - if ($this->session->getCurrencyCode()) { - $currentStore->setCurrentCurrencyCode($this->session->getCurrencyCode()); + if (!empty($headerValue)) { + $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); + if (in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { + $currentStore->setCurrentCurrencyCode($headerCurrency); + } } else { - $this->httpContext->setValue( - HttpContext::CONTEXT_CURRENCY, - $defaultStore->getCurrentCurrencyCode(), - $defaultStore->getDefaultCurrencyCode() - ); + if ($this->session->getCurrencyCode()) { + $currentStore->setCurrentCurrencyCode($this->session->getCurrencyCode()); + } else { + $this->httpContext->setValue( + HttpContext::CONTEXT_CURRENCY, + $defaultStore->getCurrentCurrencyCode(), + $defaultStore->getDefaultCurrencyCode() + ); + } } + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + //skip store not found exception as it will be handled in graphql validation } } } diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php index 6d28d712fdf9..9203523338ca 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php @@ -48,16 +48,23 @@ public function __construct( */ public function validate(HttpRequestInterface $request): void { - /** @var \Magento\Store\Model\Store $currentStore */ - $currentStore = $this->storeManager->getStore(); - $headerValue = $request->getHeader('Content-Currency'); - if (!empty($headerValue)) { - $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); - if (!in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { - throw new GraphQlInputException( - new \Magento\Framework\Phrase('Currency not allowed for store %1', [$currentStore->getStoreId()]) - ); + try { + $headerValue = $request->getHeader('Content-Currency'); + if (!empty($headerValue)) { + $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); + /** @var \Magento\Store\Model\Store $currentStore */ + $currentStore = $this->storeManager->getStore(); + if (!in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { + throw new GraphQlInputException( + __('Currency not allowed for store %1', [$currentStore->getCode()]) + ); + } } + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + $this->storeManager->setCurrentStore(null); + throw new GraphQlInputException( + __("The store that was requested wasn't found. Verify the store and try again.") + ); } } } diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php new file mode 100644 index 000000000000..2572b4516f57 --- /dev/null +++ b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php @@ -0,0 +1,73 @@ +storeManager = $storeManager; + $this->httpContext = $httpContext; + $this->storeCookieManager = $storeCookieManager; + } + + /** + * Validate the header 'Store' value. + * + * @param HttpRequestInterface $request + * @return void + */ + public function validate(HttpRequestInterface $request): void + { + $headerValue = $request->getHeader('Store'); + if (!empty($headerValue)) { + $storeCode = ltrim(rtrim($headerValue)); + $stores = $this->storeManager->getStores(false, true); + if (!isset($stores[$storeCode])) { + if (strtolower($storeCode) !== 'default') { + $this->storeManager->setCurrentStore(null); + throw new GraphQlInputException( + __("The store that was requested wasn't found. Verify the store and try again.") + ); + } + } + } + } +} diff --git a/app/code/Magento/StoreGraphQl/etc/graphql/di.xml b/app/code/Magento/StoreGraphQl/etc/graphql/di.xml index 973abc50a8aa..50f612194893 100644 --- a/app/code/Magento/StoreGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/StoreGraphQl/etc/graphql/di.xml @@ -11,6 +11,9 @@ Magento\StoreGraphQl\Controller\HttpHeaderProcessor\StoreProcessor + + Magento\StoreGraphQl\Controller\HttpHeaderProcessor\StoreValidator + From 630c36152191d50449ea3a59eb9490e938c466a9 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 4 Apr 2019 19:22:12 -0500 Subject: [PATCH 054/247] Issue-230: adding varnish - removing context --- .../HttpHeaderProcessor/CurrencyValidator.php | 11 +---------- .../HttpHeaderProcessor/StoreValidator.php | 19 +------------------ 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php index 9203523338ca..1a2938c7d753 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php @@ -11,7 +11,6 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpRequestValidatorInterface; use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\App\Http\Context as HttpContext; /** * Validate the "Currency" header entry @@ -23,21 +22,13 @@ class CurrencyValidator implements HttpRequestValidatorInterface */ private $storeManager; - /** - * @var HttpContext - */ - private $httpContext; - /** * @param StoreManagerInterface $storeManager - * @param HttpContext $httpContext */ public function __construct( - StoreManagerInterface $storeManager, - HttpContext $httpContext + StoreManagerInterface $storeManager ) { $this->storeManager = $storeManager; - $this->httpContext = $httpContext; } /** diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php index 2572b4516f57..b3b5f1a6abd4 100644 --- a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php @@ -11,8 +11,6 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpRequestValidatorInterface; use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\App\Http\Context as HttpContext; -use Magento\Store\Api\StoreCookieManagerInterface; /** * Validate the "Store" header entry @@ -24,28 +22,13 @@ class StoreValidator implements HttpRequestValidatorInterface */ private $storeManager; - /** - * @var HttpContext - */ - private $httpContext; - - /** - * @var StoreCookieManagerInterface - */ - private $storeCookieManager; - /** * @param StoreManagerInterface $storeManager - * @param HttpContext $httpContext */ public function __construct( - StoreManagerInterface $storeManager, - HttpContext $httpContext, - StoreCookieManagerInterface $storeCookieManager + StoreManagerInterface $storeManager ) { $this->storeManager = $storeManager; - $this->httpContext = $httpContext; - $this->storeCookieManager = $storeCookieManager; } /** From 865d7df16d374246d91d35f1bdb737828c88edc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= Date: Thu, 4 Apr 2019 14:27:46 +0200 Subject: [PATCH 055/247] Fix #12802 - allow to override preference over \Magento\Quote\Api\Data\CartInterface and return correct object from QuoteRepository (+4 squashed commits) Squashed commits: [55b9f3ec52b] Fix #12802 - fix phpmd, mark quoteFactory as deprecated [56ca9a42468] Fix #12802 - change condition in quoteRepository [734212812a4] Fix #12802 - revert change of constructor parameters names [ba8ad543e0f] Fix #12802 - remove instanceof condition --- .../Magento/Quote/Model/QuoteRepository.php | 70 +++++++++------ .../Test/Unit/Model/QuoteRepositoryTest.php | 90 +++++++++++-------- 2 files changed, 93 insertions(+), 67 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteRepository.php b/app/code/Magento/Quote/Model/QuoteRepository.php index 01c21bbbe50a..fa6ab1813668 100644 --- a/app/code/Magento/Quote/Model/QuoteRepository.php +++ b/app/code/Magento/Quote/Model/QuoteRepository.php @@ -5,25 +5,28 @@ */ namespace Magento\Quote\Model; +use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\App\ObjectManager; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Api\Data\CartInterface; -use Magento\Quote\Model\Quote; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\Api\Search\FilterGroup; -use Magento\Quote\Model\ResourceModel\Quote\Collection as QuoteCollection; -use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory as QuoteCollectionFactory; -use Magento\Framework\Exception\InputException; -use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Quote\Api\Data\CartInterfaceFactory; +use Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory; use Magento\Quote\Model\QuoteRepository\SaveHandler; use Magento\Quote\Model\QuoteRepository\LoadHandler; +use Magento\Quote\Model\ResourceModel\Quote\Collection as QuoteCollection; +use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory as QuoteCollectionFactory; +use Magento\Store\Model\StoreManagerInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface +class QuoteRepository implements CartRepositoryInterface { /** * @var Quote[] @@ -37,6 +40,7 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface /** * @var QuoteFactory + * @deprecated */ protected $quoteFactory; @@ -46,13 +50,13 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface protected $storeManager; /** - * @var \Magento\Quote\Model\ResourceModel\Quote\Collection + * @var QuoteCollection * @deprecated 100.2.0 */ protected $quoteCollection; /** - * @var \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory + * @var CartSearchResultsInterfaceFactory */ protected $searchResultsDataFactory; @@ -77,39 +81,47 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface private $collectionProcessor; /** - * @var \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory + * @var QuoteCollectionFactory */ private $quoteCollectionFactory; + /** + * @var CartInterfaceFactory + */ + private $cartFactory; + /** * Constructor * * @param QuoteFactory $quoteFactory * @param StoreManagerInterface $storeManager - * @param \Magento\Quote\Model\ResourceModel\Quote\Collection $quoteCollection - * @param \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory $searchResultsDataFactory + * @param QuoteCollection $quoteCollection + * @param CartSearchResultsInterfaceFactory $searchResultsDataFactory * @param JoinProcessorInterface $extensionAttributesJoinProcessor * @param CollectionProcessorInterface|null $collectionProcessor - * @param \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory|null $quoteCollectionFactory + * @param QuoteCollectionFactory|null $quoteCollectionFactory + * @param CartInterfaceFactory|null $cartFactory * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( QuoteFactory $quoteFactory, StoreManagerInterface $storeManager, - \Magento\Quote\Model\ResourceModel\Quote\Collection $quoteCollection, - \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory $searchResultsDataFactory, + QuoteCollection $quoteCollection, + CartSearchResultsInterfaceFactory $searchResultsDataFactory, JoinProcessorInterface $extensionAttributesJoinProcessor, CollectionProcessorInterface $collectionProcessor = null, - \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory $quoteCollectionFactory = null + QuoteCollectionFactory $quoteCollectionFactory = null, + CartInterfaceFactory $cartFactory = null ) { $this->quoteFactory = $quoteFactory; $this->storeManager = $storeManager; $this->searchResultsDataFactory = $searchResultsDataFactory; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; - $this->collectionProcessor = $collectionProcessor ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\Api\SearchCriteria\CollectionProcessor::class); - $this->quoteCollectionFactory = $quoteCollectionFactory ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Quote\Model\ResourceModel\Quote\CollectionFactory::class); + $this->collectionProcessor = $collectionProcessor ?: ObjectManager::getInstance() + ->get(CollectionProcessor::class); + $this->quoteCollectionFactory = $quoteCollectionFactory ?: ObjectManager::getInstance() + ->get(QuoteCollectionFactory::class); + $this->cartFactory = $cartFactory ?: ObjectManager::getInstance()->get(CartInterfaceFactory::class); } /** @@ -166,7 +178,7 @@ public function getActiveForCustomer($customerId, array $sharedStoreIds = []) /** * {@inheritdoc} */ - public function save(\Magento\Quote\Api\Data\CartInterface $quote) + public function save(CartInterface $quote) { if ($quote->getId()) { $currentQuote = $this->get($quote->getId(), [$quote->getStoreId()]); @@ -186,7 +198,7 @@ public function save(\Magento\Quote\Api\Data\CartInterface $quote) /** * {@inheritdoc} */ - public function delete(\Magento\Quote\Api\Data\CartInterface $quote) + public function delete(CartInterface $quote) { $quoteId = $quote->getId(); $customerId = $quote->getCustomerId(); @@ -203,13 +215,13 @@ public function delete(\Magento\Quote\Api\Data\CartInterface $quote) * @param int $identifier * @param int[] $sharedStoreIds * @throws NoSuchEntityException - * @return Quote + * @return CartInterface */ protected function loadQuote($loadMethod, $loadField, $identifier, array $sharedStoreIds = []) { - /** @var Quote $quote */ - $quote = $this->quoteFactory->create(); - if ($sharedStoreIds) { + /** @var CartInterface $quote */ + $quote = $this->cartFactory->create(); + if ($sharedStoreIds && method_exists($quote, 'setSharedStoreIds')) { $quote->setSharedStoreIds($sharedStoreIds); } $quote->setStoreId($this->storeManager->getStore()->getId())->$loadMethod($identifier); @@ -222,7 +234,7 @@ protected function loadQuote($loadMethod, $loadField, $identifier, array $shared /** * {@inheritdoc} */ - public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria) + public function getList(SearchCriteriaInterface $searchCriteria) { $this->quoteCollection = $this->quoteCollectionFactory->create(); /** @var \Magento\Quote\Api\Data\CartSearchResultsInterface $searchData */ diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php index 3101c7d0677a..095e1760df86 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php @@ -5,17 +5,31 @@ */ namespace Magento\Quote\Test\Unit\Model; +use Magento\Framework\Api\SearchCriteria; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SortOrder; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Quote\Api\Data\CartInterface; +use Magento\Quote\Api\Data\CartInterfaceFactory; +use Magento\Quote\Api\Data\CartSearchResultsInterface; +use Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\QuoteRepository; use Magento\Quote\Model\QuoteRepository\LoadHandler; use Magento\Quote\Model\QuoteRepository\SaveHandler; +use Magento\Quote\Model\ResourceModel\Quote\Collection; use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\TestCase; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyMethods) */ -class QuoteRepositoryTest extends \PHPUnit\Framework\TestCase +class QuoteRepositoryTest extends TestCase { /** * @var \Magento\Quote\Api\CartRepositoryInterface @@ -23,32 +37,32 @@ class QuoteRepositoryTest extends \PHPUnit\Framework\TestCase private $model; /** - * @var \Magento\Quote\Model\QuoteFactory|\PHPUnit_Framework_MockObject_MockObject + * @var CartInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject */ - private $quoteFactoryMock; + private $cartFactoryMock; /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ private $storeManagerMock; /** - * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject + * @var Store|\PHPUnit_Framework_MockObject_MockObject */ private $storeMock; /** - * @var \Magento\Quote\Model\Quote|\PHPUnit_Framework_MockObject_MockObject + * @var Quote|\PHPUnit_Framework_MockObject_MockObject */ private $quoteMock; /** - * @var \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject + * @var CartSearchResultsInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject */ private $searchResultsDataFactory; /** - * @var \Magento\Quote\Model\ResourceModel\Quote\Collection|\PHPUnit_Framework_MockObject_MockObject + * @var Collection|\PHPUnit_Framework_MockObject_MockObject */ private $quoteCollectionMock; @@ -78,21 +92,21 @@ class QuoteRepositoryTest extends \PHPUnit\Framework\TestCase private $objectManagerMock; /** - * @var \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject */ private $quoteCollectionFactoryMock; protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $objectManager = new ObjectManager($this); - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); + $this->objectManagerMock = $this->createMock(ObjectManagerInterface::class); \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); - $this->quoteFactoryMock = $this->createPartialMock(\Magento\Quote\Model\QuoteFactory::class, ['create']); - $this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class); + $this->cartFactoryMock = $this->createPartialMock(CartInterfaceFactory::class, ['create']); + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); $this->quoteMock = $this->createPartialMock( - \Magento\Quote\Model\Quote::class, + Quote::class, [ 'load', 'loadByIdWithoutStore', @@ -108,35 +122,35 @@ protected function setUp() 'getData' ] ); - $this->storeMock = $this->createMock(\Magento\Store\Model\Store::class); + $this->storeMock = $this->createMock(Store::class); $this->searchResultsDataFactory = $this->createPartialMock( - \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory::class, + CartSearchResultsInterfaceFactory::class, ['create'] ); $this->quoteCollectionMock = - $this->createMock(\Magento\Quote\Model\ResourceModel\Quote\Collection::class); + $this->createMock(Collection::class); $this->extensionAttributesJoinProcessorMock = $this->createMock( - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface::class + JoinProcessorInterface::class ); $this->collectionProcessor = $this->createMock( - \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + CollectionProcessorInterface::class ); $this->quoteCollectionFactoryMock = $this->createPartialMock( - \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory::class, + CollectionFactory::class, ['create'] ); $this->model = $objectManager->getObject( - \Magento\Quote\Model\QuoteRepository::class, + QuoteRepository::class, [ - 'quoteFactory' => $this->quoteFactoryMock, 'storeManager' => $this->storeManagerMock, 'searchResultsDataFactory' => $this->searchResultsDataFactory, 'quoteCollection' => $this->quoteCollectionMock, 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock, 'collectionProcessor' => $this->collectionProcessor, - 'quoteCollectionFactory' => $this->quoteCollectionFactoryMock + 'quoteCollectionFactory' => $this->quoteCollectionFactoryMock, + 'cartFactory' => $this->cartFactoryMock ] ); @@ -161,7 +175,7 @@ public function testGetWithExceptionById() { $cartId = 14; - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); @@ -178,7 +192,7 @@ public function testGet() { $cartId = 15; - $this->quoteFactoryMock->expects(static::once()) + $this->cartFactoryMock->expects(static::once()) ->method('create') ->willReturn($this->quoteMock); $this->storeManagerMock->expects(static::once()) @@ -211,7 +225,7 @@ public function testGetForCustomerAfterGet() $cartId = 15; $customerId = 23; - $this->quoteFactoryMock->expects(static::exactly(2)) + $this->cartFactoryMock->expects(static::exactly(2)) ->method('create') ->willReturn($this->quoteMock); $this->storeManagerMock->expects(static::exactly(2)) @@ -249,7 +263,7 @@ public function testGetWithSharedStoreIds() $cartId = 16; $sharedStoreIds = [1, 2]; - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->once()) @@ -275,7 +289,7 @@ public function testGetForCustomer() $cartId = 17; $customerId = 23; - $this->quoteFactoryMock->expects(static::once()) + $this->cartFactoryMock->expects(static::once()) ->method('create') ->willReturn($this->quoteMock); $this->storeManagerMock->expects(static::once()) @@ -310,7 +324,7 @@ public function testGetActiveWithExceptionById() { $cartId = 14; - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); @@ -332,7 +346,7 @@ public function testGetActiveWithExceptionByIsActive() { $cartId = 15; - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); @@ -355,7 +369,7 @@ public function testGetActive() { $cartId = 15; - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); @@ -379,7 +393,7 @@ public function testGetActiveWithSharedStoreIds() $cartId = 16; $sharedStoreIds = [1, 2]; - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->once()) @@ -406,7 +420,7 @@ public function testGetActiveForCustomer() $cartId = 17; $customerId = 23; - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->never())->method('setSharedStoreIds'); @@ -430,14 +444,14 @@ public function testSave() { $cartId = 100; $quoteMock = $this->createPartialMock( - \Magento\Quote\Model\Quote::class, + Quote::class, ['getId', 'getCustomerId', 'getStoreId', 'hasData', 'setData'] ); $quoteMock->expects($this->exactly(3))->method('getId')->willReturn($cartId); $quoteMock->expects($this->once())->method('getCustomerId')->willReturn(2); $quoteMock->expects($this->once())->method('getStoreId')->willReturn(5); - $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); + $this->cartFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock); $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock); $this->storeMock->expects($this->once())->method('getId')->willReturn(1); $this->quoteMock->expects($this->once())->method('getId')->willReturn($cartId); @@ -481,8 +495,8 @@ public function testGetList() ->method('load') ->with($cartMock); - $searchResult = $this->createMock(\Magento\Quote\Api\Data\CartSearchResultsInterface::class); - $searchCriteriaMock = $this->createMock(\Magento\Framework\Api\SearchCriteria::class); + $searchResult = $this->createMock(CartSearchResultsInterface::class); + $searchCriteriaMock = $this->createMock(SearchCriteria::class); $this->searchResultsDataFactory ->expects($this->once()) ->method('create') @@ -495,7 +509,7 @@ public function testGetList() $this->extensionAttributesJoinProcessorMock->expects($this->once()) ->method('process') ->with( - $this->isInstanceOf(\Magento\Quote\Model\ResourceModel\Quote\Collection::class) + $this->isInstanceOf(Collection::class) ); $this->quoteCollectionMock->expects($this->atLeastOnce())->method('getItems')->willReturn([$cartMock]); $searchResult->expects($this->once())->method('setTotalCount')->with($pageSize); From 48b0ab873183966d3f797df97d64cf7fccc1bd5d Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 5 Apr 2019 16:20:10 +0300 Subject: [PATCH 056/247] #21737 Duplicating product with translated url keys over multiple storeviews causes non-unique url keys to be generated --- .../Magento/Catalog/Model/Product/Copier.php | 83 +++++++++++++++---- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php index 53fa11df04b3..2cd9304af789 100644 --- a/app/code/Magento/Catalog/Model/Product/Copier.php +++ b/app/code/Magento/Catalog/Model/Product/Copier.php @@ -74,22 +74,9 @@ public function copy(Product $product) $duplicate->setUpdatedAt(null); $duplicate->setId(null); $duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID); - $this->copyConstructor->build($product, $duplicate); - $isDuplicateSaved = false; - do { - $urlKey = $duplicate->getUrlKey(); - $urlKey = preg_match('/(.*)-(\d+)$/', $urlKey, $matches) - ? $matches[1] . '-' . ($matches[2] + 1) - : $urlKey . '-1'; - $duplicate->setUrlKey($urlKey); - $duplicate->setData('url_path', null); - try { - $duplicate->save(); - $isDuplicateSaved = true; - } catch (\Magento\Framework\Exception\AlreadyExistsException $e) { - } - } while (!$isDuplicateSaved); + $this->setDefaultUrl($product, $duplicate); + $this->setStoresUrl($product, $duplicate); $this->getOptionRepository()->duplicate($product, $duplicate); $product->getResource()->duplicate( $product->getData($metadata->getLinkField()), @@ -98,6 +85,72 @@ public function copy(Product $product) return $duplicate; } + /** + * Set default URL. + * + * @param Product $product + * @param Product $duplicate + * @return void + */ + private function setDefaultUrl(Product $product, Product $duplicate) : void + { + $duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID); + $resource = $product->getResource(); + $attribute = $resource->getAttribute('url_key'); + $productId = $product->getId(); + $urlKey = $resource->getAttributeRawValue($productId, 'url_key', \Magento\Store\Model\Store::DEFAULT_STORE_ID); + do { + $urlKey = $this->modifyUrl($urlKey); + $duplicate->setUrlKey($urlKey); + } while (!$attribute->getEntity()->checkAttributeUniqueValue($attribute, $duplicate)); + $duplicate->setData('url_path', null); + $duplicate->save(); + } + + /** + * Set URL for each store. + * + * @param Product $product + * @param Product $duplicate + * @return void + */ + private function setStoresUrl(Product $product, Product $duplicate) : void + { + $storeIds = $duplicate->getStoreIds(); + $resource = $product->getResource(); + $productId = $product->getId(); + $duplicate->setData('save_rewrites_history', false); + foreach ($storeIds as $storeId) { + $isDuplicateSaved = false; + $duplicate->setStoreId($storeId); + $urlKey = $resource->getAttributeRawValue($productId, 'url_key', $storeId); + do { + $urlKey = $this->modifyUrl($urlKey); + $duplicate->setUrlKey($urlKey); + $duplicate->setData('url_path', null); + try { + $duplicate->save(); + $isDuplicateSaved = true; + } catch (\Magento\Framework\Exception\AlreadyExistsException $e) { + } + } while (!$isDuplicateSaved); + } + $duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID); + } + + /** + * Modify URL key. + * + * @param string $urlKey + * @return string + */ + private function modifyUrl(string $urlKey) : string + { + return preg_match('/(.*)-(\d+)$/', $urlKey, $matches) + ? $matches[1] . '-' . ($matches[2] + 1) + : $urlKey . '-1'; + } + /** * Returns product option repository. * From 0733e7f995527ca95ea1dca26cbfb00aa2307d21 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Fri, 5 Apr 2019 11:31:52 -0500 Subject: [PATCH 057/247] Issue-230: adding varnish - fixing static errors --- .../HttpHeaderProcessor/CurrencyProcessor.php | 13 ++++++++++--- .../HttpHeaderProcessor/CurrencyValidator.php | 1 + app/code/Magento/GraphQl/Controller/GraphQl.php | 2 +- .../Controller/HttpRequestValidatorInterface.php | 3 ++- .../GraphQlCache/Controller/GraphQl/Plugin.php | 4 ++-- .../Model/App/CacheIdentifierPlugin.php | 7 ++----- .../HttpHeaderProcessor/StoreProcessor.php | 5 ++--- .../HttpHeaderProcessor/StoreValidator.php | 1 + .../GraphQlReader/Reader/InputObjectType.php | 5 +++-- .../GraphQlReader/Reader/ObjectType.php | 1 - 10 files changed, 24 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php index 8daa7750ddd3..383955772d1b 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php @@ -7,11 +7,11 @@ namespace Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpHeaderProcessorInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Http\Context as HttpContext; use Magento\Framework\Session\SessionManagerInterface; +use Psr\Log\LoggerInterface; /** * Process the "Currency" header entry @@ -33,6 +33,11 @@ class CurrencyProcessor implements HttpHeaderProcessorInterface */ private $session; + /** + * @var LoggerInterface + */ + private $logger; + /** * @param StoreManagerInterface $storeManager * @param HttpContext $httpContext @@ -41,11 +46,13 @@ class CurrencyProcessor implements HttpHeaderProcessorInterface public function __construct( StoreManagerInterface $storeManager, HttpContext $httpContext, - SessionManagerInterface $session + SessionManagerInterface $session, + LoggerInterface $logger ) { $this->storeManager = $storeManager; $this->httpContext = $httpContext; $this->session = $session; + $this->logger = $logger; } /** @@ -53,7 +60,6 @@ public function __construct( * * @param string $headerValue * @return void - * @throws GraphQlInputException */ public function processHeaderValue(string $headerValue) : void { @@ -81,6 +87,7 @@ public function processHeaderValue(string $headerValue) : void } } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { //skip store not found exception as it will be handled in graphql validation + $this->logger->warning($e->getMessage()); } } } diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php index 1a2938c7d753..0d4a6708ba43 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php @@ -36,6 +36,7 @@ public function __construct( * * @param HttpRequestInterface $request * @return void + * @throws GraphQlInputException */ public function validate(HttpRequestInterface $request): void { diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index ab7fa3648d5d..4fccec6c046e 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -82,8 +82,8 @@ public function __construct( QueryProcessor $queryProcessor, ExceptionFormatter $graphQlError, ContextInterface $resolverContext, - QueryFields $queryFields, HttpRequestProcessor $requestProcessor, + QueryFields $queryFields, JsonFactory $jsonFactory ) { $this->schemaGenerator = $schemaGenerator; diff --git a/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php b/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php index c0873b0caff8..23e19195393f 100644 --- a/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php +++ b/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php @@ -8,7 +8,7 @@ namespace Magento\GraphQl\Controller; use Magento\Framework\App\HttpRequestInterface; - +use Magento\Framework\GraphQl\Exception\GraphQlInputException; /** * Use this interface to implement a validator for a Graphql HTTP requests */ @@ -19,6 +19,7 @@ interface HttpRequestValidatorInterface * * @param HttpRequestInterface $request * @return void + * @throws GraphQlInputException */ public function validate(HttpRequestInterface $request) : void; } diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php index b5e4155a3382..8e849904a0ad 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php @@ -82,9 +82,9 @@ public function beforeDispatch( * depending if it comes from builtin cache or the dispatch. * * @param FrontControllerInterface $subject - * @param ResponseInterface | ResultInterface $response + * @param ResponseInterface|ResultInterface $response * @param RequestInterface $request - * @return ResponseInterface | ResultInterface + * @return ResponseInterface|ResultInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterDispatch( diff --git a/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php b/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php index 9b70f4305fc7..a0fa5c1f9de9 100644 --- a/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php +++ b/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php @@ -6,11 +6,8 @@ namespace Magento\GraphQlCache\Model\App; -use Magento\Framework\Serialize\Serializer\Json; - /** - * Class CachePlugin - * Should add unique identifier for graphql query + * Handles unique identifier for graphql query */ class CacheIdentifierPlugin { @@ -53,7 +50,7 @@ public function __construct( } /** - * Adds a unique key identifier for graphql specific query and variables that skips X-Magento-Vary cookie + * Add/Override a unique key identifier for graphql specific query and variables that skips X-Magento-Vary cookie * * @param \Magento\Framework\App\PageCache\Identifier $identifier * @param string $result diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index 227665cbdd28..70d4730c2a63 100644 --- a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -7,7 +7,6 @@ namespace Magento\StoreGraphQl\Controller\HttpHeaderProcessor; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Controller\HttpHeaderProcessorInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Http\Context as HttpContext; @@ -36,6 +35,7 @@ class StoreProcessor implements HttpHeaderProcessorInterface /** * @param StoreManagerInterface $storeManager * @param HttpContext $httpContext + * @param StoreCookieManagerInterface $storeCookieManager */ public function __construct( StoreManagerInterface $storeManager, @@ -54,7 +54,6 @@ public function __construct( * * @param string $headerValue * @return void - * @throws GraphQlInputException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function processHeaderValue(string $headerValue) : void @@ -74,7 +73,7 @@ public function processHeaderValue(string $headerValue) : void /** * Update context accordingly to the store code found. * - * @param string $store + * @param string $storeCode * @return void */ private function updateContext(string $storeCode) : void diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php index b3b5f1a6abd4..437ff2c5dacc 100644 --- a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php @@ -36,6 +36,7 @@ public function __construct( * * @param HttpRequestInterface $request * @return void + * @throws GraphQlInputException */ public function validate(HttpRequestInterface $request): void { diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php index e8c4f2721f65..262ae33fb0a4 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php @@ -12,7 +12,6 @@ use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\DocReader; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\CacheTagReader; - /** * Composite configuration reader to handle the input object type meta */ @@ -50,7 +49,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array { @@ -80,6 +79,8 @@ public function read(\GraphQL\Type\Definition\Type $typeMeta) : array } /** + * Read the input's meta data + * * @param \GraphQL\Type\Definition\InputObjectField $fieldMeta * @return array */ diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php index 5d38d1444e4f..97dc5a3d1f51 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php @@ -13,7 +13,6 @@ use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\ImplementsReader; use Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\CacheTagReader; - /** * Composite configuration reader to handle the object type meta */ From 282f58469d822019a951eb920596d7a757f5db7e Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Fri, 5 Apr 2019 11:34:14 -0500 Subject: [PATCH 058/247] 230: Implement cache tag generation for GraphQL queries - Removed bad code from debugging --- .../Framework/GraphQl/Config/Element/FieldFactory.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php index 000fcc298708..60191b69be47 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php @@ -52,13 +52,6 @@ public function createFromConfigData( $fieldData['itemType'] = str_replace('[]', '', $fieldData['type']); } - if (isset($fieldData['description'])) { - if ($fieldData['description'] == "The list of products assigned to the category") { - $fieldType = $fieldData['type']; - } - } - - return $this->objectManager->create( Field::class, [ From 10274e3cb1cc2a68e126f164be256a25a2dc2b4e Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Fri, 5 Apr 2019 11:46:57 -0500 Subject: [PATCH 059/247] Issue-230: adding varnish - fixing static errors --- app/code/Magento/GraphQlCache/README.md | 4 ++++ app/code/Magento/GraphQlCache/composer.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/GraphQlCache/README.md diff --git a/app/code/Magento/GraphQlCache/README.md b/app/code/Magento/GraphQlCache/README.md new file mode 100644 index 000000000000..98ccf26d038a --- /dev/null +++ b/app/code/Magento/GraphQlCache/README.md @@ -0,0 +1,4 @@ +# GraphQl Cache + +**GraphQl Cache** provides the caching ability for a graphql query. +This enabled Magento's builtin cache and varnish by leveraging FPC (Full page cache) that's used for front end. diff --git a/app/code/Magento/GraphQlCache/composer.json b/app/code/Magento/GraphQlCache/composer.json index 54e6573cb61c..2633b4ea9b35 100644 --- a/app/code/Magento/GraphQlCache/composer.json +++ b/app/code/Magento/GraphQlCache/composer.json @@ -4,7 +4,7 @@ "type": "magento2-module", "require": { "php": "~7.1.3||~7.2.0", - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "*", "magento/module-page-cache": "*" }, "license": [ From 59db1306b3f2ba08750909285278e66996721b5e Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Fri, 5 Apr 2019 16:41:41 -0500 Subject: [PATCH 060/247] 230: Implement cache tag generation for GraphQL queries - Fixed X-Magento-Tags not displaying in Developer mode --- .../Magento/Framework/App/PageCache/Kernel.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/App/PageCache/Kernel.php b/lib/internal/Magento/Framework/App/PageCache/Kernel.php index 13e18ed28fd6..2fb5b832e346 100644 --- a/lib/internal/Magento/Framework/App/PageCache/Kernel.php +++ b/lib/internal/Magento/Framework/App/PageCache/Kernel.php @@ -5,6 +5,8 @@ */ namespace Magento\Framework\App\PageCache; +use Magento\Framework\App\State as AppState; + /** * Builtin cache processor */ @@ -52,6 +54,11 @@ class Kernel */ private $httpFactory; + /** + * @var AppState + */ + private $state; + /** * @param Cache $cache * @param Identifier $identifier @@ -60,6 +67,7 @@ class Kernel * @param \Magento\Framework\App\Http\ContextFactory|null $contextFactory * @param \Magento\Framework\App\Response\HttpFactory|null $httpFactory * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer + * @param AppState $state */ public function __construct( \Magento\Framework\App\PageCache\Cache $cache, @@ -68,11 +76,13 @@ public function __construct( \Magento\Framework\App\Http\Context $context = null, \Magento\Framework\App\Http\ContextFactory $contextFactory = null, \Magento\Framework\App\Response\HttpFactory $httpFactory = null, - \Magento\Framework\Serialize\SerializerInterface $serializer = null + \Magento\Framework\Serialize\SerializerInterface $serializer = null, + AppState $state ) { $this->cache = $cache; $this->identifier = $identifier; $this->request = $request; + $this->state = $state; if ($context) { $this->context = $context; @@ -144,7 +154,9 @@ public function process(\Magento\Framework\App\Response\Http $response) $tags = $tagsHeader ? explode(',', $tagsHeader->getFieldValue()) : []; $response->clearHeader('Set-Cookie'); - $response->clearHeader('X-Magento-Tags'); + if ($this->state->getMode() != AppState::MODE_DEVELOPER) { + $response->clearHeader('X-Magento-Tags'); + } if (!headers_sent()) { header_remove('Set-Cookie'); } From dfea9bfffde7480f855ce38ebfbc696eb686109a Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 8 Apr 2019 10:12:28 -0500 Subject: [PATCH 061/247] Issue-230: adding varnish - fixing composer --- app/code/Magento/DirectoryGraphQl/composer.json | 4 +--- app/code/Magento/GraphQlCache/composer.json | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/DirectoryGraphQl/composer.json b/app/code/Magento/DirectoryGraphQl/composer.json index ca1790c949d4..d3c783e6c7bf 100644 --- a/app/code/Magento/DirectoryGraphQl/composer.json +++ b/app/code/Magento/DirectoryGraphQl/composer.json @@ -6,11 +6,9 @@ "php": "~7.1.3||~7.2.0", "magento/module-directory": "*", "magento/module-store": "*", + "magento/module-graph-ql": "*", "magento/framework": "*" }, - "suggest": { - "magento/module-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GraphQlCache/composer.json b/app/code/Magento/GraphQlCache/composer.json index 2633b4ea9b35..436ae95da40f 100644 --- a/app/code/Magento/GraphQlCache/composer.json +++ b/app/code/Magento/GraphQlCache/composer.json @@ -4,8 +4,9 @@ "type": "magento2-module", "require": { "php": "~7.1.3||~7.2.0", - "magento/module-graph-ql": "*", - "magento/module-page-cache": "*" + "magento/framework": "*", + "magento/module-page-cache": "*", + "magento/module-graph-ql": "*" }, "license": [ "OSL-3.0", From fda9e3e5392a781f3fc2cc1e4a1f43ac57d7a174 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 8 Apr 2019 11:49:04 -0500 Subject: [PATCH 062/247] Issue-230: adding varnish - fixing static --- .../CurrencyValidator.php | 2 +- .../Magento/DirectoryGraphQl/etc/graphql/di.xml | 2 +- .../App/PageCache/Identifier.php} | 7 ++++--- .../Plugin/Query/Resolver.php} | 13 ++++++------- app/code/Magento/GraphQlCache/README.md | 4 ++-- app/code/Magento/GraphQlCache/etc/graphql/di.xml | 4 ++-- .../HttpHeaderProcessor/StoreProcessor.php | 1 - .../StoreValidator.php | 2 +- app/code/Magento/StoreGraphQl/etc/graphql/di.xml | 2 +- .../Magento/Framework/App/PageCache/Kernel.php | 13 ++++++++++--- .../Framework/GraphQl/Config/Element/Field.php | 6 +++--- .../GraphQlReader/MetaReader/FieldMetaReader.php | 15 ++++++++++----- .../GraphQlReader/Reader/InputObjectType.php | 13 +++++++++---- .../GraphQlReader/Reader/InterfaceType.php | 13 +++++++++---- .../GraphQlReader/Reader/ObjectType.php | 12 +++++++++--- 15 files changed, 68 insertions(+), 41 deletions(-) rename app/code/Magento/DirectoryGraphQl/Controller/{HttpHeaderProcessor => HttpRequestValidator}/CurrencyValidator.php (96%) rename app/code/Magento/GraphQlCache/Model/{App/CacheIdentifierPlugin.php => Plugin/App/PageCache/Identifier.php} (92%) rename app/code/Magento/GraphQlCache/{Query/Resolver/Plugin.php => Model/Plugin/Query/Resolver.php} (90%) rename app/code/Magento/StoreGraphQl/Controller/{HttpHeaderProcessor => HttpRequestValidator}/StoreValidator.php (96%) diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php similarity index 96% rename from app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php rename to app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php index 0d4a6708ba43..7ecff5d1f3f6 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyValidator.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor; +namespace Magento\DirectoryGraphQl\Controller\HttpRequestValidator; use Magento\Framework\App\HttpRequestInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; diff --git a/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml b/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml index e9791654251c..63f501551f53 100644 --- a/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/DirectoryGraphQl/etc/graphql/di.xml @@ -12,7 +12,7 @@ Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor\CurrencyProcessor - Magento\DirectoryGraphQl\Controller\HttpHeaderProcessor\CurrencyValidator + Magento\DirectoryGraphQl\Controller\HttpRequestValidator\CurrencyValidator diff --git a/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php b/app/code/Magento/GraphQlCache/Model/Plugin/App/PageCache/Identifier.php similarity index 92% rename from app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php rename to app/code/Magento/GraphQlCache/Model/Plugin/App/PageCache/Identifier.php index a0fa5c1f9de9..e02a51d2c1ca 100644 --- a/app/code/Magento/GraphQlCache/Model/App/CacheIdentifierPlugin.php +++ b/app/code/Magento/GraphQlCache/Model/Plugin/App/PageCache/Identifier.php @@ -3,13 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -namespace Magento\GraphQlCache\Model\App; +namespace Magento\GraphQlCache\Model\Plugin\App\PageCache; /** * Handles unique identifier for graphql query */ -class CacheIdentifierPlugin +class Identifier { /** * @var \Magento\Framework\App\Request\Http @@ -57,7 +58,7 @@ public function __construct( * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetValue(\Magento\Framework\App\PageCache\Identifier $identifier, string $result) + public function afterGetValue(\Magento\Framework\App\PageCache\Identifier $identifier, string $result) : string { if ($this->config->isEnabled()) { $data = [ diff --git a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php similarity index 90% rename from app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php rename to app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php index 029e29df3af2..f3cccdb0995d 100644 --- a/app/code/Magento/GraphQlCache/Query/Resolver/Plugin.php +++ b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\GraphQlCache\Query\Resolver; +namespace Magento\GraphQlCache\Model\Plugin\Query; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -15,11 +15,9 @@ use Magento\Framework\App\RequestInterface; /** - * Class Plugin - * - * @package Magento\GraphQlCache\Query\Resolver + * Plugin to handle cache validation that can be done after each resolver */ -class Plugin +class Resolver { /** * @var CacheableQuery @@ -42,7 +40,7 @@ public function __construct(CacheableQuery $cacheableQuery, RequestInterface $re } /** - * @inheritdoc + * Set cache validity to the cacheableQuery after resolving any resolver in a query * * @param ResolverInterface $subject * @param Object $resolvedValue @@ -52,6 +50,7 @@ public function __construct(CacheableQuery $cacheableQuery, RequestInterface $re * @param array|null $value * @param array|null $args * @return mixed + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterResolve( ResolverInterface $subject, @@ -84,7 +83,7 @@ public function afterResolve( * @param Object $resolvedValue * @return array */ - private function extractResolvedItemsIds($resolvedValue) + private function extractResolvedItemsIds($resolvedValue) : array { if (isset($resolvedValue['ids']) && is_array($resolvedValue['ids'])) { return $resolvedValue['ids']; diff --git a/app/code/Magento/GraphQlCache/README.md b/app/code/Magento/GraphQlCache/README.md index 98ccf26d038a..fd2f19f957c5 100644 --- a/app/code/Magento/GraphQlCache/README.md +++ b/app/code/Magento/GraphQlCache/README.md @@ -1,4 +1,4 @@ # GraphQl Cache -**GraphQl Cache** provides the caching ability for a graphql query. -This enabled Magento's builtin cache and varnish by leveraging FPC (Full page cache) that's used for front end. +**GraphQL Cache** provides the ability to cache GraphQL queries. +This module allows Magento's built-in cache or Varnish as the application for serving the Full Page Cache to the front end. diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml index 5c13dbb02e06..8a5b6476c7af 100644 --- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -12,11 +12,11 @@ - + + type="Magento\GraphQlCache\Model\Plugin\App\PageCache\Identifier" sortOrder="1"/> diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php index 70d4730c2a63..7999a96917cd 100644 --- a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreProcessor.php @@ -54,7 +54,6 @@ public function __construct( * * @param string $headerValue * @return void - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function processHeaderValue(string $headerValue) : void { diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php b/app/code/Magento/StoreGraphQl/Controller/HttpRequestValidator/StoreValidator.php similarity index 96% rename from app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php rename to app/code/Magento/StoreGraphQl/Controller/HttpRequestValidator/StoreValidator.php index 437ff2c5dacc..afc84c061df4 100644 --- a/app/code/Magento/StoreGraphQl/Controller/HttpHeaderProcessor/StoreValidator.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpRequestValidator/StoreValidator.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\StoreGraphQl\Controller\HttpHeaderProcessor; +namespace Magento\StoreGraphQl\Controller\HttpRequestValidator; use Magento\Framework\App\HttpRequestInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; diff --git a/app/code/Magento/StoreGraphQl/etc/graphql/di.xml b/app/code/Magento/StoreGraphQl/etc/graphql/di.xml index 50f612194893..c2191164287f 100644 --- a/app/code/Magento/StoreGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/StoreGraphQl/etc/graphql/di.xml @@ -12,7 +12,7 @@ Magento\StoreGraphQl\Controller\HttpHeaderProcessor\StoreProcessor - Magento\StoreGraphQl\Controller\HttpHeaderProcessor\StoreValidator + Magento\StoreGraphQl\Controller\HttpRequestValidator\StoreValidator diff --git a/lib/internal/Magento/Framework/App/PageCache/Kernel.php b/lib/internal/Magento/Framework/App/PageCache/Kernel.php index 2fb5b832e346..813762c646d4 100644 --- a/lib/internal/Magento/Framework/App/PageCache/Kernel.php +++ b/lib/internal/Magento/Framework/App/PageCache/Kernel.php @@ -67,7 +67,7 @@ class Kernel * @param \Magento\Framework\App\Http\ContextFactory|null $contextFactory * @param \Magento\Framework\App\Response\HttpFactory|null $httpFactory * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer - * @param AppState $state + * @param AppState|null $state */ public function __construct( \Magento\Framework\App\PageCache\Cache $cache, @@ -77,12 +77,11 @@ public function __construct( \Magento\Framework\App\Http\ContextFactory $contextFactory = null, \Magento\Framework\App\Response\HttpFactory $httpFactory = null, \Magento\Framework\Serialize\SerializerInterface $serializer = null, - AppState $state + AppState $state = null ) { $this->cache = $cache; $this->identifier = $identifier; $this->request = $request; - $this->state = $state; if ($context) { $this->context = $context; @@ -112,6 +111,14 @@ public function __construct( \Magento\Framework\Serialize\SerializerInterface::class ); } + + if ($state) { + $this->state = $state; + } else { + $this->state = \Magento\Framework\App\ObjectManager::getInstance()->get( + AppState::class + ); + } } /** diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php index dc59e490a020..0fc51e4ecd06 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/Field.php @@ -61,8 +61,8 @@ class Field implements OutputFieldInterface * @param string $itemType * @param string $resolver * @param string $description - * @param array $cache * @param array $arguments + * @param array $cache */ public function __construct( string $name, @@ -72,8 +72,8 @@ public function __construct( string $itemType = '', string $resolver = '', string $description = '', - array $cache = [], - array $arguments = [] + array $arguments = [], + array $cache = [] ) { $this->name = $name; $this->type = $isList ? $itemType : $type; diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php index 97f169054a07..c20a3875e71f 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/FieldMetaReader.php @@ -28,19 +28,24 @@ class FieldMetaReader private $cacheTagReader; /** - * FieldMetaReader constructor. - * @param \Magento\Framework\GraphQlSchemaStitching\GraphQlReader\MetaReader\TypeMetaWrapperReader $typeMetaReader + * @param TypeMetaWrapperReader $typeMetaReader * @param DocReader $docReader - * @param CacheTagReader $cacheTagReader + * @param CacheTagReader|null $cacheTagReader */ public function __construct( TypeMetaWrapperReader $typeMetaReader, DocReader $docReader, - CacheTagReader $cacheTagReader + CacheTagReader $cacheTagReader = null ) { $this->typeMetaReader = $typeMetaReader; $this->docReader = $docReader; - $this->cacheTagReader = $cacheTagReader; + if ($cacheTagReader) { + $this->cacheTagReader = $cacheTagReader; + } else { + $this->cacheTagReader = \Magento\Framework\App\ObjectManager::getInstance()->get( + CacheTagReader::class + ); + } } /** diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php index 262ae33fb0a4..92ac22607b98 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InputObjectType.php @@ -33,19 +33,24 @@ class InputObjectType implements TypeMetaReaderInterface private $cacheTagReader; /** - * InputObjectType constructor. * @param TypeMetaWrapperReader $typeMetaReader * @param DocReader $docReader - * @param CacheTagReader $cacheTagReader + * @param CacheTagReader|null $cacheTagReader */ public function __construct( TypeMetaWrapperReader $typeMetaReader, DocReader $docReader, - CacheTagReader $cacheTagReader + CacheTagReader $cacheTagReader = null ) { $this->typeMetaReader = $typeMetaReader; $this->docReader = $docReader; - $this->cacheTagReader = $cacheTagReader; + if ($cacheTagReader) { + $this->cacheTagReader = $cacheTagReader; + } else { + $this->cacheTagReader = \Magento\Framework\App\ObjectManager::getInstance()->get( + CacheTagReader::class + ); + } } /** diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php index 2020f42dcaef..bd21e6361d4c 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/InterfaceType.php @@ -33,19 +33,24 @@ class InterfaceType implements TypeMetaReaderInterface private $cacheTagReader; /** - * InterfaceType constructor. * @param FieldMetaReader $fieldMetaReader * @param DocReader $docReader - * @param CacheTagReader $cacheTagReader + * @param CacheTagReader|null $cacheTagReader */ public function __construct( FieldMetaReader $fieldMetaReader, DocReader $docReader, - CacheTagReader $cacheTagReader + CacheTagReader $cacheTagReader = null ) { $this->fieldMetaReader = $fieldMetaReader; $this->docReader = $docReader; - $this->cacheTagReader = $cacheTagReader; + if ($cacheTagReader) { + $this->cacheTagReader = $cacheTagReader; + } else { + $this->cacheTagReader = \Magento\Framework\App\ObjectManager::getInstance()->get( + CacheTagReader::class + ); + } } /** diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php index 97dc5a3d1f51..361eb30423a9 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/Reader/ObjectType.php @@ -43,18 +43,24 @@ class ObjectType implements TypeMetaReaderInterface * @param FieldMetaReader $fieldMetaReader * @param DocReader $docReader * @param ImplementsReader $implementsAnnotation - * @param CacheTagReader $cacheTagReader + * @param CacheTagReader|null $cacheTagReader */ public function __construct( FieldMetaReader $fieldMetaReader, DocReader $docReader, ImplementsReader $implementsAnnotation, - CacheTagReader $cacheTagReader + CacheTagReader $cacheTagReader = null ) { $this->fieldMetaReader = $fieldMetaReader; $this->docReader = $docReader; $this->implementsAnnotation = $implementsAnnotation; - $this->cacheTagReader = $cacheTagReader; + if ($cacheTagReader) { + $this->cacheTagReader = $cacheTagReader; + } else { + $this->cacheTagReader = \Magento\Framework\App\ObjectManager::getInstance()->get( + CacheTagReader::class + ); + } } /** From 1575b4ac59dd14d43f0a03133b96bac471600c32 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Mon, 8 Apr 2019 15:24:12 -0500 Subject: [PATCH 063/247] GraphQL-514: Test coverage for tag cache generation - added test framework changes and api-functional tests for coverage --- .../TestFramework/TestCase/GraphQl/Client.php | 22 ++++++ .../TestCase/GraphQlAbstract.php | 23 ++++++ .../TestCase/HttpClient/CurlClient.php | 12 +++ .../GraphQl/PageCache/CacheTagTest.php | 77 +++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index 5eea3be840ae..5945124936c6 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -113,6 +113,28 @@ private function processResponse(string $response) return $responseArray['data']; } + /** + * Process the header information from response + * + * @param string $query + * @param array $variables + * @param string $operationName + * @param array $headers + * @return mixed + */ + public function getQueryResponseHeaders(string $query, array $variables = [], string $operationName = '', array $headers = []) + { + $url = $this->getEndpointUrl(); + $requestArray = [ + 'query' => $query, + 'variables' => empty($variables) ? $variables : null, + 'operationName' => empty($operationName) ? $operationName : null + ]; + + $responseHeader = $this->curlClient->getHttpHeaders($url, $requestArray, $headers); + return $responseHeader; + } + /** * Process errors * diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php index 8abd97b4b744..810ebcbb098f 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -77,6 +77,29 @@ public function graphQlMutation( ); } + /** + * Perform GraphQL query via GET and returns only the response headers + * + * @param string $query + * @param array $variables + * @param string $operationName + * @param array $headers + * @return mixed + */ + public function graphQlQueryForHttpHeaders( + string $query, + array $variables = [], + string $operationName = '', + array $headers = [] + ) { + return $response = $this->getGraphQlClient()->getQueryResponseHeaders( + $query, + $variables, + $operationName, + $this->composeHeaders($headers) + ); + } + /** * Compose headers * diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php index 787f207ef33e..24f622da7055 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php @@ -32,6 +32,18 @@ public function get($url, $data = [], $headers = []) return $resp["body"]; } + public function getHttpHeaders($url, $data = [], $headers = []) + { + if (!empty($data)) { + $url .= '?' . http_build_query($data); + } + + $curlOpts = []; + $curlOpts[CURLOPT_CUSTOMREQUEST] = \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET; + $resp = $this->invokeApi($url, $curlOpts, $headers); + return $resp["header"]; + } + /** * Perform HTTP DELETE request * diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php new file mode 100644 index 000000000000..0c9f489f91e3 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -0,0 +1,77 @@ +graphQlQueryForHttpHeaders($query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); + $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + + /** cache-debug should be a HIT for the second round */ + $responseHitHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHitHeaders, $matchesHit); + $this->assertEquals('HIT', rtrim($matchesHit[1],"\r")); + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + /** @var Product $product */ + $product =$productRepository->get($productSku,false,null, true); + /** update the price attribute for the product in test */ + $product->setPrice(15); + $product->save(); + /** cache-debug header value should be a MISS after product attribute update */ + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); + $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + + /** checks if cache tags for products are correctly displayed in the response header */ + preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); + $actualCacheTags = explode(',', rtrim($headerCacheTags[1],"\r")); + $expectedCacheTags=['cat_p','cat_p_' . $product->getId(),'FPC']; + foreach(array_keys($actualCacheTags) as $key){ + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] + ); + } + } +} From 32f2813ab8dca3d6d79e460392c1b24cbda0d89c Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Mon, 8 Apr 2019 21:48:00 +0100 Subject: [PATCH 064/247] magento/magento2#18541: Fixed static tests --- .../Test/Unit/Layout/Argument/Interpreter/ObjectTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php index 180888bcc1d3..6e3ba94de507 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Argument/Interpreter/ObjectTest.php @@ -3,10 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\View\Test\Unit\Layout\Argument\Interpreter; use Magento\Framework\View\Layout\Argument\Interpreter\DataObject; +/** + * Tests layout argument interpreter data object. + */ class ObjectTest extends \PHPUnit\Framework\TestCase { const EXPECTED_CLASS = \Magento\Framework\View\Test\Unit\Layout\Argument\Interpreter\ObjectTest::class; From 6e08072015973a368221c34c08c172aee77aeaa9 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 8 Apr 2019 16:47:12 -0500 Subject: [PATCH 065/247] Issue-230: adding varnish - fixing static plus composer --- .../Controller/HttpHeaderProcessor/CurrencyProcessor.php | 1 + .../Controller/{GraphQl/Plugin.php => Plugin/GraphQl.php} | 4 ++-- app/code/Magento/GraphQlCache/etc/graphql/di.xml | 2 +- composer.json | 1 + composer.lock | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) rename app/code/Magento/GraphQlCache/Controller/{GraphQl/Plugin.php => Plugin/GraphQl.php} (97%) diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php index 383955772d1b..7aa5f032ad4d 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php @@ -42,6 +42,7 @@ class CurrencyProcessor implements HttpHeaderProcessorInterface * @param StoreManagerInterface $storeManager * @param HttpContext $httpContext * @param SessionManagerInterface $session + * @param LoggerInterface $logger */ public function __construct( StoreManagerInterface $storeManager, diff --git a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php b/app/code/Magento/GraphQlCache/Controller/Plugin/GraphQl.php similarity index 97% rename from app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php rename to app/code/Magento/GraphQlCache/Controller/Plugin/GraphQl.php index 8e849904a0ad..1979ef1e0d0c 100644 --- a/app/code/Magento/GraphQlCache/Controller/GraphQl/Plugin.php +++ b/app/code/Magento/GraphQlCache/Controller/Plugin/GraphQl.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\GraphQlCache\Controller\GraphQl; +namespace Magento\GraphQlCache\Controller\Plugin; use Magento\Framework\App\FrontControllerInterface; use Magento\Framework\App\RequestInterface; @@ -19,7 +19,7 @@ /** * Class Plugin */ -class Plugin +class GraphQl { /** * @var CacheableQuery diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml index 8a5b6476c7af..6636ebacf9e5 100644 --- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml +++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml @@ -7,7 +7,7 @@ --> - + diff --git a/composer.json b/composer.json index 525f3a21d957..cff2d676038d 100644 --- a/composer.json +++ b/composer.json @@ -159,6 +159,7 @@ "magento/module-google-analytics": "*", "magento/module-google-optimizer": "*", "magento/module-graph-ql": "*", + "magento/module-graph-ql-cache": "*", "magento/module-catalog-graph-ql": "*", "magento/module-catalog-url-rewrite-graph-ql": "*", "magento/module-configurable-product-graph-ql": "*", diff --git a/composer.lock b/composer.lock index 06ab71ee7597..5d9f7fbdf695 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c43d19692d25afef14dd42eb893eb4ca", + "content-hash": "597fe6a47b695221292482fead498d83", "packages": [ { "name": "braintree/braintree_php", From 78eaa685ce43f5778f14be3df1da235fb4885c6e Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Tue, 9 Apr 2019 10:14:15 -0500 Subject: [PATCH 066/247] 230: Implement cache tag generation for GraphQL queries - Fixed tag generation when id's are not resolved --- .../Magento/GraphQlCache/Model/Plugin/Query/Resolver.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php index f3cccdb0995d..4fad3ede4e5b 100644 --- a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php +++ b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php @@ -65,9 +65,12 @@ public function afterResolve( $cacheTag = isset($cache['cache_tag']) ? $cache['cache_tag'] : []; $cacheable = isset($cache['cacheable']) ? $cache['cacheable'] : true; if (!empty($cacheTag) && $this->request->isGet() && $cacheable) { - $cacheTags = [$cacheTag]; + $cacheTags = []; // Resolved value must have cache IDs defined $resolvedItemsIds = $this->extractResolvedItemsIds($resolvedValue); + if (!empty($resolvedItemsIds)) { + $cacheTags = [$cacheTag]; + } foreach ($resolvedItemsIds as $itemId) { $cacheTags[] = $cacheTag . '_' . $itemId; } From 39774de802d2bc50724eaee29a8d08fb960fad3a Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Tue, 9 Apr 2019 11:06:11 -0500 Subject: [PATCH 067/247] 230: Implement cache tag generation for GraphQL queries - Fixed case sensitivity in vcls --- app/code/Magento/PageCache/etc/varnish4.vcl | 4 ++-- app/code/Magento/PageCache/etc/varnish5.vcl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/PageCache/etc/varnish4.vcl b/app/code/Magento/PageCache/etc/varnish4.vcl index 35c43171cd9b..c3698451e8ef 100644 --- a/app/code/Magento/PageCache/etc/varnish4.vcl +++ b/app/code/Magento/PageCache/etc/varnish4.vcl @@ -122,8 +122,8 @@ sub vcl_hash { hash_data(server.ip); } - if (req.http.store) { - hash_data(req.http.store); + if (req.http.Store) { + hash_data(req.http.Store); } if (req.http.Content-Currency) { hash_data(req.http.Content-Currency); diff --git a/app/code/Magento/PageCache/etc/varnish5.vcl b/app/code/Magento/PageCache/etc/varnish5.vcl index 67f9786bd3cd..7640eae43df6 100644 --- a/app/code/Magento/PageCache/etc/varnish5.vcl +++ b/app/code/Magento/PageCache/etc/varnish5.vcl @@ -129,8 +129,8 @@ sub vcl_hash { } /* {{ design_exceptions_code }} */ - if (req.http.store) { - hash_data(req.http.store); + if (req.http.Store) { + hash_data(req.http.Store); } if (req.http.Content-Currency) { hash_data(req.http.Content-Currency); From 18a294a26f0cd1e9a0964f4c045c8465c5b7c53a Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Tue, 9 Apr 2019 17:02:12 -0500 Subject: [PATCH 068/247] GraphQL-514: Test coverage for tag cache generation - added tests for coverage for category --- .../TestFramework/TestCase/GraphQl/Client.php | 4 +- .../TestCase/HttpClient/CurlClient.php | 8 +++ .../GraphQl/PageCache/CacheTagTest.php | 60 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index aeca700c8722..eac7fecc267e 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -130,8 +130,8 @@ public function getQueryResponseHeaders(string $query, array $variables = [], st $url = $this->getEndpointUrl(); $requestArray = [ 'query' => $query, - 'variables' => empty($variables) ? $variables : null, - 'operationName' => empty($operationName) ? $operationName : null + 'variables' => $variables ? $this->json->jsonEncode($variables) : null, + 'operationName' => !empty($operationName) ? $operationName : null ]; $responseHeader = $this->curlClient->getHttpHeaders($url, $requestArray, $headers); diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php index 24f622da7055..11af91bd3e00 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php @@ -32,6 +32,14 @@ public function get($url, $data = [], $headers = []) return $resp["body"]; } + /** + * Perform a HTTP GET request and returns just the response headers + * + * @param $url + * @param array $data + * @param array $headers + * @return mixed + */ public function getHttpHeaders($url, $data = [], $headers = []) { if (!empty($data)) { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 0c9f489f91e3..7cb3afbc3eac 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -74,4 +74,64 @@ public function testCacheTagsAndCacheDebugHeaderFromResponse() ); } } + + /** + * Tests if Magento cache tags for categories are generated properly + * + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCacheTagFromResponseHeaderForCategoriesWithProduct() + { + $productSku = 'simple333'; + $categoryId ='333'; + $query + = <<<'QUERY' +query GetCategoryQuery($id: Int!, $pageSize: Int!, $currentPage: Int!) { + category(id: $id) { + id + description + name + product_count + products(pageSize: $pageSize, currentPage: $currentPage) { + items { + id + name + url_key + } + total_count + } + } + } +QUERY; + $variables =[ + 'id' => 333, + 'pageSize'=> 10, + 'currentPage' => 1 + ]; + + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, $variables, '', []); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + /** @var Product $product */ + $product =$productRepository->get($productSku,false,null, true); + + /** cache-debug header value should be a MISS when category is loaded first time */ + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); + $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + + /** checks to see if the X-Magento-Tags for category is displayed correctly */ + preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); + $actualCacheTags = explode(',', rtrim($headerCacheTags[1],"\r")); + $expectedCacheTags=['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; + foreach(array_keys($actualCacheTags) as $key){ + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] + ); + } + /** cache-debug header value should be MISS after updating child-product and reloading the category */ + $product->setPrice(15); + $product->save(); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, $variables, '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); + $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + } } From 758b056aedc937ae74f37bfb1481a3f1b2a115d9 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 9 Apr 2019 17:59:25 -0500 Subject: [PATCH 069/247] Issue-230: adding varnish - fixing promises --- .../Model/Resolver/Categories.php | 56 +++++----- .../Model/CacheableQueryHandler.php | 103 ++++++++++++++++++ .../Model/Plugin/Query/Resolver.php | 85 +++------------ .../Magento/GraphQl/Catalog/CategoryTest.php | 1 + .../GraphQl/Config/GraphQlReaderTest.php | 7 +- .../Controller/GraphQlControllerTest.php | 23 +++- .../GraphQl/Query/Resolver/ValueFactory.php | 27 ++++- 7 files changed, 196 insertions(+), 106 deletions(-) create mode 100644 app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index cb392a7b2295..b31144368aa6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -94,35 +94,39 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $this->categoryIds = array_merge($this->categoryIds, $categoryIds); $that = $this; - return $this->valueFactory->create(function () use ($that, $categoryIds, $info) { - $categories = []; - if (empty($that->categoryIds)) { - return []; - } + return $this->valueFactory->create( + function () use ($that, $categoryIds, $info) { + $categories = []; + if (empty($that->categoryIds)) { + return []; + } - if (!$this->collection->isLoaded()) { - $that->attributesJoiner->join($info->fieldNodes[0], $this->collection); - $this->collection->addIdFilter($this->categoryIds); - } - /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ - foreach ($this->collection as $item) { - if (in_array($item->getId(), $categoryIds)) { - // Try to extract all requested fields from the loaded collection data - $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true); - $categories[$item->getId()]['model'] = $item; - $requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]); - $extractedFields = array_keys($categories[$item->getId()]); - $foundFields = array_intersect($requestedFields, $extractedFields); - if (count($requestedFields) === count($foundFields)) { - continue; - } + if (!$this->collection->isLoaded()) { + $that->attributesJoiner->join($info->fieldNodes[0], $this->collection); + $this->collection->addIdFilter($this->categoryIds); + } + /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ + foreach ($this->collection as $item) { + if (in_array($item->getId(), $categoryIds)) { + // Try to extract all requested fields from the loaded collection data + $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true); + $categories[$item->getId()]['model'] = $item; + $requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]); + $extractedFields = array_keys($categories[$item->getId()]); + $foundFields = array_intersect($requestedFields, $extractedFields); + if (count($requestedFields) === count($foundFields)) { + continue; + } - // If not all requested fields were extracted from the collection, start more complex extraction - $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item); + // If not all requested fields were extracted from the collection, start more complex extraction + $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item); + } } - } - return $categories; - }); + return $categories; + }, + $field, + $info + ); } } diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php new file mode 100644 index 000000000000..405b8b0473ee --- /dev/null +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -0,0 +1,103 @@ +cacheableQuery = $cacheableQuery; + $this->request = $request; + } + + /** + * Set cache validity to the cacheableQuery after resolving any resolver or evaluating a promise in a query + * + * @param mixed $resolvedValue + * @param Field|null $field + * @param ResolveInfo|null $info + */ + public function handleCacheFromResolverResponse(array $resolvedValue, Field $field) + { + $cache = $field->getCache(); + $cacheTag = isset($cache['cache_tag']) ? $cache['cache_tag'] : []; + $cacheable = isset($cache['cacheable']) ? $cache['cacheable'] : true; + if (!empty($cacheTag) && $this->request->isGet() && $cacheable) { + $cacheTags = []; + // Resolved value must have cache IDs defined + $resolvedItemsIds = $this->extractResolvedItemsIds($resolvedValue); + if (!empty($resolvedItemsIds)) { + $cacheTags = [$cacheTag]; + } + foreach ($resolvedItemsIds as $itemId) { + $cacheTags[] = $cacheTag . '_' . $itemId; + } + $this->cacheableQuery->addCacheTags($cacheTags); + } + $this->setCacheValidity($cacheable); + } + + /** + * Extract ids for resolved items + * + * @param mixed|Value $resolvedValue + * @return array + */ + private function extractResolvedItemsIds(array $resolvedValue) : array + { + $ids = []; + if (isset($resolvedValue['ids']) && is_array($resolvedValue['ids'])) { + return $resolvedValue['ids']; + } + if (isset($resolvedValue['items']) && is_array($resolvedValue['items'])) { + return array_keys($resolvedValue['items']); + } + + if (isset($resolvedValue['id'])) { + $ids[] = $resolvedValue['id']; + return $ids; + } + + foreach ($resolvedValue as $item) { + if (isset($item['id'])) { + $ids[] = $item['id']; + } + } + return $ids; + } + + /** + * Set cache validity for the graphql request + * + * @param bool $isValid + */ + private function setCacheValidity(bool $isValid): void + { + $cacheValidity = $this->cacheableQuery->isCacheable() && $isValid; + $this->cacheableQuery->setCacheValidity($cacheValidity); + } +} \ No newline at end of file diff --git a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php index 4fad3ede4e5b..ee14ba3bbdc9 100644 --- a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php +++ b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php @@ -11,8 +11,8 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\GraphQl\Model\Query\Resolver\Context; -use Magento\GraphQlCache\Model\CacheableQuery; -use Magento\Framework\App\RequestInterface; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\GraphQlCache\Model\CacheableQueryHandler; /** * Plugin to handle cache validation that can be done after each resolver @@ -20,30 +20,24 @@ class Resolver { /** - * @var CacheableQuery + * @var CacheableQueryHandler */ - private $cacheableQuery; + private $cacheableQueryHandler; /** - * @var Request + * @param CacheableQueryHandler $cacheableQueryHandler */ - private $request; - - /** - * @param CacheableQuery $cacheableQuery - * @param RequestInterface $request - */ - public function __construct(CacheableQuery $cacheableQuery, RequestInterface $request) - { - $this->cacheableQuery = $cacheableQuery; - $this->request = $request; + public function __construct( + CacheableQueryHandler $cacheableQueryHandler + ) { + $this->cacheableQueryHandler = $cacheableQueryHandler; } /** * Set cache validity to the cacheableQuery after resolving any resolver in a query * * @param ResolverInterface $subject - * @param Object $resolvedValue + * @param mixed|Value $resolvedValue * @param Field $field * @param Context $context * @param ResolveInfo $info @@ -61,63 +55,10 @@ public function afterResolve( array $value = null, array $args = null ) { - $cache = $field->getCache(); - $cacheTag = isset($cache['cache_tag']) ? $cache['cache_tag'] : []; - $cacheable = isset($cache['cacheable']) ? $cache['cacheable'] : true; - if (!empty($cacheTag) && $this->request->isGet() && $cacheable) { - $cacheTags = []; - // Resolved value must have cache IDs defined - $resolvedItemsIds = $this->extractResolvedItemsIds($resolvedValue); - if (!empty($resolvedItemsIds)) { - $cacheTags = [$cacheTag]; - } - foreach ($resolvedItemsIds as $itemId) { - $cacheTags[] = $cacheTag . '_' . $itemId; - } - $this->cacheableQuery->addCacheTags($cacheTags); - } - $this->setCacheValidity($cacheable); - return $resolvedValue; - } - - /** - * Extract ids for resolved items - * - * @param Object $resolvedValue - * @return array - */ - private function extractResolvedItemsIds($resolvedValue) : array - { - if (isset($resolvedValue['ids']) && is_array($resolvedValue['ids'])) { - return $resolvedValue['ids']; - } - if (isset($resolvedValue['items']) && is_array($resolvedValue['items'])) { - return array_keys($resolvedValue['items']); - } - $ids = []; - if (isset($resolvedValue['id'])) { - $ids[] = $resolvedValue['id']; - return $ids; - } - + /** Only if array @see \Magento\Framework\GraphQl\Query\Resolver\Value */ if (is_array($resolvedValue)) { - foreach ($resolvedValue as $item) { - if (isset($item['id'])) { - $ids[] = $item['id']; - } - } + $this->cacheableQueryHandler->handleCacheFromResolverResponse($resolvedValue, $field); } - return $ids; - } - - /** - * Set cache validity for the graphql request - * - * @param bool $isValid - */ - private function setCacheValidity(bool $isValid): void - { - $cacheValidity = $this->cacheableQuery->isCacheable() && $isValid; - $this->cacheableQuery->setCacheValidity($cacheValidity); + return $resolvedValue; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index b2ce0400f7d8..63073a389f27 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -347,6 +347,7 @@ public function testCategoryProducts() $this->assertAttributes($response['category']['products']['items'][0]); $this->assertWebsites($firstProduct, $response['category']['products']['items'][0]['websites']); } + /** * @magentoApiDataFixture Magento/Catalog/_files/categories.php */ diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php index 10a6b9d8caae..61cbd556ea23 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -183,7 +183,12 @@ enumValues(includeDeprecated: true) { $headers = $this->objectManager->create(\Zend\Http\Headers::class) ->addHeaders(['Content-Type' => 'application/json']); $request->setHeaders($headers); - $response = $this->graphQlController->dispatch($request); + + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->create(\Magento\Framework\App\Response\Http::class); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphQlController->dispatch($request); + $result->renderResult($response); $output = $this->jsonSerializer->unserialize($response->getContent()); $expectedOutput = require __DIR__ . '/../_files/schema_response_sdl_description.php'; diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php index d0d746812ec4..49cdca837259 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlControllerTest.php @@ -101,7 +101,11 @@ public function testDispatch() : void $headers = $this->objectManager->create(\Zend\Http\Headers::class) ->addHeaders(['Content-Type' => 'application/json']); $this->request->setHeaders($headers); - $response = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->create(\Magento\Framework\App\Response\Http::class); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + $result->renderResult($response); $output = $this->jsonSerializer->unserialize($response->getContent()); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); @@ -143,7 +147,11 @@ public function testDispatchWithGet() : void $this->request->setPathInfo('/graphql'); $this->request->setMethod('GET'); $this->request->setQueryValue('query', $query); - $response = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->create(\Magento\Framework\App\Response\Http::class); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + $result->renderResult($response); $output = $this->jsonSerializer->unserialize($response->getContent()); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); @@ -195,6 +203,11 @@ public function testDispatchGetWithParameterizedVariables() : void $this->request->setMethod('GET'); $this->request->setParams($queryParams); $response = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->create(\Magento\Framework\App\Response\Http::class); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + $result->renderResult($response); $output = $this->jsonSerializer->unserialize($response->getContent()); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); @@ -244,7 +257,11 @@ public function testError() : void $headers = $this->objectManager->create(\Zend\Http\Headers::class) ->addHeaders(['Content-Type' => 'application/json']); $this->request->setHeaders($headers); - $response = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->create(\Magento\Framework\App\Response\Http::class); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + $result->renderResult($response); $outputResponse = $this->jsonSerializer->unserialize($response->getContent()); if (isset($outputResponse['errors'][0])) { if (is_array($outputResponse['errors'][0])) { diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php index 5bd34224bb07..7f4c0da5bc0f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php @@ -8,6 +8,9 @@ namespace Magento\Framework\GraphQl\Query\Resolver; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\GraphQlCache\Model\CacheableQueryHandler; /** * Create @see Value to return data from passed in callback to GraphQL library @@ -19,22 +22,38 @@ class ValueFactory */ private $objectManager; + /** + * @var CacheableQueryHandler + */ + private $cacheableQueryHandler; + /** * @param ObjectManagerInterface $objectManager + * @param CacheableQueryHandler $cacheableQueryHandler */ - public function __construct(ObjectManagerInterface $objectManager) + public function __construct(ObjectManagerInterface $objectManager, CacheableQueryHandler $cacheableQueryHandler) { $this->objectManager = $objectManager; + $this->cacheableQueryHandler = $cacheableQueryHandler; } /** - * Create value with passed in callback that returns data as parameter; + * Create value with passed in callback that returns data as parameter * * @param callable $callback + * @param ResolveInfo $info * @return Value + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function create(callable $callback) + public function create(callable $callback, Field $field = null, ResolveInfo $info = null) : Value { - return $this->objectManager->create(Value::class, ['callback' => $callback]); + /** @var \Magento\Framework\GraphQl\Query\Resolver\Value $value */ + $value = $this->objectManager->create(Value::class, ['callback' => $callback]); + $value->then(function () use ($value, $field, $info) { + if (is_array($value->promise->result) && $field) { + $this->cacheableQueryHandler->handleCacheFromResolverResponse($value->promise->result, $field); + } + }); + return $value; } } From 8e8dc28bc55e5bda8a1b98c97d044efc4529e32f Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 10 Apr 2019 11:30:56 +0300 Subject: [PATCH 070/247] graphQl-533: fixed set purchase order --- .../Model/Resolver/SetPaymentMethodOnCart.php | 5 +-- .../Customer/SetPaymentMethodOnCartTest.php | 38 +++++++++++++++++++ .../Guest/SetPaymentMethodOnCartTest.php | 38 +++++++++++++++++++ 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php index d1dcb4a48a76..7d8933975779 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php @@ -69,10 +69,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } $paymentMethodCode = $args['input']['payment_method']['code']; - $poNumber = isset($args['input']['payment_method']['purchase_order_number']) - && empty($args['input']['payment_method']['purchase_order_number']) - ? $args['input']['payment_method']['purchase_order_number'] - : null; + $poNumber = $args['input']['payment_method']['purchase_order_number'] ?? null; $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); $payment = $this->paymentFactory->create([ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php index 73feefe2b094..8241debc8b09 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php @@ -60,6 +60,44 @@ public function testSetPaymentOnCartWithSimpleProduct() self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + */ + public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() + { + $methodCode = Checkmo::PAYMENT_METHOD_CHECKMO_CODE; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('setPaymentMethodOnCart', $response); + self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); + self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); + self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); + } + /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php index 879d0fd91729..9dfb6b4c15a6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php @@ -10,6 +10,7 @@ use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; use Magento\OfflinePayments\Model\Cashondelivery; use Magento\OfflinePayments\Model\Checkmo; +use Magento\OfflinePayments\Model\Purchaseorder; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -52,6 +53,43 @@ public function testSetPaymentOnCartWithSimpleProduct() self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); } + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + */ + public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() + { + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlQuery($query); + + self::assertArrayHasKey('setPaymentMethodOnCart', $response); + self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); + self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); + self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); + } + /** * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php From 4e15099e35a4493c3925d10d1b2df1623ab6e3b7 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Wed, 10 Apr 2019 14:27:08 +0300 Subject: [PATCH 071/247] tests_correct --- .../Magento/Catalog/Model/Product/Copier.php | 12 +++- .../Test/Unit/Model/Product/CopierTest.php | 57 ++++++++++++++----- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php index 2cd9304af789..3e899decaeb5 100644 --- a/app/code/Magento/Catalog/Model/Product/Copier.php +++ b/app/code/Magento/Catalog/Model/Product/Copier.php @@ -117,13 +117,21 @@ private function setDefaultUrl(Product $product, Product $duplicate) : void private function setStoresUrl(Product $product, Product $duplicate) : void { $storeIds = $duplicate->getStoreIds(); - $resource = $product->getResource(); $productId = $product->getId(); + $productResource = $product->getResource(); + $defaultUrlKey = $productResource->getAttributeRawValue( + $productId, + 'url_key', + \Magento\Store\Model\Store::DEFAULT_STORE_ID + ); $duplicate->setData('save_rewrites_history', false); foreach ($storeIds as $storeId) { $isDuplicateSaved = false; $duplicate->setStoreId($storeId); - $urlKey = $resource->getAttributeRawValue($productId, 'url_key', $storeId); + $urlKey = $productResource->getAttributeRawValue($productId, 'url_key', $storeId); + if ($urlKey === $defaultUrlKey) { + continue; + } do { $urlKey = $this->modifyUrl($urlKey); $duplicate->setUrlKey($urlKey); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php index e9eee5c76688..7ae5f70285fa 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php @@ -103,8 +103,44 @@ public function testCopy() ['linkField', null, '1'], ]); - $resourceMock = $this->createMock(\Magento\Catalog\Model\ResourceModel\Product::class); - $this->productMock->expects($this->once())->method('getResource')->will($this->returnValue($resourceMock)); + $entityMock = $this->getMockForAbstractClass( + \Magento\Eav\Model\Entity\AbstractEntity::class, + [], + '', + false, + true, + true, + ['checkAttributeUniqueValue'] + ); + $entityMock->expects($this->any()) + ->method('checkAttributeUniqueValue') + ->willReturn(true); + + $attributeMock = $this->getMockForAbstractClass( + \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, + [], + '', + false, + true, + true, + ['getEntity'] + ); + $attributeMock->expects($this->any()) + ->method('getEntity') + ->willReturn($entityMock); + + $resourceMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeRawValue', 'duplicate', 'getAttribute']) + ->getMock(); + $resourceMock->expects($this->any()) + ->method('getAttributeRawValue') + ->willReturn('urk-key-1'); + $resourceMock->expects($this->any()) + ->method('getAttribute') + ->willReturn($attributeMock); + + $this->productMock->expects($this->any())->method('getResource')->will($this->returnValue($resourceMock)); $duplicateMock = $this->createPartialMock( Product::class, @@ -119,11 +155,11 @@ public function testCopy() 'setCreatedAt', 'setUpdatedAt', 'setId', - 'setStoreId', 'getEntityId', 'save', 'setUrlKey', - 'getUrlKey', + 'setStoreId', + 'getStoreIds', ] ); $this->productFactoryMock->expects($this->once())->method('create')->will($this->returnValue($duplicateMock)); @@ -138,19 +174,13 @@ public function testCopy() )->with( \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED ); + $duplicateMock->expects($this->atLeastOnce())->method('setStoreId'); $duplicateMock->expects($this->once())->method('setCreatedAt')->with(null); $duplicateMock->expects($this->once())->method('setUpdatedAt')->with(null); $duplicateMock->expects($this->once())->method('setId')->with(null); - $duplicateMock->expects( - $this->once() - )->method( - 'setStoreId' - )->with( - \Magento\Store\Model\Store::DEFAULT_STORE_ID - ); + $duplicateMock->expects($this->atLeastOnce())->method('getStoreIds')->willReturn([]); $duplicateMock->expects($this->atLeastOnce())->method('setData')->willReturn($duplicateMock); $this->copyConstructorMock->expects($this->once())->method('build')->with($this->productMock, $duplicateMock); - $duplicateMock->expects($this->once())->method('getUrlKey')->willReturn('urk-key-1'); $duplicateMock->expects($this->once())->method('setUrlKey')->with('urk-key-2')->willReturn($duplicateMock); $duplicateMock->expects($this->once())->method('save'); @@ -158,7 +188,8 @@ public function testCopy() $duplicateMock->expects($this->any())->method('getData')->willReturnMap([ ['linkField', null, '2'], - ]); $this->optionRepositoryMock->expects($this->once()) + ]); + $this->optionRepositoryMock->expects($this->once()) ->method('duplicate') ->with($this->productMock, $duplicateMock); $resourceMock->expects($this->once())->method('duplicate')->with(1, 2); From aa7af6b33ce0dd4adf31e2d74a13fb973123d3eb Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 10 Apr 2019 10:55:10 -0500 Subject: [PATCH 072/247] Issue-230: adding varnish - fixing static --- .../Controller/HttpRequestValidatorInterface.php | 1 + .../GraphQlCache/Model/CacheableQueryHandler.php | 6 ++++++ .../Magento/TestFramework/TestCase/GraphQl/Client.php | 8 ++++++-- .../Magento/TestFramework/TestCase/GraphQlAbstract.php | 10 +++++----- .../TestCase/HttpClient/CurlClientWithCookies.php | 2 -- .../Framework/GraphQl/Query/Resolver/ValueFactory.php | 1 + 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php b/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php index 23e19195393f..2d9d50569e34 100644 --- a/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php +++ b/app/code/Magento/GraphQl/Controller/HttpRequestValidatorInterface.php @@ -9,6 +9,7 @@ use Magento\Framework\App\HttpRequestInterface; use Magento\Framework\GraphQl\Exception\GraphQlInputException; + /** * Use this interface to implement a validator for a Graphql HTTP requests */ diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php index 405b8b0473ee..cb070baa2868 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -12,6 +12,12 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\GraphQl\Query\Resolver\Value; +/** + * Handler of collecting tagging on cache. + * + * This class would be used to collect tags after each operation where we need to collect tags + * usually after data is fetched or resolved. + */ class CacheableQueryHandler { /** diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index eac7fecc267e..870f840bdfa1 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -125,8 +125,12 @@ private function processResponse(string $response) * @param array $headers * @return mixed */ - public function getQueryResponseHeaders(string $query, array $variables = [], string $operationName = '', array $headers = []) - { + public function getQueryResponseHeaders( + string $query, + array $variables = [], + string $operationName = '', + array $headers = [] + ) { $url = $this->getEndpointUrl(); $requestArray = [ 'query' => $query, diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php index 810ebcbb098f..44ce9aeca8b6 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -93,11 +93,11 @@ public function graphQlQueryForHttpHeaders( array $headers = [] ) { return $response = $this->getGraphQlClient()->getQueryResponseHeaders( - $query, - $variables, - $operationName, - $this->composeHeaders($headers) - ); + $query, + $variables, + $operationName, + $this->composeHeaders($headers) + ); } /** diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php index ecd748d89bb2..626e319e8668 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php @@ -23,8 +23,6 @@ class CurlClientWithCookies protected $jsonSerializer; /** - * CurlClient constructor. - * * @param CurlClient $curlClient * @param \Magento\TestFramework\Helper\JsonSerializer $jsonSerializer */ diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php index 7f4c0da5bc0f..bdacc4a7f419 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php @@ -41,6 +41,7 @@ public function __construct(ObjectManagerInterface $objectManager, CacheableQuer * Create value with passed in callback that returns data as parameter * * @param callable $callback + * @param Field $field * @param ResolveInfo $info * @return Value * @SuppressWarnings(PHPMD.UnusedFormalParameter) From 87af7d28f843bcae1dbf110622d982fa848ee213 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 10 Apr 2019 11:58:39 -0500 Subject: [PATCH 073/247] Issue-230: adding varnish - fixing static --- .../Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php | 2 +- .../testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php | 2 +- .../testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php index 2ef081ebcfa9..9eb9bc76047a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php @@ -94,7 +94,7 @@ public function testProductFromSpecificAndDefaultStore() $nonExistingStoreCode = "non_existent_store"; $headerMapInvalidStoreCode = ['Store' => $nonExistingStoreCode]; $this->expectException(\Exception::class); - $this->expectExceptionMessage('Store code non_existent_store does not exist'); + $this->expectExceptionMessage('The store that was requested wasn\'t found. Verify the store and try again.'); $this->graphQlQuery($query, [], '', $headerMapInvalidStoreCode); } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php index 19b72b9e3ca4..a19ad16cf60c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php @@ -163,7 +163,7 @@ public function testGetCartWithWrongStore() * @magentoApiDataFixture Magento/Checkout/_files/active_quote_customer_not_default_store.php * * @expectedException \Exception - * @expectedExceptionMessage Store code not_existing_store does not exist + * @expectedExceptionMessage The store that was requested wasn't found. Verify the store and try again. */ public function testGetCartWithNotExistingStore() { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php index 832e15058a4e..2678cf1be154 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php @@ -133,7 +133,7 @@ public function testGetCartWithWrongStore() * @magentoApiDataFixture Magento/Checkout/_files/active_quote_guest_not_default_store.php * * @expectedException \Exception - * @expectedExceptionMessage Store code not_existing_store does not exist + * @expectedExceptionMessage The store that was requested wasn't found. Verify the store and try again. */ public function testGetCartWithNotExistingStore() { From e6182866ef31aa9be2378d7c4d02d71a3de488d2 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 10 Apr 2019 12:01:34 -0500 Subject: [PATCH 074/247] Issue-230: adding varnish - fixing static --- .../Magento/GraphQlCache/Model/CacheableQueryHandler.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php index cb070baa2868..61c756daeff4 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -45,9 +45,9 @@ public function __construct(CacheableQuery $cacheableQuery, RequestInterface $re * * @param mixed $resolvedValue * @param Field|null $field - * @param ResolveInfo|null $info + * @return void */ - public function handleCacheFromResolverResponse(array $resolvedValue, Field $field) + public function handleCacheFromResolverResponse(array $resolvedValue, Field $field) : void { $cache = $field->getCache(); $cacheTag = isset($cache['cache_tag']) ? $cache['cache_tag'] : []; @@ -100,10 +100,11 @@ private function extractResolvedItemsIds(array $resolvedValue) : array * Set cache validity for the graphql request * * @param bool $isValid + * @return void */ private function setCacheValidity(bool $isValid): void { $cacheValidity = $this->cacheableQuery->isCacheable() && $isValid; $this->cacheableQuery->setCacheValidity($cacheValidity); } -} \ No newline at end of file +} From 066a68febbd4cfb15e8cc271a984ce75bc8f6f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torben=20Ho=CC=88hn?= Date: Wed, 10 Apr 2019 20:39:09 +0200 Subject: [PATCH 075/247] only trigger livereload by .css files --- dev/tools/grunt/configs/watch.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dev/tools/grunt/configs/watch.js b/dev/tools/grunt/configs/watch.js index 356d0b4b7b2d..c85ecb00f780 100644 --- a/dev/tools/grunt/configs/watch.js +++ b/dev/tools/grunt/configs/watch.js @@ -11,11 +11,8 @@ var combo = require('./combo'), var themeOptions = {}; -_.each(themes, function(theme, name) { +_.each(themes, function (theme, name) { themeOptions[name] = { - 'options': { - livereload: true - }, 'files': [ '<%= combo.autopath(\''+name+'\', path.pub) %>/**/*.less' ], From 3e59df0b8a49c1f8a34438ebb2a031e037d750d8 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 10 Apr 2019 22:05:04 +0300 Subject: [PATCH 076/247] Update SetPaymentMethodOnCartTest.php --- .../GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php index 8241debc8b09..8fa1af3fbc89 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php @@ -70,7 +70,7 @@ public function testSetPaymentOnCartWithSimpleProduct() */ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() { - $methodCode = Checkmo::PAYMENT_METHOD_CHECKMO_CODE; + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); $query = << Date: Wed, 10 Apr 2019 14:31:30 -0500 Subject: [PATCH 077/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- .../Magento/Backend/Model/Auth/Session.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Backend/Model/Auth/Session.php b/app/code/Magento/Backend/Model/Auth/Session.php index 01f762de83de..e253881c2253 100644 --- a/app/code/Magento/Backend/Model/Auth/Session.php +++ b/app/code/Magento/Backend/Model/Auth/Session.php @@ -314,7 +314,7 @@ public function isValidForPath($path) * * @return User|null */ - public function getUser(): ?User + public function getUser() { if (!$this->user) { $userData = $this->getUserData(); @@ -335,7 +335,7 @@ public function getUser(): ?User * @param User|null $user * @return Session */ - public function setUser(?User $user): self + public function setUser($user) { $this->setUserData(null); if ($user) { @@ -351,7 +351,7 @@ public function setUser(?User $user): self * * @return bool */ - public function hasUser(): bool + public function hasUser() { return $this->user || $this->hasUserData(); } @@ -361,10 +361,10 @@ public function hasUser(): bool * * @return Session */ - public function unsUser(): self + public function unsUser() { $this->user = null; - $this->unsUserData(); + return $this->unsUserData(); } /** @@ -372,7 +372,7 @@ public function unsUser(): self * * @return Acl|null */ - public function getAcl(): ?Acl + public function getAcl() { if (!$this->acl) { $aclData = $this->getUserAclData(); @@ -393,7 +393,7 @@ public function getAcl(): ?Acl * @param Acl|null $acl * @return Session */ - public function setAcl(?Acl $acl): self + public function setAcl($acl) { $this->setUserAclData(null); if ($acl) { @@ -409,7 +409,7 @@ public function setAcl(?Acl $acl): self * * @return bool */ - public function hasAcl(): bool + public function hasAcl() { return $this->acl || $this->hasUserAclData(); } @@ -419,10 +419,10 @@ public function hasAcl(): bool * * @return Session */ - public function unsAcl(): self + public function unsAcl() { $this->acl = null; - $this->unsUserAclData(); + return $this->unsUserAclData(); } /** From 45ed4224e7bb423ab3ddca847de5f649706b9b91 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 10 Apr 2019 14:40:58 -0500 Subject: [PATCH 078/247] Issue-230: adding varnish - fix dependencies --- .../Model/Resolver/Categories.php | 56 +++++++++---------- .../Model/CacheableQueryHandler.php | 6 +- .../Model/Plugin/Query/Resolver.php | 9 +++ .../GraphQl/Query/Resolver/ValueFactory.php | 28 ++-------- 4 files changed, 41 insertions(+), 58 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index b31144368aa6..cb392a7b2295 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -94,39 +94,35 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $this->categoryIds = array_merge($this->categoryIds, $categoryIds); $that = $this; - return $this->valueFactory->create( - function () use ($that, $categoryIds, $info) { - $categories = []; - if (empty($that->categoryIds)) { - return []; - } - - if (!$this->collection->isLoaded()) { - $that->attributesJoiner->join($info->fieldNodes[0], $this->collection); - $this->collection->addIdFilter($this->categoryIds); - } - /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ - foreach ($this->collection as $item) { - if (in_array($item->getId(), $categoryIds)) { - // Try to extract all requested fields from the loaded collection data - $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true); - $categories[$item->getId()]['model'] = $item; - $requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]); - $extractedFields = array_keys($categories[$item->getId()]); - $foundFields = array_intersect($requestedFields, $extractedFields); - if (count($requestedFields) === count($foundFields)) { - continue; - } + return $this->valueFactory->create(function () use ($that, $categoryIds, $info) { + $categories = []; + if (empty($that->categoryIds)) { + return []; + } - // If not all requested fields were extracted from the collection, start more complex extraction - $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item); + if (!$this->collection->isLoaded()) { + $that->attributesJoiner->join($info->fieldNodes[0], $this->collection); + $this->collection->addIdFilter($this->categoryIds); + } + /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ + foreach ($this->collection as $item) { + if (in_array($item->getId(), $categoryIds)) { + // Try to extract all requested fields from the loaded collection data + $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true); + $categories[$item->getId()]['model'] = $item; + $requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]); + $extractedFields = array_keys($categories[$item->getId()]); + $foundFields = array_intersect($requestedFields, $extractedFields); + if (count($requestedFields) === count($foundFields)) { + continue; } + + // If not all requested fields were extracted from the collection, start more complex extraction + $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item); } + } - return $categories; - }, - $field, - $info - ); + return $categories; + }); } } diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php index 61c756daeff4..b408d29eeb4f 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -8,9 +8,7 @@ namespace Magento\GraphQlCache\Model; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\App\RequestInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; /** * Handler of collecting tagging on cache. @@ -44,7 +42,7 @@ public function __construct(CacheableQuery $cacheableQuery, RequestInterface $re * Set cache validity to the cacheableQuery after resolving any resolver or evaluating a promise in a query * * @param mixed $resolvedValue - * @param Field|null $field + * @param Field $field * @return void */ public function handleCacheFromResolverResponse(array $resolvedValue, Field $field) : void @@ -70,7 +68,7 @@ public function handleCacheFromResolverResponse(array $resolvedValue, Field $fie /** * Extract ids for resolved items * - * @param mixed|Value $resolvedValue + * @param array $resolvedValue * @return array */ private function extractResolvedItemsIds(array $resolvedValue) : array diff --git a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php index ee14ba3bbdc9..3c98d292b0de 100644 --- a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php +++ b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php @@ -58,6 +58,15 @@ public function afterResolve( /** Only if array @see \Magento\Framework\GraphQl\Query\Resolver\Value */ if (is_array($resolvedValue)) { $this->cacheableQueryHandler->handleCacheFromResolverResponse($resolvedValue, $field); + } elseif ($resolvedValue instanceof \Magento\Framework\GraphQl\Query\Resolver\Value) { + $resolvedValue->then(function () use ($resolvedValue, $field) { + if (is_array($resolvedValue->promise->result) && $field) { + $this->cacheableQueryHandler->handleCacheFromResolverResponse( + $resolvedValue->promise->result, + $field + ); + } + }); } return $resolvedValue; } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php index bdacc4a7f419..5bd34224bb07 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/ValueFactory.php @@ -8,9 +8,6 @@ namespace Magento\Framework\GraphQl\Query\Resolver; use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\GraphQlCache\Model\CacheableQueryHandler; /** * Create @see Value to return data from passed in callback to GraphQL library @@ -22,39 +19,22 @@ class ValueFactory */ private $objectManager; - /** - * @var CacheableQueryHandler - */ - private $cacheableQueryHandler; - /** * @param ObjectManagerInterface $objectManager - * @param CacheableQueryHandler $cacheableQueryHandler */ - public function __construct(ObjectManagerInterface $objectManager, CacheableQueryHandler $cacheableQueryHandler) + public function __construct(ObjectManagerInterface $objectManager) { $this->objectManager = $objectManager; - $this->cacheableQueryHandler = $cacheableQueryHandler; } /** - * Create value with passed in callback that returns data as parameter + * Create value with passed in callback that returns data as parameter; * * @param callable $callback - * @param Field $field - * @param ResolveInfo $info * @return Value - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function create(callable $callback, Field $field = null, ResolveInfo $info = null) : Value + public function create(callable $callback) { - /** @var \Magento\Framework\GraphQl\Query\Resolver\Value $value */ - $value = $this->objectManager->create(Value::class, ['callback' => $callback]); - $value->then(function () use ($value, $field, $info) { - if (is_array($value->promise->result) && $field) { - $this->cacheableQueryHandler->handleCacheFromResolverResponse($value->promise->result, $field); - } - }); - return $value; + return $this->objectManager->create(Value::class, ['callback' => $callback]); } } From 435d269809ac8b3fdc182f7a5f4ef05b6f70c888 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 10 Apr 2019 17:53:39 -0500 Subject: [PATCH 079/247] Issue-230: adding varnish - fix Boc con constructor --- app/code/Magento/GraphQl/Controller/GraphQl.php | 17 ++++++++++++++--- .../GraphQlCache/Controller/Plugin/GraphQl.php | 12 ++++++------ .../GraphQlCache/Model/CacheableQuery.php | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index 4fccec6c046e..748793b54154 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -16,8 +16,10 @@ use Magento\Framework\GraphQl\Schema\SchemaGeneratorInterface; use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\Webapi\Response; use Magento\Framework\GraphQl\Query\Fields as QueryFields; use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\App\ObjectManager; /** * Front controller for web API GraphQL area. @@ -26,6 +28,12 @@ */ class GraphQl implements FrontControllerInterface { + /** + * @var Response + * @deprecated + */ + private $response; + /** * @var SchemaGeneratorInterface */ @@ -67,6 +75,7 @@ class GraphQl implements FrontControllerInterface private $jsonFactory; /** + * @param Response $response * @param SchemaGeneratorInterface $schemaGenerator * @param SerializerInterface $jsonSerializer * @param QueryProcessor $queryProcessor @@ -74,9 +83,10 @@ class GraphQl implements FrontControllerInterface * @param ContextInterface $resolverContext * @param HttpRequestProcessor $requestProcessor * @param QueryFields $queryFields - * @param JsonFactory $jsonFactory + * @param JsonFactory|null $jsonFactory */ public function __construct( + Response $response, SchemaGeneratorInterface $schemaGenerator, SerializerInterface $jsonSerializer, QueryProcessor $queryProcessor, @@ -84,8 +94,9 @@ public function __construct( ContextInterface $resolverContext, HttpRequestProcessor $requestProcessor, QueryFields $queryFields, - JsonFactory $jsonFactory + JsonFactory $jsonFactory = null ) { + $this->response = $response; $this->schemaGenerator = $schemaGenerator; $this->jsonSerializer = $jsonSerializer; $this->queryProcessor = $queryProcessor; @@ -93,7 +104,7 @@ public function __construct( $this->resolverContext = $resolverContext; $this->requestProcessor = $requestProcessor; $this->queryFields = $queryFields; - $this->jsonFactory = $jsonFactory; + $this->jsonFactory = $jsonFactory ?:ObjectManager::getInstance()->get(JsonFactory::class); } /** diff --git a/app/code/Magento/GraphQlCache/Controller/Plugin/GraphQl.php b/app/code/Magento/GraphQlCache/Controller/Plugin/GraphQl.php index 1979ef1e0d0c..588aa851e880 100644 --- a/app/code/Magento/GraphQlCache/Controller/Plugin/GraphQl.php +++ b/app/code/Magento/GraphQlCache/Controller/Plugin/GraphQl.php @@ -24,7 +24,7 @@ class GraphQl /** * @var CacheableQuery */ - private $cacheInfo; + private $cacheableQuery; /** * @var Config @@ -42,18 +42,18 @@ class GraphQl private $requestProcessor; /** - * @param CacheableQuery $cacheInfo + * @param CacheableQuery $cacheableQuery * @param Config $config * @param HttpResponse $response * @param HttpRequestProcessor $requestProcessor */ public function __construct( - CacheableQuery $cacheInfo, + CacheableQuery $cacheableQuery, Config $config, HttpResponse $response, HttpRequestProcessor $requestProcessor ) { - $this->cacheInfo = $cacheInfo; + $this->cacheableQuery = $cacheableQuery; $this->config = $config; $this->response = $response; $this->requestProcessor = $requestProcessor; @@ -94,9 +94,9 @@ public function afterDispatch( ) { $sendNoCacheHeaders = false; if ($this->config->isEnabled() && $request->isGet()) { - if ($this->cacheInfo->shouldPopulateCacheHeadersWithTags()) { + if ($this->cacheableQuery->shouldPopulateCacheHeadersWithTags()) { $this->response->setPublicHeaders($this->config->getTtl()); - $this->response->setHeader('X-Magento-Tags', implode(',', $this->cacheInfo->getCacheTags()), true); + $this->response->setHeader('X-Magento-Tags', implode(',', $this->cacheableQuery->getCacheTags()), true); } else { $sendNoCacheHeaders = true; } diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQuery.php b/app/code/Magento/GraphQlCache/Model/CacheableQuery.php index 3a7600b58f66..451e1039eec5 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQuery.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQuery.php @@ -8,7 +8,7 @@ namespace Magento\GraphQlCache\Model; /** - * CacheableQuery object is a registry for collecting cache related info and tags of all entities. + * CacheableQuery should be used as a singleton for collecting cache related info and tags of all entities. */ class CacheableQuery { From 39597253aac488f85fee3f87fafad9ec7effd12d Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Thu, 11 Apr 2019 11:21:33 +0300 Subject: [PATCH 080/247] Fix integration tests. --- .../Magento/Framework/View/Layout/etc/elements.xsd | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd index a5f8ace17bdc..17857c9ab065 100755 --- a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd +++ b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd @@ -14,7 +14,13 @@ - + + + + + + + From c75c2e16c610b02c02ec303155ce1352c2d992e2 Mon Sep 17 00:00:00 2001 From: Marcel Hauri Date: Thu, 11 Apr 2019 10:23:41 +0200 Subject: [PATCH 081/247] [fix] make return_path_email and set_return_path configurable in website and store scope --- app/code/Magento/Backend/etc/adminhtml/system.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 98b8e702b1c5..c762dbf58de6 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -323,11 +323,11 @@ For Windows server only. - + Magento\Config\Model\Config\Source\Yesnocustom - + validate-email Magento\Config\Model\Config\Backend\Email\Address From 62e7573d9bd6079ab368394cafdb641de6a4d127 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 11 Apr 2019 17:38:51 -0500 Subject: [PATCH 082/247] Issue-230: adding varnish - fix composer suggest - put tags on cms - fix graphical passing variables as non decodable json - removing cacheable true, adding cacheable false to cart query to get accurate data --- app/code/Magento/CatalogGraphQl/composer.json | 1 + app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 8 ++++---- app/code/Magento/CmsGraphQl/composer.json | 1 + app/code/Magento/CmsGraphQl/etc/schema.graphqls | 4 ++-- app/code/Magento/GraphQl/Controller/GraphQl.php | 2 ++ app/code/Magento/GraphQl/composer.json | 3 ++- app/code/Magento/QuoteGraphQl/composer.json | 3 ++- app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 8 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/composer.json b/app/code/Magento/CatalogGraphQl/composer.json index eb86ac634412..950b496263ff 100644 --- a/app/code/Magento/CatalogGraphQl/composer.json +++ b/app/code/Magento/CatalogGraphQl/composer.json @@ -14,6 +14,7 @@ }, "suggest": { "magento/module-graph-ql": "*", + "magento/module-graph-ql-cache": "*", "magento/module-store-graph-ql": "*" }, "license": [ diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index ec7cd62ad9d2..92f155c9c5ed 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -9,11 +9,11 @@ type Query { currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_p", cacheable: true) + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_p") category ( id: Int @doc(description: "Id of the category") ): CategoryTree - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_c", cacheable: true) + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_c") } enum CurrencyEnum @doc(description: "The list of available currency codes") { @@ -275,7 +275,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") manufacturer: Int @doc(description: "A number representing the product's manufacturer") - categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @cache(cache_tag: "cat_c", cacheable: true) @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") + categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @cache(cache_tag: "cat_c") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl") } @@ -396,7 +396,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @doc(description: "The list of products assigned to the category") @cache(cache_tag: "cat_p", cacheable: true) @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + ): CategoryProducts @doc(description: "The list of products assigned to the category") @cache(cache_tag: "cat_p") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } diff --git a/app/code/Magento/CmsGraphQl/composer.json b/app/code/Magento/CmsGraphQl/composer.json index 6a2e3950f93d..18a6f1aa95e3 100644 --- a/app/code/Magento/CmsGraphQl/composer.json +++ b/app/code/Magento/CmsGraphQl/composer.json @@ -10,6 +10,7 @@ }, "suggest": { "magento/module-graph-ql": "*", + "magento/module-graph-ql-cache": "*", "magento/module-store-graph-ql": "*" }, "license": [ diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index e8abd2201b88..385c7ee1eacc 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -13,10 +13,10 @@ type StoreConfig @doc(description: "The type contains information about a store type Query { cmsPage ( id: Int @doc(description: "Id of the CMS page") - ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") + ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") @cache(cache_tag: "cms_p") cmsBlocks ( identifiers: [String] @doc(description: "Identifiers of the CMS blocks") - ): CmsBlocks @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Blocks") @doc(description: "The CMS block query returns information about CMS blocks") + ): CmsBlocks @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Blocks") @doc(description: "The CMS block query returns information about CMS blocks") @cache(cache_tag: "cms_b") } type CmsPage @doc(description: "CMS page defines all CMS page information") { diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index 748793b54154..ed66c92c3bfb 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -162,6 +162,8 @@ private function getDataFromRequest(RequestInterface $request) : array $data = $request->getParams(); $data['variables'] = isset($data['variables']) ? $this->jsonSerializer->unserialize($data['variables']) : null; + $data['variables'] = is_array($data['variables']) ? + $data['variables'] : null; } else { return []; } diff --git a/app/code/Magento/GraphQl/composer.json b/app/code/Magento/GraphQl/composer.json index a81fb61984e0..3a1e8d1bfd9f 100644 --- a/app/code/Magento/GraphQl/composer.json +++ b/app/code/Magento/GraphQl/composer.json @@ -9,7 +9,8 @@ "magento/framework": "*" }, "suggest": { - "magento/module-webapi": "*" + "magento/module-webapi": "*", + "magento/module-graph-ql-cache": "*" }, "license": [ "OSL-3.0", diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 22ca9cfdfae9..a3c07f7df2ce 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -14,7 +14,8 @@ "magento/module-sales": "*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "*", + "magento/module-graph-ql-cache": "*" }, "license": [ "OSL-3.0", diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 9ec3492f6453..4f26d9260b34 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - cart(cart_id: String!): Cart @resolver (class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart") @doc(description:"Returns information about shopping cart") + cart(cart_id: String!): Cart @resolver (class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart") @doc(description:"Returns information about shopping cart") @cache(cacheable: false) } type Mutation { From 5c84c1ad6aecbf6209d04bcaa160c49f356344d4 Mon Sep 17 00:00:00 2001 From: Marius Strajeru Date: Fri, 12 Apr 2019 14:13:14 +0300 Subject: [PATCH 083/247] #22299: Cms block cache key does not contain the store id --- app/code/Magento/Cms/Block/Block.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/code/Magento/Cms/Block/Block.php b/app/code/Magento/Cms/Block/Block.php index d0d75ea69119..4fc37b50dcbc 100644 --- a/app/code/Magento/Cms/Block/Block.php +++ b/app/code/Magento/Cms/Block/Block.php @@ -84,4 +84,14 @@ public function getIdentities() { return [\Magento\Cms\Model\Block::CACHE_TAG . '_' . $this->getBlockId()]; } + + /** + * {@inheritdoc} + */ + public function getCacheKeyInfo() + { + $cacheKeyInfo = parent::getCacheKeyInfo(); + $cacheKeyInfo[] = $this->_storeManager->getStore()->getId(); + return $cacheKeyInfo; + } } From 2f797226d472b51e6cffded421f6b53e75bf2b10 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Fri, 12 Apr 2019 10:09:05 -0500 Subject: [PATCH 084/247] Issue-230: adding varnish - add Id to the cms resovlers --- .../Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php | 1 + app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php index 47a2439c4fad..fa4944381b85 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php @@ -59,6 +59,7 @@ public function getData(string $blockIdentifier): array $renderedContent = $this->widgetFilter->filter($block->getContent()); $blockData = [ + BlockInterface::BLOCK_ID => $block->getId(), BlockInterface::IDENTIFIER => $block->getIdentifier(), BlockInterface::TITLE => $block->getTitle(), BlockInterface::CONTENT => $renderedContent, diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index 22009824452b..001209ba7967 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -55,6 +55,7 @@ public function getData(int $pageId): array $renderedContent = $this->widgetFilter->filter($page->getContent()); $pageData = [ + PageInterface::PAGE_ID => $page->getId(), 'url_key' => $page->getIdentifier(), PageInterface::TITLE => $page->getTitle(), PageInterface::CONTENT => $renderedContent, From 955e16c7b9920ee41260d5873aac8756fceff111 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Fri, 12 Apr 2019 11:46:12 -0500 Subject: [PATCH 085/247] Issue-230: Implement cache tag generation for GraphQL queries - Implement cache tag indentity resolvers --- .../Resolver/Category/IdentityResolver.php | 26 +++++++ .../Resolver/Product/IdentityResolver.php | 33 +++++++++ .../CatalogGraphQl/etc/schema.graphqls | 10 ++- .../Model/Resolver/Block/IdentityResolver.php | 36 +++++++++ .../Model/Resolver/DataProvider/Page.php | 1 + .../Model/Resolver/Page/IdentityResolver.php | 28 +++++++ .../Magento/CmsGraphQl/etc/schema.graphqls | 4 +- .../Model/IdentityResolverInterface.php | 20 +++++ .../Model/CacheableQueryHandler.php | 74 ++++++++----------- .../Model/Plugin/Query/Resolver.php | 2 +- .../MetaReader/CacheTagReader.php | 6 ++ 11 files changed, 190 insertions(+), 50 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/IdentityResolver.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php create mode 100644 app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php create mode 100644 app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php create mode 100644 app/code/Magento/GraphQl/Model/IdentityResolverInterface.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/IdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/IdentityResolver.php new file mode 100644 index 000000000000..9334e3383f2f --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/IdentityResolver.php @@ -0,0 +1,26 @@ +widgetFilter->filter($page->getContent()); $pageData = [ + PageInterface::PAGE_ID => $page->getId(), 'url_key' => $page->getIdentifier(), PageInterface::TITLE => $page->getTitle(), PageInterface::CONTENT => $renderedContent, diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php new file mode 100644 index 000000000000..f912f7665026 --- /dev/null +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php @@ -0,0 +1,28 @@ +cacheableQuery = $cacheableQuery; $this->request = $request; + $this->objectManager = $objectManager; } /** * Set cache validity to the cacheableQuery after resolving any resolver or evaluating a promise in a query * - * @param mixed $resolvedValue + * @param array $resolvedValue * @param Field $field * @return void */ public function handleCacheFromResolverResponse(array $resolvedValue, Field $field) : void { $cache = $field->getCache(); - $cacheTag = isset($cache['cache_tag']) ? $cache['cache_tag'] : []; - $cacheable = isset($cache['cacheable']) ? $cache['cacheable'] : true; - if (!empty($cacheTag) && $this->request->isGet() && $cacheable) { - $cacheTags = []; - // Resolved value must have cache IDs defined - $resolvedItemsIds = $this->extractResolvedItemsIds($resolvedValue); - if (!empty($resolvedItemsIds)) { - $cacheTags = [$cacheTag]; - } - foreach ($resolvedItemsIds as $itemId) { - $cacheTags[] = $cacheTag . '_' . $itemId; - } - $this->cacheableQuery->addCacheTags($cacheTags); - } - $this->setCacheValidity($cacheable); - } + $cacheIdentityResolverClass = $cache['cacheIdentityResolver'] ?? null; + $cacheable = $cache['cacheable']; + $cacheTag = $cache['cache_tag'] ?? null; - /** - * Extract ids for resolved items - * - * @param array $resolvedValue - * @return array - */ - private function extractResolvedItemsIds(array $resolvedValue) : array - { - $ids = []; - if (isset($resolvedValue['ids']) && is_array($resolvedValue['ids'])) { - return $resolvedValue['ids']; - } - if (isset($resolvedValue['items']) && is_array($resolvedValue['items'])) { - return array_keys($resolvedValue['items']); - } - - if (isset($resolvedValue['id'])) { - $ids[] = $resolvedValue['id']; - return $ids; - } + if (false === $cacheable) { + $this->setCacheValidity(false); + } elseif ($cacheTag && $cacheIdentityResolverClass && $this->request->isGet()) { + $cacheIdentityResolver = $this->objectManager->get($cacheIdentityResolverClass); + $cacheTagIds = $cacheIdentityResolver->getIdentifiers($resolvedValue); - foreach ($resolvedValue as $item) { - if (isset($item['id'])) { - $ids[] = $item['id']; + if (!empty($cacheTagIds)) { + $cacheTags = array_map( + function ($id) use ($cacheTag) { + return $cacheTag . '_' . $id; + }, + $cacheTagIds + ); + $this->cacheableQuery->addCacheTags($cacheTags); } + $this->setCacheValidity(true); } - return $ids; } /** diff --git a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php index 3c98d292b0de..54cb5559923a 100644 --- a/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php +++ b/app/code/Magento/GraphQlCache/Model/Plugin/Query/Resolver.php @@ -56,7 +56,7 @@ public function afterResolve( array $args = null ) { /** Only if array @see \Magento\Framework\GraphQl\Query\Resolver\Value */ - if (is_array($resolvedValue)) { + if (is_array($resolvedValue) && !empty($field->getCache())) { $this->cacheableQueryHandler->handleCacheFromResolverResponse($resolvedValue, $field); } elseif ($resolvedValue instanceof \Magento\Framework\GraphQl\Query\Resolver\Value) { $resolvedValue->then(function () use ($resolvedValue, $field) { diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php index 6fa66b80a8c8..e3a11a73c262 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php @@ -36,6 +36,12 @@ public function read(\GraphQL\Language\AST\NodeList $directives) : array ["cacheable" => $directiveArgument->value->value] ); } + if ($directiveArgument->name->value == 'cacheIdentityResolver') { + $argMap = array_merge( + $argMap, + ["cacheIdentityResolver" => $directiveArgument->value->value] + ); + } } } } From 1a6e8bbb65c11c1fec1f7a178e033e1ca6e7ae68 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Fri, 12 Apr 2019 12:07:05 -0500 Subject: [PATCH 086/247] GraphQL-514: Test coverage for tag cache generation - integration test coverage for product --- .../GraphQl/PageCache/CacheTagTest.php | 21 ++- .../Controller/GraphQlCacheControllerTest.php | 122 ++++++++++++++++++ 2 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 7cb3afbc3eac..a01f31abb65d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -10,6 +10,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; +use Magento\Deploy\Model\Mode; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\App\State; use Magento\TestFramework\Helper\Bootstrap; @@ -18,16 +19,18 @@ class CacheTagTest extends GraphQlAbstract { /** - * @var \Magento\Framework\App\State - */ - protected $state; - - /** - * Tests various use cases for built-in cache for graphql query + * Tests if Magento cache tags and debug headers for products are generated properly * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_url_key.php */ public function testCacheTagsAndCacheDebugHeaderFromResponse() { + $this->markTestSkipped( + 'This test will stay skipped until DEVOPS-4924 is resolved' + ); + /** @var State $state */ + $state = Bootstrap::getObjectManager()->get(State::class); + $state->setMode(State::MODE_DEVELOPER); + $productSku='simple2'; $query = <<graphQlQueryForHttpHeaders($query, [], '', []); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); @@ -60,7 +64,7 @@ public function testCacheTagsAndCacheDebugHeaderFromResponse() /** update the price attribute for the product in test */ $product->setPrice(15); $product->save(); - /** cache-debug header value should be a MISS after product attribute update */ + /** Cache invalidation happens and cache-debug header value is a MISS after product update */ $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); @@ -82,6 +86,9 @@ public function testCacheTagsAndCacheDebugHeaderFromResponse() */ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() { + $this->markTestSkipped( + 'This test will stay skipped until DEVOPS-4924 is resolved' + ); $productSku = 'simple333'; $categoryId ='333'; $query diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php new file mode 100644 index 000000000000..98965ff41e73 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php @@ -0,0 +1,122 @@ +getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + protected function setUp(): void + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + $this->metadataPool = $this->objectManager->get(MetadataPool::class); + $this->request = $this->objectManager->get(Http::class); + $this->response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + + } + + /** + * Test request is dispatched and response is checked for debug headers and cache tags + * + * @magentoCache all enabled + * @return void + */ + public function testDispatchWithGetForCacheDebugHeadersAndCacheTags(): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + + /** @var ProductInterface $product */ + $product = $productRepository->get('simple1'); + + $query + = <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($this->response); // + $this->assertEquals('MISS', $this->response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $this->response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; + foreach (array_keys($actualCacheTags) as $key) { + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] + ); + } + } +} + + From b0bac8b9ed13be9def9d6265a0962db25d216e5d Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Fri, 12 Apr 2019 12:40:23 -0500 Subject: [PATCH 087/247] Issue-230: Implement cache tag generation for GraphQL queries - Implement cache tag indentity resolvers --- .../Category/CategoriesIdentityResolver.php | 32 +++++++++++++++++++ ...r.php => CategoryTreeIdentityResolver.php} | 2 +- .../CatalogGraphQl/etc/schema.graphqls | 8 ++--- .../Model/CacheableQueryHandler.php | 8 ++--- 4 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php rename app/code/Magento/CatalogGraphQl/Model/Resolver/Category/{IdentityResolver.php => CategoryTreeIdentityResolver.php} (88%) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php new file mode 100644 index 000000000000..df6689ae902e --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php @@ -0,0 +1,32 @@ +getCache(); $cacheIdentityResolverClass = $cache['cacheIdentityResolver'] ?? null; - $cacheable = $cache['cacheable']; + $cacheable = $cache['cacheable'] ?? true; $cacheTag = $cache['cache_tag'] ?? null; - if (false === $cacheable) { - $this->setCacheValidity(false); - } elseif ($cacheTag && $cacheIdentityResolverClass && $this->request->isGet()) { + if ($cacheTag && $cacheIdentityResolverClass && $this->request->isGet()) { $cacheIdentityResolver = $this->objectManager->get($cacheIdentityResolverClass); $cacheTagIds = $cacheIdentityResolver->getIdentifiers($resolvedValue); @@ -78,8 +76,8 @@ function ($id) use ($cacheTag) { ); $this->cacheableQuery->addCacheTags($cacheTags); } - $this->setCacheValidity(true); } + $this->setCacheValidity($cacheable); } /** From 1d2e260798ee816a181cca5234964f81ff2d393f Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Fri, 12 Apr 2019 15:51:06 -0500 Subject: [PATCH 088/247] Issue-230: Implement cache tag generation for GraphQL queries - Implement cache tag indentity resolvers --- .../Category/CategoriesIdentityResolver.php | 7 +-- .../Category/CategoryTreeIdentityResolver.php | 3 +- .../Resolver/Product/IdentityResolver.php | 4 +- .../CatalogGraphQl/etc/schema.graphqls | 8 +-- .../Model/Resolver/Block/IdentityResolver.php | 4 +- .../Model/Resolver/Page/IdentityResolver.php | 2 +- .../Magento/CmsGraphQl/etc/schema.graphqls | 4 +- .../Model/CacheableQueryHandler.php | 44 +++++++++-------- .../Model/IdentityResolverPool.php | 49 +++++++++++++++++++ .../Query}/IdentityResolverInterface.php | 2 +- .../MetaReader/CacheTagReader.php | 4 +- 11 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php rename {app/code/Magento/GraphQl/Model => lib/internal/Magento/Framework/GraphQl/Query}/IdentityResolverInterface.php (89%) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php index df6689ae902e..1fad463ddee1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php @@ -3,10 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\CatalogGraphQl\Model\Resolver\Category; -use Magento\GraphQl\Model\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\IdentityResolverInterface; /** * Identity for multiple resolved categories @@ -22,8 +23,8 @@ class CategoriesIdentityResolver implements IdentityResolverInterface public function getIdentifiers(array $resolvedData): array { $ids = []; - if(!empty($resolvedData)) { - foreach($resolvedData as $category){ + if (!empty($resolvedData)) { + foreach ($resolvedData as $category) { $ids[] = $category['id']; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentityResolver.php index a03fcbf71c79..0bfe6d2e4699 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentityResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentityResolver.php @@ -3,10 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\CatalogGraphQl\Model\Resolver\Category; -use Magento\GraphQl\Model\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\IdentityResolverInterface; /** * Identity for resolved category diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php index 8c659bc96821..eece587eb429 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\GraphQl\Model\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\IdentityResolverInterface; /** * Identity for resolved products @@ -20,7 +20,7 @@ class IdentityResolver implements IdentityResolverInterface * @param array $resolvedData * @return array */ - public function getIdentifiers(array $resolvedData) : array + public function getIdentifiers(array $resolvedData): array { $ids = []; $items = $resolvedData['items'] ?? []; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 829e604f3b27..eece33fc2658 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -9,11 +9,11 @@ type Query { currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_p", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\IdentityResolver") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") @cache(cacheTag: "cat_p", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\IdentityResolver") category ( id: Int @doc(description: "Id of the category") ): CategoryTree - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes") @cache(cache_tag: "cat_c", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentityResolver") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes") @cache(cacheTag: "cat_c", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentityResolver") } enum CurrencyEnum @doc(description: "The list of available currency codes") { @@ -275,7 +275,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") manufacturer: Int @doc(description: "A number representing the product's manufacturer") - categories: [CategoryInterface] @doc(description: "The categories assigned to a product")@cache(cache_tag: "cat_c", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoriesIdentityResolver") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") + categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @cache(cacheTag: "cat_c", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoriesIdentityResolver") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl") } @@ -396,7 +396,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @doc(description: "The list of products assigned to the category") @cache(cache_tag: "cat_p", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\IdentityResolver") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + ): CategoryProducts @doc(description: "The list of products assigned to the category") @cache(cacheTag: "cat_p", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\IdentityResolver") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php index 0dd99ee558cb..4f5913c458d0 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php @@ -8,7 +8,7 @@ namespace Magento\CmsGraphQl\Model\Resolver\Block; use Magento\Cms\Api\Data\BlockInterface; -use Magento\GraphQl\Model\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\IdentityResolverInterface; /** * Identity for resolved CMS block @@ -26,7 +26,7 @@ public function getIdentifiers(array $resolvedData): array $ids = []; $items = $resolvedData['items'] ?? []; foreach ($items as $item) { - if (!empty($item[BlockInterface::IDENTIFIER])) { + if (is_array($item) && !empty($item[BlockInterface::IDENTIFIER])) { $ids[] = $item[BlockInterface::IDENTIFIER ]; } } diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php index f912f7665026..d139cb383233 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php @@ -8,7 +8,7 @@ namespace Magento\CmsGraphQl\Model\Resolver\Page; use Magento\Cms\Api\Data\PageInterface; -use Magento\GraphQl\Model\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\IdentityResolverInterface; /** * Identity for resolved CMS page diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index b9a81b3457a3..1734cf80afd6 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -13,10 +13,10 @@ type StoreConfig @doc(description: "The type contains information about a store type Query { cmsPage ( id: Int @doc(description: "Id of the CMS page") - ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") @cache(cache_tag: "cms_p", cacheIdentityResolver: "Magento\\CmsGraphQl\\Model\\Resolver\\Page\\IdentityResolver") + ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") @cache(cacheTag: "cms_p", cacheIdentityResolver: "Magento\\CmsGraphQl\\Model\\Resolver\\Page\\IdentityResolver") cmsBlocks ( identifiers: [String] @doc(description: "Identifiers of the CMS blocks") - ): CmsBlocks @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Blocks") @doc(description: "The CMS block query returns information about CMS blocks") @cache(cache_tag: "cms_b", cacheIdentityResolver: "Magento\\CmsGraphQl\\Model\\Resolver\\Block\\IdentityResolver") + ): CmsBlocks @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Blocks") @doc(description: "The CMS block query returns information about CMS blocks") @cache(cacheTag: "cms_b", cacheIdentityResolver: "Magento\\CmsGraphQl\\Model\\Resolver\\Block\\IdentityResolver") } type CmsPage @doc(description: "CMS page defines all CMS page information") { diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php index b5d1fdaaff4f..786c822d6822 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -9,7 +9,6 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\App\RequestInterface; -use Magento\Framework\ObjectManagerInterface; /** * Handler of collecting tagging on cache. @@ -30,23 +29,23 @@ class CacheableQueryHandler private $request; /** - * @var ObjectManagerInterface + * @var IdentityResolverPool */ - private $objectManager; + private $identityResolverPool; /** * @param CacheableQuery $cacheableQuery * @param RequestInterface $request - * @param ObjectManagerInterface $objectManager + * @param IdentityResolverPool $identityResolverPool */ public function __construct( CacheableQuery $cacheableQuery, RequestInterface $request, - ObjectManagerInterface $objectManager + IdentityResolverPool $identityResolverPool ) { $this->cacheableQuery = $cacheableQuery; $this->request = $request; - $this->objectManager = $objectManager; + $this->identityResolverPool = $identityResolverPool; } /** @@ -59,23 +58,28 @@ public function __construct( public function handleCacheFromResolverResponse(array $resolvedValue, Field $field) : void { $cache = $field->getCache(); - $cacheIdentityResolverClass = $cache['cacheIdentityResolver'] ?? null; + $cacheIdentityResolverClass = $cache['cacheIdentityResolver'] ?? ''; $cacheable = $cache['cacheable'] ?? true; - $cacheTag = $cache['cache_tag'] ?? null; + $cacheTag = $cache['cacheTag'] ?? null; - if ($cacheTag && $cacheIdentityResolverClass && $this->request->isGet()) { - $cacheIdentityResolver = $this->objectManager->get($cacheIdentityResolverClass); - $cacheTagIds = $cacheIdentityResolver->getIdentifiers($resolvedValue); - - if (!empty($cacheTagIds)) { - $cacheTags = array_map( - function ($id) use ($cacheTag) { - return $cacheTag . '_' . $id; - }, - $cacheTagIds - ); - $this->cacheableQuery->addCacheTags($cacheTags); + $cacheTags = []; + if ($cacheTag && $this->request->isGet()) { + if (!empty($cacheIdentityResolverClass)) { + $cacheIdentityResolver = $this->identityResolverPool->get($cacheIdentityResolverClass); + $cacheTagIds = $cacheIdentityResolver->getIdentifiers($resolvedValue); + if (!empty($cacheTagIds)) { + $cacheTags = array_map( + function ($id) use ($cacheTag) { + return $cacheTag . '_' . $id; + }, + $cacheTagIds + ); + } + } else { + $cacheTags[] = $cacheTag; } + + $this->cacheableQuery->addCacheTags($cacheTags); } $this->setCacheValidity($cacheable); } diff --git a/app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php b/app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php new file mode 100644 index 000000000000..da97e5ba4f2e --- /dev/null +++ b/app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php @@ -0,0 +1,49 @@ +objectManager = $objectManager; + } + + /** + * Get an identity resolver by class name + * + * @param string $identityResolverClass + * @return IdentityResolverInterface + */ + public function get(string $identityResolverClass): IdentityResolverInterface + { + if (!isset($this->identityResolvers[$identityResolverClass])) { + $this->identityResolvers[$identityResolverClass] = $this->objectManager->create($identityResolverClass); + } + return $this->identityResolvers[$identityResolverClass]; + } +} diff --git a/app/code/Magento/GraphQl/Model/IdentityResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Query/IdentityResolverInterface.php similarity index 89% rename from app/code/Magento/GraphQl/Model/IdentityResolverInterface.php rename to lib/internal/Magento/Framework/GraphQl/Query/IdentityResolverInterface.php index c9c6feff3399..588052c8df6e 100644 --- a/app/code/Magento/GraphQl/Model/IdentityResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/IdentityResolverInterface.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\GraphQl\Model; +namespace Magento\Framework\GraphQl\Query; interface IdentityResolverInterface { diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php index e3a11a73c262..ae7ee4a1ec38 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php @@ -24,10 +24,10 @@ public function read(\GraphQL\Language\AST\NodeList $directives) : array foreach ($directives as $directive) { if ($directive->name->value == 'cache') { foreach ($directive->arguments as $directiveArgument) { - if ($directiveArgument->name->value == 'cache_tag') { + if ($directiveArgument->name->value == 'cacheTag') { $argMap = array_merge( $argMap, - ["cache_tag" => $directiveArgument->value->value] + ["cacheTag" => $directiveArgument->value->value] ); } if ($directiveArgument->name->value == 'cacheable') { From 999766cf2ffd177766e7fbcf253ff50d28264ab2 Mon Sep 17 00:00:00 2001 From: Arnoud Beekman Date: Sun, 31 Mar 2019 16:22:32 +0200 Subject: [PATCH 089/247] Remove @SuppressWarnings and optimize imports Two @SuppressWarnings could be removed by splitting up the execute method by moving logic to separate private methods. Also the imports of this file are improved. --- .../Catalog/Controller/Category/View.php | 136 +++++++++++------- .../Unit/Controller/Category/ViewTest.php | 2 +- 2 files changed, 88 insertions(+), 50 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php index 2088bb5ea77c..5129692146ff 100644 --- a/app/code/Magento/Catalog/Controller/Category/View.php +++ b/app/code/Magento/Catalog/Controller/Category/View.php @@ -6,14 +6,28 @@ */ namespace Magento\Catalog\Controller\Category; -use Magento\Framework\App\Action\HttpPostActionInterface; -use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Catalog\Api\CategoryRepositoryInterface; +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Design; use Magento\Catalog\Model\Layer\Resolver; use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; +use Magento\Catalog\Model\Session; +use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; +use Magento\Framework\App\Action\Action; +use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\ActionInterface; +use Magento\Framework\Controller\Result\ForwardFactory; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\Framework\View\Result\Page; use Magento\Framework\View\Result\PageFactory; -use Magento\Framework\App\Action\Action; +use Magento\Store\Model\StoreManagerInterface; +use Psr\Log\LoggerInterface; /** * View a category on storefront. Needs to be accessible by POST because of the store switching. @@ -25,41 +39,41 @@ class View extends Action implements HttpGetActionInterface, HttpPostActionInter /** * Core registry * - * @var \Magento\Framework\Registry + * @var Registry */ protected $_coreRegistry = null; /** * Catalog session * - * @var \Magento\Catalog\Model\Session + * @var Session */ protected $_catalogSession; /** * Catalog design * - * @var \Magento\Catalog\Model\Design + * @var Design */ protected $_catalogDesign; /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ protected $_storeManager; /** - * @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator + * @var CategoryUrlPathGenerator */ protected $categoryUrlPathGenerator; /** - * @var \Magento\Framework\View\Result\PageFactory + * @var PageFactory */ protected $resultPageFactory; /** - * @var \Magento\Framework\Controller\Result\ForwardFactory + * @var ForwardFactory */ protected $resultForwardFactory; @@ -83,28 +97,28 @@ class View extends Action implements HttpGetActionInterface, HttpPostActionInter /** * Constructor * - * @param \Magento\Framework\App\Action\Context $context - * @param \Magento\Catalog\Model\Design $catalogDesign - * @param \Magento\Catalog\Model\Session $catalogSession - * @param \Magento\Framework\Registry $coreRegistry - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator - * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory - * @param \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory + * @param Context $context + * @param Design $catalogDesign + * @param Session $catalogSession + * @param Registry $coreRegistry + * @param StoreManagerInterface $storeManager + * @param CategoryUrlPathGenerator $categoryUrlPathGenerator + * @param PageFactory $resultPageFactory + * @param ForwardFactory $resultForwardFactory * @param Resolver $layerResolver * @param CategoryRepositoryInterface $categoryRepository * @param ToolbarMemorizer|null $toolbarMemorizer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Framework\App\Action\Context $context, - \Magento\Catalog\Model\Design $catalogDesign, - \Magento\Catalog\Model\Session $catalogSession, - \Magento\Framework\Registry $coreRegistry, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator, + Context $context, + Design $catalogDesign, + Session $catalogSession, + Registry $coreRegistry, + StoreManagerInterface $storeManager, + CategoryUrlPathGenerator $categoryUrlPathGenerator, PageFactory $resultPageFactory, - \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory, + ForwardFactory $resultForwardFactory, Resolver $layerResolver, CategoryRepositoryInterface $categoryRepository, ToolbarMemorizer $toolbarMemorizer = null @@ -125,7 +139,7 @@ public function __construct( /** * Initialize requested category object * - * @return \Magento\Catalog\Model\Category|bool + * @return Category|bool */ protected function _initCategory() { @@ -150,8 +164,8 @@ protected function _initCategory() 'catalog_controller_category_init_after', ['category' => $category, 'controller_action' => $this] ); - } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e); + } catch (LocalizedException $e) { + $this->_objectManager->get(LoggerInterface::class)->critical($e); return false; } @@ -161,13 +175,12 @@ protected function _initCategory() /** * Category view action * - * @return \Magento\Framework\Controller\ResultInterface - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) + * @return ResultInterface + * @throws NoSuchEntityException */ public function execute() { - if ($this->_request->getParam(\Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED)) { + if ($this->_request->getParam(ActionInterface::PARAM_NAME_URL_ENCODED)) { return $this->resultRedirectFactory->create()->setUrl($this->_redirect->getRedirectUrl()); } $category = $this->_initCategory(); @@ -188,29 +201,18 @@ public function execute() $page->getConfig()->setPageLayout($settings->getPageLayout()); } - $hasChildren = $category->hasChildren(); - if ($category->getIsAnchor()) { - $type = $hasChildren ? 'layered' : 'layered_without_children'; - } else { - $type = $hasChildren ? 'default' : 'default_without_children'; - } + $pageType = $this->getPageType($category); - if (!$hasChildren) { + if (!$category->hasChildren()) { // Two levels removed from parent. Need to add default page type. - $parentType = strtok($type, '_'); - $page->addPageLayoutHandles(['type' => $parentType], null, false); + $parentPageType = strtok($pageType, '_'); + $page->addPageLayoutHandles(['type' => $parentPageType], null, false); } - $page->addPageLayoutHandles(['type' => $type], null, false); + $page->addPageLayoutHandles(['type' => $pageType], null, false); $page->addPageLayoutHandles(['id' => $category->getId()]); // apply custom layout update once layout is loaded - $layoutUpdates = $settings->getLayoutUpdates(); - if ($layoutUpdates && is_array($layoutUpdates)) { - foreach ($layoutUpdates as $layoutUpdate) { - $page->addUpdate($layoutUpdate); - $page->addPageLayoutHandles(['layout_update' => sha1($layoutUpdate)], null, false); - } - } + $this->applyLayoutUpdates($page, $settings); $page->getConfig()->addBodyClass('page-products') ->addBodyClass('categorypath-' . $this->categoryUrlPathGenerator->getUrlPath($category)) @@ -221,4 +223,40 @@ public function execute() return $this->resultForwardFactory->create()->forward('noroute'); } } + + /** + * Get page type based on category + * + * @param Category $category + * @return string + */ + private function getPageType(Category $category) + { + $hasChildren = $category->hasChildren(); + if ($category->getIsAnchor()) { + return $hasChildren ? 'layered' : 'layered_without_children'; + } + + return $hasChildren ? 'default' : 'default_without_children'; + } + + /** + * Apply custom layout updates + * + * @param Page $page + * @param DataObject $settings + * @return void + */ + private function applyLayoutUpdates( + Page $page, + DataObject $settings + ) { + $layoutUpdates = $settings->getLayoutUpdates(); + if ($layoutUpdates && is_array($layoutUpdates)) { + foreach ($layoutUpdates as $layoutUpdate) { + $page->addUpdate($layoutUpdate); + $page->addPageLayoutHandles(['layout_update' => sha1($layoutUpdate)], null, false); + } + } + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Category/ViewTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Category/ViewTest.php index d93520297e48..60c6f2f1bd82 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Category/ViewTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Category/ViewTest.php @@ -124,7 +124,7 @@ protected function setUp() ->disableOriginalConstructor()->getMock(); $this->pageConfig->expects($this->any())->method('addBodyClass')->will($this->returnSelf()); - $this->page = $this->getMockBuilder(\Magento\Framework\View\Page::class) + $this->page = $this->getMockBuilder(\Magento\Framework\View\Result\Page::class) ->setMethods(['getConfig', 'initLayout', 'addPageLayoutHandles', 'getLayout', 'addUpdate']) ->disableOriginalConstructor()->getMock(); $this->page->expects($this->any())->method('getConfig')->will($this->returnValue($this->pageConfig)); From 1a64bfe09b09366539ff6858097ad564b385d777 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Fri, 12 Apr 2019 16:09:13 -0500 Subject: [PATCH 090/247] Issue-230: Implement cache tag generation for GraphQL queries - Add general cache tag for cache type --- .../GraphQlCache/Model/CacheableQueryHandler.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php index 786c822d6822..bf57e8c9736c 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -64,21 +64,16 @@ public function handleCacheFromResolverResponse(array $resolvedValue, Field $fie $cacheTags = []; if ($cacheTag && $this->request->isGet()) { + $cacheTags[] = $cacheTag; if (!empty($cacheIdentityResolverClass)) { $cacheIdentityResolver = $this->identityResolverPool->get($cacheIdentityResolverClass); $cacheTagIds = $cacheIdentityResolver->getIdentifiers($resolvedValue); if (!empty($cacheTagIds)) { - $cacheTags = array_map( - function ($id) use ($cacheTag) { - return $cacheTag . '_' . $id; - }, - $cacheTagIds - ); + foreach ($cacheTagIds as $cacheTagId) { + $cacheTags[] = $cacheTag . '_' . $cacheTagId; + } } - } else { - $cacheTags[] = $cacheTag; } - $this->cacheableQuery->addCacheTags($cacheTags); } $this->setCacheValidity($cacheable); From 3c3d7ffbd99b2bf445d95375363d724ec8f8ed3d Mon Sep 17 00:00:00 2001 From: eugene-shab Date: Sat, 13 Apr 2019 17:41:57 +0300 Subject: [PATCH 091/247] - Remove cart_address_id - remove condition from SetShippingMethodsOnCart --- .../QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php | 9 ++------- app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php index 730cf1b0ffee..3516f1fbea1a 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php @@ -50,11 +50,6 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s } $shippingMethodInput = current($shippingMethodsInput); - if (!isset($shippingMethodInput['cart_address_id']) || empty($shippingMethodInput['cart_address_id'])) { - throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing.')); - } - $cartAddressId = $shippingMethodInput['cart_address_id']; - if (!isset($shippingMethodInput['carrier_code']) || empty($shippingMethodInput['carrier_code'])) { throw new GraphQlInputException(__('Required parameter "carrier_code" is missing.')); } @@ -65,7 +60,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s } $methodCode = $shippingMethodInput['method_code']; - $quoteAddress = $this->getQuoteAddress->execute($cart, $cartAddressId, $context->getUserId()); - $this->assignShippingMethodToCart->execute($cart, $quoteAddress, $carrierCode, $methodCode); +// $quoteAddress = $this->getQuoteAddress->execute($cart, $context->getUserId()); +// $this->assignShippingMethodToCart->execute($cart, $quoteAddress, $carrierCode, $methodCode); } } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 9ec3492f6453..2f5e5b54c2fa 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -110,7 +110,6 @@ input SetShippingMethodsOnCartInput { } input ShippingMethodInput { - cart_address_id: Int! carrier_code: String! method_code: String! } From 6ab1392502017a73629e2b5d2abc7cbd8aebb43f Mon Sep 17 00:00:00 2001 From: eugene-shab Date: Sat, 13 Apr 2019 18:41:08 +0300 Subject: [PATCH 092/247] debug --- .../QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php index 3516f1fbea1a..fccda9e28c11 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php @@ -62,5 +62,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s // $quoteAddress = $this->getQuoteAddress->execute($cart, $context->getUserId()); // $this->assignShippingMethodToCart->execute($cart, $quoteAddress, $carrierCode, $methodCode); + $quoteAddress = $cart->getShippingAddress(); + $this->assignShippingMethodToCart->execute($cart, $quoteAddress, $carrierCode, $methodCode); } } From e1f8e52bdbad27695bb91fbd0e86eee9f2b88afc Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 15 Apr 2019 09:29:17 -0500 Subject: [PATCH 093/247] Issue-230: adding varnish - mark cacheable false the queries we can't cache yet --- app/code/Magento/CustomerGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/DirectoryGraphQl/etc/schema.graphqls | 6 +++--- app/code/Magento/DownloadableGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/EavGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/SalesGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/StoreGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/VaultGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/WishlistGraphQl/etc/schema.graphqls | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index 4e4fd1d0fa8a..123818407505 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - customer: Customer @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\Customer") @doc(description: "The customer query returns information about a customer account") + customer: Customer @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\Customer") @doc(description: "The customer query returns information about a customer account") @cache(cacheable: false) isEmailAvailable ( email: String! @doc(description: "The new customer email") ): IsEmailAvailableOutput @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\IsEmailAvailable") diff --git a/app/code/Magento/DirectoryGraphQl/etc/schema.graphqls b/app/code/Magento/DirectoryGraphQl/etc/schema.graphqls index 8da1920f9a44..6daf13f567d4 100644 --- a/app/code/Magento/DirectoryGraphQl/etc/schema.graphqls +++ b/app/code/Magento/DirectoryGraphQl/etc/schema.graphqls @@ -2,9 +2,9 @@ # See COPYING.txt for license details. type Query { - currency: Currency @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency") @doc(description: "The currency query returns information about store currency.") - countries: [Country] @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Countries") @doc(description: "The countries query provides information for all countries.") - country (id: String): Country @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Country") @doc(description: "The countries query provides information for a single country.") + currency: Currency @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency") @doc(description: "The currency query returns information about store currency.") @cache(cacheable: false) + countries: [Country] @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Countries") @doc(description: "The countries query provides information for all countries.") @cache(cacheable: false) + country (id: String): Country @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Country") @doc(description: "The countries query provides information for a single country.") @cache(cacheable: false) } type Currency { diff --git a/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls b/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls index e2cacdf7608d..788a5fc601ee 100644 --- a/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls +++ b/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - customerDownloadableProducts: CustomerDownloadableProducts @resolver(class: "Magento\\DownloadableGraphQl\\Model\\Resolver\\CustomerDownloadableProducts") @doc(description: "The query returns the contents of a customer's downloadable products") + customerDownloadableProducts: CustomerDownloadableProducts @resolver(class: "Magento\\DownloadableGraphQl\\Model\\Resolver\\CustomerDownloadableProducts") @doc(description: "The query returns the contents of a customer's downloadable products") @cache(cacheable: false) } type CustomerDownloadableProducts { diff --git a/app/code/Magento/EavGraphQl/etc/schema.graphqls b/app/code/Magento/EavGraphQl/etc/schema.graphqls index adada3030f50..0299067bd052 100644 --- a/app/code/Magento/EavGraphQl/etc/schema.graphqls +++ b/app/code/Magento/EavGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") @doc(description: "The customAttributeMetadata query returns the attribute type, given an attribute code and entity type") + customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") @doc(description: "The customAttributeMetadata query returns the attribute type, given an attribute code and entity type") @cache(cacheable: false) } type CustomAttributeMetadata @doc(description: "CustomAttributeMetadata defines an array of attribute_codes and entity_types") { diff --git a/app/code/Magento/SalesGraphQl/etc/schema.graphqls b/app/code/Magento/SalesGraphQl/etc/schema.graphqls index 44f106532858..06146f805c64 100644 --- a/app/code/Magento/SalesGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SalesGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - customerOrders: CustomerOrders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") + customerOrders: CustomerOrders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") @cache(cacheable: false) } type CustomerOrder @doc(description: "Order mapping fields") { diff --git a/app/code/Magento/StoreGraphQl/etc/schema.graphqls b/app/code/Magento/StoreGraphQl/etc/schema.graphqls index d9f7eaaaa294..376635e5c8f7 100644 --- a/app/code/Magento/StoreGraphQl/etc/schema.graphqls +++ b/app/code/Magento/StoreGraphQl/etc/schema.graphqls @@ -1,7 +1,7 @@ # Copyright © Magento, Inc. All rights reserved. # See COPYING.txt for license details. type Query { - storeConfig : StoreConfig @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\StoreConfigResolver") @doc(description: "The store config query") + storeConfig : StoreConfig @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\StoreConfigResolver") @doc(description: "The store config query") @cache(cacheable: false) } type Website @doc(description: "The type contains information about a website") { diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls index 5aea482a0fe0..e9033880704c 100644 --- a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\EntityUrl") @doc(description: "The urlResolver query returns the relative URL for a specified product, category or CMS page") + urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\EntityUrl") @doc(description: "The urlResolver query returns the relative URL for a specified product, category or CMS page") @cache(cacheable: false) } type EntityUrl @doc(description: "EntityUrl is an output object containing the `id`, `relative_url`, and `type` attributes") { diff --git a/app/code/Magento/VaultGraphQl/etc/schema.graphqls b/app/code/Magento/VaultGraphQl/etc/schema.graphqls index cdaeced027f6..64484fe9e814 100644 --- a/app/code/Magento/VaultGraphQl/etc/schema.graphqls +++ b/app/code/Magento/VaultGraphQl/etc/schema.graphqls @@ -11,7 +11,7 @@ type DeletePaymentTokenOutput { } type Query { - customerPaymentTokens: CustomerPaymentTokens @doc(description: "Return a list of customer payment tokens") @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\PaymentTokens") + customerPaymentTokens: CustomerPaymentTokens @doc(description: "Return a list of customer payment tokens") @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\PaymentTokens") @cache(cacheable: false) } type CustomerPaymentTokens @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\PaymentTokens") { diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index f5b5034fb734..2aa5f03a787d 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "The wishlist query returns the contents of a customer's wish list") + wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "The wishlist query returns the contents of a customer's wish list") @cache(cacheable: false) } type WishlistOutput { From a04f5c3caa2e6c6bbee58d76f309b06c132cadac Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 15 Apr 2019 10:58:51 -0500 Subject: [PATCH 094/247] Issue-230: adding varnish - fix static test --- .../Model/Resolver/DataProvider/Page.php | 2 ++ .../HttpClient/CurlClientWithCookies.php | 4 ++- .../Catalog/ProductInMultipleStoresTest.php | 4 +++ .../GraphQl/PageCache/CacheTagTest.php | 34 ++++++++----------- .../Controller/GraphQlCacheControllerTest.php | 16 ++++----- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php index 001209ba7967..8e1e770b01e9 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Page.php @@ -40,6 +40,8 @@ public function __construct( } /** + * Get the page data + * * @param int $pageId * @return array * @throws NoSuchEntityException diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php index 626e319e8668..1dd9d17f904b 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClientWithCookies.php @@ -36,6 +36,8 @@ public function __construct( } /** + * Compose the resource url + * * @param string $resourcePath Resource URL like /V1/Resource1/123 * @return string resource URL * @throws \Exception @@ -80,7 +82,7 @@ public function get($resourcePath, $data = [], $headers = []) * ], * ] * - * @param $headerBlock + * @param string $headerBlock * @return array */ private function cookieParse($headerBlock) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php index 9eb9bc76047a..a63d417eaef1 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php @@ -10,10 +10,14 @@ use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; +/** + * Class ProductInMultipleStoresTest + */ class ProductInMultipleStoresTest extends GraphQlAbstract { /** + * Test a product from a specific and a default store * * @magentoApiDataFixture Magento/Store/_files/second_store.php * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index a01f31abb65d..59cc83d6a5d6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -7,10 +7,8 @@ namespace Magento\GraphQl\PageCache; - use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; -use Magento\Deploy\Model\Mode; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\App\State; use Magento\TestFramework\Helper\Bootstrap; @@ -48,34 +46,33 @@ public function testCacheTagsAndCacheDebugHeaderFromResponse() /** cache-debug should be a MISS when product is queried for first time */ - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); + $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); /** cache-debug should be a HIT for the second round */ $responseHitHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHitHeaders, $matchesHit); - $this->assertEquals('HIT', rtrim($matchesHit[1],"\r")); + $this->assertEquals('HIT', rtrim($matchesHit[1], "\r")); /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); /** @var Product $product */ - $product =$productRepository->get($productSku,false,null, true); + $product =$productRepository->get($productSku, false, null, true); /** update the price attribute for the product in test */ $product->setPrice(15); $product->save(); /** Cache invalidation happens and cache-debug header value is a MISS after product update */ $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); /** checks if cache tags for products are correctly displayed in the response header */ preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); - $actualCacheTags = explode(',', rtrim($headerCacheTags[1],"\r")); + $actualCacheTags = explode(',', rtrim($headerCacheTags[1], "\r")); $expectedCacheTags=['cat_p','cat_p_' . $product->getId(),'FPC']; - foreach(array_keys($actualCacheTags) as $key){ - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] - ); + foreach (array_keys($actualCacheTags) as $key) { + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); } } @@ -120,25 +117,24 @@ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); /** @var Product $product */ - $product =$productRepository->get($productSku,false,null, true); + $product =$productRepository->get($productSku, false, null, true); /** cache-debug header value should be a MISS when category is loaded first time */ preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); /** checks to see if the X-Magento-Tags for category is displayed correctly */ preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); - $actualCacheTags = explode(',', rtrim($headerCacheTags[1],"\r")); + $actualCacheTags = explode(',', rtrim($headerCacheTags[1], "\r")); $expectedCacheTags=['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; - foreach(array_keys($actualCacheTags) as $key){ - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] - ); + foreach (array_keys($actualCacheTags) as $key) { + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); } /** cache-debug header value should be MISS after updating child-product and reloading the category */ $product->setPrice(15); $product->save(); $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, $variables, '', []); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1],"\r")); + $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php index 98965ff41e73..5ddbc4b029a4 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php @@ -46,6 +46,9 @@ class GraphQlCacheControllerTest extends \Magento\TestFramework\Indexer\TestCase private $response; + /** + * @inheritdoc + */ public static function setUpBeforeClass() { $db = Bootstrap::getInstance()->getBootstrap() @@ -59,6 +62,9 @@ public static function setUpBeforeClass() parent::setUpBeforeClass(); } + /** + * @inheritdoc + */ protected function setUp(): void { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -67,7 +73,6 @@ protected function setUp(): void $this->metadataPool = $this->objectManager->get(MetadataPool::class); $this->request = $this->objectManager->get(Http::class); $this->response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - } /** @@ -103,20 +108,15 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTags(): void $this->request->setQueryValue('query', $query); /** @var \Magento\Framework\Controller\Result\Json $result */ $result = $this->graphql->dispatch($this->request); - /** @var \Magento\Framework\App\Response\Http $response */ - $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); /** @var $registry \Magento\Framework\Registry */ $registry = $this->objectManager->get(\Magento\Framework\Registry::class); $registry->register('use_page_cache_plugin', true, true); - $result->renderResult($this->response); // + $result->renderResult($this->response); $this->assertEquals('MISS', $this->response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $this->response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; foreach (array_keys($actualCacheTags) as $key) { - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] - ); + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); } } } - - From 4cc11f56910cc005e426d5a32c4efc4df44f4423 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Mon, 15 Apr 2019 11:31:27 -0500 Subject: [PATCH 095/247] Issue-230: Implement cache tag generation for GraphQL queries - Add unit test for CacheableQueryHandler --- .../Unit/Model/CacheableQueryHandlerTest.php | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php diff --git a/app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php b/app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php new file mode 100644 index 000000000000..c595881472e5 --- /dev/null +++ b/app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php @@ -0,0 +1,99 @@ +cacheableQueryMock = $this->createMock(CacheableQuery::class); + $this->requestMock = $this->createMock(Http::class); + $this->identityResolverPoolMock = $this->createMock(IdentityResolverPool::class); + $this->cacheableQueryHandler = $objectManager->getObject( + CacheableQueryHandler::class, + [ + 'cacheableQuery' => $this->cacheableQueryMock, + 'request' => $this->requestMock, + 'identityResolverPool' => $this->identityResolverPoolMock + ] + ); + } + + /** + * @param array $resolvedData + * @param array $resolvedIdentities + * @dataProvider resolvedDataProvider + */ + public function testhandleCacheFromResolverResponse( + array $resolvedData, + array $resolvedIdentities, + array $expectedCacheTags + ): void { + $cacheData = [ + 'cacheIdentityResolver' => IdentityResolverInterface::class, + 'cacheTag' => 'cat_p' + ]; + $fieldMock = $this->createMock(Field::class); + $mockIdentityResolver = $this->getMockBuilder($cacheData['cacheIdentityResolver']) + ->setMethods(['getIdentifiers']) + ->getMockForAbstractClass(); + + $this->requestMock->expects($this->once())->method('isGet')->willReturn(true); + $this->identityResolverPoolMock->expects($this->once())->method('get')->willReturn($mockIdentityResolver); + $fieldMock->expects($this->once())->method('getCache')->willReturn($cacheData); + $mockIdentityResolver->expects($this->once()) + ->method('getIdentifiers') + ->with($resolvedData) + ->willReturn($resolvedIdentities); + $this->cacheableQueryMock->expects($this->once())->method('addCacheTags')->with($expectedCacheTags); + $this->cacheableQueryMock->expects($this->once())->method('isCacheable')->willReturn(true); + $this->cacheableQueryMock->expects($this->once())->method('setCacheValidity')->with(true); + + $this->cacheableQueryHandler->handleCacheFromResolverResponse($resolvedData, $fieldMock); + } + + /** + * @return array + */ + public function resolvedDataProvider(): array + { + return [ + [ + "resolvedData" => [ + "id" => 10, + "name" => "TesName", + "sku" => "TestSku" + ], + "resolvedIdentities" => [10], + "expectedCacheTags" => ["cat_p", "cat_p_10"] + ] + ]; + } +} From eaea57d3cde774f8249ee2e121472dd65840c8fb Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Mon, 15 Apr 2019 11:52:53 -0500 Subject: [PATCH 096/247] GraphQL-594: Test coverage for tag cache generation for cateogry - integration test coverage for category --- .../Controller/GraphQlCacheControllerTest.php | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php index 5ddbc4b029a4..400dea5dd12d 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php @@ -72,7 +72,7 @@ protected function setUp(): void $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); $this->metadataPool = $this->objectManager->get(MetadataPool::class); $this->request = $this->objectManager->get(Http::class); - $this->response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + // $this->response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); } /** @@ -108,10 +108,12 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTags(): void $this->request->setQueryValue('query', $query); /** @var \Magento\Framework\Controller\Result\Json $result */ $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); /** @var $registry \Magento\Framework\Registry */ $registry = $this->objectManager->get(\Magento\Framework\Registry::class); $registry->register('use_page_cache_plugin', true, true); - $result->renderResult($this->response); + $result->renderResult($response); $this->assertEquals('MISS', $this->response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $this->response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; @@ -119,4 +121,46 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTags(): void $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); } } + + /** + * Test cache tags and debug header for category and querying only for category + * + * @magentoCache all enabled + * @magentoDataFixture Magento/Catalog/_files/category_product.php + * + */ + public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void + { + $categoryId ='333'; + $query + = <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'FPC']; + foreach (array_keys($actualCacheTags) as $key) { + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] + ); + } + } } From 09488fc3369ccba16cd2ed1e4e8667df2b499a29 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Mon, 15 Apr 2019 17:10:18 -0500 Subject: [PATCH 097/247] GraphQL-594: Test coverage for tag cache generation for category - integration test coverage for category with products --- .../Controller/GraphQlCacheControllerTest.php | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php index 400dea5dd12d..29aac2ffa378 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php @@ -163,4 +163,74 @@ public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void ); } } + + /** + * Test cache tags and debug header for category with products querying for products and category + * + * @magentoCache all enabled + * @magentoDataFixture Magento/Catalog/_files/category_product.php + * + */ + public function testDispatchForCacheHeadersAndCacheTagsForCategoryWtihProducts(): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var ProductInterface $product */ + $product= $productRepository->get('simple333'); + $categoryId ='333'; + $query + = << 333, + 'pageSize'=> 10, + 'currentPage' => 1 + ]; + $queryParams = [ + 'query' => $query, + 'variables' => json_encode($variables), + 'operationName' => 'GetCategoryWithProducts' + ]; + + $this->request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setParams($queryParams); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } } + From 16ee54e2ae405217efe9fe61e9b8c6d3f302cbef Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Mon, 15 Apr 2019 17:15:14 -0500 Subject: [PATCH 098/247] Issue-230: Implement cache tag generation for GraphQL queries --- .../CmsGraphQl/Model/Resolver/Block/IdentityResolver.php | 4 ++-- app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php index 4f5913c458d0..a393f6ab04f4 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php @@ -26,8 +26,8 @@ public function getIdentifiers(array $resolvedData): array $ids = []; $items = $resolvedData['items'] ?? []; foreach ($items as $item) { - if (is_array($item) && !empty($item[BlockInterface::IDENTIFIER])) { - $ids[] = $item[BlockInterface::IDENTIFIER ]; + if (is_array($item) && !empty($item[BlockInterface::BLOCK_ID])) { + $ids[] = $item[BlockInterface::BLOCK_ID]; } } diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php index bf57e8c9736c..326c53b58991 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -64,11 +64,11 @@ public function handleCacheFromResolverResponse(array $resolvedValue, Field $fie $cacheTags = []; if ($cacheTag && $this->request->isGet()) { - $cacheTags[] = $cacheTag; if (!empty($cacheIdentityResolverClass)) { $cacheIdentityResolver = $this->identityResolverPool->get($cacheIdentityResolverClass); $cacheTagIds = $cacheIdentityResolver->getIdentifiers($resolvedValue); if (!empty($cacheTagIds)) { + $cacheTags[] = $cacheTag; foreach ($cacheTagIds as $cacheTagId) { $cacheTags[] = $cacheTag . '_' . $cacheTagId; } From a396e2fcc65e2c7d030b6eaafab34c0cd9fcffcd Mon Sep 17 00:00:00 2001 From: Ravi Chandra Date: Tue, 16 Apr 2019 10:58:29 +0530 Subject: [PATCH 099/247] Correct spelling --- .../Magento/Catalog/Model/ResourceModel/Product/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 136c7e800bf0..a50864e90833 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -445,7 +445,7 @@ protected function _preparePriceExpressionParameters($select) */ public function getPriceExpression($select) { - //@todo: Add caching of price expresion + //@todo: Add caching of price expression $this->_preparePriceExpressionParameters($select); return $this->_priceExpression; } From fa5cf907e0bd9f0fda4431a551e798a911dfe875 Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Tue, 16 Apr 2019 17:24:30 +0300 Subject: [PATCH 100/247] Fix static tests. --- .../Magento/Quote/Model/QuoteRepository.php | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteRepository.php b/app/code/Magento/Quote/Model/QuoteRepository.php index fa6ab1813668..30931821ddc7 100644 --- a/app/code/Magento/Quote/Model/QuoteRepository.php +++ b/app/code/Magento/Quote/Model/QuoteRepository.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Quote\Model; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; @@ -24,6 +25,8 @@ use Magento\Store\Model\StoreManagerInterface; /** + * Quote repository. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class QuoteRepository implements CartRepositoryInterface @@ -125,7 +128,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function get($cartId, array $sharedStoreIds = []) { @@ -138,7 +141,7 @@ public function get($cartId, array $sharedStoreIds = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function getForCustomer($customerId, array $sharedStoreIds = []) { @@ -152,7 +155,7 @@ public function getForCustomer($customerId, array $sharedStoreIds = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function getActive($cartId, array $sharedStoreIds = []) { @@ -164,7 +167,7 @@ public function getActive($cartId, array $sharedStoreIds = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function getActiveForCustomer($customerId, array $sharedStoreIds = []) { @@ -176,7 +179,7 @@ public function getActiveForCustomer($customerId, array $sharedStoreIds = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function save(CartInterface $quote) { @@ -196,7 +199,7 @@ public function save(CartInterface $quote) } /** - * {@inheritdoc} + * @inheritdoc */ public function delete(CartInterface $quote) { @@ -232,7 +235,7 @@ protected function loadQuote($loadMethod, $loadField, $identifier, array $shared } /** - * {@inheritdoc} + * @inheritdoc */ public function getList(SearchCriteriaInterface $searchCriteria) { @@ -277,6 +280,7 @@ protected function addFilterGroupToCollection(FilterGroup $filterGroup, QuoteCol /** * Get new SaveHandler dependency for application code. + * * @return SaveHandler * @deprecated 100.1.0 */ @@ -289,6 +293,8 @@ private function getSaveHandler() } /** + * Get load handler instance. + * * @return LoadHandler * @deprecated 100.1.0 */ From e995c1ba60c6eef45c3523fb0ca14d0bf57ef2f0 Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Tue, 16 Apr 2019 12:50:51 -0500 Subject: [PATCH 101/247] 596: Category with Products with...(deep nesting) (Integration Test for Tag Cache Generation) - Added integration test --- .../Controller/GraphQlCacheControllerTest.php | 97 ++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php index 400dea5dd12d..c6df4f6135a0 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php @@ -13,6 +13,8 @@ use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Serialize\SerializerInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; +use Magento\Catalog\Api\CategoryRepositoryInterface; /** * Tests cache debug headers and cache tag validation for a simple product query @@ -45,7 +47,6 @@ class GraphQlCacheControllerTest extends \Magento\TestFramework\Indexer\TestCase /** @var \Magento\Framework\App\Response\Http */ private $response; - /** * @inheritdoc */ @@ -159,8 +160,100 @@ public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'FPC']; foreach (array_keys($actualCacheTags) as $key) { - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key] + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); + } + } + + /** + * Test cache tags and debug header for deep nested queries involving category and products + * + * @magentoCache all enabled + * @magentoDataFixture Magento/Catalog/_files/product_in_multiple_categories.php + * + */ + public function testDispatchForCacheHeadersOnDeepNestedQueries(): void + { + $categoryId ='333'; + $query + = <<get(CategoryRepositoryInterface::class); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + $categoryIds = []; + $category = $categoryRepository->get('333'); + + $productIdsFromCategory = $category->getProductCollection()->getAllIds(); + foreach ($productIdsFromCategory as $productId) { + $categoryIds = array_merge($categoryIds, $productRepository->getById($productId)->getCategoryIds()); + } + + $categoryIds = array_merge($categoryIds, ['333']); + foreach ($categoryIds as $categoryId) { + $category = $categoryRepository->get($categoryId); + $productIdsFromCategory= array_merge( + $productIdsFromCategory, + $category->getProductCollection()->getAllIds() ); } + + $uniqueProductIds = array_unique($productIdsFromCategory); + $uniqueCategoryIds = array_unique($categoryIds); + $expectedCacheTags = ['cat_c', 'cat_p', 'FPC']; + foreach ($uniqueProductIds as $productId) { + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_'.$productId]); + } + foreach ($uniqueCategoryIds as $categoryId) { + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_'.$categoryId]); + } + + $this->request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $this->assertEmpty( + array_merge( + array_diff($expectedCacheTags, $actualCacheTags), + array_diff($actualCacheTags, $expectedCacheTags) + ) + ); } } From ee6c054ac3de1036a7fd14f5503d6fd8b3657f25 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Tue, 16 Apr 2019 15:34:31 -0500 Subject: [PATCH 102/247] GraphQL-594: Test coverage for tag cache generation for category - fixing minor issues with test --- .../GraphQl/Controller/GraphQlCacheControllerTest.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php index 29aac2ffa378..822946cd7c36 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php @@ -18,9 +18,8 @@ * Tests cache debug headers and cache tag validation for a simple product query * * @magentoAppArea graphql - * - * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php * @magentoDbIsolation disabled + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class GraphQlCacheControllerTest extends \Magento\TestFramework\Indexer\TestCase @@ -81,7 +80,7 @@ protected function setUp(): void * @magentoCache all enabled * @return void */ - public function testDispatchWithGetForCacheDebugHeadersAndCacheTags(): void + public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts(): void { /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); @@ -98,6 +97,7 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTags(): void id name sku + description } } } @@ -117,9 +117,7 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTags(): void $this->assertEquals('MISS', $this->response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $this->response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; - foreach (array_keys($actualCacheTags) as $key) { - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); - } + $this->assertEquals($expectedCacheTags, $actualCacheTags); } /** From 417894cb136acba3405cff4350f459406fb1defe Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Tue, 16 Apr 2019 16:28:25 -0500 Subject: [PATCH 103/247] GraphQL-594: Test coverage for tag cache generation for category - fix product query --- .../GraphQl/Controller/GraphQlCacheControllerTest.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php index 822946cd7c36..cf5b95e4d269 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php @@ -97,7 +97,9 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts() id name sku - description + description { + html + } } } } @@ -114,8 +116,8 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts() $registry = $this->objectManager->get(\Magento\Framework\Registry::class); $registry->register('use_page_cache_plugin', true, true); $result->renderResult($response); - $this->assertEquals('MISS', $this->response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $actualCacheTags = explode(',', $this->response->getHeader('X-Magento-Tags')->getFieldValue()); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; $this->assertEquals($expectedCacheTags, $actualCacheTags); } @@ -169,7 +171,7 @@ public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void * @magentoDataFixture Magento/Catalog/_files/category_product.php * */ - public function testDispatchForCacheHeadersAndCacheTagsForCategoryWtihProducts(): void + public function testDispatchForCacheHeadersAndCacheTagsForCategoryWithProducts(): void { /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); @@ -231,4 +233,3 @@ public function testDispatchForCacheHeadersAndCacheTagsForCategoryWtihProducts() $this->assertEquals($expectedCacheTags, $actualCacheTags); } } - From caa0618618f8171e5ca780aeeb5d908b44325428 Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Tue, 16 Apr 2019 16:46:48 -0500 Subject: [PATCH 104/247] 230: Implement cache tag generation for GraphQL queries - Refactored Integration test to GraphQlCacheModule --- .../CategoriesWithProductsDispatchTest.php | 143 +++++++++++++++ .../Catalog/CategoryDispatchTest.php | 112 ++++++++++++ .../DeepNestedCategoriesAndProductsTest.php | 168 ++++++++++++++++++ 3 files changed, 423 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php new file mode 100644 index 000000000000..385fb4c66d1d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php @@ -0,0 +1,143 @@ +getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + $this->metadataPool = $this->objectManager->get(MetadataPool::class); + $this->request = $this->objectManager->get(Http::class); + } + + /** + * Test cache tags and debug header for category with products querying for products and category + * + * @magentoCache all enabled + * @magentoDataFixture Magento/Catalog/_files/category_product.php + * + */ + public function testDispatchForCacheHeadersAndCacheTagsForCategoryWtihProducts(): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var ProductInterface $product */ + $product= $productRepository->get('simple333'); + $categoryId ='333'; + $query + = << 333, + 'pageSize'=> 10, + 'currentPage' => 1 + ]; + $queryParams = [ + 'query' => $query, + 'variables' => json_encode($variables), + 'operationName' => 'GetCategoryWithProducts' + ]; + + $this->request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setParams($queryParams); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } +} + diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php new file mode 100644 index 000000000000..1f51f5b12960 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php @@ -0,0 +1,112 @@ +getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + $this->metadataPool = $this->objectManager->get(MetadataPool::class); + $this->request = $this->objectManager->get(Http::class); + } + + /** + * Test cache tags and debug header for category and querying only for category + * + * @magentoCache all enabled + * @magentoDataFixture Magento/Catalog/_files/category_product.php + * + */ + public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void + { + $categoryId ='333'; + $query + = <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'FPC']; + foreach (array_keys($actualCacheTags) as $key) { + $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); + } + } +} + diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php new file mode 100644 index 000000000000..c8c2893e7c4d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -0,0 +1,168 @@ +getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + $this->metadataPool = $this->objectManager->get(MetadataPool::class); + $this->request = $this->objectManager->get(Http::class); + } + + /** + * Test cache tags and debug header for deep nested queries involving category and products + * + * @magentoCache all enabled + * @magentoDataFixture Magento/Catalog/_files/product_in_multiple_categories.php + * + */ + public function testDispatchForCacheHeadersOnDeepNestedQueries(): void + { + $categoryId ='333'; + $query + = <<get(CategoryRepositoryInterface::class); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + $categoryIds = []; + $category = $categoryRepository->get('333'); + + $productIdsFromCategory = $category->getProductCollection()->getAllIds(); + foreach ($productIdsFromCategory as $productId) { + $categoryIds = array_merge($categoryIds, $productRepository->getById($productId)->getCategoryIds()); + } + + $categoryIds = array_merge($categoryIds, ['333']); + foreach ($categoryIds as $categoryId) { + $category = $categoryRepository->get($categoryId); + $productIdsFromCategory= array_merge( + $productIdsFromCategory, + $category->getProductCollection()->getAllIds() + ); + } + + $uniqueProductIds = array_unique($productIdsFromCategory); + $uniqueCategoryIds = array_unique($categoryIds); + $expectedCacheTags = ['cat_c', 'cat_p', 'FPC']; + foreach ($uniqueProductIds as $productId) { + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_'.$productId]); + } + foreach ($uniqueCategoryIds as $categoryId) { + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_'.$categoryId]); + } + + $this->request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $this->assertEmpty( + array_merge( + array_diff($expectedCacheTags, $actualCacheTags), + array_diff($actualCacheTags, $expectedCacheTags) + ) + ); + } +} + From 53ce80a50b3113037b8de78a8fb80c3590da8d0b Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Tue, 16 Apr 2019 16:54:56 -0500 Subject: [PATCH 105/247] Issue-230: Implement cache tag generation for GraphQL queries - add tests for caching cms blocks --- .../Model/Resolver/Block/IdentityResolver.php | 1 + .../GraphQl/PageCache/Cms/BlockCacheTest.php | 152 ++++++++++++++++++ .../Controller/Cms/BlockCacheTest.php | 120 ++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php index a393f6ab04f4..5f18bce21f37 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php @@ -28,6 +28,7 @@ public function getIdentifiers(array $resolvedData): array foreach ($items as $item) { if (is_array($item) && !empty($item[BlockInterface::BLOCK_ID])) { $ids[] = $item[BlockInterface::BLOCK_ID]; + $ids[] = $item[BlockInterface::IDENTIFIER]; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php new file mode 100644 index 000000000000..54a96ef2d949 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php @@ -0,0 +1,152 @@ +get(BlockRepository::class); + $block = $blockRepository->getById($blockIdentifier); + $blockId = $block->getId(); + $query = $this->getBlockQuery([$blockIdentifier]); + + //cache-debug should be a MISS on first request + $responseHeaders = $this->graphQlQueryForHttpHeaders($query); + preg_match('/X-Magento-Tags: (.*)/', $responseHeaders, $matches); + $this->assertNotEmpty($matches[1]); + $actualTags = explode(',', $matches[1]); + $expectedTags = ["cms_b_{$blockIdentifier}", "cms_b_{$blockId}"]; + foreach ($expectedTags as $expectedTag) { + $this->assertContains($expectedTag, $actualTags); + } + } + + /** + * Test the second request for the same block will return a cached result + * + * @magentoApiDataFixture Magento/Cms/_files/block.php + */ + public function testCacheIsUsedOnSecondRequest() + { + $blockIdentifier = 'fixture_block'; + $query = $this->getBlockQuery([$blockIdentifier]); + + //cache-debug should be a MISS on first request + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + + //cache-debug should be a HIT on second request + $responseHitHeaders = $this->graphQlQueryForHttpHeaders($query); + $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); + + //cached data should be correct + $blockQueryData = $this->graphQlQuery($query); + $blocks = $blockQueryData['cmsBlocks']['items']; + $this->assertArrayNotHasKey('errors', $blockQueryData); + $this->assertEquals($blockIdentifier, $blocks[0]['identifier']); + $this->assertEquals('CMS Block Title', $blocks[0]['title']); + } + + /** + * Test that cache is invalidated when block is updated + * + * @magentoApiDataFixture Magento/Cms/_files/blocks.php + * @magentoApiDataFixture Magento/Cms/_files/block.php + */ + public function testCacheIsInvalidatedOnBlockUpdate() + { + $fixtureBlockIdentifier = 'fixture_block'; + $enabledBlockIdentifier = 'enabled_block'; + $fixtureBlockQuery = $this->getBlockQuery([$fixtureBlockIdentifier]); + $enabledBlockQuery = $this->getBlockQuery([$enabledBlockIdentifier]); + + //cache-debug should be a MISS on first request + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($fixtureBlockQuery); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($enabledBlockQuery); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + + //cache-debug should be a HIT on second request + $responseHitHeaders = $this->graphQlQueryForHttpHeaders($fixtureBlockQuery); + $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); + $responseHitHeaders = $this->graphQlQueryForHttpHeaders($enabledBlockQuery); + $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); + + $newBlockContent = 'New block content!!!'; + $this->updateBlockContent($fixtureBlockIdentifier, $newBlockContent); + + //cache-debug should be a MISS after update the block + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($fixtureBlockQuery); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + $responseHitHeaders = $this->graphQlQueryForHttpHeaders($enabledBlockQuery); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHitHeaders); + + //updated block data should be correct + $blockQueryData = $this->graphQlQuery($fixtureBlockQuery); + $blocks = $blockQueryData['cmsBlocks']['items']; + $this->assertArrayNotHasKey('errors', $blockQueryData); + $this->assertEquals($fixtureBlockIdentifier, $blocks[0]['identifier']); + $this->assertEquals('CMS Block Title', $blocks[0]['title']); + $this->assertEquals($newBlockContent, $blocks[0]['content']); + } + + /** + * Update the content of a CMS block + * + * @param $identifier + * @param $newContent + * @return Block + */ + private function updateBlockContent($identifier, $newContent): Block + { + $blockRepository = Bootstrap::getObjectManager()->get(BlockRepository::class); + $block = $blockRepository->getById($identifier); + $block->setContent($newContent); + $blockRepository->save($block); + + return $block; + } + + /** + * Get cmsBlocks query + * + * @param array $identifiers + * @return string + */ + private function getBlockQuery(array $identifiers): string + { + $identifiersString = implode(',', $identifiers); + $query = <<getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->request = $this->objectManager->create(Http::class); + $this->enableFullPageCache(); + } + + /** + * Test that the correct cache tags get added to request for cmsBlocks + * + * @magentoDataFixture Magento/Cms/_files/block.php + */ + public function testCmsBlocksRequestHasCorrectTags(): void + { + $blockIdentifier = 'fixture_block'; + $blockRepository = $this->objectManager->get(BlockRepository::class); + $block = $blockRepository->getById($blockIdentifier); + + $query + = <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphqlController->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $expectedCacheTags = ['cms_b', 'cms_b_' . $block->getId(), 'cms_b_' . $block->getIdentifier(), 'FPC']; + $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); + $actualCacheTags = explode(',', $rawActualCacheTags); + foreach ($expectedCacheTags as $expectedCacheTag) { + $this->assertContains($expectedCacheTag, $actualCacheTags); + } + } + + /** + * Enable full page cache so plugins are called + */ + private function enableFullPageCache() + { + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + + /** @var \Magento\Framework\App\Cache\StateInterface $cacheState */ + $cacheState = $this->objectManager->get(\Magento\Framework\App\Cache\StateInterface::class); + $cacheState->setEnabled(\Magento\PageCache\Model\Cache\Type::TYPE_IDENTIFIER, true); + } +} From 05660302d304ac695c407aef19fe532a64aa5155 Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Tue, 16 Apr 2019 16:59:20 -0500 Subject: [PATCH 106/247] 596: Category with Products with...(deep nesting) (Integration Test for Tag Cache Generation) - Added integration test and refactored to new structure --- .../Controller/GraphQlCacheControllerTest.php | 328 ------------------ .../CategoriesWithProductsDispatchTest.php | 2 +- .../Catalog/CategoryDispatchTest.php | 3 +- .../DeepNestedCategoriesAndProductsTest.php | 2 +- .../Catalog/ProductsDispatchTest.php | 122 +++++++ 5 files changed, 126 insertions(+), 331 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php b/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php deleted file mode 100644 index f0450aa0369d..000000000000 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Controller/GraphQlCacheControllerTest.php +++ /dev/null @@ -1,328 +0,0 @@ -getBootstrap() - ->getApplication() - ->getDbInstance(); - if (!$db->isDbDumpExists()) { - throw new \LogicException('DB dump does not exist.'); - } - $db->restoreFromDbDump(); - - parent::setUpBeforeClass(); - } - - /** - * @inheritdoc - */ - protected function setUp(): void - { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->metadataPool = $this->objectManager->get(MetadataPool::class); - $this->request = $this->objectManager->get(Http::class); - // $this->response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - } - - /** - * Test request is dispatched and response is checked for debug headers and cache tags - * - * @magentoCache all enabled - * @return void - */ - public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts(): void - { - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); - - /** @var ProductInterface $product */ - $product = $productRepository->get('simple1'); - - $query - = <<request->setPathInfo('/graphql'); - $this->request->setMethod('GET'); - $this->request->setQueryValue('query', $query); - /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); - /** @var \Magento\Framework\App\Response\Http $response */ - $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); - $result->renderResult($response); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; - $this->assertEquals($expectedCacheTags, $actualCacheTags); - } - - /** - * Test cache tags and debug header for category and querying only for category - * - * @magentoCache all enabled - * @magentoDataFixture Magento/Catalog/_files/category_product.php - * - */ - public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void - { - $categoryId ='333'; - $query - = <<request->setPathInfo('/graphql'); - $this->request->setMethod('GET'); - $this->request->setQueryValue('query', $query); - /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); - /** @var \Magento\Framework\App\Response\Http $response */ - $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); - $result->renderResult($response); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'FPC']; - foreach (array_keys($actualCacheTags) as $key) { - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); - } - } - - /** - * Test cache tags and debug header for deep nested queries involving category and products - * - * @magentoCache all enabled - * @magentoDataFixture Magento/Catalog/_files/product_in_multiple_categories.php - * - */ - public function testDispatchForCacheHeadersOnDeepNestedQueries(): void - { - $categoryId ='333'; - $query - = <<get(CategoryRepositoryInterface::class); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - $categoryIds = []; - $category = $categoryRepository->get('333'); - - $productIdsFromCategory = $category->getProductCollection()->getAllIds(); - foreach ($productIdsFromCategory as $productId) { - $categoryIds = array_merge($categoryIds, $productRepository->getById($productId)->getCategoryIds()); - } - - $categoryIds = array_merge($categoryIds, ['333']); - foreach ($categoryIds as $categoryId) { - $category = $categoryRepository->get($categoryId); - $productIdsFromCategory= array_merge( - $productIdsFromCategory, - $category->getProductCollection()->getAllIds() - ); - } - - $uniqueProductIds = array_unique($productIdsFromCategory); - $uniqueCategoryIds = array_unique($categoryIds); - $expectedCacheTags = ['cat_c', 'cat_p', 'FPC']; - foreach ($uniqueProductIds as $productId) { - $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_'.$productId]); - } - foreach ($uniqueCategoryIds as $categoryId) { - $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_'.$categoryId]); - } - - $this->request->setPathInfo('/graphql'); - $this->request->setMethod('GET'); - $this->request->setQueryValue('query', $query); - /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); - /** @var \Magento\Framework\App\Response\Http $response */ - $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); - $result->renderResult($response); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $this->assertEmpty( - array_merge( - array_diff($expectedCacheTags, $actualCacheTags), - array_diff($actualCacheTags, $expectedCacheTags) - ) - ); - } - - /** - * Test cache tags and debug header for category with products querying for products and category - * - * @magentoCache all enabled - * @magentoDataFixture Magento/Catalog/_files/category_product.php - * - */ - public function testDispatchForCacheHeadersAndCacheTagsForCategoryWithProducts(): void - { - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); - /** @var ProductInterface $product */ - $product= $productRepository->get('simple333'); - $categoryId ='333'; - $query - = << 333, - 'pageSize'=> 10, - 'currentPage' => 1 - ]; - $queryParams = [ - 'query' => $query, - 'variables' => json_encode($variables), - 'operationName' => 'GetCategoryWithProducts' - ]; - - $this->request->setPathInfo('/graphql'); - $this->request->setMethod('GET'); - $this->request->setParams($queryParams); - /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); - /** @var \Magento\Framework\App\Response\Http $response */ - $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); - $result->renderResult($response); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; - $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $this->assertEquals($expectedCacheTags, $actualCacheTags); - } -} diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php index 385fb4c66d1d..ed8809d35440 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php @@ -15,7 +15,7 @@ use Magento\TestFramework\Helper\Bootstrap; /** - * Tests cache debug headers and cache tag validation for a simple product query + * Tests cache debug headers and cache tag validation for a category with product query * * @magentoAppArea graphql * @magentoDbIsolation disabled diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php index 1f51f5b12960..454bbabc1b7e 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php @@ -13,7 +13,7 @@ use Magento\TestFramework\Helper\Bootstrap; /** - * Tests cache debug headers and cache tag validation for a simple product query + * Tests cache debug headers and cache tag validation for a simple category query * * @magentoAppArea graphql * @magentoDbIsolation disabled @@ -100,6 +100,7 @@ public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); /** @var $registry \Magento\Framework\Registry */ $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php index c8c2893e7c4d..082c8815a737 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -16,7 +16,7 @@ use Magento\TestFramework\ObjectManager; /** - * Tests cache debug headers and cache tag validation for a simple product query + * Tests cache debug headers and cache tag validation for a deep nested category and product query * * @magentoAppArea graphql * @magentoDbIsolation disabled diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php new file mode 100644 index 000000000000..b8eb47195691 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php @@ -0,0 +1,122 @@ +getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + $this->metadataPool = $this->objectManager->get(MetadataPool::class); + $this->request = $this->objectManager->get(Http::class); + } + + /** + * Test request is dispatched and response is checked for debug headers and cache tags + * + * @magentoCache all enabled + * @return void + */ + public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts(): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + + /** @var ProductInterface $product */ + $product = $productRepository->get('simple1'); + + $query + = <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } +} + From 862937aad682ff19065c9cb1c392eaaa6bd5f201 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Tue, 16 Apr 2019 17:02:36 -0500 Subject: [PATCH 107/247] Issue-230: Implement cache tag generation for GraphQL queries - Skip api functional tests due to cicd limitation --- .../Magento/GraphQl/PageCache/Cms/BlockCacheTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php index 54a96ef2d949..aed568b0d5d7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php @@ -17,6 +17,16 @@ */ class BlockCacheTest extends GraphQlAbstract { + /** + * @inheritdoc + */ + protected function setUp() + { + $this->markTestSkipped( + 'This test will stay skipped until DEVOPS-4924 is resolved' + ); + } + /** * Test that X-Magento-Tags are correct * From a87e52e2731c9d61ab46f4a55bcb85bd66eeafce Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 16 Apr 2019 17:14:07 -0500 Subject: [PATCH 108/247] Issue-230: adding varnish - fixing currency validator and processor for default, non specific and specific cached or non cached --- app/code/Magento/Directory/i18n/en_US.csv | 1 + .../HttpHeaderProcessor/CurrencyProcessor.php | 27 +++++++++++++------ .../CurrencyValidator.php | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Directory/i18n/en_US.csv b/app/code/Magento/Directory/i18n/en_US.csv index 3dcd2ceebf13..79a99eb97fec 100644 --- a/app/code/Magento/Directory/i18n/en_US.csv +++ b/app/code/Magento/Directory/i18n/en_US.csv @@ -52,3 +52,4 @@ Service,Service "The """%1"" is not allowed as base currency for your subscription plan.","The """%1"" is not allowed as base currency for your subscription plan." "An invalid base currency has been entered.","An invalid base currency has been entered." "Currency rates can't be retrieved.","Currency rates can't be retrieved." +"Currency not allowed for store %1","Currency not allowed for store %1" \ No newline at end of file diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php index 7aa5f032ad4d..bcff22467b90 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php @@ -65,24 +65,35 @@ public function __construct( public function processHeaderValue(string $headerValue) : void { try { - /** @var \Magento\Store\Model\Store $defaultStore */ - $defaultStore = $this->storeManager->getWebsite()->getDefaultStore(); - /** @var \Magento\Store\Model\Store $currentStore */ - $currentStore = $this->storeManager->getStore(); - if (!empty($headerValue)) { $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); - if (in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { + /** @var \Magento\Store\Model\Store $currentStore */ + $currentStore = $this->storeManager->getStore(); + if (in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes(true))) { $currentStore->setCurrentCurrencyCode($headerCurrency); + } else { + /** @var \Magento\Store\Model\Store $store */ + $store = $this->storeManager->getStore() ?? $this->storeManager->getDefaultStoreView(); + //skip store not found exception as it will be handled in graphql validation + $this->logger->warning(__('Currency not allowed for store %1', [$store->getCode()])); + $this->httpContext->setValue( + HttpContext::CONTEXT_CURRENCY, + $headerCurrency, + $store->getCurrentCurrency()->getCode() + ); } } else { if ($this->session->getCurrencyCode()) { + /** @var \Magento\Store\Model\Store $currentStore */ + $currentStore = $this->storeManager->getStore() ?? $this->storeManager->getDefaultStoreView(); $currentStore->setCurrentCurrencyCode($this->session->getCurrencyCode()); } else { + /** @var \Magento\Store\Model\Store $store */ + $store = $this->storeManager->getStore() ?? $this->storeManager->getDefaultStoreView(); $this->httpContext->setValue( HttpContext::CONTEXT_CURRENCY, - $defaultStore->getCurrentCurrencyCode(), - $defaultStore->getDefaultCurrencyCode() + $store->getCurrentCurrency()->getCode(), + $store->getCurrentCurrency()->getCode() ); } } diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php index 7ecff5d1f3f6..6c0d4ec2e7be 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php @@ -46,7 +46,7 @@ public function validate(HttpRequestInterface $request): void $headerCurrency = strtoupper(ltrim(rtrim($headerValue))); /** @var \Magento\Store\Model\Store $currentStore */ $currentStore = $this->storeManager->getStore(); - if (!in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes())) { + if (!in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes(true))) { throw new GraphQlInputException( __('Currency not allowed for store %1', [$currentStore->getCode()]) ); From 1dec67693b7244953e544623f06d4653cc7fdec4 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 16 Apr 2019 17:22:32 -0500 Subject: [PATCH 109/247] Issue-230: adding varnish - fixing default currency --- .../Controller/HttpHeaderProcessor/CurrencyProcessor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php index bcff22467b90..b076b6fe9e76 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpHeaderProcessor/CurrencyProcessor.php @@ -79,7 +79,7 @@ public function processHeaderValue(string $headerValue) : void $this->httpContext->setValue( HttpContext::CONTEXT_CURRENCY, $headerCurrency, - $store->getCurrentCurrency()->getCode() + $store->getDefaultCurrency()->getCode() ); } } else { @@ -93,7 +93,7 @@ public function processHeaderValue(string $headerValue) : void $this->httpContext->setValue( HttpContext::CONTEXT_CURRENCY, $store->getCurrentCurrency()->getCode(), - $store->getCurrentCurrency()->getCode() + $store->getDefaultCurrency()->getCode() ); } } From 924dac8485a1072c92de99261472055bd79fd790 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 16 Apr 2019 17:28:52 -0500 Subject: [PATCH 110/247] Issue-230: adding varnish - adding currency api test - fixing static --- .../Catalog/ProductInMultipleStoresTest.php | 1 - .../GraphQl/PageCache/CacheTagTest.php | 1 - .../ProductInMultipleStoresCacheTest.php | 240 ++++++++++++++++++ 3 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php index a63d417eaef1..d49eef8a887e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php @@ -15,7 +15,6 @@ */ class ProductInMultipleStoresTest extends GraphQlAbstract { - /** * Test a product from a specific and a default store * diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 59cc83d6a5d6..cbdd1ebc13bc 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -44,7 +44,6 @@ public function testCacheTagsAndCacheDebugHeaderFromResponse() } QUERY; - /** cache-debug should be a MISS when product is queried for first time */ $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php new file mode 100644 index 000000000000..916a25ea5acd --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php @@ -0,0 +1,240 @@ + 'default', 'Content-Currency' => 'someNonExistentCurrency']; + $this->expectExceptionMessage('Currency someNonExistentCurrency not allowed for store default'); + $this->graphQlQuery($query, [], '', $headerMap); + + //test not allowed existing currency + $headerMap = ['Store' => $storeCodeFromFixture, 'Content-Currency' => 'CAD']; + $this->expectExceptionMessage('Currency not allowed for store ' . $storeCodeFromFixture); + $this->graphQlQuery($query, [], '', $headerMap); + } + + /** + * Test a product from a custom and default store, with cache with repeating queries asserting different results. + * + * @magentoApiDataFixture Magento/Store/_files/second_website_with_second_currency.php + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testProductFromSpecificAndDefaultStoreWithMultiCurrency() + { + $productSku = 'simple'; + + $query = <<get(\Magento\Store\Model\Store::class); + $storeCodeFromFixture = 'fixture_second_store'; + $storeId = $store->load($storeCodeFromFixture)->getStoreId(); + + $configResource = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class); + + $configResource->saveConfig( + \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_DEFAULT, + 'EUR', + \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES, + $store->load($storeCodeFromFixture)->getWebsiteId() + ); + + // allow USD & EUR currency + $configResource->saveConfig( + \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW, + 'EUR,USD', + \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES, + $store->load($storeCodeFromFixture)->getWebsiteId() + ); + + /** @var \Magento\Config\App\Config\Type\System $config */ + $config = ObjectManager::getInstance()->get(\Magento\Config\App\Config\Type\System::class); + // configuration cache clean is required to reload currency setting + $config->clean(); + + /** @var \Magento\Catalog\Model\Product $product */ + $product = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Product::class); + $product->load($product->getIdBySku($productSku)); + + $website = ObjectManager::getInstance()->get(\Magento\Store\Model\Website::class); + /** @var $website \Magento\Store\Model\Website */ + $website->load('test', 'code'); + $product->setWebsiteIds([1, $website->getId()]); + + // change product name for custom store + $productNameInFixtureStore = 'Product\'s Name in Fixture Store'; + $product->setName($productNameInFixtureStore)->setStoreId($storeId)->save(); + + // test store header only, query is cached at this point in EUR + $headerMap = ['Store' => $storeCodeFromFixture]; + $response = $this->graphQlQuery($query, [], '', $headerMap); + $this->assertEquals( + $productNameInFixtureStore, + $response['products']['items'][0]['name'], + 'Product name in fixture store is invalid.' + ); + $this->assertEquals( + 'EUR', + $response['products']['items'][0]['price']['minimalPrice']['amount']['currency'], + 'Currency code EUR in fixture ' . $storeCodeFromFixture . ' is unexpected' + ); + + // test cached store + currency header in Euros + $headerMap = ['Store' => $storeCodeFromFixture, 'Content-Currency' => 'EUR']; + $response = $this->graphQlQuery($query, [], '', $headerMap); + $this->assertEquals( + $productNameInFixtureStore, + $response['products']['items'][0]['name'], + 'Product name in fixture ' . $storeCodeFromFixture . ' is invalid.' + ); + $this->assertEquals( + 'EUR', + $response['products']['items'][0]['price']['minimalPrice']['amount']['currency'], + 'Currency code EUR in fixture ' . $storeCodeFromFixture . ' is unexpected' + ); + + // test non cached store + currency header in USD + $headerMap = ['Store' => $storeCodeFromFixture, 'Content-Currency' => 'USD']; + $response = $this->graphQlQuery($query, [], '', $headerMap); + $this->assertEquals( + $productNameInFixtureStore, + $response['products']['items'][0]['name'], + 'Product name in fixture store is invalid.' + ); + $this->assertEquals( + 'USD', + $response['products']['items'][0]['price']['minimalPrice']['amount']['currency'], + 'Currency code USD in fixture ' . $storeCodeFromFixture . ' is unexpected' + ); + + // test non cached store + currency header in USD not cached + $headerMap = ['Store' => 'default', 'Content-Currency' => 'USD']; + $response = $this->graphQlQuery($query, [], '', $headerMap); + $this->assertEquals( + 'Simple Product', + $response['products']['items'][0]['name'], + 'Product name in fixture store is invalid.' + ); + $this->assertEquals( + 'USD', + $response['products']['items'][0]['price']['minimalPrice']['amount']['currency'], + 'Currency code USD in fixture store default is unexpected' + ); + + // test non cached store + currency header in USD not cached + $headerMap = ['Store' => 'default', 'Content-Currency' => 'EUR']; + $response = $this->graphQlQuery($query, [], '', $headerMap); + $this->assertEquals( + 'Simple Product', + $response['products']['items'][0]['name'], + 'Product name in fixture store is invalid.' + ); + $this->assertEquals( + 'EUR', + $response['products']['items'][0]['price']['minimalPrice']['amount']['currency'], + 'Currency code EUR in fixture store default is unexpected' + ); + + // test non cached store + currency header in USD cached + $headerMap = ['Store' => 'default']; + $response = $this->graphQlQuery($query, [], '', $headerMap); + $this->assertEquals( + 'Simple Product', + $response['products']['items'][0]['name'], + 'Product name in fixture store is invalid.' + ); + $this->assertEquals( + 'USD', + $response['products']['items'][0]['price']['minimalPrice']['amount']['currency'], + 'Currency code USD in fixture store default is unexpected' + ); + + // test cached response store + currency header with non existing currency, and no valid response, no cache + $headerMap = ['Store' => $storeCodeFromFixture, 'Content-Currency' => 'SOMECURRENCY']; + $this->expectExceptionMessage('Currency not allowed for store ' . $storeCodeFromFixture); + $this->graphQlQuery($query, [], '', $headerMap); + } +} From cd7935f4709b85b27d5e54de08fc3bcb10cb0717 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Tue, 16 Apr 2019 17:54:29 -0500 Subject: [PATCH 111/247] GraphQL-598: CMS Page Integration Test for Tag Cache Generation --- .../testsuite/Magento/Cms/_files/pages.php | 9 ++ .../Controller/Cms/CmsPageCacheTest.php | 114 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php diff --git a/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php b/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php index a0b7b99a877a..5edb2a79b148 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php +++ b/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php @@ -11,15 +11,24 @@ ->setStores([0]) ->setIsActive(1) ->setContent('

Cms Page 100 Title

') + ->setContentHeading('

Cms Page 100 Title

') + ->setMetaTitle('Cms Meta title for page100') + ->setMetaKeywords('Cms Meta Keywords for page100') + ->setsetMetaDescription('Cms Meta Description for page100') ->setPageLayout('1column') ->save(); + $page = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Cms\Model\Page::class); $page->setTitle('Cms Page Design Blank') ->setIdentifier('page_design_blank') ->setStores([0]) ->setIsActive(1) ->setContent('

Cms Page Design Blank Title

') + ->setContentHeading('

Cms Page Blank Title

') + ->setMetaTitle('Cms Meta title for Blank page') + ->setMetaKeywords('Cms Meta Keywords for Blank page') + ->setsetMetaDescription('Cms Meta Description for Blank page') ->setPageLayout('1column') ->setCustomTheme('Magento/blank') ->save(); diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php new file mode 100644 index 000000000000..510df327df36 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -0,0 +1,114 @@ +getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); + $this->metadataPool = $this->objectManager->get(MetadataPool::class); + $this->request = $this->objectManager->get(Http::class); + } + /** + * Test cache tags and debug header for category and querying only cms page + * + * @magentoCache all enabled + * @magentoDataFixture Magento/Cms/_files/pages.php + */ + public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForCmsPage(): void + { + $cmsPage = $this->objectManager->get(GetPageByIdentifier::class)->execute('page100', 0); + $pageId = $cmsPage->getId(); + + $query = + <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphql->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId , 'FPC']; + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } +} From 9cd00fa8d80e085719d5a23491d9235e21da327f Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Tue, 16 Apr 2019 15:55:20 +0300 Subject: [PATCH 112/247] Fix static tests. --- .../NewRelicReporting/Plugin/CommandPlugin.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php b/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php index 065455e2a27c..04ad3d0504d3 100644 --- a/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php +++ b/app/code/Magento/NewRelicReporting/Plugin/CommandPlugin.php @@ -3,11 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\NewRelicReporting\Plugin; use Magento\NewRelicReporting\Model\Config; use Magento\NewRelicReporting\Model\NewRelicWrapper; +use Symfony\Component\Console\Command\Command; +/** + * Describe NewRelic commands plugin. + */ class CommandPlugin { /** @@ -32,7 +37,14 @@ public function __construct( $this->newRelicWrapper = $newRelicWrapper; } - public function beforeRun(\Symfony\Component\Console\Command\Command $command, ...$args) + /** + * Set NewRelic Transaction name before running command. + * + * @param Command $command + * @param array $args + * @return array + */ + public function beforeRun(Command $command, ...$args) { $this->newRelicWrapper->setTransactionName( sprintf('CLI %s', $command->getName()) From 0348d7da7806633ff031274c942dc25937eb6b1b Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 17 Apr 2019 14:24:58 +0300 Subject: [PATCH 113/247] graphQl-533: added additional data to payment methods, added tests --- .../Model/Resolver/SetPaymentMethodOnCart.php | 3 +- .../Magento/QuoteGraphQl/etc/schema.graphqls | 8 + .../SetOfflinePaymentMethodOnCartTest.php | 166 ++++++++++++++++++ .../Customer/SetPaymentMethodOnCartTest.php | 38 ---- .../SetOfflinePaymentMethodOnCartTest.php | 144 +++++++++++++++ .../Guest/SetPaymentMethodOnCartTest.php | 37 ---- 6 files changed, 320 insertions(+), 76 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php index 7d8933975779..7b81964f111c 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php @@ -70,13 +70,14 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $paymentMethodCode = $args['input']['payment_method']['code']; $poNumber = $args['input']['payment_method']['purchase_order_number'] ?? null; + $additionalData = $args['input']['payment_method']['additional_data'] ?? []; $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); $payment = $this->paymentFactory->create([ 'data' => [ PaymentInterface::KEY_METHOD => $paymentMethodCode, PaymentInterface::KEY_PO_NUMBER => $poNumber, - PaymentInterface::KEY_ADDITIONAL_DATA => [], + PaymentInterface::KEY_ADDITIONAL_DATA => $additionalData, ] ]); diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 9ec3492f6453..76bc51b00757 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -126,9 +126,13 @@ input SetPaymentMethodOnCartInput { input PaymentMethodInput { code: String! @doc(description:"Payment method code") + additional_data: PaymentMethodAdditionalDataInput @doc(description:"Additional payment data") purchase_order_number: String @doc(description:"Purchase order number") } +input PaymentMethodAdditionalDataInput { +} + type SetPaymentMethodOnCartOutput { cart: Cart! } @@ -222,9 +226,13 @@ type AvailablePaymentMethod { type SelectedPaymentMethod { code: String @doc(description: "The payment method code") + additional_data: SelectedPaymentMethodAdditionalData @doc(description: "Additional payment data") purchase_order_number: String @doc(description: "The purchase order number.") } +type SelectedPaymentMethodAdditionalData { +} + enum AdressTypeEnum { SHIPPING BILLING diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php new file mode 100644 index 000000000000..36189db4094e --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php @@ -0,0 +1,166 @@ +getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + */ + public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() + { + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $purchaseOrderNumber = '123456'; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('setPaymentMethodOnCart', $response); + self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); + self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); + self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); + self::assertEquals($purchaseOrderNumber, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['purchase_order_number']); + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + * + * @expectedException Exception + * @expectedExceptionMessage Purchase order number is a required field. + */ + public function testSetPurchaseOrderPaymentMethodOnCartWithoutPurchaseOrderNumber() + { + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * + * @expectedException Exception + * @expectedExceptionMessage The requested Payment Method is not available. + */ + public function testSetDisabledPurchaseOrderPaymentMethodOnCart() + { + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $purchaseOrderNumber = '123456'; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); + } + + /** + * @param string $username + * @param string $password + * @return array + */ + private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password); + $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; + return $headerMap; + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php index 8241debc8b09..73feefe2b094 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php @@ -60,44 +60,6 @@ public function testSetPaymentOnCartWithSimpleProduct() self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); } - /** - * @magentoApiDataFixture Magento/Customer/_files/customer.php - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php - */ - public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() - { - $methodCode = Checkmo::PAYMENT_METHOD_CHECKMO_CODE; - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - - $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); - - self::assertArrayHasKey('setPaymentMethodOnCart', $response); - self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); - self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); - self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); - } - /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php new file mode 100644 index 000000000000..bbc7fc9df839 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php @@ -0,0 +1,144 @@ +getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + */ + public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() + { + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $purchaseOrderNumber = '123456'; + + $query = <<graphQlQuery($query); + + self::assertArrayHasKey('setPaymentMethodOnCart', $response); + self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); + self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); + self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); + self::assertEquals($purchaseOrderNumber, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['purchase_order_number']); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php + * + * @expectedException Exception + * @expectedExceptionMessage Purchase order number is a required field. + */ + public function testSetPurchaseOrderPaymentMethodOnCartWithoutPurchaseOrderNumber() + { + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * + * @expectedException Exception + * @expectedExceptionMessage The requested Payment Method is not available. + */ + public function testSetDisabledPurchaseOrderPaymentMethodOnCart() + { + $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $purchaseOrderNumber = '123456'; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<graphQlQuery($query); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php index 9dfb6b4c15a6..062dd2863b78 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php @@ -53,43 +53,6 @@ public function testSetPaymentOnCartWithSimpleProduct() self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); } - /** - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php - */ - public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() - { - $methodCode = Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - - $query = <<graphQlQuery($query); - - self::assertArrayHasKey('setPaymentMethodOnCart', $response); - self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); - self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); - self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); - } - /** * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php From 753f8230315337f2cc19cd2c9cc70f5d7dd2126d Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 17 Apr 2019 14:29:31 +0300 Subject: [PATCH 114/247] graphQl-533: removed redundant import --- .../Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php index 062dd2863b78..879d0fd91729 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php @@ -10,7 +10,6 @@ use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; use Magento\OfflinePayments\Model\Cashondelivery; use Magento\OfflinePayments\Model\Checkmo; -use Magento\OfflinePayments\Model\Purchaseorder; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; From 2ccf78b11ce40bba8bd02c9569207648aa53fe35 Mon Sep 17 00:00:00 2001 From: Stas Puga Date: Wed, 17 Apr 2019 17:14:34 +0300 Subject: [PATCH 115/247] MC-5831: Apply cross border taxes, product with category --- .../app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php index 0f163933d260..40d3401a207a 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php @@ -37,7 +37,6 @@ class TaxWithCrossBorderTest extends Injectable { /* tags */ const MVP = 'yes'; - const STABLE = 'no'; /* end tags */ /** From cda62bff652d6d7fc10e2a5b332001aaeea036a7 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 17 Apr 2019 09:32:05 -0500 Subject: [PATCH 116/247] Issue-230: adding varnish - fixing static on tests --- app/code/Magento/GraphQl/Controller/GraphQl.php | 1 + .../Magento/TestFramework/TestCase/GraphQlAbstract.php | 2 +- .../testsuite/Magento/GraphQl/PageCache/CacheTagTest.php | 3 +++ .../Magento/Framework/GraphQl/Config/GraphQlReaderTest.php | 3 +++ .../Controller/Catalog/CategoriesWithProductsDispatchTest.php | 4 ---- .../GraphQlCache/Controller/Catalog/CategoryDispatchTest.php | 4 ---- .../Catalog/DeepNestedCategoriesAndProductsTest.php | 4 ---- .../GraphQlCache/Controller/Catalog/ProductsDispatchTest.php | 4 ---- 8 files changed, 8 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index ed66c92c3bfb..f31492f8389f 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -25,6 +25,7 @@ * Front controller for web API GraphQL area. * * @api + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class GraphQl implements FrontControllerInterface { diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php index 44ce9aeca8b6..f8aa95061926 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -92,7 +92,7 @@ public function graphQlQueryForHttpHeaders( string $operationName = '', array $headers = [] ) { - return $response = $this->getGraphQlClient()->getQueryResponseHeaders( + return $this->getGraphQlClient()->getQueryResponseHeaders( $query, $variables, $operationName, diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index cbdd1ebc13bc..0a0ca960d5ac 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -14,6 +14,9 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; +/** + * Class CacheTagTest + */ class CacheTagTest extends GraphQlAbstract { /** diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php index 61cbd556ea23..f6994931562c 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -35,6 +35,9 @@ class GraphQlReaderTest extends \PHPUnit\Framework\TestCase /** @var SerializerInterface */ private $jsonSerializer; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php index ed8809d35440..c999c75307dd 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php @@ -40,9 +40,6 @@ class CategoriesWithProductsDispatchTest extends \Magento\TestFramework\Indexer\ /** @var Http */ private $request; - /** @var \Magento\Framework\App\Response\Http */ - private $response; - /** * @inheritdoc */ @@ -140,4 +137,3 @@ public function testDispatchForCacheHeadersAndCacheTagsForCategoryWtihProducts() $this->assertEquals($expectedCacheTags, $actualCacheTags); } } - diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php index 454bbabc1b7e..c6c523aff3d0 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php @@ -38,9 +38,6 @@ class CategoryDispatchTest extends \Magento\TestFramework\Indexer\TestCase /** @var Http */ private $request; - /** @var \Magento\Framework\App\Response\Http */ - private $response; - /** * @inheritdoc */ @@ -110,4 +107,3 @@ public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void } } } - diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php index 082c8815a737..f6628be18ff5 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -41,9 +41,6 @@ class DeepNestedCategoriesAndProductsTest extends \Magento\TestFramework\Indexer /** @var Http */ private $request; - /** @var \Magento\Framework\App\Response\Http */ - private $response; - /** * @inheritdoc */ @@ -165,4 +162,3 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void ); } } - diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php index b8eb47195691..53b8e2123063 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php @@ -40,9 +40,6 @@ class ProductsDispatchTest extends \Magento\TestFramework\Indexer\TestCase /** @var Http */ private $request; - /** @var \Magento\Framework\App\Response\Http */ - private $response; - /** * @inheritdoc */ @@ -119,4 +116,3 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts() $this->assertEquals($expectedCacheTags, $actualCacheTags); } } - From 653e57cabef1939ff78b1d6ba6aa6b97504ab259 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Wed, 17 Apr 2019 10:32:48 -0500 Subject: [PATCH 117/247] changes to CmsPageCaheTest --- .../Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php index 510df327df36..61b16a3387df 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -39,9 +39,6 @@ class CmsPageCacheTest extends \Magento\TestFramework\Indexer\TestCase /** @var Http */ private $request; - /** @var \Magento\Framework\App\Response\Http */ - private $response; - /** * @inheritdoc */ From e0e7873fbb60f22adf20b657de39871be71c1f78 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 17 Apr 2019 19:11:04 +0300 Subject: [PATCH 118/247] graphQl-309: fixed request type in tests --- .../Quote/Customer/SetOfflinePaymentMethodOnCartTest.php | 6 +++--- .../Quote/Guest/SetOfflinePaymentMethodOnCartTest.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php index 36189db4094e..ed7b6288f091 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodOnCartTest.php @@ -71,7 +71,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() } } QUERY; - $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); self::assertArrayHasKey('setPaymentMethodOnCart', $response); self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); @@ -112,7 +112,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithoutPurchaseOrderNumbe } } QUERY; - $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /** @@ -149,7 +149,7 @@ public function testSetDisabledPurchaseOrderPaymentMethodOnCart() } } QUERY; - $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php index bbc7fc9df839..70996f584b9d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodOnCartTest.php @@ -63,7 +63,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() } } QUERY; - $response = $this->graphQlQuery($query); + $response = $this->graphQlMutation($query); self::assertArrayHasKey('setPaymentMethodOnCart', $response); self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); @@ -103,7 +103,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithoutPurchaseOrderNumbe } } QUERY; - $this->graphQlQuery($query); + $this->graphQlMutation($query); } /** @@ -139,6 +139,6 @@ public function testSetDisabledPurchaseOrderPaymentMethodOnCart() } } QUERY; - $this->graphQlQuery($query); + $this->graphQlMutation($query); } } From 4d821390cbf0e792b9e47e97fd56453c28c4cbc3 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Wed, 17 Apr 2019 12:39:52 -0500 Subject: [PATCH 119/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- app/code/Magento/Backend/Model/Auth/Session.php | 1 + .../Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php | 3 +++ lib/internal/Magento/Framework/App/Response/Http.php | 2 ++ 3 files changed, 6 insertions(+) diff --git a/app/code/Magento/Backend/Model/Auth/Session.php b/app/code/Magento/Backend/Model/Auth/Session.php index e253881c2253..61db71c1803e 100644 --- a/app/code/Magento/Backend/Model/Auth/Session.php +++ b/app/code/Magento/Backend/Model/Auth/Session.php @@ -23,6 +23,7 @@ * @method \Magento\Backend\Model\Auth\Session setUpdatedAt(int $value) * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @todo implement solution that keeps is_first_visit flag in session during redirects * @api * @since 100.0.2 diff --git a/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php index eaa93887fee9..f3baaeebc137 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Spi/SessionAclHydratorInterfaceTest.php @@ -13,6 +13,9 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\Acl\Builder as AclBuilder; +/** + * Test for session hydrator. + */ class SessionAclHydratorInterfaceTest extends TestCase { /** diff --git a/lib/internal/Magento/Framework/App/Response/Http.php b/lib/internal/Magento/Framework/App/Response/Http.php index a152b655e42a..a80d9cbdd668 100644 --- a/lib/internal/Magento/Framework/App/Response/Http.php +++ b/lib/internal/Magento/Framework/App/Response/Http.php @@ -17,6 +17,8 @@ /** * HTTP Response. + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class Http extends \Magento\Framework\HTTP\PhpEnvironment\Response { From bf84115dee655e77405d02d7f1735d9bfce330bf Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Wed, 17 Apr 2019 12:45:50 -0500 Subject: [PATCH 120/247] Issue-230: Implement cache tag generation for GraphQL queries - Integration tests --- .../Controller/AbstractGraphqlCacheTest.php | 42 +++++++++++++++++ .../Controller/Cms/BlockCacheTest.php | 45 ++----------------- 2 files changed, 46 insertions(+), 41 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php new file mode 100644 index 000000000000..d2e853c2aa0e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php @@ -0,0 +1,42 @@ +objectManager = Bootstrap::getObjectManager(); + $this->usePageCachePlugin(); + } + + /** + * Enable full page cache plugin + */ + protected function usePageCachePlugin(): void + { + /** @var $registry \Magento\Framework\Registry */ + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $registry->register('use_page_cache_plugin', true, true); + } +} diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php index fe90a42c9f7c..005007fce58f 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php @@ -10,22 +10,16 @@ use Magento\Cms\Model\BlockRepository; use Magento\Framework\App\Request\Http; use Magento\GraphQl\Controller\GraphQl; -use Magento\TestFramework\ObjectManager; -use Magento\TestFramework\Helper\Bootstrap; +use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** * Test caching works for CMS blocks * * @magentoAppArea graphql - * @magentoDbIsolation disabled + * @magentoCache full_page enabled */ -class BlockCacheTest extends \Magento\TestFramework\Indexer\TestCase +class BlockCacheTest extends AbstractGraphqlCacheTest { - /** - * @var ObjectManager - */ - private $objectManager; - /** * @var GraphQl */ @@ -36,31 +30,14 @@ class BlockCacheTest extends \Magento\TestFramework\Indexer\TestCase */ private $request; - /** - * @inheritdoc - */ - public static function setUpBeforeClass() - { - $db = Bootstrap::getInstance()->getBootstrap() - ->getApplication() - ->getDbInstance(); - if (!$db->isDbDumpExists()) { - throw new \LogicException('DB dump does not exist.'); - } - $db->restoreFromDbDump(); - - parent::setUpBeforeClass(); - } - /** * @inheritdoc */ protected function setUp(): void { - $this->objectManager = Bootstrap::getObjectManager(); + parent::setUp(); $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); $this->request = $this->objectManager->create(Http::class); - $this->enableFullPageCache(); } /** @@ -103,18 +80,4 @@ public function testCmsBlocksRequestHasCorrectTags(): void $this->assertContains($expectedCacheTag, $actualCacheTags); } } - - /** - * Enable full page cache so plugins are called - */ - private function enableFullPageCache() - { - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); - - /** @var \Magento\Framework\App\Cache\StateInterface $cacheState */ - $cacheState = $this->objectManager->get(\Magento\Framework\App\Cache\StateInterface::class); - $cacheState->setEnabled(\Magento\PageCache\Model\Cache\Type::TYPE_IDENTIFIER, true); - } } From c51ec5257ca8a67d04bc384ae7c61123c9ce2b79 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 17 Apr 2019 14:25:48 -0500 Subject: [PATCH 121/247] Issue-230: adding varnish - fixing test - handling error codes > 400 --- .../TestFramework/TestCase/GraphQl/Client.php | 7 +- .../ProductInMultipleStoresCacheTest.php | 140 ++++++++++++++---- 2 files changed, 117 insertions(+), 30 deletions(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index 870f840bdfa1..d5a33cfe281f 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -86,7 +86,12 @@ public function get(string $query, array $variables = [], string $operationName ]; array_filter($requestArray); - $responseBody = $this->curlClient->get($url, $requestArray, $headers); + try { + $responseBody = $this->curlClient->get($url, $requestArray, $headers); + } catch (\Exception $e) { + // if response code > 400 then response is the exception message + $responseBody = $e->getMessage(); + } return $this->processResponse($responseBody); } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php index 916a25ea5acd..12cd8894659b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php @@ -18,13 +18,73 @@ class ProductInMultipleStoresCacheTest extends GraphQlAbstract { /** - * Test a non existing or non allowed currency + * @inheritdoc + */ + protected function setUp() + { + /** @var \Magento\Store\Model\Store $store */ + $store = ObjectManager::getInstance()->get(\Magento\Store\Model\Store::class); + $storeCodeFromFixture = 'fixture_second_store'; + + /** @var \Magento\Config\Model\ResourceModel\Config $configResource */ + $configResource = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class); + /** @var \Magento\Config\App\Config\Type\System $config */ + $config = ObjectManager::getInstance()->get(\Magento\Config\App\Config\Type\System::class); + + $configResource->saveConfig( + \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_DEFAULT, + 'EUR', + \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES, + $store->load($storeCodeFromFixture)->getWebsiteId() + ); + + // allow USD & EUR currency + $configResource->saveConfig( + \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW, + 'EUR,USD', + \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES, + $store->load($storeCodeFromFixture)->getWebsiteId() + ); + + // allow USD & EUR currency + $configResource->saveConfig( + \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW, + 'EUR,USD' + ); + + // configuration cache clean is required to reload currency setting + $config->clean(); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + /** @var \Magento\Config\App\Config\Type\System $config */ + $config = ObjectManager::getInstance()->get(\Magento\Config\App\Config\Type\System::class); + /** @var \Magento\Config\Model\ResourceModel\Config $configResource */ + $configResource = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class); + + // restore allow USD currency + $configResource->saveConfig( + \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW, + 'USD' + ); + + // configuration cache clean is required to reload currency setting + $config->clean(); + parent::tearDown(); + } + + /** + * Test a non existing or non existing currency * * @magentoApiDataFixture Magento/Store/_files/second_website_with_second_currency.php * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testProductFromSpecificAndDefaultStoreWithMultiCurrencyNotAllowed() + public function testProductFromSpecificAndDefaultStoreWithMultiCurrencyNonExisting() { $productSku = 'simple'; @@ -56,16 +116,58 @@ public function testProductFromSpecificAndDefaultStoreWithMultiCurrencyNotAllowe } QUERY; - $storeCodeFromFixture = 'fixture_second_store'; - //test non existing currency $headerMap = ['Store' => 'default', 'Content-Currency' => 'someNonExistentCurrency']; - $this->expectExceptionMessage('Currency someNonExistentCurrency not allowed for store default'); + $this->expectExceptionMessage('GraphQL response contains errors: Currency not allowed for store default'); $this->graphQlQuery($query, [], '', $headerMap); + } + + /** + * Test a non existing or non allowed currency + * + * @magentoApiDataFixture Magento/Store/_files/second_website_with_second_currency.php + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testProductFromSpecificAndDefaultStoreWithMultiCurrencyNotAllowed() + { + $productSku = 'simple'; + + $query = << $storeCodeFromFixture, 'Content-Currency' => 'CAD']; - $this->expectExceptionMessage('Currency not allowed for store ' . $storeCodeFromFixture); + $this->expectExceptionMessage( + "GraphQL response contains errors: Currency not allowed for store {$storeCodeFromFixture}" + ); $this->graphQlQuery($query, [], '', $headerMap); } @@ -113,28 +215,6 @@ public function testProductFromSpecificAndDefaultStoreWithMultiCurrency() $storeCodeFromFixture = 'fixture_second_store'; $storeId = $store->load($storeCodeFromFixture)->getStoreId(); - $configResource = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class); - - $configResource->saveConfig( - \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_DEFAULT, - 'EUR', - \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES, - $store->load($storeCodeFromFixture)->getWebsiteId() - ); - - // allow USD & EUR currency - $configResource->saveConfig( - \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW, - 'EUR,USD', - \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES, - $store->load($storeCodeFromFixture)->getWebsiteId() - ); - - /** @var \Magento\Config\App\Config\Type\System $config */ - $config = ObjectManager::getInstance()->get(\Magento\Config\App\Config\Type\System::class); - // configuration cache clean is required to reload currency setting - $config->clean(); - /** @var \Magento\Catalog\Model\Product $product */ $product = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Product::class); $product->load($product->getIdBySku($productSku)); @@ -234,7 +314,9 @@ public function testProductFromSpecificAndDefaultStoreWithMultiCurrency() // test cached response store + currency header with non existing currency, and no valid response, no cache $headerMap = ['Store' => $storeCodeFromFixture, 'Content-Currency' => 'SOMECURRENCY']; - $this->expectExceptionMessage('Currency not allowed for store ' . $storeCodeFromFixture); + $this->expectExceptionMessage( + "GraphQL response contains errors: Currency not allowed for store {$storeCodeFromFixture}" + ); $this->graphQlQuery($query, [], '', $headerMap); } } From 9ecc0583301b670ac0eabc3dacaf21305e98679c Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Wed, 17 Apr 2019 14:38:17 -0500 Subject: [PATCH 122/247] GraphQL-598: CMS Page Integration Test for Tag Cache Generation Code refactoring --- .../Controller/Cms/CmsPageCacheTest.php | 67 ++++++------------- 1 file changed, 19 insertions(+), 48 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php index 61b16a3387df..bc436b8f3578 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -9,70 +9,43 @@ use Magento\Cms\Model\GetPageByIdentifier; use Magento\Framework\App\Request\Http; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\TestFramework\Helper\Bootstrap; use Magento\GraphQl\Controller\GraphQl; +use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** * Test caching works for CMS page * * @magentoAppArea graphql - * @magentoDbIsolation disabled + * @magentoCache full_page enabled */ -class CmsPageCacheTest extends \Magento\TestFramework\Indexer\TestCase +class CmsPageCacheTest extends AbstractGraphqlCacheTest { - const CONTENT_TYPE = 'application/json'; - - /** @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager; - - /** @var GraphQl */ - private $graphql; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var MetadataPool */ - private $metadataPool; - - /** @var Http */ - private $request; - /** - * @inheritdoc + * @var GraphQl */ - public static function setUpBeforeClass() - { - $db = Bootstrap::getInstance()->getBootstrap() - ->getApplication() - ->getDbInstance(); - if (!$db->isDbDumpExists()) { - throw new \LogicException('DB dump does not exist.'); - } - $db->restoreFromDbDump(); + private $graphqlController; - parent::setUpBeforeClass(); - } + /** + * @var Http + */ + private $request; /** * @inheritdoc */ protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->metadataPool = $this->objectManager->get(MetadataPool::class); - $this->request = $this->objectManager->get(Http::class); + parent::setUp(); + $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->request = $this->objectManager->create(Http::class); } + /** - * Test cache tags and debug header for category and querying only cms page + * Test that the correct cache tags get added to request for cmsPage query * - * @magentoCache all enabled * @magentoDataFixture Magento/Cms/_files/pages.php */ - public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForCmsPage(): void + public function testToCheckCmsPageRequestCacheTags(): void { $cmsPage = $this->objectManager->get(GetPageByIdentifier::class)->execute('page100', 0); $pageId = $cmsPage->getId(); @@ -92,20 +65,18 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForCmsPage(): } } QUERY; + $this->request->setPathInfo('/graphql'); $this->request->setMethod('GET'); $this->request->setQueryValue('query', $query); /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); + $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId , 'FPC']; - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $this->assertEquals($expectedCacheTags, $requestedCacheTags); } } From 7ab4ddd46bbce1e7d2a69bf3e555f8ffae896d13 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Wed, 17 Apr 2019 14:41:26 -0500 Subject: [PATCH 123/247] GraphQL-577: Test coverage for tag cache generation for category - api functional test coverage for cache invalidation --- .../GraphQl/PageCache/CacheTagTest.php | 99 ++++++++++++++----- .../Magento/Catalog/_files/categories.php | 21 ++++ .../Catalog/_files/categories_rollback.php | 2 +- 3 files changed, 98 insertions(+), 24 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 0a0ca960d5ac..0c0631ae2983 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -17,13 +17,16 @@ /** * Class CacheTagTest */ +/** + * Test the caching works properly for products and categories + */ class CacheTagTest extends GraphQlAbstract { /** * Tests if Magento cache tags and debug headers for products are generated properly - * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_url_key.php + * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php */ - public function testCacheTagsAndCacheDebugHeaderFromResponse() + public function testCacheTagsAndCacheDebugHeaderForProducts() { $this->markTestSkipped( 'This test will stay skipped until DEVOPS-4924 is resolved' @@ -79,18 +82,19 @@ public function testCacheTagsAndCacheDebugHeaderFromResponse() } /** - * Tests if Magento cache tags for categories are generated properly + * Tests if Magento cache tags for categories are generated properly. Also tests the use case for cache invalidation * - * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + * @magentoApiDataFixture Magento/Catalog/_files/categories.php */ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() { - $this->markTestSkipped( + /*$this->markTestSkipped( 'This test will stay skipped until DEVOPS-4924 is resolved' - ); - $productSku = 'simple333'; - $categoryId ='333'; - $query + );*/ + $firstProductSku = 'simple-4'; + $secondProductSku = 'simple-5'; + $categoryId ='10'; + $categoryQuery = <<<'QUERY' query GetCategoryQuery($id: Int!, $pageSize: Int!, $currentPage: Int!) { category(id: $id) { @@ -110,33 +114,82 @@ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() } QUERY; $variables =[ - 'id' => 333, + 'id' => 10, 'pageSize'=> 10, 'currentPage' => 1 ]; - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, $variables, '', []); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - /** @var Product $product */ - $product =$productRepository->get($productSku, false, null, true); + $product1Query + = <<graphQlQueryForHttpHeaders($categoryQuery, $variables, '', []); /** cache-debug header value should be a MISS when category is loaded first time */ preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + /** @var Product $firstProduct */ + $firstProduct = $productRepository->get($firstProductSku, false, null, true); + /** @var Product $secondProduct */ + $secondProduct = $productRepository->get($secondProductSku, false, null, true); + /** checks to see if the X-Magento-Tags for category is displayed correctly */ preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); $actualCacheTags = explode(',', rtrim($headerCacheTags[1], "\r")); - $expectedCacheTags=['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; - foreach (array_keys($actualCacheTags) as $key) { - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); - } - /** cache-debug header value should be MISS after updating child-product and reloading the category */ - $product->setPrice(15); - $product->save(); - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, $variables, '', []); + $expectedCacheTags = + ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $firstProduct->getId(),'cat_p_' .$secondProduct->getId(),'FPC']; + $this->assertEquals($expectedCacheTags, $actualCacheTags); + // Cach-debug header should be a MISS for product 1 during first load + $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersFirstProduct, $match); + $this->assertEquals('MISS', rtrim($match[1], "\r")); + + // Cach-debug header should be a MISS for product 2 during first load + $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersSecondProduct, $match); + $this->assertEquals('MISS', rtrim($match[1], "\r")); + + /** cache-debug header value should be MISS after updating product1 and reloading the category */ + $firstProduct->setPrice(20); + $firstProduct->save(); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables, '', []); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); + + /** cache-debug should be a MISS for product 1 after it is updated - cache invalidation */ + $responseHeadersForProd1 = $this->graphQlQueryForHttpHeaders($product1Query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersForProd1, $match); + $this->assertEquals('MISS', rtrim($match[1], "\r")); + + // Cach-debug header should be a HIT for prod 2 during second load since prod 2 should be fetched from cache + $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query, [], '', []); + preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersSecondProduct, $match); + $this->assertEquals('HIT', rtrim($match[1], "\r")); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index a5ab96193246..dc2d3939cf69 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -267,3 +267,24 @@ $product->getSku(), [10, 11, 12, 13] ); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setAttributeSetId($defaultAttributeSet) + ->setStoreId(1) + ->setWebsiteIds([1]) + ->setName('Simple Product Five') + ->setSku('simple-5') + ->setPrice(10) + ->setWeight(18) + ->setStockData(['use_config_manage_stock' => 0]) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); + +$categoryLinkManagement->assignProductToCategories( + $product->getSku(), + [10, 11, 12, 13] +); \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php index 16c2fab0c617..6f8bfc14e5ca 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php @@ -14,7 +14,7 @@ // Remove products /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); -$productsToDelete = ['simple', '12345', 'simple-3', 'simple-4']; +$productsToDelete = ['simple', '12345', 'simple-3', 'simple-4','simple-5']; foreach ($productsToDelete as $sku) { try { From 965e3bf81f0a5118259595463cc7a5097ef4877e Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Wed, 17 Apr 2019 15:11:09 -0500 Subject: [PATCH 124/247] GraphQL-598: CMS Page Integration Test for Tag Cache Generation - addressed review comments --- dev/tests/integration/testsuite/Magento/Cms/_files/pages.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php b/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php index 5edb2a79b148..0b7c3a2242fe 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php +++ b/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php @@ -18,7 +18,6 @@ ->setPageLayout('1column') ->save(); - $page = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Cms\Model\Page::class); $page->setTitle('Cms Page Design Blank') ->setIdentifier('page_design_blank') From afac739965143b3b08724e75af136e5781cab0a3 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Wed, 17 Apr 2019 16:16:26 -0500 Subject: [PATCH 125/247] GraphQL-577: Test coverage for tag cache generation for category and products - address review comments --- .../GraphQl/PageCache/CacheTagTest.php | 61 ++++++++----------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 0c0631ae2983..3a84d1eb519d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -31,9 +31,6 @@ public function testCacheTagsAndCacheDebugHeaderForProducts() $this->markTestSkipped( 'This test will stay skipped until DEVOPS-4924 is resolved' ); - /** @var State $state */ - $state = Bootstrap::getObjectManager()->get(State::class); - $state->setMode(State::MODE_DEVELOPER); $productSku='simple2'; $query @@ -51,14 +48,13 @@ public function testCacheTagsAndCacheDebugHeaderForProducts() QUERY; /** cache-debug should be a MISS when product is queried for first time */ - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); /** cache-debug should be a HIT for the second round */ - $responseHitHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHitHeaders, $matchesHit); - $this->assertEquals('HIT', rtrim($matchesHit[1], "\r")); + $responseHitHeaders = $this->graphQlQueryForHttpHeaders($query); + //preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHitHeaders, $matchesHit); + $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); @@ -68,17 +64,14 @@ public function testCacheTagsAndCacheDebugHeaderForProducts() $product->setPrice(15); $product->save(); /** Cache invalidation happens and cache-debug header value is a MISS after product update */ - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); /** checks if cache tags for products are correctly displayed in the response header */ preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); $actualCacheTags = explode(',', rtrim($headerCacheTags[1], "\r")); $expectedCacheTags=['cat_p','cat_p_' . $product->getId(),'FPC']; - foreach (array_keys($actualCacheTags) as $key) { - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); - } + $this->assertEquals($expectedCacheTags, $actualCacheTags); } /** @@ -88,9 +81,9 @@ public function testCacheTagsAndCacheDebugHeaderForProducts() */ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() { - /*$this->markTestSkipped( + $this->markTestSkipped( 'This test will stay skipped until DEVOPS-4924 is resolved' - );*/ + ); $firstProductSku = 'simple-4'; $secondProductSku = 'simple-5'; $categoryId ='10'; @@ -146,11 +139,10 @@ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() } QUERY; - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables, '', []); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables); /** cache-debug header value should be a MISS when category is loaded first time */ - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); @@ -165,31 +157,28 @@ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $firstProduct->getId(),'cat_p_' .$secondProduct->getId(),'FPC']; $this->assertEquals($expectedCacheTags, $actualCacheTags); + // Cach-debug header should be a MISS for product 1 during first load - $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersFirstProduct, $match); - $this->assertEquals('MISS', rtrim($match[1], "\r")); + $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersFirstProduct); // Cach-debug header should be a MISS for product 2 during first load - $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersSecondProduct, $match); - $this->assertEquals('MISS', rtrim($match[1], "\r")); + $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersSecondProduct); - /** cache-debug header value should be MISS after updating product1 and reloading the category */ + /** cache-debug header value should be MISS after updating product1 and reloading the Category */ $firstProduct->setPrice(20); $firstProduct->save(); - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables, '', []); + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); /** cache-debug should be a MISS for product 1 after it is updated - cache invalidation */ - $responseHeadersForProd1 = $this->graphQlQueryForHttpHeaders($product1Query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersForProd1, $match); - $this->assertEquals('MISS', rtrim($match[1], "\r")); - - // Cach-debug header should be a HIT for prod 2 during second load since prod 2 should be fetched from cache - $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query, [], '', []); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHeadersSecondProduct, $match); - $this->assertEquals('HIT', rtrim($match[1], "\r")); + $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersFirstProduct); + + // Cach-debug header should be a HIT for prod 2 during second load since prod 2 is fetched from cache. + $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query); + $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHeadersSecondProduct); } } From cede6e9afa62183d489915844f685479548c6d3c Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Wed, 17 Apr 2019 17:18:22 -0500 Subject: [PATCH 126/247] 596: Category with Products with...(deep nesting) (Integration Test for Tag Cache Generation) - Fixed review comments --- .../DeepNestedCategoriesAndProductsTest.php | 44 +++---------------- 1 file changed, 5 insertions(+), 39 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php index f6628be18ff5..2ca31a3ebf29 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -10,9 +10,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Framework\App\Request\Http; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\TestFramework\Helper\Bootstrap; +use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; use Magento\TestFramework\ObjectManager; /** @@ -22,50 +20,21 @@ * @magentoDbIsolation disabled * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class DeepNestedCategoriesAndProductsTest extends \Magento\TestFramework\Indexer\TestCase +class DeepNestedCategoriesAndProductsTest extends AbstractGraphqlCacheTest { - const CONTENT_TYPE = 'application/json'; - - /** @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager; - - /** @var GraphQl */ + /** @var \Magento\GraphQl\Controller\GraphQl */ private $graphql; - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var MetadataPool */ - private $metadataPool; - /** @var Http */ private $request; - /** - * @inheritdoc - */ - public static function setUpBeforeClass() - { - $db = Bootstrap::getInstance()->getBootstrap() - ->getApplication() - ->getDbInstance(); - if (!$db->isDbDumpExists()) { - throw new \LogicException('DB dump does not exist.'); - } - $db->restoreFromDbDump(); - - parent::setUpBeforeClass(); - } - /** * @inheritdoc */ protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + parent::setUp(); $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->metadataPool = $this->objectManager->get(MetadataPool::class); $this->request = $this->objectManager->get(Http::class); } @@ -148,9 +117,6 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void $result = $this->graphql->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); @@ -161,4 +127,4 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void ) ); } -} +} \ No newline at end of file From af4b0446d6d29dee3583df382053df006c8a79fa Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Wed, 17 Apr 2019 17:35:16 -0500 Subject: [PATCH 127/247] GraphQL-577: Test coverage for tag cache generation for category and products - reverted fixture changes --- .../GraphQl/PageCache/CacheTagTest.php | 10 ++++----- .../Magento/Catalog/_files/categories.php | 21 ------------------- .../Catalog/_files/categories_rollback.php | 2 +- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 3a84d1eb519d..44ef97db3593 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -77,16 +77,16 @@ public function testCacheTagsAndCacheDebugHeaderForProducts() /** * Tests if Magento cache tags for categories are generated properly. Also tests the use case for cache invalidation * - * @magentoApiDataFixture Magento/Catalog/_files/categories.php + * @magentoApiDataFixture Magento/Catalog/_files/product_in_multiple_categories.php */ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() { $this->markTestSkipped( 'This test will stay skipped until DEVOPS-4924 is resolved' ); - $firstProductSku = 'simple-4'; - $secondProductSku = 'simple-5'; - $categoryId ='10'; + $firstProductSku = 'simple333'; + $secondProductSku = 'simple444'; + $categoryId ='4'; $categoryQuery = <<<'QUERY' query GetCategoryQuery($id: Int!, $pageSize: Int!, $currentPage: Int!) { @@ -107,7 +107,7 @@ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() } QUERY; $variables =[ - 'id' => 10, + 'id' => 4, 'pageSize'=> 10, 'currentPage' => 1 ]; diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index dc2d3939cf69..a5ab96193246 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -267,24 +267,3 @@ $product->getSku(), [10, 11, 12, 13] ); - -/** @var $product \Magento\Catalog\Model\Product */ -$product = $objectManager->create(\Magento\Catalog\Model\Product::class); -$product->isObjectNew(true); -$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) - ->setAttributeSetId($defaultAttributeSet) - ->setStoreId(1) - ->setWebsiteIds([1]) - ->setName('Simple Product Five') - ->setSku('simple-5') - ->setPrice(10) - ->setWeight(18) - ->setStockData(['use_config_manage_stock' => 0]) - ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) - ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) - ->save(); - -$categoryLinkManagement->assignProductToCategories( - $product->getSku(), - [10, 11, 12, 13] -); \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php index 6f8bfc14e5ca..16c2fab0c617 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php @@ -14,7 +14,7 @@ // Remove products /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); -$productsToDelete = ['simple', '12345', 'simple-3', 'simple-4','simple-5']; +$productsToDelete = ['simple', '12345', 'simple-3', 'simple-4']; foreach ($productsToDelete as $sku) { try { From 43a22d4c3af0835d2adf83c87b7aa1d7be2c4063 Mon Sep 17 00:00:00 2001 From: Hailong Zhao Date: Wed, 17 Apr 2019 23:23:06 -0400 Subject: [PATCH 128/247] Needs to provide the currency code explicitly in the -bash.00 verification call, otherwise the payment would fail when store's default currency is not USD. --- .../Magento/Paypal/Model/Payflow/Service/Request/SecureToken.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Paypal/Model/Payflow/Service/Request/SecureToken.php b/app/code/Magento/Paypal/Model/Payflow/Service/Request/SecureToken.php index da5599984b70..8a2825a16d33 100644 --- a/app/code/Magento/Paypal/Model/Payflow/Service/Request/SecureToken.php +++ b/app/code/Magento/Paypal/Model/Payflow/Service/Request/SecureToken.php @@ -64,6 +64,7 @@ public function requestToken(Quote $quote) $request->setTrxtype(Payflowpro::TRXTYPE_AUTH_ONLY); $request->setVerbosity('HIGH'); $request->setAmt(0); + $request->setCurrency($quote->getBaseCurrencyCode()); $request->setCreatesecuretoken('Y'); $request->setSecuretokenid($this->mathRandom->getUniqueHash()); $request->setReturnurl($this->url->getUrl('paypal/transparent/response')); From 3beb15adfd769cbf259f45313948e6e3d04dcd4d Mon Sep 17 00:00:00 2001 From: niravkrish Date: Thu, 18 Apr 2019 15:09:02 +0530 Subject: [PATCH 129/247] fixed - issue 21596 --- .../view/frontend/web/js/view/payment.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js index c17e5e40d5c9..ad6f39b7d6d5 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js @@ -66,9 +66,21 @@ define([ navigate: function () { var self = this; - getPaymentInformation().done(function () { - self.isVisible(true); - }); + if(!self.hasShippingMethod()) { + this.isVisible(false); + stepNavigator.setHash('shipping'); + } else { + getPaymentInformation().done(function () { + self.isVisible(true); + }); + } + }, + + /** + * @return {Boolean} + */ + hasShippingMethod: function () { + return window.checkoutConfig.selectedShippingMethod !== null; }, /** From 875fa4ce039a177d4f0f597f392a68218cfea007 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Thu, 18 Apr 2019 15:31:02 +0300 Subject: [PATCH 130/247] magento/magento2#21856: Static test fix. --- lib/internal/Magento/Framework/Validator/Factory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/Validator/Factory.php b/lib/internal/Magento/Framework/Validator/Factory.php index 87c29dd6681c..2a296f7cdcb2 100644 --- a/lib/internal/Magento/Framework/Validator/Factory.php +++ b/lib/internal/Magento/Framework/Validator/Factory.php @@ -52,6 +52,7 @@ class Factory * @param ObjectManagerInterface $objectManager * @param Reader $moduleReader * @param FrontendInterface $cache @deprecated + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( ObjectManagerInterface $objectManager, From 1cb3488686fb99814edcc0a898acc8a26f2ab16a Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Thu, 18 Apr 2019 16:22:28 +0300 Subject: [PATCH 131/247] magento/magento2#19913: Static test fix. --- app/code/Magento/Webapi/Controller/PathProcessor.php | 2 +- .../Webapi/Test/Unit/Controller/PathProcessorTest.php | 5 ++++- .../WebapiAsync/Test/Unit/Controller/PathProcessorTest.php | 3 +++ .../Magento/Webapi/Controller/PathProcessorTest.php | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Webapi/Controller/PathProcessor.php b/app/code/Magento/Webapi/Controller/PathProcessor.php index b5f0be97de2f..f32c93fb0c76 100644 --- a/app/code/Magento/Webapi/Controller/PathProcessor.php +++ b/app/code/Magento/Webapi/Controller/PathProcessor.php @@ -1,9 +1,9 @@ storeManagerMock->expects($this->exactly($setCurrentStoreCallCtr)) ->method('setCurrentStore') ->with($storeCodeSet); - if($setCurrentStoreCallCtr > 0) { + if ($setCurrentStoreCallCtr > 0) { $this->localeResolverMock->expects($this->once()) ->method('emulate'); } diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php index cea7a4168ea4..570df6afd3c5 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Controller/PathProcessorTest.php @@ -10,6 +10,9 @@ use Magento\Store\Model\Store; +/** + * Test for Magento\Webapi\Controller\PathProcessor class. + */ class PathProcessorTest extends \PHPUnit\Framework\TestCase { /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Store\Model\StoreManagerInterface */ diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php index 43aa788dea3a..14fbc2ffc67d 100644 --- a/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php +++ b/dev/tests/integration/testsuite/Magento/Webapi/Controller/PathProcessorTest.php @@ -8,6 +8,9 @@ use Magento\Store\Model\Store; +/** + * Test for Magento\Webapi\Controller\PathProcessor class. + */ class PathProcessorTest extends \PHPUnit\Framework\TestCase { /** From d4eeb4400790989ca35cc36e801c73b62242c36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Culotta?= Date: Thu, 18 Apr 2019 10:47:02 -0300 Subject: [PATCH 132/247] Checkout Totals Sort Order fields can not be empty and should be a number. --- app/code/Magento/Sales/etc/adminhtml/system.xml | 5 +++++ app/code/Magento/Weee/etc/adminhtml/system.xml | 1 + 2 files changed, 6 insertions(+) diff --git a/app/code/Magento/Sales/etc/adminhtml/system.xml b/app/code/Magento/Sales/etc/adminhtml/system.xml index 2dc467d6ca24..e437918b683b 100644 --- a/app/code/Magento/Sales/etc/adminhtml/system.xml +++ b/app/code/Magento/Sales/etc/adminhtml/system.xml @@ -27,18 +27,23 @@ + required-number validate-number + required-number validate-number + required-number validate-number + required-number validate-number + required-number validate-number diff --git a/app/code/Magento/Weee/etc/adminhtml/system.xml b/app/code/Magento/Weee/etc/adminhtml/system.xml index ae02b27d10c7..d3e9efb8f0b4 100644 --- a/app/code/Magento/Weee/etc/adminhtml/system.xml +++ b/app/code/Magento/Weee/etc/adminhtml/system.xml @@ -44,6 +44,7 @@ + required-number validate-number
From 7dc85ece16f068f663012b333e7367ffbc9e8d44 Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Thu, 18 Apr 2019 11:45:32 -0500 Subject: [PATCH 133/247] 596: Category with Products with...(deep nesting) (Integration Test for Tag Cache Generation) - Fixed review comments --- .../DeepNestedCategoriesAndProductsTest.php | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php index 2ca31a3ebf29..f8cc7f0e5910 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -11,14 +11,12 @@ use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Framework\App\Request\Http; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; -use Magento\TestFramework\ObjectManager; /** * Tests cache debug headers and cache tag validation for a deep nested category and product query * * @magentoAppArea graphql * @magentoDbIsolation disabled - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DeepNestedCategoriesAndProductsTest extends AbstractGraphqlCacheTest { @@ -47,11 +45,11 @@ protected function setUp(): void */ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void { - $categoryId ='333'; + $baseCategoryId ='333'; $query = <<get(CategoryRepositoryInterface::class); + $categoryRepository = $this->objectManager->get(CategoryRepositoryInterface::class); /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - $categoryIds = []; - $category = $categoryRepository->get('333'); + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + + $resolvedCategoryIds = []; + $category = $categoryRepository->get($baseCategoryId); $productIdsFromCategory = $category->getProductCollection()->getAllIds(); foreach ($productIdsFromCategory as $productId) { - $categoryIds = array_merge($categoryIds, $productRepository->getById($productId)->getCategoryIds()); + $resolvedCategoryIds = array_merge( + $resolvedCategoryIds, + $productRepository->getById($productId)->getCategoryIds() + ); } - $categoryIds = array_merge($categoryIds, ['333']); - foreach ($categoryIds as $categoryId) { + $resolvedCategoryIds = array_merge($resolvedCategoryIds, [$baseCategoryId]); + foreach ($resolvedCategoryIds as $categoryId) { $category = $categoryRepository->get($categoryId); $productIdsFromCategory= array_merge( $productIdsFromCategory, @@ -101,13 +103,13 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void } $uniqueProductIds = array_unique($productIdsFromCategory); - $uniqueCategoryIds = array_unique($categoryIds); + $uniqueCategoryIds = array_unique($resolvedCategoryIds); $expectedCacheTags = ['cat_c', 'cat_p', 'FPC']; - foreach ($uniqueProductIds as $productId) { - $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_'.$productId]); + foreach ($uniqueProductIds as $uniqueProductId) { + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_'.$uniqueProductId]); } - foreach ($uniqueCategoryIds as $categoryId) { - $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_'.$categoryId]); + foreach ($uniqueCategoryIds as $uniqueCategoryId) { + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_'.$uniqueCategoryId]); } $this->request->setPathInfo('/graphql'); @@ -127,4 +129,4 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void ) ); } -} \ No newline at end of file +} From ddeb43e3ef6f479962d04ded3216697a8d68d2e9 Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Thu, 18 Apr 2019 12:03:59 -0500 Subject: [PATCH 134/247] GraphQL-594,595,600:code refactored for the integretaion tests --- ...hp => CategoriesWithProductsCacheTest.php} | 60 +++++------------- ...DispatchTest.php => CategoryCacheTest.php} | 59 +++++------------- ...DispatchTest.php => ProductsCacheTest.php} | 62 +++++-------------- 3 files changed, 46 insertions(+), 135 deletions(-) rename dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/{CategoriesWithProductsDispatchTest.php => CategoriesWithProductsCacheTest.php} (62%) rename dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/{CategoryDispatchTest.php => CategoryCacheTest.php} (52%) rename dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/{ProductsDispatchTest.php => ProductsCacheTest.php} (54%) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php similarity index 62% rename from dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php rename to dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php index c999c75307dd..142e0770937f 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php @@ -10,64 +10,37 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\App\Request\Http; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\TestFramework\Helper\Bootstrap; +use Magento\GraphQl\Controller\GraphQl; +use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** * Tests cache debug headers and cache tag validation for a category with product query * * @magentoAppArea graphql + * @magentoCache full_page enabled * @magentoDbIsolation disabled - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class CategoriesWithProductsDispatchTest extends \Magento\TestFramework\Indexer\TestCase +class CategoriesWithProductsCacheTest extends AbstractGraphqlCacheTest { - const CONTENT_TYPE = 'application/json'; - - /** @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager; - - /** @var GraphQl */ - private $graphql; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var MetadataPool */ - private $metadataPool; - - /** @var Http */ - private $request; - /** - * @inheritdoc + * @var GraphQl */ - public static function setUpBeforeClass() - { - $db = Bootstrap::getInstance()->getBootstrap() - ->getApplication() - ->getDbInstance(); - if (!$db->isDbDumpExists()) { - throw new \LogicException('DB dump does not exist.'); - } - $db->restoreFromDbDump(); + private $graphqlController; - parent::setUpBeforeClass(); - } + /** + * @var Http + */ + private $request; /** * @inheritdoc */ protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->metadataPool = $this->objectManager->get(MetadataPool::class); - $this->request = $this->objectManager->get(Http::class); + parent::setUp(); + $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->request = $this->objectManager->create(Http::class); } - /** * Test cache tags and debug header for category with products querying for products and category * @@ -75,7 +48,7 @@ protected function setUp(): void * @magentoDataFixture Magento/Catalog/_files/category_product.php * */ - public function testDispatchForCacheHeadersAndCacheTagsForCategoryWtihProducts(): void + public function testToCheckRequestCacheTagsForCategoryWithProducts(): void { /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); @@ -124,12 +97,9 @@ public function testDispatchForCacheHeadersAndCacheTagsForCategoryWtihProducts() $this->request->setMethod('GET'); $this->request->setParams($queryParams); /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); + $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php similarity index 52% rename from dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php rename to dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php index c6c523aff3d0..d665a0cb5302 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php @@ -8,64 +8,37 @@ namespace Magento\GraphQlCache\Controller\Catalog; use Magento\Framework\App\Request\Http; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\TestFramework\Helper\Bootstrap; +use Magento\GraphQl\Controller\GraphQl; +use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** * Tests cache debug headers and cache tag validation for a simple category query * * @magentoAppArea graphql + * @magentoCache full_page enabled * @magentoDbIsolation disabled - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class CategoryDispatchTest extends \Magento\TestFramework\Indexer\TestCase +class CategoryCacheTest extends AbstractGraphqlCacheTest { - const CONTENT_TYPE = 'application/json'; - - /** @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager; - - /** @var GraphQl */ - private $graphql; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var MetadataPool */ - private $metadataPool; - - /** @var Http */ - private $request; - /** - * @inheritdoc + * @var GraphQl */ - public static function setUpBeforeClass() - { - $db = Bootstrap::getInstance()->getBootstrap() - ->getApplication() - ->getDbInstance(); - if (!$db->isDbDumpExists()) { - throw new \LogicException('DB dump does not exist.'); - } - $db->restoreFromDbDump(); + private $graphqlController; - parent::setUpBeforeClass(); - } + /** + * @var Http + */ + private $request; /** * @inheritdoc */ protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->metadataPool = $this->objectManager->get(MetadataPool::class); - $this->request = $this->objectManager->get(Http::class); + parent::setUp(); + $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->request = $this->objectManager->create(Http::class); } - /** * Test cache tags and debug header for category and querying only for category * @@ -73,7 +46,7 @@ protected function setUp(): void * @magentoDataFixture Magento/Catalog/_files/category_product.php * */ - public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void + public function testToCheckRequestCacheTagsForForCategory(): void { $categoryId ='333'; $query @@ -92,12 +65,10 @@ public function testDispatchForCacheDebugHeadersAndCacheTagsForCategory(): void $this->request->setMethod('GET'); $this->request->setQueryValue('query', $query); /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); + $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php similarity index 54% rename from dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php rename to dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index 53b8e2123063..6b4813fe76d4 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsDispatchTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -9,72 +9,44 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\App\Request\Http; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\TestFramework\Helper\Bootstrap; +use Magento\GraphQl\Controller\GraphQl; +use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** * Tests cache debug headers and cache tag validation for a simple product query * * @magentoAppArea graphql + * @magentoCache full_page enabled * @magentoDbIsolation disabled - * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class ProductsDispatchTest extends \Magento\TestFramework\Indexer\TestCase +class ProductsCacheTest extends AbstractGraphqlCacheTest { - const CONTENT_TYPE = 'application/json'; - - /** @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager; - - /** @var GraphQl */ - private $graphql; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var MetadataPool */ - private $metadataPool; - - /** @var Http */ - private $request; - /** - * @inheritdoc + * @var GraphQl */ - public static function setUpBeforeClass() - { - $db = Bootstrap::getInstance()->getBootstrap() - ->getApplication() - ->getDbInstance(); - if (!$db->isDbDumpExists()) { - throw new \LogicException('DB dump does not exist.'); - } - $db->restoreFromDbDump(); + private $graphqlController; - parent::setUpBeforeClass(); - } + /** + * @var Http + */ + private $request; /** * @inheritdoc */ protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->metadataPool = $this->objectManager->get(MetadataPool::class); - $this->request = $this->objectManager->get(Http::class); + parent::setUp(); + $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $this->request = $this->objectManager->create(Http::class); } - /** * Test request is dispatched and response is checked for debug headers and cache tags * * @magentoCache all enabled - * @return void + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php */ - public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts(): void + public function testToCheckRequestCacheTagsForProducts(): void { /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); @@ -103,12 +75,10 @@ public function testDispatchWithGetForCacheDebugHeadersAndCacheTagsForProducts() $this->request->setMethod('GET'); $this->request->setQueryValue('query', $query); /** @var \Magento\Framework\Controller\Result\Json $result */ - $result = $this->graphql->dispatch($this->request); + $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); /** @var $registry \Magento\Framework\Registry */ - $registry = $this->objectManager->get(\Magento\Framework\Registry::class); - $registry->register('use_page_cache_plugin', true, true); $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); From 7ab95ac818a410b08509b1a0889864e208a58b40 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 18 Apr 2019 12:08:51 -0500 Subject: [PATCH 135/247] Issue-230: adding varnish - fixing static --- app/code/Magento/GraphQlCache/etc/module.xml | 1 + .../TestCase/HttpClient/CurlClient.php | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GraphQlCache/etc/module.xml b/app/code/Magento/GraphQlCache/etc/module.xml index d7f08c552933..3cbd4d8f0cb4 100644 --- a/app/code/Magento/GraphQlCache/etc/module.xml +++ b/app/code/Magento/GraphQlCache/etc/module.xml @@ -8,6 +8,7 @@ + diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php index 11af91bd3e00..11d7ee08cb82 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php @@ -35,7 +35,7 @@ public function get($url, $data = [], $headers = []) /** * Perform a HTTP GET request and returns just the response headers * - * @param $url + * @param string $url * @param array $data * @param array $headers * @return mixed @@ -118,8 +118,10 @@ public function put($url, $data, $headers = []) public function invokeApi($url, $additionalCurlOpts, $headers = []) { // initialize cURL + // phpcs:ignore Magento2.Functions.DiscouragedFunction $curl = curl_init($url); if ($curl === false) { + // phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception("Error Initializing cURL for baseUrl: " . $url); } @@ -128,28 +130,40 @@ public function invokeApi($url, $additionalCurlOpts, $headers = []) // add CURL opts foreach ($curlOpts as $opt => $val) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_setopt($curl, $opt, $val); } + // phpcs:ignore Magento2.Functions.DiscouragedFunction $response = curl_exec($curl); if ($response === false) { - throw new \Exception(curl_error($curl)); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $error = curl_error($curl); + // phpcs:ignore Magento2.Exceptions.DirectThrow + throw new \Exception($error; } $resp = []; + // phpcs:ignore Magento2.Functions.DiscouragedFunction $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $resp["header"] = substr($response, 0, $headerSize); $resp["body"] = substr($response, $headerSize); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $resp["meta"] = curl_getinfo($curl); if ($resp["meta"] === false) { - throw new \Exception(curl_error($curl)); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $error = curl_error($curl); + // phpcs:ignore Magento2.Exceptions.DirectThrow + throw new \Exception($error); } + // phpcs:ignore Magento2.Functions.DiscouragedFunction curl_close($curl); $meta = $resp["meta"]; if ($meta && $meta['http_code'] >= 400) { + // phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception($resp["body"], $meta['http_code']); } From 1e135ca5d979562fd82f6ff669a5c99d1f39800d Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 18 Apr 2019 12:29:48 -0500 Subject: [PATCH 136/247] Issue-230: adding varnish - fixing static --- .../Magento/TestFramework/TestCase/HttpClient/CurlClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php index 11d7ee08cb82..0a24e64297e1 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php @@ -140,7 +140,7 @@ public function invokeApi($url, $additionalCurlOpts, $headers = []) // phpcs:ignore Magento2.Functions.DiscouragedFunction $error = curl_error($curl); // phpcs:ignore Magento2.Exceptions.DirectThrow - throw new \Exception($error; + throw new \Exception($error); } $resp = []; From 0e78cca8b562a437993f875181666e96c9fa35e9 Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Thu, 18 Apr 2019 12:40:51 -0500 Subject: [PATCH 137/247] GraphQL-594,595,600:fixed some code review comments for integration tests --- .../Controller/Catalog/CategoriesWithProductsCacheTest.php | 4 +--- .../GraphQlCache/Controller/Catalog/CategoryCacheTest.php | 2 -- .../GraphQlCache/Controller/Catalog/ProductsCacheTest.php | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php index 142e0770937f..fc9b8f38ed1f 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php @@ -44,16 +44,14 @@ protected function setUp(): void /** * Test cache tags and debug header for category with products querying for products and category * - * @magentoCache all enabled * @magentoDataFixture Magento/Catalog/_files/category_product.php - * */ public function testToCheckRequestCacheTagsForCategoryWithProducts(): void { /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); /** @var ProductInterface $product */ - $product= $productRepository->get('simple333'); + $product = $productRepository->get('simple333'); $categoryId ='333'; $query = << Date: Thu, 18 Apr 2019 13:35:49 -0500 Subject: [PATCH 138/247] GraphQL-594,595,600:fixed additional code review comments for integration tests --- dev/tests/integration/testsuite/Magento/Cms/_files/pages.php | 4 ++-- .../Controller/Catalog/CategoriesWithProductsCacheTest.php | 4 ++-- .../GraphQlCache/Controller/Catalog/CategoryCacheTest.php | 5 ++--- .../GraphQlCache/Controller/Catalog/ProductsCacheTest.php | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php b/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php index 0b7c3a2242fe..b2742ecd380f 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php +++ b/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php @@ -14,7 +14,7 @@ ->setContentHeading('

Cms Page 100 Title

') ->setMetaTitle('Cms Meta title for page100') ->setMetaKeywords('Cms Meta Keywords for page100') - ->setsetMetaDescription('Cms Meta Description for page100') + ->setMetaDescription('Cms Meta Description for page100') ->setPageLayout('1column') ->save(); @@ -27,7 +27,7 @@ ->setContentHeading('

Cms Page Blank Title

') ->setMetaTitle('Cms Meta title for Blank page') ->setMetaKeywords('Cms Meta Keywords for Blank page') - ->setsetMetaDescription('Cms Meta Description for Blank page') + ->setMetaDescription('Cms Meta Description for Blank page') ->setPageLayout('1column') ->setCustomTheme('Magento/blank') ->save(); diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php index fc9b8f38ed1f..bcd3b7fecad5 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php @@ -18,7 +18,6 @@ * * @magentoAppArea graphql * @magentoCache full_page enabled - * @magentoDbIsolation disabled */ class CategoriesWithProductsCacheTest extends AbstractGraphqlCacheTest { @@ -81,7 +80,7 @@ public function testToCheckRequestCacheTagsForCategoryWithProducts(): void } QUERY; $variables =[ - 'id' => 333, + 'id' => $categoryId, 'pageSize'=> 10, 'currentPage' => 1 ]; @@ -105,3 +104,4 @@ public function testToCheckRequestCacheTagsForCategoryWithProducts(): void $this->assertEquals($expectedCacheTags, $actualCacheTags); } } + diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php index efa08b32d35e..06d9fc1ff596 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php @@ -71,8 +71,7 @@ public function testToCheckRequestCacheTagsForForCategory(): void $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'FPC']; - foreach (array_keys($actualCacheTags) as $key) { - $this->assertEquals($expectedCacheTags[$key], $actualCacheTags[$key]); - } + $this->assertEquals($expectedCacheTags, $actualCacheTags); } } + diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index b9f3a4c9a395..4cfd74ee49b8 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -17,7 +17,6 @@ * * @magentoAppArea graphql * @magentoCache full_page enabled - * @magentoDbIsolation disabled */ class ProductsCacheTest extends AbstractGraphqlCacheTest { @@ -85,3 +84,4 @@ public function testToCheckRequestCacheTagsForProducts(): void $this->assertEquals($expectedCacheTags, $actualCacheTags); } } + From c84a7a3b00fe78af13bb4a263b91da5677ea531f Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Thu, 18 Apr 2019 13:39:50 -0500 Subject: [PATCH 139/247] GraphQL-577: Test coverage for tag cache generation for category and products - refactored test --- .../GraphQl/PageCache/CacheTagTest.php | 136 ++++++++++-------- 1 file changed, 74 insertions(+), 62 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 44ef97db3593..457461d24d35 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -10,28 +10,31 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; use Magento\TestFramework\ObjectManager; -use Magento\TestFramework\App\State; -use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; -/** - * Class CacheTagTest - */ /** * Test the caching works properly for products and categories */ class CacheTagTest extends GraphQlAbstract { + /** - * Tests if Magento cache tags and debug headers for products are generated properly - * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php + * @inheritdoc */ - public function testCacheTagsAndCacheDebugHeaderForProducts() + protected function setUp() { $this->markTestSkipped( 'This test will stay skipped until DEVOPS-4924 is resolved' ); + } + /** + * Tests if Magento cache tags and debug headers for products are generated properly + * + * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php + */ + public function testCacheTagsAndCacheDebugHeaderForProducts() + { $productSku='simple2'; $query = <<markTestSkipped( - 'This test will stay skipped until DEVOPS-4924 is resolved' - ); $firstProductSku = 'simple333'; $secondProductSku = 'simple444'; $categoryId ='4'; - $categoryQuery - = <<<'QUERY' -query GetCategoryQuery($id: Int!, $pageSize: Int!, $currentPage: Int!) { - category(id: $id) { - id - description - name - product_count - products(pageSize: $pageSize, currentPage: $currentPage) { - items { - id - name - url_key - } - total_count - } - } - } -QUERY; + $variables =[ - 'id' => 4, + 'id' => $categoryId, 'pageSize'=> 10, 'currentPage' => 1 ]; - $product1Query - = <<getProductQuery($firstProductSku); + $product2Query =$this->getProductQuery($secondProductSku); + $categoryQuery = $this->getCategoryQuery(); $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables); /** cache-debug header value should be a MISS when category is loaded first time */ @@ -155,10 +113,12 @@ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); $actualCacheTags = explode(',', rtrim($headerCacheTags[1], "\r")); $expectedCacheTags = - ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $firstProduct->getId(),'cat_p_' .$secondProduct->getId(),'FPC']; + ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $firstProduct->getId(), + 'cat_p_' .$secondProduct->getId(),'FPC' + ]; $this->assertEquals($expectedCacheTags, $actualCacheTags); - // Cach-debug header should be a MISS for product 1 during first load + // Cach-debug header should be a MISS for product 1 on first request $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query); $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersFirstProduct); @@ -181,4 +141,56 @@ public function testCacheTagFromResponseHeaderForCategoriesWithProduct() $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query); $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHeadersSecondProduct); } + + /** + * Get Product query + * + * @param string $productSku + * @return string + */ + private function getProductQuery(string $productSku): string + { + $productQuery = << Date: Thu, 18 Apr 2019 14:32:08 -0500 Subject: [PATCH 140/247] MAGETWO-99027: Customizable Option Price input is not saved on Store View level when Catalog Price Scope set to Global --- .../Model/ResourceModel/Product/Option/Value.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php index 318c9bd132cc..8224d9674956 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php @@ -17,6 +17,7 @@ use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; +use Magento\Catalog\Helper\Data; /** * Catalog product custom option resource model @@ -51,6 +52,11 @@ class Value extends AbstractDb */ private $localeFormat; + /** + * @var Data + */ + private $dataHelper; + /** * Class constructor * @@ -59,17 +65,21 @@ class Value extends AbstractDb * @param StoreManagerInterface $storeManager * @param ScopeConfigInterface $config * @param string $connectionName + * @param Data $dataHelper */ public function __construct( Context $context, CurrencyFactory $currencyFactory, StoreManagerInterface $storeManager, ScopeConfigInterface $config, - $connectionName = null + $connectionName = null, + Data $dataHelper = null ) { $this->_currencyFactory = $currencyFactory; $this->_storeManager = $storeManager; $this->_config = $config; + $this->dataHelper = $dataHelper ?: ObjectManager::getInstance() + ->get(Data::class); parent::__construct($context, $connectionName); } @@ -131,7 +141,7 @@ protected function _saveValuePrices(AbstractModel $object) $optionTypeId = $this->getConnection()->fetchOne($select); if ($optionTypeId) { - if ($object->getStoreId() == '0') { + if ($object->getStoreId() == '0' || $this->dataHelper->isPriceGlobal()) { $bind = ['price' => $price, 'price_type' => $priceType]; $where = [ 'option_type_id = ?' => $optionTypeId, From b792752740da09176763e2e35aa8f30c8f56a247 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Thu, 18 Apr 2019 15:25:27 -0500 Subject: [PATCH 141/247] MAGETWO-99027: Customizable Option Price input is not saved on Store View level when Catalog Price Scope set to Global --- .../Catalog/Model/ResourceModel/Product/Option/Value.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php index 8224d9674956..494dbac02d79 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php @@ -22,7 +22,7 @@ /** * Catalog product custom option resource model * - * @author Magento Core Team + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Value extends AbstractDb { From 822359d4b43581590113ca0de1456672015a883d Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 18 Apr 2019 16:19:15 -0500 Subject: [PATCH 142/247] Issue-230: adding varnish - fixing static --- .../Framework/App/PageCache/Kernel.php | 51 +++++-------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/lib/internal/Magento/Framework/App/PageCache/Kernel.php b/lib/internal/Magento/Framework/App/PageCache/Kernel.php index 813762c646d4..a76847f64e45 100644 --- a/lib/internal/Magento/Framework/App/PageCache/Kernel.php +++ b/lib/internal/Magento/Framework/App/PageCache/Kernel.php @@ -6,6 +6,7 @@ namespace Magento\Framework\App\PageCache; use Magento\Framework\App\State as AppState; +use Magento\Framework\App\ObjectManager; /** * Builtin cache processor @@ -82,43 +83,17 @@ public function __construct( $this->cache = $cache; $this->identifier = $identifier; $this->request = $request; - - if ($context) { - $this->context = $context; - } else { - $this->context = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\App\Http\Context::class - ); - } - if ($contextFactory) { - $this->contextFactory = $contextFactory; - } else { - $this->contextFactory = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\App\Http\ContextFactory::class - ); - } - if ($httpFactory) { - $this->httpFactory = $httpFactory; - } else { - $this->httpFactory = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\App\Response\HttpFactory::class - ); - } - if ($serializer) { - $this->serializer = $serializer; - } else { - $this->serializer = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\Serialize\SerializerInterface::class - ); - } - - if ($state) { - $this->state = $state; - } else { - $this->state = \Magento\Framework\App\ObjectManager::getInstance()->get( - AppState::class - ); - } + $this->context = $context ?? ObjectManager::getInstance()->get(\Magento\Framework\App\Http\Context::class); + $this->contextFactory = $contextFactory ?? ObjectManager::getInstance()->get( + \Magento\Framework\App\Http\ContextFactory::class + ); + $this->httpFactory = $httpFactory ?? ObjectManager::getInstance()->get( + \Magento\Framework\App\Response\HttpFactory::class + ); + $this->serializer = $serializer ?? ObjectManager::getInstance()->get( + \Magento\Framework\Serialize\SerializerInterface::class + ); + $this->state = $state ?? ObjectManager::getInstance()->get(AppState::class); } /** @@ -231,7 +206,7 @@ private function buildResponse($responseData) private function getCache() { if (!$this->fullPageCache) { - $this->fullPageCache = \Magento\Framework\App\ObjectManager::getInstance()->get( + $this->fullPageCache = $objectManager->get( \Magento\PageCache\Model\Cache\Type::class ); } From c4947cedb0965c9208202d40116885c6f134fa04 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Thu, 18 Apr 2019 17:07:10 -0500 Subject: [PATCH 143/247] Issue-230: adding varnish - fixing objectmanager --- lib/internal/Magento/Framework/App/PageCache/Kernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/PageCache/Kernel.php b/lib/internal/Magento/Framework/App/PageCache/Kernel.php index a76847f64e45..9f6d796ad39f 100644 --- a/lib/internal/Magento/Framework/App/PageCache/Kernel.php +++ b/lib/internal/Magento/Framework/App/PageCache/Kernel.php @@ -206,7 +206,7 @@ private function buildResponse($responseData) private function getCache() { if (!$this->fullPageCache) { - $this->fullPageCache = $objectManager->get( + $this->fullPageCache = ObjectManager::getInstance()->get( \Magento\PageCache\Model\Cache\Type::class ); } From 3ac980d873f49d570be4f264581fa4c7916d978f Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Thu, 18 Apr 2019 17:19:30 -0500 Subject: [PATCH 144/247] GraphQL-597: Test coverage for cart-not cached test - api-functional test coverage --- .../GraphQl/PageCache/CacheTagTest.php | 10 +- .../PageCache/Quote/Guest/CartCacheTest.php | 132 ++++++++++++++++++ 2 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 457461d24d35..824f29cf0b1e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -17,7 +17,6 @@ */ class CacheTagTest extends GraphQlAbstract { - /** * @inheritdoc */ @@ -87,7 +86,6 @@ public function testCacheTagForCategoriesWithProduct() $firstProductSku = 'simple333'; $secondProductSku = 'simple444'; $categoryId ='4'; - $variables =[ 'id' => $categoryId, 'pageSize'=> 10, @@ -118,22 +116,22 @@ public function testCacheTagForCategoriesWithProduct() ]; $this->assertEquals($expectedCacheTags, $actualCacheTags); - // Cach-debug header should be a MISS for product 1 on first request + // Cache-debug header should be a MISS for product 1 on first request $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query); $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersFirstProduct); - // Cach-debug header should be a MISS for product 2 during first load + // Cache-debug header should be a MISS for product 2 during first load $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query); $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersSecondProduct); - /** cache-debug header value should be MISS after updating product1 and reloading the Category */ + /** Cache-debug header value should be MISS after updating product1 and reloading the Category */ $firstProduct->setPrice(20); $firstProduct->save(); $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables); preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); - /** cache-debug should be a MISS for product 1 after it is updated - cache invalidation */ + /** Cache-debug should be a MISS for product 1 after it is updated - cache invalidation */ $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query); $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersFirstProduct); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php new file mode 100644 index 000000000000..e0c57ea37382 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php @@ -0,0 +1,132 @@ +markTestSkipped( + 'This test will stay skipped until DEVOPS-4924 is resolved' + ); + } + /** + * Tests that X-Magento-Tags are correct + */ + public function testCartIsNotCached() + { + $qty = 2; + $sku = 'simple'; + $cartId = $this->createEmptyCart(); + $this->addSimpleProductToCart($cartId, $qty, $sku); + $getCartQuery = $this->checkCart($cartId); + $response = $this->graphQlQuery($getCartQuery); + self::assertArrayHasKey('cart', $response); + self::assertArrayHasKey('items', $response['cart']); + + $responseMissHeaders = $this->graphQlQueryForHttpHeaders($getCartQuery); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + + /** Cache debug header value is still a MISS for any subsequent request */ + $responseMissHeadersNext = $this->graphQlQueryForHttpHeaders($getCartQuery); + $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeadersNext); + } + + /** + * Create a guest cart which generates a maskedQuoteId + * + * @return mixed + */ + private function createEmptyCart() + { + $query = + <<graphQlMutation($query); + $this->maskedQuoteId = $response['createEmptyCart']; + return $this->maskedQuoteId; + } + + /** + * Add simple product to the cart using the maskedQuoteId + * @param $maskedCartId + * @param $qty + * @param $sku + */ + private function addSimpleProductToCart($maskedCartId, $qty, $sku) + { + $addProductToCartQuery = + <<graphQlMutation($addProductToCartQuery); + self::assertArrayHasKey('cart', $response['addSimpleProductsToCart']); + } + + /** + * + * @param string $maskedQuoteId + * @return string + */ + private function checkCart(string $maskedQuoteId): string + { + return << Date: Thu, 18 Apr 2019 17:23:09 -0500 Subject: [PATCH 145/247] Issue-230: adding varnish - fixing objectmanager --- .../Framework/App/PageCache/Kernel.php | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/lib/internal/Magento/Framework/App/PageCache/Kernel.php b/lib/internal/Magento/Framework/App/PageCache/Kernel.php index 9f6d796ad39f..f89fe93957a9 100644 --- a/lib/internal/Magento/Framework/App/PageCache/Kernel.php +++ b/lib/internal/Magento/Framework/App/PageCache/Kernel.php @@ -69,6 +69,7 @@ class Kernel * @param \Magento\Framework\App\Response\HttpFactory|null $httpFactory * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer * @param AppState|null $state + * @param \Magento\PageCache\Model\Cache\Type $fullPageCache */ public function __construct( \Magento\Framework\App\PageCache\Cache $cache, @@ -78,7 +79,8 @@ public function __construct( \Magento\Framework\App\Http\ContextFactory $contextFactory = null, \Magento\Framework\App\Response\HttpFactory $httpFactory = null, \Magento\Framework\Serialize\SerializerInterface $serializer = null, - AppState $state = null + AppState $state = null, + \Magento\PageCache\Model\Cache\Type $fullPageCache = null ) { $this->cache = $cache; $this->identifier = $identifier; @@ -94,6 +96,9 @@ public function __construct( \Magento\Framework\Serialize\SerializerInterface::class ); $this->state = $state ?? ObjectManager::getInstance()->get(AppState::class); + $this->fullPageCache = $fullPageCache ?? ObjectManager::getInstance()->get( + \Magento\PageCache\Model\Cache\Type::class + ); } /** @@ -104,7 +109,7 @@ public function __construct( public function load() { if ($this->request->isGet() || $this->request->isHead()) { - $responseData = $this->getCache()->load($this->identifier->getValue()); + $responseData = $this->fullPageCache->load($this->identifier->getValue()); if (!$responseData) { return false; } @@ -143,7 +148,7 @@ public function process(\Magento\Framework\App\Response\Http $response) header_remove('Set-Cookie'); } - $this->getCache()->save( + $this->fullPageCache->save( $this->serializer->serialize($this->getPreparedData($response)), $this->identifier->getValue(), $tags, @@ -197,19 +202,4 @@ private function buildResponse($responseData) return $response; } - - /** - * TODO: Workaround to support backwards compatibility, will rework to use Dependency Injection in MAGETWO-49547 - * - * @return \Magento\PageCache\Model\Cache\Type - */ - private function getCache() - { - if (!$this->fullPageCache) { - $this->fullPageCache = ObjectManager::getInstance()->get( - \Magento\PageCache\Model\Cache\Type::class - ); - } - return $this->fullPageCache; - } } From 4ba98bfee94828e4dc36afd9d34f24db43ab42ab Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Thu, 18 Apr 2019 17:29:21 -0500 Subject: [PATCH 146/247] GraphQL-597: Test coverage for cart-not cached test - minor changes to annotations --- .../Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php index e0c57ea37382..0ef60e1fbde3 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php @@ -7,7 +7,6 @@ namespace Magento\GraphQl\PageCache\Quote\Guest; -use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; /** @@ -27,6 +26,7 @@ protected function setUp() 'This test will stay skipped until DEVOPS-4924 is resolved' ); } + /** * Tests that X-Magento-Tags are correct */ @@ -52,9 +52,9 @@ public function testCartIsNotCached() /** * Create a guest cart which generates a maskedQuoteId * - * @return mixed + * @return string */ - private function createEmptyCart() + private function createEmptyCart(): string { $query = << Date: Fri, 19 Apr 2019 15:16:10 +0300 Subject: [PATCH 147/247] Fix static test. --- app/code/Magento/Checkout/view/frontend/web/js/view/payment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js index ad6f39b7d6d5..e8994c61b722 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js @@ -66,7 +66,7 @@ define([ navigate: function () { var self = this; - if(!self.hasShippingMethod()) { + if (!self.hasShippingMethod()) { this.isVisible(false); stepNavigator.setHash('shipping'); } else { From a45d5196c23985068c8250a9d79fae25e89b4a1d Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Fri, 19 Apr 2019 15:46:13 +0300 Subject: [PATCH 148/247] magento/magento2#22178: Static test fix. --- .../Magento/Catalog/Model/Product/Copier.php | 17 ++++---- .../Test/Unit/Model/Product/CopierTest.php | 39 +++++++++++-------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php index 3e899decaeb5..44ebdf0f1f28 100644 --- a/app/code/Magento/Catalog/Model/Product/Copier.php +++ b/app/code/Magento/Catalog/Model/Product/Copier.php @@ -1,7 +1,5 @@ getId(); $productResource = $product->getResource(); $defaultUrlKey = $productResource->getAttributeRawValue( - $productId, - 'url_key', - \Magento\Store\Model\Store::DEFAULT_STORE_ID - ); + $productId, + 'url_key', + \Magento\Store\Model\Store::DEFAULT_STORE_ID + ); $duplicate->setData('save_rewrites_history', false); foreach ($storeIds as $storeId) { $isDuplicateSaved = false; @@ -139,6 +141,7 @@ private function setStoresUrl(Product $product, Product $duplicate) : void try { $duplicate->save(); $isDuplicateSaved = true; + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock } catch (\Magento\Framework\Exception\AlreadyExistsException $e) { } } while (!$isDuplicateSaved); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php index 7ae5f70285fa..80b6db2a516b 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php @@ -6,10 +6,12 @@ namespace Magento\Catalog\Test\Unit\Model\Product; use Magento\Catalog\Api\Data\ProductInterface; -use \Magento\Catalog\Model\Product\Copier; use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Copier; /** + * Test for Magento\Catalog\Model\Product\Copier class. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class CopierTest extends \PHPUnit\Framework\TestCase @@ -76,6 +78,9 @@ protected function setUp() ]); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testCopy() { $stockItem = $this->getMockBuilder(\Magento\CatalogInventory\Api\Data\StockItemInterface::class) @@ -104,27 +109,27 @@ public function testCopy() ]); $entityMock = $this->getMockForAbstractClass( - \Magento\Eav\Model\Entity\AbstractEntity::class, - [], - '', - false, - true, - true, - ['checkAttributeUniqueValue'] - ); + \Magento\Eav\Model\Entity\AbstractEntity::class, + [], + '', + false, + true, + true, + ['checkAttributeUniqueValue'] + ); $entityMock->expects($this->any()) ->method('checkAttributeUniqueValue') ->willReturn(true); $attributeMock = $this->getMockForAbstractClass( - \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, - [], - '', - false, - true, - true, - ['getEntity'] - ); + \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, + [], + '', + false, + true, + true, + ['getEntity'] + ); $attributeMock->expects($this->any()) ->method('getEntity') ->willReturn($entityMock); From a7d1f1b183b573bb8dbcfb7e266759a1bb647ba5 Mon Sep 17 00:00:00 2001 From: Evgeny Petrov Date: Fri, 19 Apr 2019 17:44:36 +0300 Subject: [PATCH 149/247] MAGETWO-98584: Google chart API used by Magento dashboard scheduled to be turned off --- .../Magento/Backend/Block/Dashboard/Graph.php | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Backend/Block/Dashboard/Graph.php b/app/code/Magento/Backend/Block/Dashboard/Graph.php index f57b03fdbfa0..b76421e4e6f6 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Graph.php +++ b/app/code/Magento/Backend/Block/Dashboard/Graph.php @@ -114,8 +114,8 @@ public function __construct( \Magento\Backend\Helper\Dashboard\Data $dashboardData, array $data = [] ) { - $this->_dashboardData = $dashboardData; parent::__construct($context, $collectionFactory, $data); + $this->_dashboardData = $dashboardData; } /** @@ -131,7 +131,7 @@ protected function _getTabTemplate() /** * Set data rows * - * @param array $rows + * @param string $rows * @return void */ public function setDataRows($rows) @@ -155,15 +155,14 @@ public function addSeries($seriesId, array $options) * Get series * * @param string $seriesId - * @return array|false + * @return array|bool */ public function getSeries($seriesId) { if (isset($this->_allSeries[$seriesId])) { return $this->_allSeries[$seriesId]; - } else { - return false; } + return false; } /** @@ -308,7 +307,7 @@ public function getChartUrl($directUrl = true) if ($minvalue >= 0 && $maxvalue >= 0) { if ($maxvalue > 10) { - $p = pow(10, $this->_getPow($maxvalue)); + $p = pow(10, $this->_getPow((int) $maxvalue)); $maxy = ceil($maxvalue / $p) * $p; $yLabels = range($miny, $maxy, $p); } else { @@ -349,7 +348,7 @@ public function getChartUrl($directUrl = true) $indexid = 0; foreach ($this->_axisLabels as $idx => $labels) { if ($idx == 'x') { - $this->formatAxisLabelDate($idx, $timezoneLocal); + $this->formatAxisLabelDate((string) $idx, (string) $timezoneLocal); $tmpstring = implode('|', $this->_axisLabels[$idx]); $valueBuffer[] = $indexid . ":|" . $tmpstring; } elseif ($idx == 'y') { @@ -369,13 +368,12 @@ public function getChartUrl($directUrl = true) foreach ($params as $name => $value) { $p[] = $name . '=' . urlencode($value); } - return self::API_URL . '?' . implode('&', $p); - } else { - $gaData = urlencode(base64_encode(json_encode($params))); - $gaHash = $this->_dashboardData->getChartDataHash($gaData); - $params = ['ga' => $gaData, 'h' => $gaHash]; - return $this->getUrl('adminhtml/*/tunnel', ['_query' => $params]); + return (string) self::API_URL . '?' . implode('&', $p); } + $gaData = urlencode(base64_encode(json_encode($params))); + $gaHash = $this->_dashboardData->getChartDataHash($gaData); + $params = ['ga' => $gaData, 'h' => $gaHash]; + return $this->getUrl('adminhtml/*/tunnel', ['_query' => $params]); } /** @@ -394,7 +392,7 @@ private function formatAxisLabelDate($idx, $timezoneLocal) switch ($this->getDataHelper()->getParam('period')) { case '24h': $this->_axisLabels[$idx][$_index] = $this->_localeDate->formatDateTime( - $period->setTime($period->format('H'), 0, 0), + $period->setTime((int) $period->format('H'), 0, 0), \IntlDateFormatter::NONE, \IntlDateFormatter::SHORT ); From 82c2eab9edb06d4e242fd0436d262a015f0eabd1 Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Fri, 19 Apr 2019 10:50:01 -0500 Subject: [PATCH 150/247] 230: Implement cache tag generation for GraphQL queries - Added integration tests for cache tag in the schema --- .../Framework/GraphQl/GraphQlConfigTest.php | 29 ++++++++++++------- .../GraphQl/_files/query_array_output.php | 6 +++- .../Framework/GraphQl/_files/schemaC.graphqls | 2 +- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php index ef4612ea357e..5668c1bef668 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/GraphQlConfigTest.php @@ -7,11 +7,8 @@ namespace Magento\Framework\GraphQl; -use Magento\Framework\App\Bootstrap; use Magento\Framework\App\Cache; -use Magento\Framework\Config\FileResolverInterface; use Magento\Framework\GraphQl\Config\Config; -use Magento\Framework\GraphQl\Config\ConfigElementInterface; use Magento\Framework\GraphQl\Config\Data\Argument; use Magento\Framework\GraphQl\Config\Data\Enum; use Magento\Framework\GraphQl\Config\Data\Field; @@ -19,9 +16,11 @@ use Magento\Framework\GraphQl\Config\Data\Type; use Magento\Framework\GraphQl\Config\Element\EnumValue; use Magento\Framework\GraphQl\Config\Element\InterfaceType; -use Magento\Framework\GraphQl\Config\Element\TypeFactory; use Magento\Framework\ObjectManagerInterface; +/** + * Test of schema configuration reading and parsing + */ class GraphQlConfigTest extends \PHPUnit\Framework\TestCase { /** @var \Magento\Framework\GraphQl\Config */ @@ -76,7 +75,12 @@ public function testGraphQlTypeAndFieldConfigStructure() ['response_field' => 'required', 'expected_value' => $queryFields[$fieldKey]->isRequired()], ['response_field' => 'isList', 'expected_value' => $queryFields[$fieldKey]->isList()], ['response_field' => 'resolver', 'expected_value' => $queryFields[$fieldKey]->getResolver()], - ['response_field' => 'description', 'expected_value' => $queryFields[$fieldKey]->getDescription()] + ['response_field' => 'description', 'expected_value' => $queryFields[$fieldKey]->getDescription()], + [ + 'response_field' => 'cache', + 'expected_value' => $queryFields[$fieldKey]->getCache(), + 'optional' => true + ] ]; $this->assertResponseFields($expectedOutputArray['Query']['fields'][$fieldKey], $fieldAssertionMap); /** @var \Magento\Framework\GraphQl\Config\Element\Argument $queryFieldArguments */ @@ -212,12 +216,15 @@ private function assertResponseFields($actualResponse, $assertionMap) $expectedValue, "Value of '{$responseField}' field must not be NULL" ); - $this->assertEquals( - $expectedValue, - $actualResponse[$responseField], - "Value of '{$responseField}' field in response does not match expected value: " - . var_export($expectedValue, true) - ); + $optionalField = isset($assertionData['optional']) ? $assertionData['optional'] : false; + if (!$optionalField || isset($actualResponse[$responseField])) { + $this->assertEquals( + $expectedValue, + $actualResponse[$responseField], + "Value of '{$responseField}' field in response does not match expected value: " + . var_export($expectedValue, true) + ); + } } } diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php index 9ebd0160240a..f7c2597fe571 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php @@ -32,7 +32,11 @@ 'required' => false, 'isList' => false, 'resolver' => 'Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata', - 'description' => 'Returns the attribute type, given an attribute code and entity type' + 'description' => 'Returns the attribute type, given an attribute code and entity type', + 'cache' => [ + 'cacheTag' => 'cat_test', + 'cacheIdentityResolver' => 'Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata' + ] ], 'products' => [ 'name' => 'products', diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls index 84609293f31a..895185bc6dd2 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls @@ -1,6 +1,6 @@ type Query { customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") - @doc(description: "Returns the attribute type, given an attribute code and entity type") + @doc(description: "Returns the attribute type, given an attribute code and entity type") @cache(cacheTag: "cat_test", cacheIdentityResolver: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") } type CustomAttributeMetadata { From 26a3573d8993499f0b8ba31936f9d26b1e33b654 Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Fri, 19 Apr 2019 13:12:43 -0500 Subject: [PATCH 151/247] GraphQL-595,600,598:code refactored for the integretaion tests --- .../Controller/Catalog/CategoriesWithProductsCacheTest.php | 1 + .../GraphQlCache/Controller/Catalog/ProductsCacheTest.php | 1 + .../Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php | 1 + 3 files changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php index bcd3b7fecad5..621030650ac6 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php @@ -18,6 +18,7 @@ * * @magentoAppArea graphql * @magentoCache full_page enabled + * @magentoDbIsolation disabled */ class CategoriesWithProductsCacheTest extends AbstractGraphqlCacheTest { diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index 4cfd74ee49b8..7fd7002142de 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -17,6 +17,7 @@ * * @magentoAppArea graphql * @magentoCache full_page enabled + * @magentoDbIsolation disabled */ class ProductsCacheTest extends AbstractGraphqlCacheTest { diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php index bc436b8f3578..8fa84505f147 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -17,6 +17,7 @@ * * @magentoAppArea graphql * @magentoCache full_page enabled + * @magentoDbIsolation disabled */ class CmsPageCacheTest extends AbstractGraphqlCacheTest { From 81acb65a8f701533f7c44ed05e2281885a5f1e6c Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Fri, 19 Apr 2019 14:36:56 -0500 Subject: [PATCH 152/247] GraphQL-577: Test coverage for tag cache generation - Refactor graphql test framework for caching --- .../TestFramework/TestCase/GraphQl/Client.php | 39 +++++- .../TestCase/GraphQlAbstract.php | 8 +- .../TestCase/HttpClient/CurlClient.php | 9 +- .../GraphQl/PageCache/CacheTagTest.php | 122 ++++++++++-------- .../GraphQl/PageCache/Cms/BlockCacheTest.php | 58 ++++----- .../Controller/AbstractGraphqlCacheTest.php | 2 +- .../Controller/Cms/BlockCacheTest.php | 1 + 7 files changed, 137 insertions(+), 102 deletions(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index d5a33cfe281f..cdc9d5e8a4c9 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -122,29 +122,33 @@ private function processResponse(string $response) } /** - * Process the header information from response + * Perform HTTP GET request, return response data and headers * * @param string $query * @param array $variables * @param string $operationName * @param array $headers - * @return mixed + * @return array */ - public function getQueryResponseHeaders( + public function getWithResponseHeaders( string $query, array $variables = [], string $operationName = '', array $headers = [] - ) { + ): array { $url = $this->getEndpointUrl(); $requestArray = [ 'query' => $query, 'variables' => $variables ? $this->json->jsonEncode($variables) : null, 'operationName' => !empty($operationName) ? $operationName : null ]; + array_filter($requestArray); + + $response = $this->curlClient->getWithFullResponse($url, $requestArray, $headers); + $responseBody = $this->processResponse($response['body']); + $responseHeaders = !empty($response['header']) ? $this->processResponseHeaders($response['header']) : []; - $responseHeader = $this->curlClient->getHttpHeaders($url, $requestArray, $headers); - return $responseHeader; + return ['headers' => $responseHeaders, 'body' => $responseBody]; } /** @@ -191,4 +195,27 @@ public function getEndpointUrl() { return rtrim(TESTS_BASE_URL, '/') . '/graphql'; } + + /** + * Parse response headers into associative array + * + * @param string $headers + * @return array + */ + private function processResponseHeaders(string $headers): array + { + $headersArray = []; + + $headerLines = preg_split('/((\r?\n)|(\r\n?))/', $headers); + foreach ($headerLines as $headerLine) { + $headerParts = preg_split('/:/', $headerLine); + if (count($headerParts) == 2) { + $headersArray[trim($headerParts[0])] = trim($headerParts[1]); + } elseif (preg_match('/HTTP\/[\.0-9]+/', $headerLine)) { + $headersArray[trim('Status-Line')] = trim($headerLine); + } + } + + return $headersArray; + } } diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php index f8aa95061926..94eb5ddec860 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -84,15 +84,15 @@ public function graphQlMutation( * @param array $variables * @param string $operationName * @param array $headers - * @return mixed + * @return array */ - public function graphQlQueryForHttpHeaders( + public function graphQlQueryWithResponseHeaders( string $query, array $variables = [], string $operationName = '', array $headers = [] - ) { - return $this->getGraphQlClient()->getQueryResponseHeaders( + ): array { + return $this->getGraphQlClient()->getWithResponseHeaders( $query, $variables, $operationName, diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php index 0a24e64297e1..67691a3c909b 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/HttpClient/CurlClient.php @@ -33,14 +33,14 @@ public function get($url, $data = [], $headers = []) } /** - * Perform a HTTP GET request and returns just the response headers + * Perform a HTTP GET request and return the full response * * @param string $url * @param array $data * @param array $headers - * @return mixed + * @return array */ - public function getHttpHeaders($url, $data = [], $headers = []) + public function getWithFullResponse($url, $data = [], $headers = []): array { if (!empty($data)) { $url .= '?' . http_build_query($data); @@ -48,8 +48,7 @@ public function getHttpHeaders($url, $data = [], $headers = []) $curlOpts = []; $curlOpts[CURLOPT_CUSTOMREQUEST] = \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET; - $resp = $this->invokeApi($url, $curlOpts, $headers); - return $resp["header"]; + return $this->invokeApi($url, $curlOpts, $headers); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index 824f29cf0b1e..e9ff8d93177c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -28,7 +28,7 @@ protected function setUp() } /** - * Tests if Magento cache tags and debug headers for products are generated properly + * Test if Magento cache tags and debug headers for products are generated properly * * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php */ @@ -49,35 +49,38 @@ public function testCacheTagsAndCacheDebugHeaderForProducts() } QUERY; - /** cache-debug should be a MISS when product is queried for first time */ - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + // Cache-debug should be a MISS when product is queried for first time + $responseMiss = $this->graphQlQueryWithResponseHeaders($query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseMiss['headers']); + $this->assertEquals('MISS', $responseMiss['headers']['X-Magento-Cache-Debug']); - /** cache-debug should be a HIT for the second round */ - $responseHitHeaders = $this->graphQlQueryForHttpHeaders($query); - //preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseHitHeaders, $matchesHit); - $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); + // Cache-debug should be a HIT for the second round + $responseHit = $this->graphQlQueryWithResponseHeaders($query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseHit['headers']); + $this->assertEquals('HIT', $responseHit['headers']['X-Magento-Cache-Debug']); /** @var ProductRepositoryInterface $productRepository */ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); /** @var Product $product */ - $product =$productRepository->get($productSku, false, null, true); - /** update the price attribute for the product in test */ + $product = $productRepository->get($productSku, false, null, true); $product->setPrice(15); - $product->save(); - /** Cache invalidation happens and cache-debug header value is a MISS after product update */ - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); - - /** checks if cache tags for products are correctly displayed in the response header */ - preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); - $actualCacheTags = explode(',', rtrim($headerCacheTags[1], "\r")); - $expectedCacheTags=['cat_p','cat_p_' . $product->getId(),'FPC']; - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $productRepository->save($product); + // Cache invalidation happens and cache-debug header value is a MISS after product update + $responseMiss = $this->graphQlQueryWithResponseHeaders($query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseMiss['headers']); + $this->assertEquals('MISS', $responseMiss['headers']['X-Magento-Cache-Debug']); + $this->assertArrayHasKey('X-Magento-Tags', $responseMiss['headers']); + $expectedCacheTags = ['cat_p','cat_p_' . $product->getId(),'FPC']; + $actualCacheTags = explode(',', $responseMiss['headers']['X-Magento-Tags']); + foreach ($expectedCacheTags as $expectedCacheTag) { + $this->assertContains($expectedCacheTag, $actualCacheTags); + } } /** - * Tests if X-Magento-Tags for categories are generated properly. Also tests the use case for cache invalidation + * Test if X-Magento-Tags for categories are generated properly + * + * Also tests the use case for cache invalidation * * @magentoApiDataFixture Magento/Catalog/_files/product_in_multiple_categories.php */ @@ -86,7 +89,15 @@ public function testCacheTagForCategoriesWithProduct() $firstProductSku = 'simple333'; $secondProductSku = 'simple444'; $categoryId ='4'; - $variables =[ + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + /** @var Product $firstProduct */ + $firstProduct = $productRepository->get($firstProductSku, false, null, true); + /** @var Product $secondProduct */ + $secondProduct = $productRepository->get($secondProductSku, false, null, true); + + $categoryQueryVariables =[ 'id' => $categoryId, 'pageSize'=> 10, 'currentPage' => 1 @@ -95,49 +106,46 @@ public function testCacheTagForCategoriesWithProduct() $product1Query = $this->getProductQuery($firstProductSku); $product2Query =$this->getProductQuery($secondProductSku); $categoryQuery = $this->getCategoryQuery(); - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables); - - /** cache-debug header value should be a MISS when category is loaded first time */ - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); - - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - /** @var Product $firstProduct */ - $firstProduct = $productRepository->get($firstProductSku, false, null, true); - /** @var Product $secondProduct */ - $secondProduct = $productRepository->get($secondProductSku, false, null, true); - /** checks to see if the X-Magento-Tags for category is displayed correctly */ - preg_match('/X-Magento-Tags: (.*?)\n/', $responseMissHeaders, $headerCacheTags); - $actualCacheTags = explode(',', rtrim($headerCacheTags[1], "\r")); + // cache-debug header value should be a MISS when category is loaded first time + $responseMiss = $this->graphQlQueryWithResponseHeaders($categoryQuery, $categoryQueryVariables); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseMiss['headers']); + $this->assertEquals('MISS', $responseMiss['headers']['X-Magento-Cache-Debug']); + $this->assertArrayHasKey('X-Magento-Tags', $responseMiss['headers']); + $actualCacheTags = explode(',', $responseMiss['headers']['X-Magento-Tags']); $expectedCacheTags = - ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $firstProduct->getId(), - 'cat_p_' .$secondProduct->getId(),'FPC' - ]; + [ + 'cat_c', + 'cat_c_' . $categoryId, + 'cat_p', + 'cat_p_' . $firstProduct->getId(), + 'cat_p_' . $secondProduct->getId(), + 'FPC' + ]; $this->assertEquals($expectedCacheTags, $actualCacheTags); // Cache-debug header should be a MISS for product 1 on first request - $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersFirstProduct); - + $responseFirstProduct = $this->graphQlQueryWithResponseHeaders($product1Query); + $this->assertEquals('MISS', $responseFirstProduct['headers']['X-Magento-Cache-Debug']); // Cache-debug header should be a MISS for product 2 during first load - $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersSecondProduct); + $responseSecondProduct = $this->graphQlQueryWithResponseHeaders($product2Query); + $this->assertEquals('MISS', $responseSecondProduct['headers']['X-Magento-Cache-Debug']); - /** Cache-debug header value should be MISS after updating product1 and reloading the Category */ $firstProduct->setPrice(20); - $firstProduct->save(); - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($categoryQuery, $variables); - preg_match('/X-Magento-Cache-Debug: (.*?)\n/', $responseMissHeaders, $matchesMiss); - $this->assertEquals('MISS', rtrim($matchesMiss[1], "\r")); - - /** Cache-debug should be a MISS for product 1 after it is updated - cache invalidation */ - $responseHeadersFirstProduct = $this->graphQlQueryForHttpHeaders($product1Query); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHeadersFirstProduct); - - // Cach-debug header should be a HIT for prod 2 during second load since prod 2 is fetched from cache. - $responseHeadersSecondProduct = $this->graphQlQueryForHttpHeaders($product2Query); - $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHeadersSecondProduct); + $productRepository->save($firstProduct); + // cache-debug header value should be MISS after updating product1 and reloading the Category + $responseMissCategory = $this->graphQlQueryWithResponseHeaders($categoryQuery, $categoryQueryVariables); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseMissCategory['headers']); + $this->assertEquals('MISS', $responseMissCategory['headers']['X-Magento-Cache-Debug']); + + // cache-debug should be a MISS for product 1 after it is updated - cache invalidation + $responseMissFirstProduct = $this->graphQlQueryWithResponseHeaders($product1Query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseMissFirstProduct['headers']); + $this->assertEquals('MISS', $responseMissFirstProduct['headers']['X-Magento-Cache-Debug']); + // Cache-debug header should be a HIT for product 2 + $responseHitSecondProduct = $this->graphQlQueryWithResponseHeaders($product2Query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseHitSecondProduct['headers']); + $this->assertEquals('HIT', $responseHitSecondProduct['headers']['X-Magento-Cache-Debug']); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php index aed568b0d5d7..3e8c3e0c9b47 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php @@ -41,11 +41,11 @@ public function testCacheTagsHaveExpectedValue() $query = $this->getBlockQuery([$blockIdentifier]); //cache-debug should be a MISS on first request - $responseHeaders = $this->graphQlQueryForHttpHeaders($query); - preg_match('/X-Magento-Tags: (.*)/', $responseHeaders, $matches); - $this->assertNotEmpty($matches[1]); - $actualTags = explode(',', $matches[1]); - $expectedTags = ["cms_b_{$blockIdentifier}", "cms_b_{$blockId}"]; + $response = $this->graphQlQueryWithResponseHeaders($query); + + $this->assertArrayHasKey('X-Magento-Tags', $response['headers']); + $actualTags = explode(',', $response['headers']['X-Magento-Tags']); + $expectedTags = ["cms_b", "cms_b_{$blockIdentifier}", "cms_b_{$blockId}", "FPC"]; foreach ($expectedTags as $expectedTag) { $this->assertContains($expectedTag, $actualTags); } @@ -62,17 +62,18 @@ public function testCacheIsUsedOnSecondRequest() $query = $this->getBlockQuery([$blockIdentifier]); //cache-debug should be a MISS on first request - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($query); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + $responseMiss = $this->graphQlQueryWithResponseHeaders($query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseMiss['headers']); + $this->assertEquals('MISS', $responseMiss['headers']['X-Magento-Cache-Debug']); //cache-debug should be a HIT on second request - $responseHitHeaders = $this->graphQlQueryForHttpHeaders($query); - $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); - + $responseHit = $this->graphQlQueryWithResponseHeaders($query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseHit['headers']); + $this->assertEquals('HIT', $responseHit['headers']['X-Magento-Cache-Debug']); //cached data should be correct - $blockQueryData = $this->graphQlQuery($query); - $blocks = $blockQueryData['cmsBlocks']['items']; - $this->assertArrayNotHasKey('errors', $blockQueryData); + $this->assertNotEmpty($responseHit['body']); + $this->assertArrayNotHasKey('errors', $responseHit['body']); + $blocks = $responseHit['body']['cmsBlocks']['items']; $this->assertEquals($blockIdentifier, $blocks[0]['identifier']); $this->assertEquals('CMS Block Title', $blocks[0]['title']); } @@ -91,30 +92,29 @@ public function testCacheIsInvalidatedOnBlockUpdate() $enabledBlockQuery = $this->getBlockQuery([$enabledBlockIdentifier]); //cache-debug should be a MISS on first request - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($fixtureBlockQuery); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($enabledBlockQuery); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + $fixtureBlockMiss = $this->graphQlQueryWithResponseHeaders($fixtureBlockQuery); + $this->assertEquals('MISS', $fixtureBlockMiss['headers']['X-Magento-Cache-Debug']); + $enabledBlockMiss = $this->graphQlQueryWithResponseHeaders($enabledBlockQuery); + $this->assertEquals('MISS', $enabledBlockMiss['headers']['X-Magento-Cache-Debug']); //cache-debug should be a HIT on second request - $responseHitHeaders = $this->graphQlQueryForHttpHeaders($fixtureBlockQuery); - $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); - $responseHitHeaders = $this->graphQlQueryForHttpHeaders($enabledBlockQuery); - $this->assertContains('X-Magento-Cache-Debug: HIT', $responseHitHeaders); + $fixtureBlockHit = $this->graphQlQueryWithResponseHeaders($fixtureBlockQuery); + $this->assertEquals('HIT', $fixtureBlockHit['headers']['X-Magento-Cache-Debug']); + $enabledBlockHit = $this->graphQlQueryWithResponseHeaders($enabledBlockQuery); + $this->assertEquals('HIT', $enabledBlockHit['headers']['X-Magento-Cache-Debug']); $newBlockContent = 'New block content!!!'; $this->updateBlockContent($fixtureBlockIdentifier, $newBlockContent); //cache-debug should be a MISS after update the block - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($fixtureBlockQuery); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); - $responseHitHeaders = $this->graphQlQueryForHttpHeaders($enabledBlockQuery); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseHitHeaders); - + $fixtureBlockMiss = $this->graphQlQueryWithResponseHeaders($fixtureBlockQuery); + $this->assertEquals('MISS', $fixtureBlockMiss['headers']['X-Magento-Cache-Debug']); + $enabledBlockHit = $this->graphQlQueryWithResponseHeaders($enabledBlockQuery); + $this->assertEquals('HIT', $enabledBlockHit['headers']['X-Magento-Cache-Debug']); //updated block data should be correct - $blockQueryData = $this->graphQlQuery($fixtureBlockQuery); - $blocks = $blockQueryData['cmsBlocks']['items']; - $this->assertArrayNotHasKey('errors', $blockQueryData); + $this->assertNotEmpty($fixtureBlockMiss['body']); + $blocks = $fixtureBlockMiss['body']['cmsBlocks']['items']; + $this->assertArrayNotHasKey('errors', $fixtureBlockMiss['body']); $this->assertEquals($fixtureBlockIdentifier, $blocks[0]['identifier']); $this->assertEquals('CMS Block Title', $blocks[0]['title']); $this->assertEquals($newBlockContent, $blocks[0]['content']); diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php index d2e853c2aa0e..4cc46a8e745e 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php @@ -14,7 +14,7 @@ /** * Abstract test class for Graphql cache tests */ -class AbstractGraphqlCacheTest extends TestCase +abstract class AbstractGraphqlCacheTest extends TestCase { /** * @var ObjectManager diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php index 005007fce58f..58e665c057f0 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php @@ -17,6 +17,7 @@ * * @magentoAppArea graphql * @magentoCache full_page enabled + * @magentoDbIsolation disabled */ class BlockCacheTest extends AbstractGraphqlCacheTest { From 980cba8bfef16c7c23241377ff3b92f5aeb283a4 Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Fri, 19 Apr 2019 15:03:17 -0500 Subject: [PATCH 153/247] GraphQl:598 Cache Tag generation test changes added --- .../Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php index 8fa84505f147..bb358d32278c 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -10,6 +10,7 @@ use Magento\Cms\Model\GetPageByIdentifier; use Magento\Framework\App\Request\Http; use Magento\GraphQl\Controller\GraphQl; +use Magento\Framework\App\ResponseInterface; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -18,6 +19,7 @@ * @magentoAppArea graphql * @magentoCache full_page enabled * @magentoDbIsolation disabled + * */ class CmsPageCacheTest extends AbstractGraphqlCacheTest { @@ -74,6 +76,7 @@ public function testToCheckCmsPageRequestCacheTags(): void $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); From 66d1c70c06d9f93c9dfdc73f9d4a6cac28a6e4e2 Mon Sep 17 00:00:00 2001 From: Prabhu Ram Date: Fri, 19 Apr 2019 15:16:40 -0500 Subject: [PATCH 154/247] 230: Implement cache tag generation for GraphQL queries - Fixed static tests --- .../Framework/GraphQl/_files/query_array_output.php | 9 +++++---- .../Catalog/CategoriesWithProductsCacheTest.php | 1 - .../Controller/Catalog/CategoryCacheTest.php | 1 - .../Controller/Catalog/ProductsCacheTest.php | 1 - 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php index f7c2597fe571..adfe03cdd321 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php @@ -31,11 +31,12 @@ ], 'required' => false, 'isList' => false, - 'resolver' => 'Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata', + 'resolver' => Magento\EavGraphQl\Model\Resolver\CustomAttributeMetadata::class, 'description' => 'Returns the attribute type, given an attribute code and entity type', 'cache' => [ 'cacheTag' => 'cat_test', - 'cacheIdentityResolver' => 'Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata' + 'cacheIdentityResolver' => + Magento\EavGraphQl\Model\Resolver\CustomAttributeMetadata::class ] ], 'products' => [ @@ -99,7 +100,7 @@ ], 'required' => false, 'isList' => false, - 'resolver' => 'Magento\\CatalogGraphQl\\Model\\Resolver\\Products', + 'resolver' => Magento\CatalogGraphQl\Model\Resolver\Products::class, 'description' => 'comment for products fields' ] ] @@ -278,7 +279,7 @@ ] ], - 'typeResolver' => 'Magento\\CatalogGraphQl\\Model\\ProductLinkTypeResolverComposite', + 'typeResolver' => Magento\CatalogGraphQl\Model\ProductLinkTypeResolverComposite::class, 'description' => 'description for ProductLinksInterface' ] ]; diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php index 621030650ac6..f137a2aca8d4 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php @@ -105,4 +105,3 @@ public function testToCheckRequestCacheTagsForCategoryWithProducts(): void $this->assertEquals($expectedCacheTags, $actualCacheTags); } } - diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php index 06d9fc1ff596..3c2f46e1474b 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php @@ -74,4 +74,3 @@ public function testToCheckRequestCacheTagsForForCategory(): void $this->assertEquals($expectedCacheTags, $actualCacheTags); } } - diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index 7fd7002142de..b9f3a4c9a395 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -85,4 +85,3 @@ public function testToCheckRequestCacheTagsForProducts(): void $this->assertEquals($expectedCacheTags, $actualCacheTags); } } - From 453ceabeedc0343db221637dd60645a522ba574b Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Fri, 19 Apr 2019 16:17:23 -0500 Subject: [PATCH 155/247] GraphlQL:597 Cart - No Cache Test (Api-functional Test for Tag Cache Generation) No cache tags tests are added --- .../PageCache/Quote/Guest/CartCacheTest.php | 1 + .../Controller/Catalog/ProductsCacheTest.php | 39 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php index 0ef60e1fbde3..814cc0779401 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php @@ -109,6 +109,7 @@ private function addSimpleProductToCart($maskedCartId, $qty, $sku) } /** + * Get Check Cart query * * @param string $maskedQuoteId * @return string diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index 7fd7002142de..d0b95b20656c 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -40,6 +40,7 @@ protected function setUp(): void $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); $this->request = $this->objectManager->create(Http::class); } + /** * Test request is dispatched and response is checked for debug headers and cache tags * @@ -84,5 +85,41 @@ public function testToCheckRequestCacheTagsForProducts(): void $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; $this->assertEquals($expectedCacheTags, $actualCacheTags); } -} + /** + * Test request is checked for debug headers and no cache tags for not existing product + */ + public function testToCheckRequestNoTagsForProducts(): void + { + $query + = <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphqlController->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = [ 'FPC']; + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } +} From 962ad5e055717c22af8c8f6414d49bc178aaaee3 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Fri, 19 Apr 2019 16:30:51 -0500 Subject: [PATCH 156/247] Issue-230: Implement cache tag generation for GraphQL queries - Refactor IdentityInterface --- ...ityResolver.php => CategoriesIdentity.php} | 6 +-- ...yResolver.php => CategoryTreeIdentity.php} | 6 +-- .../{IdentityResolver.php => Identity.php} | 6 +-- .../CatalogGraphQl/etc/schema.graphqls | 8 +-- .../{IdentityResolver.php => Identity.php} | 8 +-- .../{IdentityResolver.php => Identity.php} | 6 +-- .../Magento/CmsGraphQl/etc/schema.graphqls | 4 +- .../Model/CacheableQueryHandler.php | 19 +++---- .../Model/IdentityResolverPool.php | 49 ------------------- .../Model/Resolver/IdentityPool.php | 49 +++++++++++++++++++ .../Unit/Model/CacheableQueryHandlerTest.php | 30 ++++++------ .../GraphQl/_files/query_array_output.php | 2 +- .../Framework/GraphQl/_files/schemaC.graphqls | 2 +- .../IdentityInterface.php} | 8 +-- .../MetaReader/CacheTagReader.php | 4 +- 15 files changed, 104 insertions(+), 103 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Category/{CategoriesIdentityResolver.php => CategoriesIdentity.php} (74%) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Category/{CategoryTreeIdentityResolver.php => CategoryTreeIdentity.php} (69%) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/{IdentityResolver.php => Identity.php} (74%) rename app/code/Magento/CmsGraphQl/Model/Resolver/Block/{IdentityResolver.php => Identity.php} (75%) rename app/code/Magento/CmsGraphQl/Model/Resolver/Page/{IdentityResolver.php => Identity.php} (73%) delete mode 100644 app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php create mode 100644 app/code/Magento/GraphQlCache/Model/Resolver/IdentityPool.php rename lib/internal/Magento/Framework/GraphQl/Query/{IdentityResolverInterface.php => Resolver/IdentityInterface.php} (53%) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentity.php similarity index 74% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentity.php index 1fad463ddee1..d81f6db574a3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentityResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoriesIdentity.php @@ -7,12 +7,12 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Category; -use Magento\Framework\GraphQl\Query\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface; /** * Identity for multiple resolved categories */ -class CategoriesIdentityResolver implements IdentityResolverInterface +class CategoriesIdentity implements IdentityInterface { /** * Get category IDs from resolved data @@ -20,7 +20,7 @@ class CategoriesIdentityResolver implements IdentityResolverInterface * @param array $resolvedData * @return array */ - public function getIdentifiers(array $resolvedData): array + public function getIdentities(array $resolvedData): array { $ids = []; if (!empty($resolvedData)) { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentity.php similarity index 69% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentityResolver.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentity.php index 0bfe6d2e4699..8cc77b53c5aa 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentityResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryTreeIdentity.php @@ -7,12 +7,12 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Category; -use Magento\Framework\GraphQl\Query\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface; /** * Identity for resolved category */ -class CategoryTreeIdentityResolver implements IdentityResolverInterface +class CategoryTreeIdentity implements IdentityInterface { /** * Get category ID from resolved data @@ -20,7 +20,7 @@ class CategoryTreeIdentityResolver implements IdentityResolverInterface * @param array $resolvedData * @return array */ - public function getIdentifiers(array $resolvedData): array + public function getIdentities(array $resolvedData): array { return empty($resolvedData['id']) ? [] : [$resolvedData['id']]; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Identity.php similarity index 74% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Identity.php index eece587eb429..bbb0057befc7 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/IdentityResolver.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Identity.php @@ -7,12 +7,12 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Query\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface; /** * Identity for resolved products */ -class IdentityResolver implements IdentityResolverInterface +class Identity implements IdentityInterface { /** * Get product ids for cache tag @@ -20,7 +20,7 @@ class IdentityResolver implements IdentityResolverInterface * @param array $resolvedData * @return array */ - public function getIdentifiers(array $resolvedData): array + public function getIdentities(array $resolvedData): array { $ids = []; $items = $resolvedData['items'] ?? []; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index eece33fc2658..08066e5fdfed 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -9,11 +9,11 @@ type Query { currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") @cache(cacheTag: "cat_p", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\IdentityResolver") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") @cache(cacheTag: "cat_p", cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Identity") category ( id: Int @doc(description: "Id of the category") ): CategoryTree - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes") @cache(cacheTag: "cat_c", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentityResolver") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes") @cache(cacheTag: "cat_c", cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentity") } enum CurrencyEnum @doc(description: "The list of available currency codes") { @@ -275,7 +275,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") manufacturer: Int @doc(description: "A number representing the product's manufacturer") - categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @cache(cacheTag: "cat_c", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoriesIdentityResolver") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") + categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @cache(cacheTag: "cat_c", cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoriesIdentity") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl") } @@ -396,7 +396,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @doc(description: "The list of products assigned to the category") @cache(cacheTag: "cat_p", cacheIdentityResolver: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\IdentityResolver") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + ): CategoryProducts @doc(description: "The list of products assigned to the category") @cache(cacheTag: "cat_p", cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Identity") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/Identity.php similarity index 75% rename from app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php rename to app/code/Magento/CmsGraphQl/Model/Resolver/Block/Identity.php index 5f18bce21f37..9431d2069218 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Block/IdentityResolver.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Block/Identity.php @@ -8,20 +8,20 @@ namespace Magento\CmsGraphQl\Model\Resolver\Block; use Magento\Cms\Api\Data\BlockInterface; -use Magento\Framework\GraphQl\Query\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface; /** * Identity for resolved CMS block */ -class IdentityResolver implements IdentityResolverInterface +class Identity implements IdentityInterface { /** - * Get block identifiers from resolved data + * Get block identities from resolved data * * @param array $resolvedData * @return array */ - public function getIdentifiers(array $resolvedData): array + public function getIdentities(array $resolvedData): array { $ids = []; $items = $resolvedData['items'] ?? []; diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Page/Identity.php similarity index 73% rename from app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php rename to app/code/Magento/CmsGraphQl/Model/Resolver/Page/Identity.php index d139cb383233..5a11587f4b1e 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Page/IdentityResolver.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Page/Identity.php @@ -8,12 +8,12 @@ namespace Magento\CmsGraphQl\Model\Resolver\Page; use Magento\Cms\Api\Data\PageInterface; -use Magento\Framework\GraphQl\Query\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface; /** * Identity for resolved CMS page */ -class IdentityResolver implements IdentityResolverInterface +class Identity implements IdentityInterface { /** * Get page ID from resolved data @@ -21,7 +21,7 @@ class IdentityResolver implements IdentityResolverInterface * @param array $resolvedData * @return array */ - public function getIdentifiers(array $resolvedData): array + public function getIdentities(array $resolvedData): array { return empty($resolvedData[PageInterface::PAGE_ID]) ? [] : [$resolvedData[PageInterface::PAGE_ID]]; } diff --git a/app/code/Magento/CmsGraphQl/etc/schema.graphqls b/app/code/Magento/CmsGraphQl/etc/schema.graphqls index 1734cf80afd6..04d2efa4c7cd 100644 --- a/app/code/Magento/CmsGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CmsGraphQl/etc/schema.graphqls @@ -13,10 +13,10 @@ type StoreConfig @doc(description: "The type contains information about a store type Query { cmsPage ( id: Int @doc(description: "Id of the CMS page") - ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") @cache(cacheTag: "cms_p", cacheIdentityResolver: "Magento\\CmsGraphQl\\Model\\Resolver\\Page\\IdentityResolver") + ): CmsPage @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Page") @doc(description: "The CMS page query returns information about a CMS page") @cache(cacheTag: "cms_p", cacheIdentity: "Magento\\CmsGraphQl\\Model\\Resolver\\Page\\Identity") cmsBlocks ( identifiers: [String] @doc(description: "Identifiers of the CMS blocks") - ): CmsBlocks @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Blocks") @doc(description: "The CMS block query returns information about CMS blocks") @cache(cacheTag: "cms_b", cacheIdentityResolver: "Magento\\CmsGraphQl\\Model\\Resolver\\Block\\IdentityResolver") + ): CmsBlocks @resolver(class: "Magento\\CmsGraphQl\\Model\\Resolver\\Blocks") @doc(description: "The CMS block query returns information about CMS blocks") @cache(cacheTag: "cms_b", cacheIdentity: "Magento\\CmsGraphQl\\Model\\Resolver\\Block\\Identity") } type CmsPage @doc(description: "CMS page defines all CMS page information") { diff --git a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php index 326c53b58991..7e624845f568 100644 --- a/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php +++ b/app/code/Magento/GraphQlCache/Model/CacheableQueryHandler.php @@ -9,6 +9,7 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\App\RequestInterface; +use Magento\GraphQlCache\Model\Resolver\IdentityPool; /** * Handler of collecting tagging on cache. @@ -29,23 +30,23 @@ class CacheableQueryHandler private $request; /** - * @var IdentityResolverPool + * @var IdentityPool */ - private $identityResolverPool; + private $identityPool; /** * @param CacheableQuery $cacheableQuery * @param RequestInterface $request - * @param IdentityResolverPool $identityResolverPool + * @param IdentityPool $identityPool */ public function __construct( CacheableQuery $cacheableQuery, RequestInterface $request, - IdentityResolverPool $identityResolverPool + IdentityPool $identityPool ) { $this->cacheableQuery = $cacheableQuery; $this->request = $request; - $this->identityResolverPool = $identityResolverPool; + $this->identityPool = $identityPool; } /** @@ -58,15 +59,15 @@ public function __construct( public function handleCacheFromResolverResponse(array $resolvedValue, Field $field) : void { $cache = $field->getCache(); - $cacheIdentityResolverClass = $cache['cacheIdentityResolver'] ?? ''; + $cacheIdentityClass = $cache['cacheIdentity'] ?? ''; $cacheable = $cache['cacheable'] ?? true; $cacheTag = $cache['cacheTag'] ?? null; $cacheTags = []; if ($cacheTag && $this->request->isGet()) { - if (!empty($cacheIdentityResolverClass)) { - $cacheIdentityResolver = $this->identityResolverPool->get($cacheIdentityResolverClass); - $cacheTagIds = $cacheIdentityResolver->getIdentifiers($resolvedValue); + if (!empty($cacheIdentityClass)) { + $cacheIdentity = $this->identityPool->get($cacheIdentityClass); + $cacheTagIds = $cacheIdentity->getIdentities($resolvedValue); if (!empty($cacheTagIds)) { $cacheTags[] = $cacheTag; foreach ($cacheTagIds as $cacheTagId) { diff --git a/app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php b/app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php deleted file mode 100644 index da97e5ba4f2e..000000000000 --- a/app/code/Magento/GraphQlCache/Model/IdentityResolverPool.php +++ /dev/null @@ -1,49 +0,0 @@ -objectManager = $objectManager; - } - - /** - * Get an identity resolver by class name - * - * @param string $identityResolverClass - * @return IdentityResolverInterface - */ - public function get(string $identityResolverClass): IdentityResolverInterface - { - if (!isset($this->identityResolvers[$identityResolverClass])) { - $this->identityResolvers[$identityResolverClass] = $this->objectManager->create($identityResolverClass); - } - return $this->identityResolvers[$identityResolverClass]; - } -} diff --git a/app/code/Magento/GraphQlCache/Model/Resolver/IdentityPool.php b/app/code/Magento/GraphQlCache/Model/Resolver/IdentityPool.php new file mode 100644 index 000000000000..00ef8762c28e --- /dev/null +++ b/app/code/Magento/GraphQlCache/Model/Resolver/IdentityPool.php @@ -0,0 +1,49 @@ +objectManager = $objectManager; + } + + /** + * Get an identity resolver by class name + * + * @param string $identityClass + * @return IdentityInterface + */ + public function get(string $identityClass): IdentityInterface + { + if (!isset($this->identityInstances[$identityClass])) { + $this->identityInstances[$identityClass] = $this->objectManager->create($identityClass); + } + return $this->identityInstances[$identityClass]; + } +} diff --git a/app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php b/app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php index c595881472e5..9c1be8992821 100644 --- a/app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php +++ b/app/code/Magento/GraphQlCache/Test/Unit/Model/CacheableQueryHandlerTest.php @@ -9,9 +9,9 @@ use Magento\Framework\App\Request\Http; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\IdentityResolverInterface; +use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface; use Magento\GraphQlCache\Model\CacheableQueryHandler; -use Magento\GraphQlCache\Model\IdentityResolverPool; +use Magento\GraphQlCache\Model\Resolver\IdentityPool; use Magento\GraphQlCache\Model\CacheableQuery; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit\Framework\TestCase; @@ -28,50 +28,50 @@ class CacheableQueryHandlerTest extends TestCase private $requestMock; - private $identityResolverPoolMock; + private $identityPoolMock; protected function setup(): void { $objectManager = new ObjectManager($this); $this->cacheableQueryMock = $this->createMock(CacheableQuery::class); $this->requestMock = $this->createMock(Http::class); - $this->identityResolverPoolMock = $this->createMock(IdentityResolverPool::class); + $this->identityPoolMock = $this->createMock(IdentityPool::class); $this->cacheableQueryHandler = $objectManager->getObject( CacheableQueryHandler::class, [ 'cacheableQuery' => $this->cacheableQueryMock, 'request' => $this->requestMock, - 'identityResolverPool' => $this->identityResolverPoolMock + 'identityPool' => $this->identityPoolMock ] ); } /** * @param array $resolvedData - * @param array $resolvedIdentities + * @param array $identities * @dataProvider resolvedDataProvider */ public function testhandleCacheFromResolverResponse( array $resolvedData, - array $resolvedIdentities, + array $identities, array $expectedCacheTags ): void { $cacheData = [ - 'cacheIdentityResolver' => IdentityResolverInterface::class, + 'cacheIdentity' => IdentityInterface::class, 'cacheTag' => 'cat_p' ]; $fieldMock = $this->createMock(Field::class); - $mockIdentityResolver = $this->getMockBuilder($cacheData['cacheIdentityResolver']) - ->setMethods(['getIdentifiers']) + $mockIdentity = $this->getMockBuilder($cacheData['cacheIdentity']) + ->setMethods(['getIdentities']) ->getMockForAbstractClass(); $this->requestMock->expects($this->once())->method('isGet')->willReturn(true); - $this->identityResolverPoolMock->expects($this->once())->method('get')->willReturn($mockIdentityResolver); + $this->identityPoolMock->expects($this->once())->method('get')->willReturn($mockIdentity); $fieldMock->expects($this->once())->method('getCache')->willReturn($cacheData); - $mockIdentityResolver->expects($this->once()) - ->method('getIdentifiers') + $mockIdentity->expects($this->once()) + ->method('getIdentities') ->with($resolvedData) - ->willReturn($resolvedIdentities); + ->willReturn($identities); $this->cacheableQueryMock->expects($this->once())->method('addCacheTags')->with($expectedCacheTags); $this->cacheableQueryMock->expects($this->once())->method('isCacheable')->willReturn(true); $this->cacheableQueryMock->expects($this->once())->method('setCacheValidity')->with(true); @@ -91,7 +91,7 @@ public function resolvedDataProvider(): array "name" => "TesName", "sku" => "TestSku" ], - "resolvedIdentities" => [10], + "identities" => [10], "expectedCacheTags" => ["cat_p", "cat_p_10"] ] ]; diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php index f7c2597fe571..c7c9c04c5eac 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/query_array_output.php @@ -35,7 +35,7 @@ 'description' => 'Returns the attribute type, given an attribute code and entity type', 'cache' => [ 'cacheTag' => 'cat_test', - 'cacheIdentityResolver' => 'Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata' + 'cacheIdentity' => 'Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata' ] ], 'products' => [ diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls index 895185bc6dd2..92682468c42b 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/_files/schemaC.graphqls @@ -1,6 +1,6 @@ type Query { customAttributeMetadata(attributes: [AttributeInput!]!): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") - @doc(description: "Returns the attribute type, given an attribute code and entity type") @cache(cacheTag: "cat_test", cacheIdentityResolver: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") + @doc(description: "Returns the attribute type, given an attribute code and entity type") @cache(cacheTag: "cat_test", cacheIdentity: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") } type CustomAttributeMetadata { diff --git a/lib/internal/Magento/Framework/GraphQl/Query/IdentityResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/IdentityInterface.php similarity index 53% rename from lib/internal/Magento/Framework/GraphQl/Query/IdentityResolverInterface.php rename to lib/internal/Magento/Framework/GraphQl/Query/Resolver/IdentityInterface.php index 588052c8df6e..b0cad2f133a7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/IdentityResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/IdentityInterface.php @@ -5,16 +5,16 @@ */ declare(strict_types=1); -namespace Magento\Framework\GraphQl\Query; +namespace Magento\Framework\GraphQl\Query\Resolver; -interface IdentityResolverInterface +interface IdentityInterface { /** - * Get identifiers from resolved data + * Get identities from resolved data * * @param array $resolvedData * @return array */ - public function getIdentifiers(array $resolvedData) : array; + public function getIdentities(array $resolvedData) : array; } diff --git a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php index ae7ee4a1ec38..666dfa8d3e8a 100644 --- a/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php +++ b/lib/internal/Magento/Framework/GraphQlSchemaStitching/GraphQlReader/MetaReader/CacheTagReader.php @@ -36,10 +36,10 @@ public function read(\GraphQL\Language\AST\NodeList $directives) : array ["cacheable" => $directiveArgument->value->value] ); } - if ($directiveArgument->name->value == 'cacheIdentityResolver') { + if ($directiveArgument->name->value == 'cacheIdentity') { $argMap = array_merge( $argMap, - ["cacheIdentityResolver" => $directiveArgument->value->value] + ["cacheIdentity" => $directiveArgument->value->value] ); } } From 67fc3e3ed7eaeff5d6075a611e0693cce9c18c9a Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Fri, 19 Apr 2019 16:31:29 -0500 Subject: [PATCH 157/247] GraphQL-597: Test coverage for cart-not cached test - refactor test --- .../PageCache/Quote/Guest/CartCacheTest.php | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php index 0ef60e1fbde3..34cc50e891dc 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php @@ -10,16 +10,15 @@ use Magento\TestFramework\TestCase\GraphQlAbstract; /** - * End to end test which creates an empty cart and add product to the cart and load the cart. - * Validates that the cache-debug header is a MISS for any subsequent cart requests + * Test cart queries are note cached * * @magentoApiDataFixture Magento/Catalog/_files/products.php */ class CartCacheTest extends GraphQlAbstract { - /** @var string */ - private $maskedQuoteId; - + /** + * @inheritdoc + */ protected function setUp() { $this->markTestSkipped( @@ -27,26 +26,22 @@ protected function setUp() ); } - /** - * Tests that X-Magento-Tags are correct - */ public function testCartIsNotCached() { $qty = 2; $sku = 'simple'; $cartId = $this->createEmptyCart(); $this->addSimpleProductToCart($cartId, $qty, $sku); - $getCartQuery = $this->checkCart($cartId); - $response = $this->graphQlQuery($getCartQuery); - self::assertArrayHasKey('cart', $response); - self::assertArrayHasKey('items', $response['cart']); - $responseMissHeaders = $this->graphQlQueryForHttpHeaders($getCartQuery); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeaders); + $getCartQuery = $this->getCartQuery($cartId); + $responseMiss = $this->graphQlQueryWithResponseHeaders($getCartQuery); + $this->assertArrayHasKey('cart', $responseMiss['body']); + $this->assertArrayHasKey('items', $responseMiss['body']['cart']); + $this->assertEquals('MISS', $responseMiss['headers']['X-Magento-Cache-Debug']); /** Cache debug header value is still a MISS for any subsequent request */ - $responseMissHeadersNext = $this->graphQlQueryForHttpHeaders($getCartQuery); - $this->assertContains('X-Magento-Cache-Debug: MISS', $responseMissHeadersNext); + $responseMissNext = $this->graphQlQueryWithResponseHeaders($getCartQuery); + $this->assertEquals('MISS', $responseMissNext['headers']['X-Magento-Cache-Debug']); } /** @@ -65,12 +60,13 @@ private function createEmptyCart(): string QUERY; $response = $this->graphQlMutation($query); - $this->maskedQuoteId = $response['createEmptyCart']; - return $this->maskedQuoteId; + $maskedQuoteId = $response['createEmptyCart']; + return $maskedQuoteId; } /** * Add simple product to the cart using the maskedQuoteId + * * @param $maskedCartId * @param $qty * @param $sku @@ -109,11 +105,12 @@ private function addSimpleProductToCart($maskedCartId, $qty, $sku) } /** + * Get cart query string * * @param string $maskedQuoteId * @return string */ - private function checkCart(string $maskedQuoteId): string + private function getCartQuery(string $maskedQuoteId): string { return << Date: Fri, 19 Apr 2019 17:04:17 -0500 Subject: [PATCH 158/247] Updated test changes for the CartCacheTest and ProductsCacheTest --- .../PageCache/Quote/Guest/CartCacheTest.php | 4 +- .../Controller/Catalog/ProductsCacheTest.php | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php index a40912fa1bb5..176fa0dff2f0 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php @@ -38,7 +38,7 @@ public function testCartIsNotCached() $this->assertArrayHasKey('cart', $responseMiss['body']); $this->assertArrayHasKey('items', $responseMiss['body']['cart']); $this->assertEquals('MISS', $responseMiss['headers']['X-Magento-Cache-Debug']); - + /** Cache debug header value is still a MISS for any subsequent request */ $responseMissNext = $this->graphQlQueryWithResponseHeaders($getCartQuery); $this->assertEquals('MISS', $responseMissNext['headers']['X-Magento-Cache-Debug']); @@ -105,7 +105,7 @@ private function addSimpleProductToCart($maskedCartId, $qty, $sku) } /** - * Get Check Cart query + * Get cart query string * * @param string $maskedQuoteId * @return string diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index a544e5355454..d0b95b20656c 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -17,6 +17,7 @@ * * @magentoAppArea graphql * @magentoCache full_page enabled + * @magentoDbIsolation disabled */ class ProductsCacheTest extends AbstractGraphqlCacheTest { @@ -39,6 +40,7 @@ protected function setUp(): void $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); $this->request = $this->objectManager->create(Http::class); } + /** * Test request is dispatched and response is checked for debug headers and cache tags * @@ -83,4 +85,41 @@ public function testToCheckRequestCacheTagsForProducts(): void $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; $this->assertEquals($expectedCacheTags, $actualCacheTags); } + + /** + * Test request is checked for debug headers and no cache tags for not existing product + */ + public function testToCheckRequestNoTagsForProducts(): void + { + $query + = <<request->setPathInfo('/graphql'); + $this->request->setMethod('GET'); + $this->request->setQueryValue('query', $query); + /** @var \Magento\Framework\Controller\Result\Json $result */ + $result = $this->graphqlController->dispatch($this->request); + /** @var \Magento\Framework\App\Response\Http $response */ + $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); + /** @var $registry \Magento\Framework\Registry */ + $result->renderResult($response); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = [ 'FPC']; + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } } From 9205c6fa88e3de4ac09e48a85cd193507d47e1f7 Mon Sep 17 00:00:00 2001 From: Nazarn96 Date: Fri, 19 Apr 2019 12:19:00 +0300 Subject: [PATCH 159/247] PUT /V1/products/:sku/media/:entryId does not change the file --- .../Catalog/Model/Product/Gallery/GalleryManagement.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 0e08b0af9286..9e5cf084c25a 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -105,7 +105,10 @@ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) if ($existingEntry->getId() == $entry->getId()) { $found = true; - if ($entry->getFile()) { + + $file = $entry->getContent(); + + if ($file && $file->getBase64EncodedData() || $entry->getFile()) { $entry->setId(null); } $existingMediaGalleryEntries[$key] = $entry; From 0ef9ba0678f387b8b74ee23e4487a2200176ecee Mon Sep 17 00:00:00 2001 From: eugene-shab Date: Sat, 20 Apr 2019 14:13:13 +0300 Subject: [PATCH 160/247] Update cartAddressId through cart billing address. --- .../QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php index fccda9e28c11..d4e3923846b3 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodsOnCart.php @@ -60,9 +60,8 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s } $methodCode = $shippingMethodInput['method_code']; -// $quoteAddress = $this->getQuoteAddress->execute($cart, $context->getUserId()); -// $this->assignShippingMethodToCart->execute($cart, $quoteAddress, $carrierCode, $methodCode); - $quoteAddress = $cart->getShippingAddress(); + $cartAddressId = $cart->getBillingAddress()->getId(); + $quoteAddress = $this->getQuoteAddress->execute($cart, $cartAddressId, $context->getUserId()); $this->assignShippingMethodToCart->execute($cart, $quoteAddress, $carrierCode, $methodCode); } } From 0c1ffcd398d09adf28abcfd5d3c5d3d253a4b2d4 Mon Sep 17 00:00:00 2001 From: Yannis Livasov Date: Tue, 9 Apr 2019 02:40:24 +0300 Subject: [PATCH 161/247] Shortening currency list in Configuration->General use isset array_flip --- .../Model/Config/Source/Locale/Currency.php | 64 ++++++++++++++++--- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Config/Model/Config/Source/Locale/Currency.php b/app/code/Magento/Config/Model/Config/Source/Locale/Currency.php index b3474674cf76..5beff0d043ad 100644 --- a/app/code/Magento/Config/Model/Config/Source/Locale/Currency.php +++ b/app/code/Magento/Config/Model/Config/Source/Locale/Currency.php @@ -4,12 +4,15 @@ * See COPYING.txt for license details. */ -/** - * Locale currency source - */ namespace Magento\Config\Model\Config\Source\Locale; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Locale\ListsInterface; + /** + * Locale currency source. + * * @api * @since 100.0.2 */ @@ -21,27 +24,70 @@ class Currency implements \Magento\Framework\Option\ArrayInterface protected $_options; /** - * @var \Magento\Framework\Locale\ListsInterface + * @var ListsInterface */ protected $_localeLists; /** - * @param \Magento\Framework\Locale\ListsInterface $localeLists + * @var ScopeConfigInterface */ - public function __construct(\Magento\Framework\Locale\ListsInterface $localeLists) - { + private $config; + + /** + * @var array + */ + private $installedCurrencies; + + /** + * @param ListsInterface $localeLists + * @param ScopeConfigInterface $config + */ + public function __construct( + ListsInterface $localeLists, + ScopeConfigInterface $config = null + ) { $this->_localeLists = $localeLists; + $this->config = $config ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class); } /** - * @return array + * @inheritdoc */ public function toOptionArray() { if (!$this->_options) { $this->_options = $this->_localeLists->getOptionCurrencies(); } - $options = $this->_options; + + $selected = array_flip($this->getInstalledCurrencies()); + + $options = array_filter( + $this->_options, + function ($option) use ($selected) { + return isset($selected[$option['value']]); + } + ); + return $options; } + + /** + * Retrieve Installed Currencies. + * + * @return array + */ + private function getInstalledCurrencies() + { + if (!$this->installedCurrencies) { + $this->installedCurrencies = explode( + ',', + $this->config->getValue( + 'system/currency/installed', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ) + ); + } + + return $this->installedCurrencies; + } } From c7da38b4b8d364235871919d5e1fbf21cbcc95b5 Mon Sep 17 00:00:00 2001 From: eugene-shab Date: Sat, 20 Apr 2019 20:07:14 +0300 Subject: [PATCH 162/247] Updates. --- .../Quote/Guest/SetOfflineShippingMethodsOnCartTest.php | 9 ++------- .../GraphQl/Quote/Guest/SetShippingMethodsOnCartTest.php | 5 +---- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflineShippingMethodsOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflineShippingMethodsOnCartTest.php index 2c1333aa7732..a89419b51df4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflineShippingMethodsOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflineShippingMethodsOnCartTest.php @@ -56,13 +56,11 @@ protected function setUp() public function testSetOfflineShippingMethod(string $carrierCode, string $methodCode, float $amount, string $label) { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - $quoteAddressId = $this->getQuoteShippingAddressIdByReservedQuoteId->execute('test_quote'); $query = $this->getQuery( $maskedQuoteId, $methodCode, - $carrierCode, - $quoteAddressId + $carrierCode ); $response = $this->graphQlMutation($query); @@ -103,14 +101,12 @@ public function offlineShippingMethodDataProvider(): array * @param string $maskedQuoteId * @param string $shippingMethodCode * @param string $shippingCarrierCode - * @param int $shippingAddressId * @return string */ private function getQuery( string $maskedQuoteId, string $shippingMethodCode, - string $shippingCarrierCode, - int $shippingAddressId + string $shippingCarrierCode ): string { return <<getMaskedQuoteIdByReservedOrderId->execute('test_quote'); $carrierCode = 'flatrate'; $methodCode = 'flatrate'; - $quoteAddressId = $this->getQuoteShippingAddressIdByReservedQuoteId->execute('test_quote'); $query = $this->getQuery( $maskedQuoteId, $methodCode, - $carrierCode, - $quoteAddressId + $carrierCode ); $response = $this->graphQlMutation($query); @@ -425,7 +423,6 @@ private function getQuery( { cart_id: "$maskedQuoteId", shipping_methods: [{ - cart_address_id: $shippingAddressId carrier_code: "$shippingCarrierCode" method_code: "$shippingMethodCode" }] From f22e16b6f7bd84303cfd22dd5dc17d9a58b8101b Mon Sep 17 00:00:00 2001 From: Pieter Hoste Date: Sun, 21 Apr 2019 17:56:28 +0200 Subject: [PATCH 163/247] Removes usage of classes which don't exist from DB migration scripts. --- app/code/Magento/Catalog/Setup/CategorySetup.php | 3 --- .../Patch/Data/MigrateStoresAllowedCountriesToWebsite.php | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Setup/CategorySetup.php b/app/code/Magento/Catalog/Setup/CategorySetup.php index 271387932829..581a5bf48919 100644 --- a/app/code/Magento/Catalog/Setup/CategorySetup.php +++ b/app/code/Magento/Catalog/Setup/CategorySetup.php @@ -10,7 +10,6 @@ use Magento\Catalog\Block\Adminhtml\Category\Helper\Pricestep; use Magento\Catalog\Block\Adminhtml\Category\Helper\Sortby\Available; use Magento\Catalog\Block\Adminhtml\Category\Helper\Sortby\DefaultSortby; -use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\BaseImage; use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Category as CategoryFormHelper; use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Weight as WeightFormHelper; use Magento\Catalog\Model\Attribute\Backend\Customlayoutupdate; @@ -593,7 +592,6 @@ public function getDefaultEntities() 'label' => 'Base Image', 'input' => 'media_image', 'frontend' => ImageFrontendModel::class, - 'input_renderer' => BaseImage::class, 'required' => false, 'sort_order' => 0, 'global' => ScopedAttributeInterface::SCOPE_STORE, @@ -626,7 +624,6 @@ public function getDefaultEntities() 'type' => 'varchar', 'label' => 'Media Gallery', 'input' => 'gallery', - 'backend' => Media::class, 'required' => false, 'sort_order' => 4, 'group' => 'Images', diff --git a/app/code/Magento/Customer/Setup/Patch/Data/MigrateStoresAllowedCountriesToWebsite.php b/app/code/Magento/Customer/Setup/Patch/Data/MigrateStoresAllowedCountriesToWebsite.php index 7488f3fd4a92..8ed940250e21 100644 --- a/app/code/Magento/Customer/Setup/Patch/Data/MigrateStoresAllowedCountriesToWebsite.php +++ b/app/code/Magento/Customer/Setup/Patch/Data/MigrateStoresAllowedCountriesToWebsite.php @@ -8,7 +8,6 @@ use Magento\Directory\Model\AllowedCountries; use Magento\Framework\Setup\ModuleDataSetupInterface; -use Magento\Directory\Model\AllowedCountriesFactory; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; @@ -27,7 +26,7 @@ class MigrateStoresAllowedCountriesToWebsite implements DataPatchInterface, Patc private $storeManager; /** - * @var AllowedCountriesFactory + * @var AllowedCountries */ private $allowedCountries; From c4e4cbd105515d9207d5f802ae5ee32aa448babf Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Mon, 22 Apr 2019 12:37:37 +0300 Subject: [PATCH 164/247] magento/magento2#21787: Static test fix. --- app/code/Magento/Quote/Model/QuoteManagement.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index a7a9bf4efde8..0ad99ffe759f 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -299,6 +299,7 @@ public function assignCustomer($cartId, $customerId, $storeId) throw new StateException( __("The customer can't be assigned to the cart because the customer already has an active cart.") ); + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { } @@ -653,12 +654,14 @@ private function rollbackAddresses( 'exception' => $e, ] ); + // phpcs:ignore Magento2.Exceptions.ThrowCatch } catch (\Exception $consecutiveException) { $message = sprintf( "An exception occurred on 'sales_model_service_quote_submit_failure' event: %s", $consecutiveException->getMessage() ); + // phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception($message, 0, $e); } } From 1a5cb909c6d92ef262afa85675647bc29c20cb49 Mon Sep 17 00:00:00 2001 From: Nikita Fomin Date: Mon, 22 Apr 2019 14:50:14 +0300 Subject: [PATCH 165/247] MC-11925: Update Product from Mini Shopping Cart --- .../UpdateProductFromMiniShoppingCartEntityTest.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml index b4c97a11b914..4b99de09f2a7 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml @@ -26,7 +26,7 @@ - test_type:extended_acceptance_test, to_maintain:yes, severity:S0 + test_type:extended_acceptance_test, severity:S0 configurableProduct::default configurable_update_mini_shopping_cart @@ -35,7 +35,7 @@ - test_type:extended_acceptance_test, to_maintain:yes, severity:S0 + test_type:extended_acceptance_test, severity:S0 bundleProduct::bundle_fixed_product bundle_update_mini_shopping_cart @@ -44,7 +44,7 @@ - test_type:extended_acceptance_test, to_maintain:yes, severity:S1 + test_type:extended_acceptance_test, severity:S1 downloadableProduct::with_two_separately_links downloadable_update_mini_shopping_cart @@ -53,7 +53,7 @@ - test_type:extended_acceptance_test, to_maintain:yes, severity:S1 + test_type:extended_acceptance_test, severity:S1 catalogProductVirtual::default virtual_update_mini_shopping_cart From 24580ee3eb4c87cca94d73b9e377621750708234 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Mon, 22 Apr 2019 16:00:04 +0300 Subject: [PATCH 166/247] magento/magento2#22424: Static test fix. --- .../Magento/Catalog/Model/Product/Gallery/GalleryManagement.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 9e5cf084c25a..c993e51c8bc0 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -71,8 +71,10 @@ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) $product->setMediaGalleryEntries($existingMediaGalleryEntries); try { $product = $this->productRepository->save($product); + // phpcs:ignore Magento2.Exceptions.ThrowCatch } catch (InputException $inputException) { throw $inputException; + // phpcs:ignore Magento2.Exceptions.ThrowCatch } catch (\Exception $e) { throw new StateException(__("The product can't be saved.")); } From 27e048ff422c5d5b82b4b428ecabf4f1ac3622bf Mon Sep 17 00:00:00 2001 From: hiren pandya Date: Mon, 22 Apr 2019 18:52:15 +0530 Subject: [PATCH 167/247] Fixed issue of drop-down arrow direction in cart price rule --- app/design/adminhtml/Magento/backend/web/css/styles-old.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/styles-old.less b/app/design/adminhtml/Magento/backend/web/css/styles-old.less index 2dbe68ef96ee..c9e56abbba8d 100644 --- a/app/design/adminhtml/Magento/backend/web/css/styles-old.less +++ b/app/design/adminhtml/Magento/backend/web/css/styles-old.less @@ -820,7 +820,7 @@ padding-right: 44px; - &:focus { + &:active { background-image+: url('../images/arrows-bg.svg'); background-position+: ~'calc(100% - 12px)' 13px; From dd7cb583b112f82ba58ef87d612631ac0eb1c57c Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 22 Apr 2019 08:38:54 -0500 Subject: [PATCH 168/247] MAGETWO-99307: Authorize.net Transaction Fails but Order goes through --- .../TransactionResponseValidator.php | 10 +++--- .../TransactionResponseValidatorTest.php | 35 +++++++++++++------ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php index 93b5f2bb62a7..326f4fb29ac8 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php +++ b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php @@ -54,7 +54,7 @@ public function validate(array $validationSubject): ResultInterface if (isset($transactionResponse['messages']['message']['code'])) { $errorCodes[] = $transactionResponse['messages']['message']['code']; $errorMessages[] = $transactionResponse['messages']['message']['text']; - } elseif ($transactionResponse['messages']['message']) { + } elseif (isset($transactionResponse['messages']['message'])) { foreach ($transactionResponse['messages']['message'] as $message) { $errorCodes[] = $message['code']; $errorMessages[] = $message['description']; @@ -62,7 +62,7 @@ public function validate(array $validationSubject): ResultInterface } elseif (isset($transactionResponse['errors'])) { foreach ($transactionResponse['errors'] as $message) { $errorCodes[] = $message['errorCode']; - $errorMessages[] = $message['errorCode']; + $errorMessages[] = $message['errorText']; } } @@ -85,8 +85,10 @@ private function isResponseCodeAnError(array $transactionResponse): bool ?? $transactionResponse['errors'][0]['errorCode'] ?? null; - return in_array($transactionResponse['responseCode'], [self::RESPONSE_CODE_APPROVED, self::RESPONSE_CODE_HELD]) - && $code + return !in_array($transactionResponse['responseCode'], [ + self::RESPONSE_CODE_APPROVED, self::RESPONSE_CODE_HELD + ]) + || $code && !in_array( $code, [ diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionResponseValidatorTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionResponseValidatorTest.php index cef7883bd5db..1188c9c4107d 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionResponseValidatorTest.php +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionResponseValidatorTest.php @@ -19,9 +19,11 @@ class TransactionResponseValidatorTest extends TestCase { private const RESPONSE_CODE_APPROVED = 1; private const RESPONSE_CODE_HELD = 4; + private const RESPONSE_CODE_DENIED = 2; private const RESPONSE_REASON_CODE_APPROVED = 1; private const RESPONSE_REASON_CODE_PENDING_REVIEW_AUTHORIZED = 252; private const RESPONSE_REASON_CODE_PENDING_REVIEW = 253; + private const ERROR_CODE_AVS_MISMATCH = 27; /** * @var ResultInterfaceFactory|MockObject @@ -86,16 +88,6 @@ public function testValidateScenarios($transactionResponse, $isValid, $errorCode public function scenarioProvider() { return [ - // This validator only cares about successful edge cases so test for default behavior - [ - [ - 'responseCode' => 'foo', - ], - true, - [], - [] - ], - // Test for acceptable reason codes [ [ @@ -208,6 +200,29 @@ public function scenarioProvider() ['foo'], ['bar'] ], + [ + [ + 'responseCode' => self::RESPONSE_CODE_DENIED, + 'errors' => [ + [ + 'errorCode' => self::ERROR_CODE_AVS_MISMATCH, + 'errorText' => 'bar' + ] + ] + ], + false, + [self::ERROR_CODE_AVS_MISMATCH], + ['bar'] + ], + // This validator only cares about successful edge cases so test for default behavior + [ + [ + 'responseCode' => 'foo', + ], + false, + [], + [] + ], ]; } } From c8569b54a7735c6c0f627aa6856d64e7f7405f25 Mon Sep 17 00:00:00 2001 From: Aliaksei Yakimovich2 Date: Mon, 22 Apr 2019 12:47:46 +0300 Subject: [PATCH 169/247] MAGETWO-98947: UPS CGI url gateway to migrate from http to https - Uskiped related integration test; --- .../integration/testsuite/Magento/Ups/Model/CarrierTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php index fe4067cdc49f..b3ced0b84e27 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php @@ -8,6 +8,9 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\Quote\Model\Quote\Address\RateRequestFactory; +/** + * Integration tests for Carrier model class + */ class CarrierTest extends \PHPUnit\Framework\TestCase { /** @@ -64,12 +67,12 @@ public function testGetShipConfirmUrlLive() /** * @magentoConfigFixture current_store carriers/ups/active 1 + * @magentoConfigFixture current_store carriers/ups/type UPS * @magentoConfigFixture current_store carriers/ups/allowed_methods 1DA,GND * @magentoConfigFixture current_store carriers/ups/free_method GND */ public function testCollectFreeRates() { - $this->markTestSkipped('Test is blocked by MAGETWO-97467.'); $rateRequest = Bootstrap::getObjectManager()->get(RateRequestFactory::class)->create(); $rateRequest->setDestCountryId('US'); $rateRequest->setDestRegionId('CA'); From d8131f6539a50b178783474405eba402d9ef8bdc Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Mon, 22 Apr 2019 10:52:32 -0500 Subject: [PATCH 170/247] GraphQL-598: CMS Page Integration Test for Tag Cache Generation - Add api-functional test --- .../GraphQl/PageCache/Cms/PageCacheTest.php | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php new file mode 100644 index 000000000000..4939088f99d9 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php @@ -0,0 +1,155 @@ +markTestSkipped( + 'This test will stay skipped until DEVOPS-4924 is resolved' + ); + $this->pageByIdentifier = Bootstrap::getObjectManager()->get(GetPageByIdentifier::class); + } + + /** + * Test that X-Magento-Tags are correct + * + * @magentoApiDataFixture Magento/Cms/_files/pages.php + */ + public function testCacheTagsHaveExpectedValue() + { + $pageIdentifier = 'page100'; + $page = $this->pageByIdentifier->execute($pageIdentifier, 0); + $pageId = (int) $page->getId(); + + $query = $this->getPageQuery($pageId); + + //cache-debug should be a MISS on first request + $response = $this->graphQlQueryWithResponseHeaders($query); + + $this->assertArrayHasKey('X-Magento-Tags', $response['headers']); + $actualTags = explode(',', $response['headers']['X-Magento-Tags']); + $expectedTags = ["cms_p", "cms_p_{$pageId}", "FPC"]; + foreach ($expectedTags as $expectedTag) { + $this->assertContains($expectedTag, $actualTags); + } + } + + /** + * Test the second request for the same page will return a cached result + * + * @magentoApiDataFixture Magento/Cms/_files/pages.php + */ + public function testCacheIsUsedOnSecondRequest() + { + $pageIdentifier = 'page100'; + $page = $this->pageByIdentifier->execute($pageIdentifier, 0); + $pageId = (int) $page->getId(); + + $query = $this->getPageQuery($pageId); + + //cache-debug should be a MISS on first request + $responseMiss = $this->graphQlQueryWithResponseHeaders($query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseMiss['headers']); + $this->assertEquals('MISS', $responseMiss['headers']['X-Magento-Cache-Debug']); + + //cache-debug should be a HIT on second request + $responseHit = $this->graphQlQueryWithResponseHeaders($query); + $this->assertArrayHasKey('X-Magento-Cache-Debug', $responseHit['headers']); + $this->assertEquals('HIT', $responseHit['headers']['X-Magento-Cache-Debug']); + //cached data should be correct + $this->assertNotEmpty($responseHit['body']); + $this->assertArrayNotHasKey('errors', $responseHit['body']); + $pageData = $responseHit['body']['cmsPage']; + $this->assertEquals('Cms Page 100', $pageData['title']); + } + + /** + * Test that cache is invalidated when page is updated + * + * @magentoApiDataFixture Magento/Cms/_files/pages.php + */ + public function testCacheIsInvalidatedOnPageUpdate() + { + $page100Identifier = 'page100'; + $page100 = $this->pageByIdentifier->execute($page100Identifier, 0); + $page100Id = (int) $page100->getId(); + $pageBlankIdentifier = 'page_design_blank'; + $pageBlank = $this->pageByIdentifier->execute($pageBlankIdentifier, 0); + $pageBlankId = (int) $pageBlank->getId(); + + $page100Query = $this->getPageQuery($page100Id); + $pageBlankQuery = $this->getPageQuery($pageBlankId); + + //cache-debug should be a MISS on first request + $page100Miss = $this->graphQlQueryWithResponseHeaders($page100Query); + $this->assertEquals('MISS', $page100Miss['headers']['X-Magento-Cache-Debug']); + $pageBlankMiss = $this->graphQlQueryWithResponseHeaders($pageBlankQuery); + $this->assertEquals('MISS', $pageBlankMiss['headers']['X-Magento-Cache-Debug']); + + //cache-debug should be a HIT on second request + $page100Hit = $this->graphQlQueryWithResponseHeaders($page100Query); + $this->assertEquals('HIT', $page100Hit['headers']['X-Magento-Cache-Debug']); + $pageBlankHit = $this->graphQlQueryWithResponseHeaders($pageBlankQuery); + $this->assertEquals('HIT', $pageBlankHit['headers']['X-Magento-Cache-Debug']); + + $pageRepository = Bootstrap::getObjectManager()->get(PageRepository::class); + $newPageContent = 'New page content for blank page.'; + $pageBlank->setContent($newPageContent); + $pageRepository->save($pageBlank); + + //cache-debug should be a MISS after updating the page + $pageBlankMiss = $this->graphQlQueryWithResponseHeaders($pageBlankQuery); + $this->assertEquals('MISS', $pageBlankMiss['headers']['X-Magento-Cache-Debug']); + $page100Hit = $this->graphQlQueryWithResponseHeaders($page100Query); + $this->assertEquals('HIT', $page100Hit['headers']['X-Magento-Cache-Debug']); + //updated page data should be correct + $this->assertNotEmpty($pageBlankMiss['body']); + $pageData = $pageBlankMiss['body']['cmsPage']; + $this->assertArrayNotHasKey('errors', $pageBlankMiss['body']); + $this->assertEquals('Cms Page Design Blank', $pageData['title']); + $this->assertEquals($newPageContent, $pageData['content']); + } + + /** + * Get page query + * + * @param int $pageId + * @return string + */ + private function getPageQuery(int $pageId): string + { + $query = << Date: Mon, 22 Apr 2019 11:13:04 -0500 Subject: [PATCH 171/247] GraphQl-595: Category with Product (Integration Test for Tag Cache Generation) --- .../Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php index bb358d32278c..fc797b01658e 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -10,7 +10,6 @@ use Magento\Cms\Model\GetPageByIdentifier; use Magento\Framework\App\Request\Http; use Magento\GraphQl\Controller\GraphQl; -use Magento\Framework\App\ResponseInterface; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -76,7 +75,6 @@ public function testToCheckCmsPageRequestCacheTags(): void $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); From 59e1ff5eccdca5e0f2c9565231098645edb777fb Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Mon, 22 Apr 2019 11:13:04 -0500 Subject: [PATCH 172/247] GraphQl-595: Category with Product (Integration Test for Tag Cache Generation) --- .../Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php index bb358d32278c..fc797b01658e 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -10,7 +10,6 @@ use Magento\Cms\Model\GetPageByIdentifier; use Magento\Framework\App\Request\Http; use Magento\GraphQl\Controller\GraphQl; -use Magento\Framework\App\ResponseInterface; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -76,7 +75,6 @@ public function testToCheckCmsPageRequestCacheTags(): void $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); From 13606623917f8fa129823b9213472851788cdf49 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Mon, 22 Apr 2019 11:27:03 -0500 Subject: [PATCH 173/247] GraphQL-597: Test coverage for cart-not cached test --- .../Magento/GraphQl/PageCache/CacheTagTest.php | 2 +- .../GraphQl/PageCache/Quote/Guest/CartCacheTest.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php index e9ff8d93177c..23bcd342ec99 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php @@ -151,7 +151,7 @@ public function testCacheTagForCategoriesWithProduct() /** * Get Product query * - * @param string $productSku + * @param string $productSku * @return string */ private function getProductQuery(string $productSku): string diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php index 176fa0dff2f0..e09ee8bc969a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Quote/Guest/CartCacheTest.php @@ -10,7 +10,7 @@ use Magento\TestFramework\TestCase\GraphQlAbstract; /** - * Test cart queries are note cached + * Test cart queries are not cached * * @magentoApiDataFixture Magento/Catalog/_files/products.php */ @@ -67,11 +67,11 @@ private function createEmptyCart(): string /** * Add simple product to the cart using the maskedQuoteId * - * @param $maskedCartId - * @param $qty - * @param $sku + * @param string $maskedCartId + * @param int $qty + * @param string $sku */ - private function addSimpleProductToCart($maskedCartId, $qty, $sku) + private function addSimpleProductToCart(string $maskedCartId, int $qty, string $sku): void { $addProductToCartQuery = << Date: Mon, 22 Apr 2019 12:37:40 -0500 Subject: [PATCH 174/247] GraphQl-599: CMS Blocks (Integration Test for Tag Cache Generation) --- .../Magento/GraphQl/PageCache/Cms/BlockCacheTest.php | 6 ++---- .../Magento/GraphQl/PageCache/Cms/PageCacheTest.php | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php index 3e8c3e0c9b47..5182ff791f57 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/BlockCacheTest.php @@ -45,10 +45,8 @@ public function testCacheTagsHaveExpectedValue() $this->assertArrayHasKey('X-Magento-Tags', $response['headers']); $actualTags = explode(',', $response['headers']['X-Magento-Tags']); - $expectedTags = ["cms_b", "cms_b_{$blockIdentifier}", "cms_b_{$blockId}", "FPC"]; - foreach ($expectedTags as $expectedTag) { - $this->assertContains($expectedTag, $actualTags); - } + $expectedTags = ["cms_b", "cms_b_{$blockId}", "cms_b_{$blockIdentifier}", "FPC"]; + $this->assertEquals($expectedTags, $actualTags); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php index 4939088f99d9..34dc9eef4c33 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/Cms/PageCacheTest.php @@ -52,9 +52,7 @@ public function testCacheTagsHaveExpectedValue() $this->assertArrayHasKey('X-Magento-Tags', $response['headers']); $actualTags = explode(',', $response['headers']['X-Magento-Tags']); $expectedTags = ["cms_p", "cms_p_{$pageId}", "FPC"]; - foreach ($expectedTags as $expectedTag) { - $this->assertContains($expectedTag, $actualTags); - } + $this->assertEquals($expectedTags, $actualTags); } /** From c018ba3fce2d1d9cc8cfc899f1e0c0eb2bb6291f Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Mon, 22 Apr 2019 12:44:08 -0500 Subject: [PATCH 175/247] GraphQl-599: CMS Blocks (Integration Test for Tag Cache Generation) --- .../Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php index 58e665c057f0..6e9d2ca0f491 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php @@ -77,8 +77,6 @@ public function testCmsBlocksRequestHasCorrectTags(): void $expectedCacheTags = ['cms_b', 'cms_b_' . $block->getId(), 'cms_b_' . $block->getIdentifier(), 'FPC']; $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); $actualCacheTags = explode(',', $rawActualCacheTags); - foreach ($expectedCacheTags as $expectedCacheTag) { - $this->assertContains($expectedCacheTag, $actualCacheTags); - } + $this->assertEquals($expectedCacheTags, $actualCacheTags); } } From 9a82db00ccfb5085478b3195e4c0cff8b64cbc60 Mon Sep 17 00:00:00 2001 From: Anusha Vattam Date: Mon, 22 Apr 2019 13:07:34 -0500 Subject: [PATCH 176/247] GraphQL-600: Integration test for simple Products query - test for cache tag and cache debug headers - Fixed review comments --- .../GraphQlCache/Controller/Catalog/ProductsCacheTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index d0b95b20656c..ec55bfcb4928 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -115,11 +115,10 @@ public function testToCheckRequestNoTagsForProducts(): void $result = $this->graphqlController->dispatch($this->request); /** @var \Magento\Framework\App\Response\Http $response */ $response = $this->objectManager->get(\Magento\Framework\App\Response\Http::class); - /** @var $registry \Magento\Framework\Registry */ $result->renderResult($response); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = [ 'FPC']; + $expectedCacheTags = ['FPC']; $this->assertEquals($expectedCacheTags, $actualCacheTags); } } From c295e5449fc87ca427f610dedce797360cb66778 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 22 Apr 2019 14:58:21 -0500 Subject: [PATCH 177/247] Issue-230: adding varnish - fixing messages --- .../Controller/HttpRequestValidator/CurrencyValidator.php | 4 ++-- .../Controller/HttpRequestValidator/StoreValidator.php | 2 +- .../Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php | 2 +- .../GraphQl/PageCache/ProductInMultipleStoresCacheTest.php | 6 +++--- .../Magento/GraphQl/Quote/Customer/GetCartTest.php | 2 +- .../testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php b/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php index 6c0d4ec2e7be..7dab90802c20 100644 --- a/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php +++ b/app/code/Magento/DirectoryGraphQl/Controller/HttpRequestValidator/CurrencyValidator.php @@ -48,14 +48,14 @@ public function validate(HttpRequestInterface $request): void $currentStore = $this->storeManager->getStore(); if (!in_array($headerCurrency, $currentStore->getAvailableCurrencyCodes(true))) { throw new GraphQlInputException( - __('Currency not allowed for store %1', [$currentStore->getCode()]) + __('Please correct the target currency') ); } } } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { $this->storeManager->setCurrentStore(null); throw new GraphQlInputException( - __("The store that was requested wasn't found. Verify the store and try again.") + __("Requested store is not found") ); } } diff --git a/app/code/Magento/StoreGraphQl/Controller/HttpRequestValidator/StoreValidator.php b/app/code/Magento/StoreGraphQl/Controller/HttpRequestValidator/StoreValidator.php index afc84c061df4..144905d72814 100644 --- a/app/code/Magento/StoreGraphQl/Controller/HttpRequestValidator/StoreValidator.php +++ b/app/code/Magento/StoreGraphQl/Controller/HttpRequestValidator/StoreValidator.php @@ -48,7 +48,7 @@ public function validate(HttpRequestInterface $request): void if (strtolower($storeCode) !== 'default') { $this->storeManager->setCurrentStore(null); throw new GraphQlInputException( - __("The store that was requested wasn't found. Verify the store and try again.") + __("Requested store is not found") ); } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php index d49eef8a887e..d17b434f39d9 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductInMultipleStoresTest.php @@ -97,7 +97,7 @@ public function testProductFromSpecificAndDefaultStore() $nonExistingStoreCode = "non_existent_store"; $headerMapInvalidStoreCode = ['Store' => $nonExistingStoreCode]; $this->expectException(\Exception::class); - $this->expectExceptionMessage('The store that was requested wasn\'t found. Verify the store and try again.'); + $this->expectExceptionMessage('Requested store is not found'); $this->graphQlQuery($query, [], '', $headerMapInvalidStoreCode); } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php index 12cd8894659b..cf4cebdfe8e4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/ProductInMultipleStoresCacheTest.php @@ -118,7 +118,7 @@ public function testProductFromSpecificAndDefaultStoreWithMultiCurrencyNonExisti //test non existing currency $headerMap = ['Store' => 'default', 'Content-Currency' => 'someNonExistentCurrency']; - $this->expectExceptionMessage('GraphQL response contains errors: Currency not allowed for store default'); + $this->expectExceptionMessage('GraphQL response contains errors: Please correct the target currency'); $this->graphQlQuery($query, [], '', $headerMap); } @@ -166,7 +166,7 @@ public function testProductFromSpecificAndDefaultStoreWithMultiCurrencyNotAllowe //test not allowed existing currency $headerMap = ['Store' => $storeCodeFromFixture, 'Content-Currency' => 'CAD']; $this->expectExceptionMessage( - "GraphQL response contains errors: Currency not allowed for store {$storeCodeFromFixture}" + 'GraphQL response contains errors: Please correct the target currency' ); $this->graphQlQuery($query, [], '', $headerMap); } @@ -315,7 +315,7 @@ public function testProductFromSpecificAndDefaultStoreWithMultiCurrency() // test cached response store + currency header with non existing currency, and no valid response, no cache $headerMap = ['Store' => $storeCodeFromFixture, 'Content-Currency' => 'SOMECURRENCY']; $this->expectExceptionMessage( - "GraphQL response contains errors: Currency not allowed for store {$storeCodeFromFixture}" + 'GraphQL response contains errors: Please correct the target currency' ); $this->graphQlQuery($query, [], '', $headerMap); } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php index a19ad16cf60c..60790aacb37b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCartTest.php @@ -163,7 +163,7 @@ public function testGetCartWithWrongStore() * @magentoApiDataFixture Magento/Checkout/_files/active_quote_customer_not_default_store.php * * @expectedException \Exception - * @expectedExceptionMessage The store that was requested wasn't found. Verify the store and try again. + * @expectedExceptionMessage Requested store is not found */ public function testGetCartWithNotExistingStore() { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php index 2678cf1be154..8e4feb1d48e8 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetCartTest.php @@ -133,7 +133,7 @@ public function testGetCartWithWrongStore() * @magentoApiDataFixture Magento/Checkout/_files/active_quote_guest_not_default_store.php * * @expectedException \Exception - * @expectedExceptionMessage The store that was requested wasn't found. Verify the store and try again. + * @expectedExceptionMessage Requested store is not found */ public function testGetCartWithNotExistingStore() { From d7006f19794e27265e15ef87e022e98b9e01e63e Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Mon, 22 Apr 2019 15:03:03 -0500 Subject: [PATCH 178/247] Issue-230: adding varnish - removing new phrase because it's not allowed in a patch release --- app/code/Magento/Directory/i18n/en_US.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Directory/i18n/en_US.csv b/app/code/Magento/Directory/i18n/en_US.csv index 79a99eb97fec..3dcd2ceebf13 100644 --- a/app/code/Magento/Directory/i18n/en_US.csv +++ b/app/code/Magento/Directory/i18n/en_US.csv @@ -52,4 +52,3 @@ Service,Service "The """%1"" is not allowed as base currency for your subscription plan.","The """%1"" is not allowed as base currency for your subscription plan." "An invalid base currency has been entered.","An invalid base currency has been entered." "Currency rates can't be retrieved.","Currency rates can't be retrieved." -"Currency not allowed for store %1","Currency not allowed for store %1" \ No newline at end of file From 6e809c1f42bb612cb1450f56f62970a2420dd489 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 22 Apr 2019 15:09:08 -0500 Subject: [PATCH 179/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- dev/tests/integration/framework/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php index 1cae393dc01c..56cffaa0c8ea 100644 --- a/dev/tests/integration/framework/bootstrap.php +++ b/dev/tests/integration/framework/bootstrap.php @@ -132,7 +132,7 @@ function ($errNo, $errStr, $errFile, $errLine) { $errName = isset($errorNames[$errNo]) ? $errorNames[$errNo] : ""; throw new \PHPUnit\Framework\Exception( - sprintf("%s: %s in %s:%s.", $errName, $errStr, $errFile, $errLine), + sprintf("%s: %s in %s:%s.\n\n%s\n\n", $errName, $errStr, $errFile, $errLine, debug_backtrace()), $errNo ); } From 47847759a72f77c7b51ff1df1d9ecd63357dacbd Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 22 Apr 2019 17:09:29 -0500 Subject: [PATCH 180/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- lib/internal/Magento/Framework/Session/SessionManager.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php index c7d201676b22..db2c6ff47f39 100644 --- a/lib/internal/Magento/Framework/Session/SessionManager.php +++ b/lib/internal/Magento/Framework/Session/SessionManager.php @@ -165,6 +165,9 @@ public function __call($method, $args) sprintf('Invalid method %s::%s(%s)', get_class($this), $method, print_r($args, 1)) ); } + if (!($this->storage instanceof StorageInterface)) { + throw new \RuntimeException('Not storage'); + } $return = call_user_func_array([$this->storage, $method], $args); return $return === $this->storage ? $this : $return; } From dfbeeabdf8c04e98799edcc4016bf10e999dd8ba Mon Sep 17 00:00:00 2001 From: Andrii-Deineha Date: Tue, 23 Apr 2019 13:54:13 +0300 Subject: [PATCH 181/247] MC-11940: Create Product Attribute --- .../ProductAttribute/CreateProductAttributeEntityTest.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml index 2287546aed10..49725d08b63e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml @@ -8,7 +8,6 @@ - to_maintain:yes custom_attribute_set Text_Field_Admin_%isolation% Text Field @@ -60,7 +59,6 @@ Yes Yes Yes - to_maintain:yes @@ -69,7 +67,6 @@ - to_maintain:yes custom_attribute_set Yes/No_Admin_%isolation% Yes/No @@ -86,6 +83,7 @@ + mftf_migrated:yes custom_attribute_set Multiple_Select_Admin_%isolation% Multiple Select @@ -102,7 +100,6 @@ Yes Yes Yes - to_maintain:yes @@ -178,7 +175,6 @@ - to_maintain:yes custom_attribute_set Fixed_Product_Tax_Admin_%isolation% Fixed Product Tax @@ -195,7 +191,6 @@ - to_maintain:yes custom_attribute_set Text_Field_Admin_%isolation% Text Field From c433cbd6fa29384bc1e0d2a760baeb83f8f53438 Mon Sep 17 00:00:00 2001 From: Bohdan Shevchenko <1408sheva@gmail.com> Date: Tue, 23 Apr 2019 14:43:14 +0300 Subject: [PATCH 182/247] MC-11930: Create Grouped Product --- .../Test/TestCase/CreateGroupedProductEntityTest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml index 39f4fd08bb92..f397c1b99e3b 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml @@ -57,7 +57,6 @@ - stable:no test-grouped-product-%isolation% GroupedProduct %isolation% GroupedProduct_sku%isolation% @@ -110,7 +109,6 @@ - stable:no test-grouped-product-%isolation% GroupedProduct %isolation% GroupedProduct_sku%isolation% From d8d8fed62ea570359c6cc60227b338dbb79d00a2 Mon Sep 17 00:00:00 2001 From: Dan Farmer Date: Tue, 23 Apr 2019 15:52:57 +0100 Subject: [PATCH 183/247] Use final price rather than base price to calculate price increases / decreases on the configurable attribute dropdown. This fixes a bug introduced in PR #17695 as detailed on issue #22270 --- .../ConfigurableProduct/view/frontend/web/js/configurable.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index e73296042154..ef40dcb9a732 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -373,7 +373,7 @@ define([ allowedProducts, i, j, - basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount), + finalPrice = parseFloat(this.options.spConfig.prices.finalPrice.amount), optionFinalPrice, optionPriceDiff, optionPrices = this.options.spConfig.optionPrices, @@ -410,7 +410,7 @@ define([ typeof optionPrices[allowedProducts[0]] !== 'undefined') { allowedProductMinPrice = this._getAllowedProductWithMinPrice(allowedProducts); optionFinalPrice = parseFloat(optionPrices[allowedProductMinPrice].finalPrice.amount); - optionPriceDiff = optionFinalPrice - basePrice; + optionPriceDiff = optionFinalPrice - finalPrice; if (optionPriceDiff !== 0) { options[i].label = options[i].label + ' ' + priceUtils.formatPrice( From 9e4ca95accf142534b7ba02ccfe38ff4a1188940 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 23 Apr 2019 11:58:04 -0500 Subject: [PATCH 184/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- lib/internal/Magento/Framework/Session/SessionManager.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php index db2c6ff47f39..c7d201676b22 100644 --- a/lib/internal/Magento/Framework/Session/SessionManager.php +++ b/lib/internal/Magento/Framework/Session/SessionManager.php @@ -165,9 +165,6 @@ public function __call($method, $args) sprintf('Invalid method %s::%s(%s)', get_class($this), $method, print_r($args, 1)) ); } - if (!($this->storage instanceof StorageInterface)) { - throw new \RuntimeException('Not storage'); - } $return = call_user_func_array([$this->storage, $method], $args); return $return === $this->storage ? $this : $return; } From 70525414941d8293049cc4c52847ef4e58158768 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 23 Apr 2019 11:58:27 -0500 Subject: [PATCH 185/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- dev/tests/integration/framework/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php index 56cffaa0c8ea..1cae393dc01c 100644 --- a/dev/tests/integration/framework/bootstrap.php +++ b/dev/tests/integration/framework/bootstrap.php @@ -132,7 +132,7 @@ function ($errNo, $errStr, $errFile, $errLine) { $errName = isset($errorNames[$errNo]) ? $errorNames[$errNo] : ""; throw new \PHPUnit\Framework\Exception( - sprintf("%s: %s in %s:%s.\n\n%s\n\n", $errName, $errStr, $errFile, $errLine, debug_backtrace()), + sprintf("%s: %s in %s:%s.", $errName, $errStr, $errFile, $errLine), $errNo ); } From 8b714b0dd22bcde3f33c2f65702596986ba10dcf Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 23 Apr 2019 12:06:03 -0500 Subject: [PATCH 186/247] MAGETWO-96975: Remove __sleep and __wakeup from code --- app/code/Magento/Authorization/Model/Role.php | 4 ++-- .../Magento/Catalog/Model/ResourceModel/Eav/Attribute.php | 4 ++-- app/code/Magento/Config/Model/Config/Backend/Encrypted.php | 4 ++-- .../Model/Product/Type/Configurable/Attribute.php | 4 ++-- .../Product/Type/Configurable/Attribute/Collection.php | 4 ++-- app/code/Magento/Customer/Model/Attribute.php | 4 ++-- app/code/Magento/Eav/Model/Entity/Attribute.php | 4 ++-- .../Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php | 4 ++-- app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php | 4 ++-- app/code/Magento/Store/Model/Store.php | 4 ++-- app/code/Magento/User/Model/User.php | 4 ++-- lib/internal/Magento/Framework/App/AreaList/Proxy.php | 4 ++-- lib/internal/Magento/Framework/App/Response/Http.php | 4 ++-- .../Magento/Framework/App/Route/ConfigInterface/Proxy.php | 4 ++-- lib/internal/Magento/Framework/DB/Select.php | 4 ++-- lib/internal/Magento/Framework/DB/Select/RendererProxy.php | 4 ++-- lib/internal/Magento/Framework/Data/Collection.php | 4 ++-- lib/internal/Magento/Framework/Data/Collection/AbstractDb.php | 4 ++-- .../Magento/Framework/DataObject/Copy/Config/Data/Proxy.php | 4 ++-- lib/internal/Magento/Framework/Interception/Interceptor.php | 4 ++-- .../Magento/Framework/Model/AbstractExtensibleModel.php | 4 ++-- lib/internal/Magento/Framework/Model/AbstractModel.php | 4 ++-- .../Magento/Framework/Model/ResourceModel/Db/AbstractDb.php | 4 ++-- .../Model/ResourceModel/Db/Collection/AbstractCollection.php | 4 ++-- lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php | 4 ++-- lib/internal/Magento/Framework/Translate/Inline/Proxy.php | 4 ++-- lib/internal/Magento/Framework/View/Layout/Proxy.php | 4 ++-- 27 files changed, 54 insertions(+), 54 deletions(-) diff --git a/app/code/Magento/Authorization/Model/Role.php b/app/code/Magento/Authorization/Model/Role.php index dcc46ee77ee1..757c80f9bca3 100644 --- a/app/code/Magento/Authorization/Model/Role.php +++ b/app/code/Magento/Authorization/Model/Role.php @@ -58,7 +58,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = parent::__sleep(); return array_diff($properties, ['_resource', '_resourceCollection']); @@ -72,7 +72,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php index d56cc40ad0fc..29e4547d7d2b 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php @@ -851,7 +851,7 @@ public function afterDelete() */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->unsetData('entity_type'); return array_diff( @@ -869,7 +869,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/app/code/Magento/Config/Model/Config/Backend/Encrypted.php b/app/code/Magento/Config/Model/Config/Backend/Encrypted.php index ea3b1d4c74a5..44f29078d607 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Encrypted.php +++ b/app/code/Magento/Config/Model/Config/Backend/Encrypted.php @@ -56,7 +56,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = parent::__sleep(); return array_diff($properties, ['_encryptor']); @@ -72,7 +72,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $this->_encryptor = \Magento\Framework\App\ObjectManager::getInstance()->get( diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php index 4ead9ffe0fe7..514d76405fc7 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php @@ -271,7 +271,7 @@ public function setProductId($value) */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return array_diff( parent::__sleep(), @@ -287,7 +287,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php index 81cbbd06c523..b378b309dcef 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute/Collection.php @@ -364,7 +364,7 @@ protected function getIncludedOptions(array $usedProducts, AbstractAttribute $pr */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return array_diff( parent::__sleep(), @@ -388,7 +388,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = ObjectManager::getInstance(); diff --git a/app/code/Magento/Customer/Model/Attribute.php b/app/code/Magento/Customer/Model/Attribute.php index ae714f993082..1d9b6b095f91 100644 --- a/app/code/Magento/Customer/Model/Attribute.php +++ b/app/code/Magento/Customer/Model/Attribute.php @@ -208,7 +208,7 @@ public function canBeFilterableInGrid() */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->unsetData('entity_type'); return array_diff( @@ -225,7 +225,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/app/code/Magento/Eav/Model/Entity/Attribute.php b/app/code/Magento/Eav/Model/Entity/Attribute.php index e23f81607a0c..510d6ef5e531 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute.php @@ -502,7 +502,7 @@ public function getIdentities() */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->unsetData('attribute_set_info'); return array_diff( @@ -520,7 +520,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = ObjectManager::getInstance(); diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php index 9ed4ac529368..bd36c55bcdee 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php @@ -1410,7 +1410,7 @@ public function setExtensionAttributes(\Magento\Eav\Api\Data\AttributeExtensionI */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return array_diff( parent::__sleep(), @@ -1440,7 +1440,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php index 5e7226e7a36d..e5b7ef7fd684 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php @@ -731,7 +731,7 @@ public function getValidAttributeIds($attributeIds) */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = parent::__sleep(); $properties = array_diff($properties, ['_storeManager']); @@ -749,7 +749,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $this->_storeManager = \Magento\Framework\App\ObjectManager::getInstance() diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index 4f69579c41bb..6e1646608933 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -429,7 +429,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = parent::__sleep(); $properties = array_diff($properties, ['_coreFileStorageDatabase', '_config']); @@ -446,7 +446,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $this->_coreFileStorageDatabase = ObjectManager::getInstance() diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php index d8040b0bbaaa..e747dd5b09e0 100644 --- a/app/code/Magento/User/Model/User.php +++ b/app/code/Magento/User/Model/User.php @@ -218,7 +218,7 @@ protected function _construct() */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = parent::__sleep(); return array_diff( @@ -251,7 +251,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/lib/internal/Magento/Framework/App/AreaList/Proxy.php b/lib/internal/Magento/Framework/App/AreaList/Proxy.php index 09115add5719..2d7a31503220 100644 --- a/lib/internal/Magento/Framework/App/AreaList/Proxy.php +++ b/lib/internal/Magento/Framework/App/AreaList/Proxy.php @@ -67,7 +67,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['_subject', '_isShared']; } @@ -82,7 +82,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/App/Response/Http.php b/lib/internal/Magento/Framework/App/Response/Http.php index a80d9cbdd668..5716857fb291 100644 --- a/lib/internal/Magento/Framework/App/Response/Http.php +++ b/lib/internal/Magento/Framework/App/Response/Http.php @@ -189,7 +189,7 @@ public function representJson($content) */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['content', 'isRedirect', 'statusCode', 'context', 'headers']; } @@ -205,7 +205,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $objectManager = ObjectManager::getInstance(); $this->cookieManager = $objectManager->create(\Magento\Framework\Stdlib\CookieManagerInterface::class); diff --git a/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php b/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php index 5e79315238f7..6aecfed8b348 100644 --- a/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php +++ b/lib/internal/Magento/Framework/App/Route/ConfigInterface/Proxy.php @@ -69,7 +69,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['_subject', '_isShared']; } @@ -84,7 +84,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/DB/Select.php b/lib/internal/Magento/Framework/DB/Select.php index f33aaea7d0e6..ad570dbc2c8a 100644 --- a/lib/internal/Magento/Framework/DB/Select.php +++ b/lib/internal/Magento/Framework/DB/Select.php @@ -519,7 +519,7 @@ public function assemble() */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = array_keys(get_object_vars($this)); $properties = array_diff( @@ -543,7 +543,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_adapter = $objectManager->get(ResourceConnection::class)->getConnection(); diff --git a/lib/internal/Magento/Framework/DB/Select/RendererProxy.php b/lib/internal/Magento/Framework/DB/Select/RendererProxy.php index dc69b96b7905..a4415ce56d3b 100644 --- a/lib/internal/Magento/Framework/DB/Select/RendererProxy.php +++ b/lib/internal/Magento/Framework/DB/Select/RendererProxy.php @@ -65,7 +65,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['_subject', '_isShared']; } @@ -80,7 +80,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index 5477b58d4e86..962ac5038bac 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -892,7 +892,7 @@ public function hasFlag($flag) */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = array_keys(get_object_vars($this)); $properties = array_diff( @@ -915,7 +915,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_entityFactory = $objectManager->get(EntityFactoryInterface::class); diff --git a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php index 1b28e367dcc3..c0d3e73c9015 100644 --- a/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php +++ b/lib/internal/Magento/Framework/Data/Collection/AbstractDb.php @@ -896,7 +896,7 @@ private function getMainTableAlias() */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return array_diff( parent::__sleep(), @@ -913,7 +913,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php b/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php index b0f5742afef1..95348cc2828e 100644 --- a/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php +++ b/lib/internal/Magento/Framework/DataObject/Copy/Config/Data/Proxy.php @@ -66,7 +66,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['_subject', '_isShared']; } @@ -81,7 +81,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/Interception/Interceptor.php b/lib/internal/Magento/Framework/Interception/Interceptor.php index df1b68023422..4ad47f3bd95f 100644 --- a/lib/internal/Magento/Framework/Interception/Interceptor.php +++ b/lib/internal/Magento/Framework/Interception/Interceptor.php @@ -68,7 +68,7 @@ public function ___callParent($method, array $arguments) */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); if (method_exists(get_parent_class($this), '__sleep')) { $properties = parent::__sleep(); @@ -89,7 +89,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); if (method_exists(get_parent_class($this), '__wakeup')) { parent::__wakeup(); diff --git a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php index e1f6c792c9c3..14255a586ec8 100644 --- a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php @@ -365,7 +365,7 @@ private function populateExtensionAttributes(array $extensionAttributesData = [] */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return array_diff(parent::__sleep(), ['extensionAttributesFactory', 'customAttributeFactory']); } @@ -378,7 +378,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php index f5095dbb6e87..0c9340d283a4 100644 --- a/lib/internal/Magento/Framework/Model/AbstractModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractModel.php @@ -225,7 +225,7 @@ protected function _init($resourceModel) */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = array_keys(get_object_vars($this)); $properties = array_diff( @@ -254,7 +254,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $this->_registry = $objectManager->get(\Magento\Framework\Registry::class); diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php index 0cadb10aaafe..395724d6e480 100644 --- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php +++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php @@ -162,7 +162,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $properties = array_keys(get_object_vars($this)); $properties = array_diff($properties, ['_resources', '_connections']); @@ -179,7 +179,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->_resources = \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Framework\App\ResourceConnection::class); diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php index bc2187f47491..11585a81de08 100644 --- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php +++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php @@ -612,7 +612,7 @@ public function save() */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return array_diff( parent::__sleep(), @@ -629,7 +629,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); parent::__wakeup(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); diff --git a/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php b/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php index d67c38020755..06b6f394a31f 100644 --- a/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php +++ b/lib/internal/Magento/Framework/Mview/Config/Data/Proxy.php @@ -64,7 +64,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['subject', 'isShared']; } @@ -79,7 +79,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/Translate/Inline/Proxy.php b/lib/internal/Magento/Framework/Translate/Inline/Proxy.php index e6d6cc57c2b0..cd0053e00ae1 100644 --- a/lib/internal/Magento/Framework/Translate/Inline/Proxy.php +++ b/lib/internal/Magento/Framework/Translate/Inline/Proxy.php @@ -64,7 +64,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['subject', 'isShared']; } @@ -79,7 +79,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } diff --git a/lib/internal/Magento/Framework/View/Layout/Proxy.php b/lib/internal/Magento/Framework/View/Layout/Proxy.php index a3d89c6ec7a8..529412faa7a3 100644 --- a/lib/internal/Magento/Framework/View/Layout/Proxy.php +++ b/lib/internal/Magento/Framework/View/Layout/Proxy.php @@ -66,7 +66,7 @@ public function __construct( */ public function __sleep() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); return ['_subject', '_isShared']; } @@ -81,7 +81,7 @@ public function __sleep() */ public function __wakeup() { - trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); + throw new \RuntimeException('tst');//trigger_error('Using PHP serialization is deprecated', E_USER_DEPRECATED); $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance(); } From 4b3317119cad79711dcf51d872ec01a01fe6a990 Mon Sep 17 00:00:00 2001 From: Aliaksei Yakimovich2 Date: Tue, 23 Apr 2019 20:19:37 +0300 Subject: [PATCH 187/247] MAGETWO-98947: UPS CGI url gateway to migrate from http to https - Added strict type declaration in test file; --- .../integration/testsuite/Magento/Ups/Model/CarrierTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php index b3ced0b84e27..042bd03b1cd4 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Ups\Model; use Magento\TestFramework\Helper\Bootstrap; From 90eff3a7f4d6189c8f55e2456d0e28d9e2d929fb Mon Sep 17 00:00:00 2001 From: Tiago Sampaio Date: Sat, 13 Apr 2019 12:40:25 -0300 Subject: [PATCH 188/247] Adding a validation before adding or executing layout generator class. --- .../Framework/View/Layout/GeneratorPool.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Layout/GeneratorPool.php b/lib/internal/Magento/Framework/View/Layout/GeneratorPool.php index 266a1f873f4b..b899e34e6b39 100644 --- a/lib/internal/Magento/Framework/View/Layout/GeneratorPool.php +++ b/lib/internal/Magento/Framework/View/Layout/GeneratorPool.php @@ -35,9 +35,9 @@ class GeneratorPool /** * @param ScheduledStructure\Helper $helper - * @param ConditionFactory $conditionFactory - * @param \Psr\Log\LoggerInterface $logger - * @param array $generators + * @param ConditionFactory $conditionFactory + * @param \Psr\Log\LoggerInterface $logger + * @param array $generators */ public function __construct( ScheduledStructure\Helper $helper, @@ -69,8 +69,9 @@ public function getGenerator($type) /** * Traverse through all generators and generate all scheduled elements * - * @param Reader\Context $readerContext + * @param Reader\Context $readerContext * @param Generator\Context $generatorContext + * * @return $this */ public function process(Reader\Context $readerContext, Generator\Context $generatorContext) @@ -86,11 +87,17 @@ public function process(Reader\Context $readerContext, Generator\Context $genera * Add generators to pool * * @param GeneratorInterface[] $generators + * * @return void */ protected function addGenerators(array $generators) { foreach ($generators as $generator) { + if (!$generator instanceof GeneratorInterface) { + throw new \InvalidArgumentException( + sprintf('Generator class must be an instance of %s', GeneratorInterface::class) + ); + } $this->generators[$generator->getType()] = $generator; } } From 04274297730c46bdeb8b95fd233d2390299cd69b Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov Date: Tue, 23 Apr 2019 12:47:54 -0500 Subject: [PATCH 189/247] MC-15993: Minisearch is broken on mobile screen --- .../view/frontend/templates/form.mini.phtml | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Search/view/frontend/templates/form.mini.phtml b/app/code/Magento/Search/view/frontend/templates/form.mini.phtml index a98a70a90ced..44c8db3f1a66 100644 --- a/app/code/Magento/Search/view/frontend/templates/form.mini.phtml +++ b/app/code/Magento/Search/view/frontend/templates/form.mini.phtml @@ -16,31 +16,26 @@ $helper = $this->helper(\Magento\Search\Helper\Data::class);