Skip to content

Commit a3a9f56

Browse files
LYNX-362: Add confirmation status (#216)
1 parent b4b00e7 commit a3a9f56

File tree

5 files changed

+289
-0
lines changed

5 files changed

+289
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\CustomerGraphQl\Model\Resolver;
20+
21+
use Magento\Customer\Api\AccountManagementInterface;
22+
use Magento\Framework\Exception\LocalizedException;
23+
use Magento\Framework\GraphQl\Config\Element\Field;
24+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
25+
use Magento\Framework\GraphQl\Query\ResolverInterface;
26+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
27+
28+
/**
29+
* Confirmation status resolver
30+
*/
31+
class ConfirmationStatus implements ResolverInterface
32+
{
33+
/**
34+
* @param AccountManagementInterface $accountManagement
35+
*/
36+
public function __construct(
37+
private readonly AccountManagementInterface $accountManagement
38+
) {
39+
}
40+
41+
/**
42+
* @inheritdoc
43+
*/
44+
public function resolve(
45+
Field $field,
46+
$context,
47+
ResolveInfo $info,
48+
array $value = null,
49+
array $args = null
50+
) {
51+
try {
52+
$confirmationStatus = $this->accountManagement->getConfirmationStatus($context->getUserId());
53+
} catch (LocalizedException $e) {
54+
throw new GraphQlInputException(__($e->getMessage()), $e);
55+
}
56+
return strtoupper($confirmationStatus);
57+
}
58+
}

app/code/Magento/CustomerGraphQl/etc/graphql/di.xml

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<item name="required_character_classes_number" xsi:type="string">customer/password/required_character_classes_number</item>
3838
<item name="minimum_password_length" xsi:type="string">customer/password/minimum_password_length</item>
3939
<item name="autocomplete_on_storefront" xsi:type="string">customer/password/autocomplete_on_storefront</item>
40+
<item name="create_account_confirmation" xsi:type="string">customer/create_account/confirm</item>
4041
</argument>
4142
</arguments>
4243
</type>

app/code/Magento/CustomerGraphQl/etc/schema.graphqls

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type StoreConfig {
55
required_character_classes_number : String @doc(description: "The number of different character classes (lowercase, uppercase, digits, special characters) required in a password.")
66
minimum_password_length : String @doc(description: "The minimum number of characters required for a valid password.")
77
autocomplete_on_storefront : Boolean @doc(description: "Indicates whether to enable autocomplete on login and forgot password forms.")
8+
create_account_confirmation: Boolean @doc(description: "Indicates if the new accounts need confirmation.")
89
}
910

1011
type Query {
@@ -146,6 +147,7 @@ type Customer @doc(description: "Defines the customer name, addresses, and other
146147
addresses: [CustomerAddress] @doc(description: "An array containing the customer's shipping and billing addresses.") @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\CustomerAddresses")
147148
gender: Int @doc(description: "The customer's gender (Male - 1, Female - 2).")
148149
custom_attributes(attributeCodes: [ID!]): [AttributeValueInterface] @doc(description: "Customer's custom attributes.") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\CustomAttributeFilter")
150+
confirmation_status: ConfirmationStatusEnum! @doc(description: "The customer's confirmation status.") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\ConfirmationStatus")
149151
}
150152

151153
type CustomerAddress @doc(description: "Contains detailed information about a customer's billing or shipping address."){
@@ -473,3 +475,8 @@ enum ValidationRuleEnum @doc(description: "List of validation rule names applied
473475
MAX_IMAGE_HEIGHT
474476
MAX_IMAGE_WIDTH
475477
}
478+
479+
enum ConfirmationStatusEnum @doc(description: "List of account confirmation statuses.") {
480+
ACCOUNT_CONFIRMED @doc(description: "Account confirmed")
481+
ACCOUNT_CONFIRMATION_NOT_REQUIRED @doc(description: "Account confirmation not required")
482+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\GraphQl\Customer;
20+
21+
use Magento\Customer\Api\AccountManagementInterface;
22+
use Magento\Customer\Api\CustomerRepositoryInterface;
23+
use Magento\Customer\Api\Data\CustomerInterface;
24+
use Magento\Customer\Test\Fixture\Customer;
25+
use Magento\Framework\Exception\AuthenticationException;
26+
use Magento\Integration\Api\CustomerTokenServiceInterface;
27+
use Magento\TestFramework\Fixture\Config;
28+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
29+
use Magento\TestFramework\Helper\Bootstrap;
30+
use Magento\TestFramework\TestCase\GraphQlAbstract;
31+
use Magento\TestFramework\Fixture\DataFixture;
32+
33+
/**
34+
* Tests for confirmation status
35+
*/
36+
class ConfirmationStatusTest extends GraphQlAbstract
37+
{
38+
/**
39+
* @var CustomerTokenServiceInterface
40+
*/
41+
private $customerTokenService;
42+
43+
/**
44+
* @var CustomerRepositoryInterface
45+
*/
46+
private $customerRepository;
47+
48+
protected function setUp(): void
49+
{
50+
parent::setUp();
51+
$this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class);
52+
$this->customerRepository = Bootstrap::getObjectManager()->get(CustomerRepositoryInterface::class);
53+
}
54+
55+
#[
56+
Config('customer/create_account/confirm', 0),
57+
DataFixture(
58+
Customer::class,
59+
[
60+
'email' => '[email protected]',
61+
],
62+
'customer'
63+
)
64+
]
65+
public function testGetConfirmationStatusConfirmationNotRequiredTest()
66+
{
67+
$customer = DataFixtureStorageManager::getStorage()->get('customer');
68+
$query = <<<QUERY
69+
query {
70+
customer {
71+
confirmation_status
72+
}
73+
}
74+
QUERY;
75+
$response = $this->graphQlQuery(
76+
$query,
77+
[],
78+
'',
79+
$this->getHeaderMap($customer->getEmail(), 'password')
80+
);
81+
$this->assertEquals(
82+
strtoupper(AccountManagementInterface::ACCOUNT_CONFIRMATION_NOT_REQUIRED),
83+
$response['customer']['confirmation_status']
84+
);
85+
}
86+
87+
#[
88+
Config('customer/create_account/confirm', 1),
89+
DataFixture(
90+
Customer::class,
91+
[
92+
'email' => '[email protected]',
93+
],
94+
'customer'
95+
)
96+
]
97+
public function testGetConfirmationStatusConfirmedTest()
98+
{
99+
$customer = DataFixtureStorageManager::getStorage()->get('customer');
100+
$query = <<<QUERY
101+
query {
102+
customer {
103+
confirmation_status
104+
}
105+
}
106+
QUERY;
107+
$response = $this->graphQlQuery(
108+
$query,
109+
[],
110+
'',
111+
$this->getHeaderMap($customer->getEmail(), 'password')
112+
);
113+
$this->assertEquals(
114+
strtoupper(AccountManagementInterface::ACCOUNT_CONFIRMED),
115+
$response['customer']['confirmation_status']
116+
);
117+
}
118+
119+
#[
120+
Config('customer/create_account/confirm', 1),
121+
DataFixture(
122+
Customer::class,
123+
[
124+
'email' => '[email protected]',
125+
],
126+
'customer'
127+
)
128+
]
129+
public function testGetConfirmationStatusConfirmationRequiredTest()
130+
{
131+
$this->expectExceptionMessage("This account isn't confirmed. Verify and try again.");
132+
/** @var CustomerInterface $customer */
133+
$customer = DataFixtureStorageManager::getStorage()->get('customer');
134+
$headersMap = $this->getHeaderMap($customer->getEmail(), 'password');
135+
$customer->setConfirmation(AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED);
136+
$this->customerRepository->save($this->customerRepository->get($customer->getEmail()));
137+
$query = <<<QUERY
138+
query {
139+
customer {
140+
confirmation_status
141+
}
142+
}
143+
QUERY;
144+
$this->graphQlQuery(
145+
$query,
146+
[],
147+
'',
148+
$headersMap
149+
);
150+
}
151+
152+
#[
153+
DataFixture(
154+
Customer::class,
155+
[
156+
'email' => '[email protected]',
157+
],
158+
'customer'
159+
)
160+
]
161+
public function testGetConfirmationStatusIfUserIsNotAuthorizedTest()
162+
{
163+
$this->expectException(\Exception::class);
164+
$this->expectExceptionMessage('The current customer isn\'t authorized.');
165+
166+
$query = <<<QUERY
167+
query {
168+
customer {
169+
confirmation_status
170+
}
171+
}
172+
QUERY;
173+
$this->graphQlQuery($query);
174+
}
175+
176+
/**
177+
* @param string $email
178+
* @param string $password
179+
*
180+
* @return array
181+
* @throws AuthenticationException
182+
*/
183+
private function getHeaderMap(string $email, string $password): array
184+
{
185+
$customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password);
186+
return ['Authorization' => 'Bearer ' . $customerToken];
187+
}
188+
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/StoreConfigTest.php

+35
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\GraphQl\Customer;
99

1010
use Exception;
11+
use Magento\TestFramework\Fixture\Config;
1112
use Magento\TestFramework\TestCase\GraphQlAbstract;
1213

1314
/**
@@ -35,4 +36,38 @@ public function testReturnTypeAutocompleteOnStorefrontConfig()
3536
self::assertArrayHasKey('autocomplete_on_storefront', $response['storeConfig']);
3637
self::assertTrue($response['storeConfig']['autocomplete_on_storefront']);
3738
}
39+
40+
#[
41+
Config('customer/create_account/confirm', 1)
42+
]
43+
public function testCreateAccountConfirmationEnabledStorefrontConfig()
44+
{
45+
$query = <<<QUERY
46+
{
47+
storeConfig {
48+
create_account_confirmation
49+
}
50+
}
51+
QUERY;
52+
$response = $this->graphQlQuery($query);
53+
self::assertArrayHasKey('create_account_confirmation', $response['storeConfig']);
54+
self::assertTrue($response['storeConfig']['create_account_confirmation']);
55+
}
56+
57+
#[
58+
Config('customer/create_account/confirm', 0)
59+
]
60+
public function testCreateAccountConfirmationDisabledStorefrontConfig()
61+
{
62+
$query = <<<QUERY
63+
{
64+
storeConfig {
65+
create_account_confirmation
66+
}
67+
}
68+
QUERY;
69+
$response = $this->graphQlQuery($query);
70+
self::assertArrayHasKey('create_account_confirmation', $response['storeConfig']);
71+
self::assertFalse($response['storeConfig']['create_account_confirmation']);
72+
}
3873
}

0 commit comments

Comments
 (0)