Skip to content

Commit 2493562

Browse files
committed
AC-10686: SRI enabled on payment pages.
Static fixes and added unit test.
1 parent 6392d67 commit 2493562

File tree

8 files changed

+158
-25
lines changed

8 files changed

+158
-25
lines changed

app/code/Magento/Csp/Model/SubresourceIntegrityCollector.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class SubresourceIntegrityCollector
2020
/**
2121
* @param array $data
2222
*/
23-
public function __construct(array $data = []) {
23+
public function __construct(array $data = [])
24+
{
2425
$this->data = $data;
2526
}
2627

app/code/Magento/Csp/Plugin/RemoveAllAssetIntegrityHashes.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ public function __construct(
3232
}
3333

3434
/**
35-
* Removes existing integrity hashes for all assets
36-
* before static content deploy.
35+
* Removes existing integrity hashes before static content deploy
3736
*
3837
* @param DeployStaticContent $subject
3938
* @param array $options

app/code/Magento/Csp/Plugin/StoreAssetIntegrityHashes.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ public function __construct(
3939
}
4040

4141
/**
42-
* Stores generated integrity hashes for all assets
43-
* after static content deploy.
42+
* Stores generated integrity hashes after static content deploy
4443
*
4544
* @param DeployStaticContent $subject
4645
* @param mixed $result

app/code/Magento/Csp/Test/Unit/Model/SubresourceIntegrityRepositoryTest.php

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,50 @@ public function testSave(): void
7979
$data = new SubresourceIntegrity(
8080
[
8181
'hash' => 'testhash',
82-
'url' => 'http://magento.test'
82+
'path' => 'js/jquery.js'
8383
]
8484
);
8585

86-
$expected[$data->getUrl()] = [
87-
'url' => $data->getUrl(),
88-
'hash' => $data->getHash()
89-
];
86+
$expected[$data->getPath()] = $data->getHash();
9087
$serialized = json_encode($expected);
9188
$this->cacheMock->expects($this->once())->method('load')->willReturn(false);
9289
$this->serializerMock->expects($this->once())->method('serialize')->with($expected)->willReturn($serialized);
9390
$this->cacheMock->expects($this->once())->method('save')->willReturn(true);
9491
$this->assertTrue($this->subresourceIntegrityRepository->save($data));
9592
}
93+
94+
/** Test that cache saves in bunch
95+
*
96+
*
97+
* @return void
98+
*/
99+
public function testSaveBunch(): void
100+
{
101+
$bunch1 = new SubresourceIntegrity(
102+
[
103+
'hash' => 'testhash',
104+
'path' => 'js/jquery.js'
105+
]
106+
);
107+
108+
$bunch2 = new SubresourceIntegrity(
109+
[
110+
'hash' => 'testhash2',
111+
'path' => 'js/test.js'
112+
]
113+
);
114+
115+
$bunches = [$bunch1, $bunch2];
116+
117+
$expected = [];
118+
119+
foreach($bunches as $bunch){
120+
$expected[$bunch->getPath()] = $bunch->getHash();
121+
}
122+
$serializedBunch = json_encode($expected);
123+
$this->cacheMock->expects($this->once())->method('load')->willReturn(false);
124+
$this->serializerMock->expects($this->once())->method('serialize')->with($expected)->willReturn($serializedBunch);
125+
$this->cacheMock->expects($this->once())->method('save')->willReturn(true);
126+
$this->assertTrue($this->subresourceIntegrityRepository->saveBunch($bunches));
127+
}
96128
}

app/code/Magento/Csp/Test/Unit/Plugin/AddDefaultPropertiesToGroupPluginTest.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ class AddDefaultPropertiesToGroupPluginTest extends TestCase
3939
*/
4040
private MockObject $stateMock;
4141

42-
/**
43-
* @var array $controllerActions
44-
*/
45-
private array $controllerActions;
46-
4742
/**
4843
* @var AddDefaultPropertiesToGroupPlugin
4944
*/
@@ -63,7 +58,7 @@ protected function setUp(): void
6358
->getMock();
6459
$this->assetInterfaceMock = $this->getMockBuilder(File::class)
6560
->disableOriginalConstructor()
66-
->onlyMethods(['getUrl', 'getContentType'])
61+
->onlyMethods(['getPath'])
6762
->getMockForAbstractClass();
6863
$this->stateMock = $this->getMockBuilder(State::class)
6964
->disableOriginalConstructor()
@@ -84,29 +79,34 @@ public function testBeforeGetFilteredProperties(): void
8479
{
8580
$integrityRepositoryMock = $this->getMockBuilder(SubresourceIntegrityRepository::class)
8681
->disableOriginalConstructor()
87-
->onlyMethods(['getByUrl'])
82+
->onlyMethods(['getByPath'])
8883
->getMock();
8984
$groupedCollectionMock = $this->getMockBuilder(GroupedCollection::class)
9085
->disableOriginalConstructor()
9186
->getMock();
92-
$url = 'https://magento.test/static/version1708401324/frontend/Magento/luma/en_US/jquery.js';
87+
$path = 'jquery.js';
9388
$area = 'frontend';
9489

9590
$data = new SubresourceIntegrity(
9691
[
9792
'hash' => 'testhash',
98-
'url' => $url
93+
'path' => $path
9994
]
10095
);
10196
$properties['attributes']['integrity'] = $data->getHash();
10297
$properties['attributes']['crossorigin'] = 'anonymous';
10398
$expected = [$this->assetInterfaceMock, $properties];
10499
$this->stateMock->expects($this->once())->method('getAreaCode')->willReturn($area);
105-
$this->integrityRepositoryPoolMock->expects($this->once())->method('get')->with($area)->willReturn($integrityRepositoryMock);
106-
$this->assetInterfaceMock->expects($this->once())->method('getUrl')->willReturn($url);
107-
$integrityRepositoryMock->expects($this->once())->method('getByUrl')->with($url)->willReturn($data);
108-
$this->assertEquals($expected,
109-
$this->plugin->beforeGetFilteredProperties($groupedCollectionMock, $this->assetInterfaceMock
100+
$this->integrityRepositoryPoolMock->expects($this->once())->method('get')->with($area)
101+
->willReturn(
102+
$integrityRepositoryMock
103+
);
104+
$this->assetInterfaceMock->expects($this->once())->method('getPath')->willReturn($path);
105+
$integrityRepositoryMock->expects($this->once())->method('getByPath')->with($path)->willReturn($data);
106+
$this->assertEquals(
107+
$expected,
108+
$this->plugin->beforeGetFilteredProperties(
109+
$groupedCollectionMock, $this->assetInterfaceMock
110110
)
111111
);
112112
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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\Csp\Test\Unit\Plugin;
9+
10+
use Magento\Csp\Model\SubresourceIntegrity;
11+
use Magento\Csp\Model\SubresourceIntegrityRepository;
12+
use Magento\Csp\Model\SubresourceIntegrityRepositoryPool;
13+
use Magento\Deploy\Service\DeployStaticContent;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use Magento\Csp\Plugin\StoreAssetIntegrityHashes;
16+
use Magento\Csp\Model\SubresourceIntegrityCollector;
17+
use PHPUnit\Framework\TestCase;
18+
19+
/**
20+
* Plugin that removes existing integrity hashes for all assets.
21+
*/
22+
class StoreAssetIntegrityHashesTest extends TestCase
23+
{
24+
/**
25+
* @var MockObject
26+
*/
27+
private MockObject $integrityRepositoryPoolMock;
28+
29+
/**
30+
* @var MockObject
31+
*/
32+
private MockObject $integrityCollectorMock;
33+
34+
/**
35+
* @var StoreAssetIntegrityHashes
36+
*/
37+
private StoreAssetIntegrityHashes $plugin;
38+
39+
/**
40+
* Initialize Dependencies
41+
*
42+
* @return void
43+
*/
44+
protected function setUp(): void
45+
{
46+
parent::setUp();
47+
$this->integrityRepositoryPoolMock = $this->getMockBuilder(SubresourceIntegrityRepositoryPool::class)
48+
->disableOriginalConstructor()
49+
->onlyMethods(['get'])
50+
->getMock();
51+
$this->integrityCollectorMock = $this->getMockBuilder(SubresourceIntegrityCollector::class)
52+
->disableOriginalConstructor()
53+
->onlyMethods(['release'])
54+
->getMock();
55+
$this->plugin = new StoreAssetIntegrityHashes(
56+
$this->integrityCollectorMock,
57+
$this->integrityRepositoryPoolMock,
58+
);
59+
}
60+
61+
/**
62+
* Test After Deploy method of plugin
63+
*
64+
* @return void
65+
* @doesNotPerformAssertions
66+
*/
67+
public function testAfterDeploy(): void
68+
{
69+
$bunch1 = new SubresourceIntegrity(
70+
[
71+
'hash' => 'testhash',
72+
'path' => 'adminhtml/js/jquery.js'
73+
]
74+
);
75+
76+
$bunch2 = new SubresourceIntegrity(
77+
[
78+
'hash' => 'testhash2',
79+
'path' => 'frontend/js/test.js'
80+
]
81+
);
82+
83+
$bunches = [$bunch1, $bunch2];
84+
$deployStaticContentMock = $this->getMockBuilder(DeployStaticContent::class)
85+
->disableOriginalConstructor()
86+
->getMock();
87+
$subResourceIntegrityMock = $this->getMockBuilder(SubresourceIntegrityRepository::class)
88+
->disableOriginalConstructor()
89+
->onlyMethods(['saveBunch'])
90+
->getMock();
91+
$this->integrityCollectorMock->expects($this->once())->method('release')->willReturn($bunches);
92+
$this->integrityRepositoryPoolMock->expects($this->any())->method('get')->willReturn($subResourceIntegrityMock);
93+
$subResourceIntegrityMock->expects($this->any())->method('saveBunch')->willReturn(true);
94+
$this->plugin->afterDeploy($deployStaticContentMock, null, []);
95+
}
96+
}
97+
98+

app/code/Magento/Csp/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"php": "~8.1.0||~8.2.0||~8.3.0",
99
"magento/framework": "*",
1010
"magento/module-store": "*",
11-
"magento/module-require-js": "*"
11+
"magento/module-require-js": "*",
12+
"magento/module-deploy": "*"
1213
},
1314
"type": "magento2-module",
1415
"license": [

app/code/Magento/Csp/view/base/templates/sri/hashes.phtml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66

77
/** @var \Magento\Csp\Block\Sri\Hashes $block */
88
/** @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer */
9+
//phpcs:ignore Magento2.GraphQL
910
?>
1011

1112
<?php $sriHashes = /* @noEscape */ $block->getSerialized();
13+
//@codingStandardsIgnoreStart
1214
$scriptString = <<<script
1315
window.sriHashes = {$sriHashes};
1416
script;
17+
//@codingStandardsIgnoreStart
1518
?>
1619

1720
<?= /* @noEscape */ $secureRenderer->renderTag('script', [], $scriptString, false) ?>

0 commit comments

Comments
 (0)