Skip to content

Commit c1a93c3

Browse files
authored
LYNX-86: Move functionality from ContactGraphQlPwa to ContractGraphQl (new module) (#86)
1 parent 78f9844 commit c1a93c3

File tree

10 files changed

+384
-0
lines changed

10 files changed

+384
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ContactGraphQl\Model;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\Framework\Validator\EmailAddress;
12+
13+
class ContactUsValidator
14+
{
15+
/**
16+
* @var EmailAddress
17+
*/
18+
private EmailAddress $emailValidator;
19+
20+
/**
21+
* @param EmailAddress $emailValidator
22+
*/
23+
public function __construct(
24+
EmailAddress $emailValidator
25+
) {
26+
$this->emailValidator = $emailValidator;
27+
}
28+
29+
/**
30+
* Validate input data
31+
*
32+
* @param string[] $input
33+
* @return void
34+
* @throws GraphQlInputException
35+
*/
36+
public function execute(array $input): void
37+
{
38+
if (!$this->emailValidator->isValid($input['email'])) {
39+
throw new GraphQlInputException(
40+
__('The email address is invalid. Verify the email address and try again.')
41+
);
42+
}
43+
44+
if ($input['name'] === '') {
45+
throw new GraphQlInputException(__('Name field is required.'));
46+
}
47+
48+
if ($input['comment'] === '') {
49+
throw new GraphQlInputException(__('Comment field is required.'));
50+
}
51+
}
52+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Magento\ContactGraphQl\Model\Resolver;
11+
12+
use Magento\Contact\Model\ConfigInterface;
13+
use Magento\Contact\Model\MailInterface;
14+
use Magento\Framework\GraphQl\Config\Element\Field;
15+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
16+
use Magento\Framework\GraphQl\Query\ResolverInterface;
17+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
18+
use Psr\Log\LoggerInterface;
19+
use Magento\ContactGraphQl\Model\ContactUsValidator;
20+
21+
class ContactUs implements ResolverInterface
22+
{
23+
/**
24+
* @var MailInterface
25+
*/
26+
private MailInterface $mail;
27+
28+
/**
29+
* @var ConfigInterface
30+
*/
31+
private ConfigInterface $contactConfig;
32+
33+
/**
34+
* @var LoggerInterface
35+
*/
36+
private LoggerInterface $logger;
37+
38+
/**
39+
* @var ContactUsValidator
40+
*/
41+
private ContactUsValidator $validator;
42+
43+
/**
44+
* @param MailInterface $mail
45+
* @param ConfigInterface $contactConfig
46+
* @param LoggerInterface $logger
47+
* @param ContactUsValidator $validator
48+
*/
49+
public function __construct(
50+
MailInterface $mail,
51+
ConfigInterface $contactConfig,
52+
LoggerInterface $logger,
53+
ContactUsValidator $validator
54+
) {
55+
$this->mail = $mail;
56+
$this->contactConfig = $contactConfig;
57+
$this->logger = $logger;
58+
$this->validator = $validator;
59+
}
60+
61+
/**
62+
* @inheritDoc
63+
*/
64+
public function resolve(
65+
Field $field,
66+
$context,
67+
ResolveInfo $info,
68+
array $value = null,
69+
array $args = null
70+
) {
71+
if (!$this->contactConfig->isEnabled()) {
72+
throw new GraphQlInputException(
73+
__('The contact form is unavailable.')
74+
);
75+
}
76+
77+
$input = array_map(function ($field) {
78+
return $field === null ? '' : trim($field);
79+
}, $args['input']);
80+
$this->validator->execute($input);
81+
82+
try {
83+
$this->mail->send($input['email'], ['data' => $input]);
84+
} catch (\Exception $e) {
85+
$this->logger->critical($e);
86+
throw new GraphQlInputException(
87+
__('An error occurred while processing your form. Please try again later.')
88+
);
89+
}
90+
91+
return [
92+
'status' => true
93+
];
94+
}
95+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# ContactGraphQlPwa
2+
3+
**ContactGraphQlPwa** provides GraphQL support for `magento/module-contact`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "magento/module-contact-graph-ql",
3+
"description": "N/A",
4+
"type": "magento2-module",
5+
"config": {
6+
"sort-packages": true
7+
},
8+
"require": {
9+
"php": "~8.1.0||~8.2.0",
10+
"magento/framework": "*",
11+
"magento/module-contact": "*"
12+
},
13+
"suggest": {
14+
"magento/module-graph-ql": "*"
15+
},
16+
"license": [
17+
"OSL-3.0",
18+
"AFL-3.0"
19+
],
20+
"autoload": {
21+
"files": [
22+
"registration.php"
23+
],
24+
"psr-4": {
25+
"Magento\\ContactGraphQl\\": ""
26+
}
27+
}
28+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="Magento\StoreGraphQl\Model\Resolver\Store\StoreConfigDataProvider">
10+
<arguments>
11+
<argument name="extendedConfigData" xsi:type="array">
12+
<item name="contact_enabled" xsi:type="string">contact/contact/enabled</item>
13+
</argument>
14+
</arguments>
15+
</type>
16+
</config>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9+
<module name="Magento_ContactGraphQl" />
10+
</config>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
type Mutation {
5+
contactUs(
6+
input: ContactUsInput! @doc(description: "An input object that defines shopper information.")
7+
): ContactUsOutput @doc(description: "Send a 'Contact Us' email to the merchant.") @resolver(class: "Magento\\ContactGraphQl\\Model\\Resolver\\ContactUs")
8+
}
9+
10+
input ContactUsInput {
11+
email: String! @doc(description: "The email address of the shopper.")
12+
name: String! @doc(description: "The full name of the shopper.")
13+
telephone: String @doc(description: "The shopper's telephone number.")
14+
comment: String! @doc(description: "The shopper's comment to the merchant.")
15+
}
16+
17+
type ContactUsOutput @doc(description: "Contains the status of the request."){
18+
status: Boolean! @doc(description: "Indicates whether the request was successful.")
19+
}
20+
21+
type StoreConfig {
22+
contact_enabled: Boolean! @doc(description: "Indicates whether the Contact Us form in enabled.")
23+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Framework\Component\ComponentRegistrar;
9+
10+
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_ContactGraphQl', __DIR__);

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
"magento/module-configurable-product": "*",
149149
"magento/module-configurable-product-sales": "*",
150150
"magento/module-contact": "*",
151+
"magento/module-contact-graph-ql": "*",
151152
"magento/module-cookie": "*",
152153
"magento/module-cron": "*",
153154
"magento/module-currency-symbol": "*",
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\ContactUs;
9+
10+
use Magento\TestFramework\Fixture\Config;
11+
use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException;
12+
use Magento\TestFramework\TestCase\GraphQlAbstract;
13+
14+
#[
15+
Config("contact/contact/enabled", "1")
16+
]
17+
class ContactUsTest extends GraphQlAbstract
18+
{
19+
/**
20+
* Successfuly send contact us form
21+
*/
22+
public function testContactUsSuccess()
23+
{
24+
$query = <<<MUTATION
25+
mutation {
26+
contactUs(input: {
27+
comment:"Test Contact Us",
28+
29+
name:"John Doe",
30+
telephone:"1111111111"
31+
})
32+
{
33+
status
34+
}
35+
}
36+
MUTATION;
37+
38+
$expected = [
39+
"contactUs" => [
40+
"status" => true
41+
]
42+
];
43+
$response = $this->graphQlMutation($query, [], '', []);
44+
$this->assertEquals($expected, $response, "Contact Us form can not be send");
45+
}
46+
47+
/**
48+
* Failed send contact us form - missing email
49+
*/
50+
public function testContactUsBadEmail()
51+
{
52+
$query = <<<MUTATION
53+
mutation {
54+
contactUs(input: {
55+
comment:"Test Contact Us",
56+
name:"John Doe",
57+
email:"adobe.com",
58+
telephone:"1111111111"
59+
})
60+
{
61+
status
62+
}
63+
}
64+
MUTATION;
65+
$this->expectException(ResponseContainsErrorsException::class);
66+
$this->expectExceptionMessage(
67+
'GraphQL response contains errors: The email address is invalid. Verify the email address and try again.'
68+
);
69+
$this->graphQlMutation($query, [], '', []);
70+
}
71+
72+
/**
73+
* Failed send contact us form - missing name
74+
*/
75+
public function testContactUsMissingName()
76+
{
77+
$query = <<<MUTATION
78+
mutation {
79+
contactUs(input: {
80+
comment:"Test Contact Us",
81+
82+
telephone:"1111111111"
83+
})
84+
{
85+
status
86+
}
87+
}
88+
MUTATION;
89+
$this->expectException(ResponseContainsErrorsException::class);
90+
$this->expectExceptionMessage(
91+
'GraphQL response contains errors: Field ContactUsInput.name of required type String! was not provided.'
92+
);
93+
$this->graphQlMutation($query, [], '', []);
94+
}
95+
96+
/**
97+
* Failed send contact us form - missing name
98+
*/
99+
public function testContactUsMissingComment()
100+
{
101+
$query = <<<MUTATION
102+
mutation {
103+
contactUs(input: {
104+
105+
name:"John Doe",
106+
telephone:"1111111111"
107+
})
108+
{
109+
status
110+
}
111+
}
112+
MUTATION;
113+
$this->expectException(ResponseContainsErrorsException::class);
114+
$this->expectExceptionMessage(
115+
'GraphQL response contains errors: Field ContactUsInput.comment of required type String! was not provided.'
116+
);
117+
$this->graphQlMutation($query, [], '', []);
118+
}
119+
120+
/**
121+
* Failed send contact us form - missing name
122+
*/
123+
#[
124+
Config("contact/contact/enabled", "0")
125+
]
126+
public function testContactUsDisabled()
127+
{
128+
$query = <<<MUTATION
129+
mutation {
130+
contactUs(input: {
131+
comment:"Test Contact Us",
132+
133+
name:"John Doe",
134+
telephone:"1111111111"
135+
})
136+
{
137+
status
138+
}
139+
}
140+
MUTATION;
141+
142+
$this->expectException(ResponseContainsErrorsException::class);
143+
$this->expectExceptionMessage('GraphQL response contains errors: The contact form is unavailable.');
144+
$this->graphQlMutation($query, [], '', []);
145+
}
146+
}

0 commit comments

Comments
 (0)