Skip to content

Commit c56c6ff

Browse files
committed
Merge remote-tracking branch 'adobe-commerce-tier-4/ACP2E-3404' into Tier4-Kings-PR-11-22-2024
2 parents 60b8bd5 + 0bede8b commit c56c6ff

File tree

5 files changed

+220
-91
lines changed

5 files changed

+220
-91
lines changed

app/code/Magento/Customer/Model/EmailNotification.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2014 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -297,14 +297,14 @@ private function sendEmailTemplate(
297297
$storeId
298298
);
299299

300+
$this->emulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND);
300301
$transport = $this->transportBuilder->setTemplateIdentifier($templateId)
301302
->setTemplateOptions(['area' => 'frontend', 'store' => $storeId])
302303
->setTemplateVars($templateParams)
303304
->setFrom($from)
304305
->addTo($email, $this->customerViewHelper->getCustomerName($customer))
305306
->getTransport();
306307

307-
$this->emulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND);
308308
$transport->sendMessage();
309309
$this->emulation->stopEnvironmentEmulation();
310310
}

app/code/Magento/StoreGraphQl/Plugin/LocalizeEmail.php

Lines changed: 0 additions & 83 deletions
This file was deleted.

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2014 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
@@ -34,9 +34,6 @@
3434
</argument>
3535
</arguments>
3636
</type>
37-
<type name="Magento\Framework\Mail\Template\TransportBuilder">
38-
<plugin name="graphQlEmulateEmail" type="Magento\StoreGraphQl\Plugin\LocalizeEmail" />
39-
</type>
4037
<type name="Magento\GraphQlCache\Model\CacheId\CacheIdCalculator">
4138
<arguments>
4239
<argument name="idFactorProviders" xsi:type="array">
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CustomerGraphQl\Model\Resolver;
9+
10+
use Magento\Customer\Test\Fixture\Customer;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Framework\Mail\Template\TransportBuilder;
13+
use Magento\Framework\ObjectManagerInterface;
14+
use Magento\Framework\Serialize\SerializerInterface;
15+
use Magento\GraphQl\Service\GraphQlRequest;
16+
use Magento\Store\Api\StoreRepositoryInterface;
17+
use Magento\Store\Model\ScopeInterface;
18+
use Magento\Store\Test\Fixture\Store as StoreFixture;
19+
use Magento\TestFramework\Fixture\AppArea;
20+
use Magento\TestFramework\Fixture\ComponentsDir;
21+
use Magento\TestFramework\Fixture\Config;
22+
use Magento\TestFramework\Fixture\DataFixture;
23+
use Magento\TestFramework\Fixture\DataFixtureStorage;
24+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
25+
use Magento\TestFramework\Helper\Bootstrap;
26+
use PHPUnit\Framework\TestCase;
27+
28+
class RequestPasswordResetEmailTest extends TestCase
29+
{
30+
/**
31+
* @var ObjectManagerInterface
32+
*/
33+
private $objectManager;
34+
35+
/**
36+
* @var GraphQlRequest
37+
*/
38+
private $graphQlRequest;
39+
40+
/**
41+
* @var SerializerInterface
42+
*/
43+
private $json;
44+
45+
/**
46+
* @var StoreRepositoryInterface
47+
*/
48+
private $storeRepository;
49+
50+
/**
51+
* @var DataFixtureStorage
52+
*/
53+
private $fixtures;
54+
55+
/**
56+
* @var TransportBuilder
57+
*/
58+
private $transportBuilder;
59+
60+
public function setUp(): void
61+
{
62+
$this->objectManager = Bootstrap::getObjectManager();
63+
$this->graphQlRequest = $this->objectManager->create(GraphQlRequest::class);
64+
$this->json = $this->objectManager->get(SerializerInterface::class);
65+
$this->storeRepository = $this->objectManager->create(StoreRepositoryInterface::class);
66+
$this->fixtures = $this->objectManager->get(DataFixtureStorageManager::class)->getStorage();
67+
$this->transportBuilder = $this->objectManager->get(TransportBuilder::class);
68+
}
69+
70+
/**
71+
* Test the consistency of the reset password email for customers registered with a custom store,
72+
* ensuring alignment between content and subject in translated languages.
73+
*
74+
* @dataProvider customerOnFrenchStore
75+
* @param string $requestFromStore
76+
* @param string $subject
77+
* @param string $message
78+
* @throws NoSuchEntityException
79+
*/
80+
#[
81+
AppArea('graphql'),
82+
Config('web/url/use_store', 1),
83+
DataFixture(StoreFixture::class, ['code' => 'fr_store_view'], 'store2'),
84+
Config('general/locale/code', 'fr_FR', ScopeInterface::SCOPE_STORE, 'fr_store_view'),
85+
ComponentsDir('Magento/CustomerGraphQl/_files'),
86+
DataFixture(Customer::class, ['email' => 'customer@example.com', 'store_id' => '$store2.id$'], as: 'customer'),
87+
]
88+
public function testResetPasswordEmailRequestFromCustomStoreWhenCustomerIsOnCustomStore(
89+
string $requestFromStore,
90+
string $subject,
91+
string $message
92+
) {
93+
$this->assertResetPasswordEmailContent($requestFromStore, $subject, $message);
94+
}
95+
96+
/**
97+
* Test the consistency of the reset password email for customers registered with a custom store,
98+
* ensuring alignment between content and subject in translated languages.
99+
*
100+
* @dataProvider customerOnDefaultStore
101+
* @param string $requestFromStore
102+
* @param string $subject
103+
* @param string $comment
104+
* @throws NoSuchEntityException
105+
*/
106+
#[
107+
AppArea('graphql'),
108+
Config('web/url/use_store', 1),
109+
DataFixture(StoreFixture::class, ['code' => 'fr_store_view'], 'store2'),
110+
Config('general/locale/code', 'fr_FR', 'store', 'fr_store_view'),
111+
ComponentsDir('Magento/CustomerGraphQl/_files'),
112+
DataFixture(Customer::class, ['email' => 'customer@example.com'], as: 'customer'),
113+
]
114+
public function testResetPasswordEmailRequestFromCustomStoreWhenCustomerIsOnDefaultStore(
115+
string $requestFromStore,
116+
string $subject,
117+
string $comment
118+
) {
119+
$this->assertResetPasswordEmailContent($requestFromStore, $subject, $comment);
120+
}
121+
122+
/**
123+
* Assert the consistency between the reset password email subject and content
124+
* when the request originates from different stores.
125+
*
126+
* @param string $store
127+
* @param string $subject
128+
* @param string $message
129+
* @throws NoSuchEntityException
130+
*/
131+
private function assertResetPasswordEmailContent(string $store, string $subject, string $message)
132+
{
133+
$customer = $this->fixtures->get('customer');
134+
$email = $customer->getEmail();
135+
136+
$query =
137+
<<<QUERY
138+
mutation {
139+
requestPasswordResetEmail(email: "{$email}")
140+
}
141+
QUERY;
142+
$response = $this->graphQlRequest->send(
143+
$query,
144+
[],
145+
'',
146+
[
147+
'Store' => $store
148+
]
149+
);
150+
$response = $this->json->unserialize($response->getContent());
151+
$this->assertArrayHasKey('requestPasswordResetEmail', $response['data']);
152+
$this->assertTrue($response['data']['requestPasswordResetEmail']);
153+
154+
$sentMessage = $this->transportBuilder->getSentMessage();
155+
// Verify an email was dispatched to the correct user
156+
$this->assertNotNull($sentMessage);
157+
$this->assertEquals($customer->getName(), $sentMessage->getTo()[0]->getName());
158+
$this->assertEquals($customer->getEmail(), $sentMessage->getTo()[0]->getEmail());
159+
160+
// Assert the email contains the expected content
161+
$subject = __($subject, $this->storeRepository->getById($customer->getStoreId())->getFrontendName())->render();
162+
$message = __($message)->render();
163+
$this->assertEquals($subject, $sentMessage->getSubject());
164+
$messageRaw = $sentMessage->getBody()->getParts()[0]->getRawContent();
165+
$this->assertStringContainsString($message, $messageRaw);
166+
}
167+
168+
/**
169+
* Variations when customer is registered from custom (french) store
170+
*
171+
* @return array
172+
*/
173+
public static function customerOnFrenchStore(): array
174+
{
175+
return [
176+
'request_from_default_store' => [
177+
'requestFromStore' => 'default',
178+
'subject' => 'Réinitialiser votre mot de passe %1',
179+
'comment' => 'Si vous êtes bien à l’origine de cette demande, veuillez cliquer ci-dessous pour' .
180+
' définir un nouveau mot de passe',
181+
],
182+
'request_from_french_store' => [
183+
'requestFromStore' => 'fr_store_view',
184+
'subject' => 'Réinitialiser votre mot de passe %1',
185+
'comment' => 'Si vous êtes bien à l’origine de cette demande, veuillez cliquer ci-dessous pour' .
186+
' définir un nouveau mot de passe',
187+
]
188+
];
189+
}
190+
191+
/**
192+
* Variations when customer is registered from default store
193+
*
194+
* @return array
195+
*/
196+
public static function customerOnDefaultStore(): array
197+
{
198+
return [
199+
'request_from_default_store' => [
200+
'requestFromStore' => 'default',
201+
'subject' => 'Reset your %1 password',
202+
'comment' => 'There was recently a request to change the password for your account'
203+
],
204+
'request_from_french_store' => [
205+
'requestFromStore' => 'fr_store_view',
206+
'subject' => 'Reset your %1 password',
207+
'comment' => 'There was recently a request to change the password for your account'
208+
]
209+
];
210+
}
211+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
"Welcome to %store_name","Bienvenue sur %store_name"
22
"Welcome to %store_name.","Bienvenue sur %store_name."
3+
"Reset your %store_name password","Réinitialiser votre mot de passe %store_name"
4+
"Reset your %store_name password.","Réinitialiser votre mot de passe %store_name."
5+
"There was recently a request to change the password for your account","Si vous êtes bien à l’origine de cette demande, veuillez cliquer ci-dessous pour définir un nouveau mot de passe"
6+
"There was recently a request to change the password for your account.","Si vous êtes bien à l’origine de cette demande, veuillez cliquer ci-dessous pour définir un nouveau mot de passe."

0 commit comments

Comments
 (0)