diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php new file mode 100644 index 0000000000000..3daf88226d8e5 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/Model/Resolver/CheckoutAgreements.php @@ -0,0 +1,91 @@ +agreementCollectionFactory = $agreementCollectionFactory; + $this->storeManager = $storeManager; + $this->scopeConfig = $scopeConfig; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!$this->scopeConfig->isSetFlag('checkout/options/enable_agreements', ScopeInterface::SCOPE_STORE)) { + return []; + } + + /** @var Collection $agreementsCollection */ + $agreementsCollection = $this->agreementCollectionFactory->create(); + $agreementsCollection->addStoreFilter($this->storeManager->getStore()->getId()); + $agreementsCollection->addFieldToFilter(AgreementInterface::IS_ACTIVE, 1); + + $checkoutAgreementData = []; + /** @var AgreementInterface $checkoutAgreement */ + foreach ($agreementsCollection->getItems() as $checkoutAgreement) { + $checkoutAgreementData[] = [ + AgreementInterface::AGREEMENT_ID => $checkoutAgreement->getAgreementId(), + AgreementInterface::CONTENT => $checkoutAgreement->getContent(), + AgreementInterface::NAME => $checkoutAgreement->getName(), + AgreementInterface::CONTENT_HEIGHT => $checkoutAgreement->getContentHeight(), + AgreementInterface::CHECKBOX_TEXT => $checkoutAgreement->getCheckboxText(), + AgreementInterface::IS_HTML => $checkoutAgreement->getIsHtml(), + AgreementInterface::MODE => + AgreementModeOptions::MODE_AUTO === (int)$checkoutAgreement->getMode() ? 'AUTO' : 'MANUAL', + ]; + } + return $checkoutAgreementData; + } +} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/README.md b/app/code/Magento/CheckoutAgreementsGraphQl/README.md new file mode 100644 index 0000000000000..3ef735e3937f5 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/README.md @@ -0,0 +1,4 @@ +# CheckoutAgreementsGraphQl + +**CheckoutAgreementsGraphQl** provides type information for the GraphQl module +to generate Checkout Agreements fields for Checkout Agreements information endpoints. diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json new file mode 100644 index 0000000000000..5972d48b35ea9 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-checkout-agreements-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-store": "*", + "magento/module-checkout-agreements": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CheckoutAgreementsGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml b/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml new file mode 100644 index 0000000000000..d18e8ee17d097 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/module.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..64ef9411dfca6 --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/etc/schema.graphqls @@ -0,0 +1,21 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Query { + checkoutAgreements: [CheckoutAgreement] @resolver(class: "Magento\\CheckoutAgreementsGraphQl\\Model\\Resolver\\CheckoutAgreements") @doc(description: "The Checkout Agreements information") +} + +type CheckoutAgreement @doc(description: "Defines all Checkout Agreement information") { + agreement_id: Int! @doc(description: "Checkout Agreement identifier") + name: String! @doc(description: "Checkout Agreement name") + content: String! @doc(description: "Checkout Agreement content") + content_height: String @doc(description: "Checkout Agreement content height") + checkbox_text: String! @doc(description: "Checkout Agreement checkbox text") + is_html: Boolean! @doc(description: "Is Checkout Agreement content in HTML format") + mode: CheckoutAgreementMode! +} + +enum CheckoutAgreementMode { + AUTO + MANUAL +} diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/registration.php b/app/code/Magento/CheckoutAgreementsGraphQl/registration.php new file mode 100644 index 0000000000000..b0b4839f33d1f --- /dev/null +++ b/app/code/Magento/CheckoutAgreementsGraphQl/registration.php @@ -0,0 +1,10 @@ +objectManager = Bootstrap::getObjectManager(); + + // TODO: remove usage of the Config, use ConfigFixture instead https://github.com/magento/graphql-ce/issues/167 + $this->config = $this->objectManager->get(Config::class); + $this->saveAgreementConfig(1); + } + + /** + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php + */ + public function testGetActiveAgreement() + { + $query = $this->getQuery(); + + $response = $this->graphQlQuery($query); + + self::assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + self::assertCount(1, $agreements); + self::assertEquals('Checkout Agreement (active)', $agreements[0]['name']); + self::assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); + self::assertEquals('200px', $agreements[0]['content_height']); + self::assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); + self::assertTrue($agreements[0]['is_html']); + self::assertEquals('AUTO', $agreements[0]['mode']); + } + + /** + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php + * @magentoApiDataFixture Magento/Store/_files/second_store.php + */ + public function testGetActiveAgreementOnSecondStore() + { + $secondStoreCode = 'fixture_second_store'; + $agreementsName = 'Checkout Agreement (active)'; + + $query = $this->getQuery(); + $this->assignAgreementsToStore($secondStoreCode, $agreementsName); + + $headerMap['Store'] = $secondStoreCode; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + self::assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + self::assertCount(1, $agreements); + self::assertEquals($agreementsName, $agreements[0]['name']); + self::assertEquals('Checkout agreement content: HTML', $agreements[0]['content']); + self::assertEquals('200px', $agreements[0]['content_height']); + self::assertEquals('Checkout agreement checkbox text.', $agreements[0]['checkbox_text']); + self::assertTrue($agreements[0]['is_html']); + self::assertEquals('AUTO', $agreements[0]['mode']); + } + + /** + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php + * @magentoApiDataFixture Magento/Store/_files/second_store.php + */ + public function testGetActiveAgreementFromSecondStoreOnDefaultStore() + { + $secondStoreCode = 'fixture_second_store'; + $agreementsName = 'Checkout Agreement (active)'; + + $query = $this->getQuery(); + $this->assignAgreementsToStore($secondStoreCode, $agreementsName); + + $response = $this->graphQlQuery($query); + + self::assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + self::assertEmpty($agreements); + } + + public function testGetAgreementNotSet() + { + $query = $this->getQuery(); + + $response = $this->graphQlQuery($query); + + self::assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + self::assertEmpty($agreements); + } + + /** + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php + * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php + */ + public function testDisabledAgreements() + { + $query = $this->getQuery(); + $this->saveAgreementConfig(0); + + $response = $this->graphQlQuery($query); + + self::assertArrayHasKey('checkoutAgreements', $response); + $agreements = $response['checkoutAgreements']; + self::assertEmpty($agreements); + } + + /** + * @return string + */ + private function getQuery(): string + { + return + <<objectManager->get(AgreementFactory::class); + /** @var Agreement $agreementsResource */ + $agreementsResource = $this->objectManager->get(Agreement::class); + /** @var StoreManagerInterface $storeManager */ + $storeManager = $this->objectManager->get(StoreManagerInterface::class); + $store = $storeManager->getStore($storeCode); + /** @var AgreementModel $agreements */ + $agreements = $agreementsFactory->create(); + $agreementsResource->load($agreements, $agreementsName, AgreementInterface::NAME); + $agreements->setData('stores', [$store->getId()]); + $agreementsResource->save($agreements); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->deleteAgreementConfig(); + } + + /** + * @param int $value + * @param StoreInterface $store + */ + private function saveAgreementConfig(int $value): void + { + $this->config->saveConfig( + $this->agreementsXmlConfigPath, + $value, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + + $this->reinitConfig(); + } + + /** + * Delete config + * + * @return void + */ + private function deleteAgreementConfig(): void + { + $this->config->deleteConfig( + $this->agreementsXmlConfigPath, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + + $this->reinitConfig(); + } + + private function reinitConfig(): void + { + /** @var ReinitableConfigInterface $config */ + $config = $this->objectManager->get(ReinitableConfigInterface::class); + $config->reinit(); + } +}