Skip to content

Commit d73a46e

Browse files
committed
MC-18116: Email template preview bugfix
1 parent 7e0a77c commit d73a46e

File tree

9 files changed

+266
-31
lines changed

9 files changed

+266
-31
lines changed

app/code/Magento/Email/Block/Adminhtml/Template/Preview.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44
* See COPYING.txt for license details.
55
*/
66

7-
/**
8-
* Adminhtml system template preview block
9-
*
10-
* @author Magento Core Team <core@magentocommerce.com>
11-
*/
127
namespace Magento\Email\Block\Adminhtml\Template;
138

149
/**
@@ -56,6 +51,7 @@ public function __construct(
5651
*
5752
* @return string
5853
* @SuppressWarnings(PHPMD.RequestAwareBlockMethod)
54+
* @throws \Exception
5955
*/
6056
protected function _toHtml()
6157
{

app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ public function __construct(
4242
* Load the page defined in view/adminhtml/layout/adminhtml_email_template_popup.xml
4343
*
4444
* @return \Magento\Framework\View\Result\Page
45+
* @throws \Magento\Framework\Exception\NotFoundException
4546
*/
4647
public function execute()
4748
{
49+
if (!$this->getRequest()->isPost()) {
50+
throw new \Magento\Framework\Exception\NotFoundException(__('Page not found.'));
51+
}
52+
4853
return $this->resultPageFactory->create();
4954
}
5055
}

app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
11
<?php
22
/**
3-
*
43
* Copyright © Magento, Inc. All rights reserved.
54
* See COPYING.txt for license details.
65
*/
76
namespace Magento\Email\Controller\Adminhtml\Email\Template;
87

8+
use Magento\Email\Controller\Adminhtml\Email\Template;
9+
910
/**
1011
* Rendering email template preview.
1112
*/
12-
class Preview extends \Magento\Email\Controller\Adminhtml\Email\Template
13+
class Preview extends Template
1314
{
1415
/**
1516
* Preview transactional email action.
16-
*
17-
* @return void
1817
*/
1918
public function execute()
2019
{
2120
try {
2221
$this->_view->loadLayout();
2322
$this->_view->getPage()->getConfig()->getTitle()->prepend(__('Email Preview'));
2423
$this->_view->renderLayout();
25-
$this->getResponse()->setHeader('Content-Security-Policy', "script-src 'self'");
2624
} catch (\Exception $e) {
2725
$this->messageManager->addErrorMessage(
2826
__('An error occurred. The email template can not be opened for preview.')

app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ class PreviewTest extends \PHPUnit\Framework\TestCase
6060
*/
6161
private $pageTitleMock;
6262

63-
/**
64-
* @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject
65-
*/
66-
private $responseMock;
67-
6863
/**
6964
* @inheritdoc
7065
*/
@@ -93,16 +88,11 @@ protected function setUp()
9388
->disableOriginalConstructor()
9489
->getMock();
9590

96-
$this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class)
97-
->setMethods(['setHeader'])
98-
->getMockForAbstractClass();
99-
10091
$this->context = $objectManager->getObject(
10192
\Magento\Backend\App\Action\Context::class,
10293
[
10394
'request' => $this->requestMock,
104-
'view' => $this->viewMock,
105-
'response' => $this->responseMock,
95+
'view' => $this->viewMock
10696
]
10797
);
10898
$this->object = $objectManager->getObject(
@@ -131,9 +121,6 @@ public function testExecute()
131121
$this->pageTitleMock->expects($this->once())
132122
->method('prepend')
133123
->willReturnSelf();
134-
$this->responseMock->expects($this->once())
135-
->method('setHeader')
136-
->with('Content-Security-Policy', "script-src 'self'");
137124

138125
$this->assertNull($this->object->execute());
139126
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Email\Test\Unit\ViewModel\Template\Preview;
8+
9+
use Magento\Email\ViewModel\Template\Preview\Form;
10+
use Magento\Framework\App\Request\Http;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
13+
14+
/**
15+
* Class FormTest
16+
*
17+
* @covers \Magento\Email\ViewModel\Template\Preview\Form
18+
*/
19+
class FormTest extends \PHPUnit\Framework\TestCase
20+
{
21+
/** @var Form */
22+
protected $form;
23+
24+
/** @var Http|\PHPUnit_Framework_MockObject_MockObject */
25+
protected $requestMock;
26+
27+
protected function setUp()
28+
{
29+
$this->requestMock = $this->createPartialMock(
30+
Http::class,
31+
['getParam', 'getMethod']
32+
);
33+
34+
$objectManagerHelper = new ObjectManager($this);
35+
36+
$this->form = $objectManagerHelper->getObject(
37+
Form::class,
38+
['request' => $this->requestMock]
39+
);
40+
}
41+
42+
/**
43+
* Tests that the form is created with the expected fields based on the request type.
44+
*
45+
* @dataProvider getFormFieldsDataProvider
46+
* @param string $httpMethod
47+
* @param array $httpParams
48+
* @param array $expectedFields
49+
* @throws LocalizedException
50+
*/
51+
public function testGetFormFields(string $httpMethod, array $httpParams, array $expectedFields)
52+
{
53+
$this->requestMock->expects($this->once())
54+
->method('getMethod')
55+
->willReturn($httpMethod);
56+
57+
$this->requestMock->expects($this->any())
58+
->method('getParam')
59+
->willReturnMap($httpParams);
60+
61+
$actualFields = $this->form->getFormFields();
62+
63+
$this->assertEquals($expectedFields, $actualFields);
64+
}
65+
66+
/**
67+
* Tests that an exception is thrown when a required parameter is missing for the request type.
68+
*
69+
* @dataProvider getFormFieldsInvalidDataProvider
70+
* @expectedException \Magento\Framework\Exception\LocalizedException
71+
* @expectedExceptionMessage Missing expected parameter
72+
* @param string $httpMethod
73+
* @param array $httpParams
74+
*/
75+
public function testGetFormFieldsMissingParameter(string $httpMethod, array $httpParams)
76+
{
77+
$this->requestMock->expects($this->once())
78+
->method('getMethod')
79+
->willReturn($httpMethod);
80+
81+
$this->requestMock->expects($this->once())
82+
->method('getParam')
83+
->willReturnMap($httpParams);
84+
85+
$this->form->getFormFields();
86+
}
87+
88+
/**
89+
* @return array
90+
*/
91+
public function getFormFieldsDataProvider()
92+
{
93+
return [
94+
'get_request_valid' => [
95+
'httpMethod' => 'GET',
96+
'httpParams' => [
97+
['id', null, 1]
98+
],
99+
'expectedFields' => [
100+
'id' => 1
101+
]
102+
],
103+
'get_request_valid_ignore_params' => [
104+
'httpMethod' => 'GET',
105+
'httpParams' => [
106+
['id', null, 1],
107+
['text', null, 'Hello World'],
108+
['type', null, 2],
109+
['styles', null, '']
110+
],
111+
'expectedFields' => [
112+
'id' => 1
113+
]
114+
],
115+
'post_request_valid' => [
116+
'httpMethod' => 'POST',
117+
'httpParams' => [
118+
['text', null, 'Hello World'],
119+
['type', null, 2],
120+
['styles', null, '']
121+
],
122+
'expectedFields' => [
123+
'text' => 'Hello World',
124+
'type' => 2,
125+
'styles' => ''
126+
]
127+
]
128+
];
129+
}
130+
131+
/**
132+
* @return array
133+
*/
134+
public function getFormFieldsInvalidDataProvider()
135+
{
136+
return [
137+
'get_request_missing_id' => [
138+
'httpMethod' => 'GET',
139+
'httpParams' => [
140+
['text', null, 'Hello World'],
141+
['type', null, 2],
142+
['styles', null, '']
143+
]
144+
],
145+
'post_request_missing_text' => [
146+
'httpMethod' => 'POST',
147+
'httpParams' => [
148+
['type', null, 2],
149+
['styles', null, '']
150+
]
151+
]
152+
];
153+
}
154+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Email\ViewModel\Template\Preview;
7+
8+
use Magento\Framework\App\RequestInterface;
9+
use Magento\Framework\Exception\LocalizedException;
10+
use Magento\Framework\View\Element\Block\ArgumentInterface;
11+
12+
/**
13+
* Class Form
14+
*/
15+
class Form implements ArgumentInterface
16+
{
17+
private $expectedParamsGetRequest = [
18+
'id'
19+
];
20+
21+
private $expectedParamsPostRequest = [
22+
'text',
23+
'type',
24+
'styles'
25+
];
26+
27+
/**
28+
* @var RequestInterface
29+
*/
30+
private $request;
31+
32+
/**
33+
* @param RequestInterface $request
34+
*/
35+
public function __construct(RequestInterface $request)
36+
{
37+
$this->request = $request;
38+
}
39+
40+
/**
41+
* Gets the fields to be included in the email preview form.
42+
*
43+
* @return array
44+
* @throws LocalizedException
45+
*/
46+
public function getFormFields()
47+
{
48+
$params = $fields = [];
49+
$method = $this->request->getMethod();
50+
51+
if ($method === 'GET') {
52+
$params = $this->expectedParamsGetRequest;
53+
} elseif ($method === 'POST') {
54+
$params = $this->expectedParamsPostRequest;
55+
}
56+
57+
foreach ($params as $paramName) {
58+
$fieldValue = $this->request->getParam($paramName);
59+
if ($fieldValue === null) {
60+
throw new LocalizedException(
61+
__("Missing expected parameter \"$paramName\" while attempting to generate template preview.")
62+
);
63+
}
64+
$fields[$paramName] = $fieldValue;
65+
}
66+
67+
return $fields;
68+
}
69+
}

app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
<referenceContainer name="backend.page" remove="true"/>
1313
<referenceContainer name="menu.wrapper" remove="true"/>
1414
<referenceContainer name="root">
15-
<block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Email::preview/iframeswitcher.phtml"/>
15+
<block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Email::preview/iframeswitcher.phtml">
16+
<arguments>
17+
<argument name="preview_form_view_model" xsi:type="object">Magento\Email\ViewModel\Template\Preview\Form</argument>
18+
</arguments>
19+
</block>
1620
</referenceContainer>
1721
</body>
1822
</page>

app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,34 @@
77
/** @var \Magento\Backend\Block\Page $block */
88
?>
99
<div id="preview" class="cms-revision-preview">
10-
<iframe
11-
name="preview_iframe"
10+
<iframe name="preview_iframe"
1211
id="preview_iframe"
1312
frameborder="0"
1413
title="<?= $block->escapeHtmlAttr(__('Preview')) ?>"
1514
width="100%"
16-
sandbox="allow-forms allow-pointer-lock"
17-
src="<?= $block->escapeUrl($block->getUrl('*/*/popup', ['_current' => true])) ?>"
18-
/>
15+
sandbox="allow-same-origin allow-pointer-lock"
16+
></iframe>
17+
<form id="preview_form"
18+
action="<?= $block->escapeUrl($block->getUrl('*/*/popup')) ?>"
19+
method="post"
20+
target="preview_iframe"
21+
>
22+
<input type="hidden" name="form_key" value="<?= /* @noEscape */ $block->getFormKey() ?>" />
23+
<?php foreach ($block->getPreviewFormViewModel()->getFormFields() as $name => $value) : ?>
24+
<input type="hidden" name="<?= $block->escapeHtmlAttr($name) ?>" value="<?= $block->escapeHtmlAttr($value) ?>"/>
25+
<?php endforeach; ?>
26+
</form>
1927
</div>
28+
<script>
29+
require([
30+
'jquery'
31+
], function($) {
32+
$(document).ready(function() {
33+
$('#preview_form').submit();
34+
});
35+
36+
$('#preview_iframe').load(function() {
37+
$(this).height($(this).contents().height());
38+
});
39+
});
40+
</script>

0 commit comments

Comments
 (0)