Skip to content

Commit 62ede2b

Browse files
committed
AC-15165: SRI Improvements.
Static test fixes. Added Unit test.
1 parent 602bd0b commit 62ede2b

File tree

5 files changed

+193
-11
lines changed

5 files changed

+193
-11
lines changed

app/code/Magento/Csp/Model/Deploy/Package/Processor/PostProcessor/Integrity.php

Lines changed: 5 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 2025 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -74,7 +74,8 @@ public function __construct(
7474
$this->integrityFactory = $integrityFactory;
7575
$this->integrityCollector = $integrityCollector;
7676
$this->logger = $logger ?? ObjectManager::getInstance()->get(LoggerInterface::class);
77-
$this->repositoryPool = $repositoryPool ?? ObjectManager::getInstance()->get(SubresourceIntegrityRepositoryPool::class);
77+
$this->repositoryPool = $repositoryPool ??
78+
ObjectManager::getInstance()->get(SubresourceIntegrityRepositoryPool::class);
7879
}
7980

8081
/**
@@ -110,6 +111,7 @@ public function process(Package $package, array $options): bool
110111
try {
111112
$this->repositoryPool->get($area)->saveBunch($collectedData);
112113
} catch (\Exception $e) {
114+
//phpcs:ignore
113115
$this->logger->error('Integrity PostProcessor: Failed saving to ' . $area . ' repository: ' . $e->getMessage());
114116
}
115117

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

Lines changed: 2 additions & 2 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 2025 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

app/code/Magento/Csp/Plugin/RemoveAllAssetIntegrityHashes.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 2025 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -61,7 +61,7 @@ public function beforeDeploy(
6161
$this->integrityRepositoryPool->get($area)
6262
->deleteAll();
6363
}
64-
64+
6565
// Clear any leftover in-memory integrity hashes from previous runs
6666
$this->integrityCollector->clear();
6767
}

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

Lines changed: 14 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 2025 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -10,6 +10,8 @@
1010
use Magento\Deploy\Service\DeployStaticContent;
1111
use Magento\Csp\Model\SubresourceIntegrityCollector;
1212
use Magento\Csp\Model\SubresourceIntegrityRepositoryPool;
13+
use Psr\Log\LoggerInterface;
14+
use Magento\Framework\App\ObjectManager;
1315

1416
/**
1517
* Plugin that stores generated integrity hashes for all assets.
@@ -26,16 +28,25 @@ class StoreAssetIntegrityHashes
2628
*/
2729
private SubresourceIntegrityRepositoryPool $integrityRepositoryPool;
2830

31+
/**
32+
* @var LoggerInterface
33+
*/
34+
private LoggerInterface $logger;
35+
2936
/**
3037
* @param SubresourceIntegrityCollector $integrityCollector
3138
* @param SubresourceIntegrityRepositoryPool $integrityRepositoryPool
39+
* @param LoggerInterface $logger|null
3240
*/
3341
public function __construct(
3442
SubresourceIntegrityCollector $integrityCollector,
35-
SubresourceIntegrityRepositoryPool $integrityRepositoryPool
43+
SubresourceIntegrityRepositoryPool $integrityRepositoryPool,
44+
LoggerInterface $logger = null
3645
) {
3746
$this->integrityCollector = $integrityCollector;
3847
$this->integrityRepositoryPool = $integrityRepositoryPool;
48+
$this->logger = $logger ??
49+
ObjectManager::getInstance()->get(LoggerInterface::class);
3950
}
4051

4152
/**
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Csp\Test\Unit\Model;
9+
10+
use Magento\Csp\Model\SubresourceIntegrity;
11+
use Magento\Csp\Model\SubresourceIntegrityCollector;
12+
use PHPUnit\Framework\MockObject\MockObject;
13+
use PHPUnit\Framework\TestCase;
14+
15+
/**
16+
* Unit Test for Class @see Magento\Csp\Model\SubresourceIntegrityCollector
17+
*/
18+
class SubresourceIntegrityCollectorTest extends TestCase
19+
{
20+
/**
21+
* @var SubresourceIntegrityCollector
22+
*/
23+
private SubresourceIntegrityCollector $collector;
24+
25+
/**
26+
* Setup test
27+
*/
28+
protected function setUp(): void
29+
{
30+
$this->collector = new SubresourceIntegrityCollector();
31+
}
32+
33+
/**
34+
* Test that collect method adds integrity objects to internal storage
35+
*/
36+
public function testCollectAddsIntegrityObject(): void
37+
{
38+
$integrityMock = $this->createMock(SubresourceIntegrity::class);
39+
40+
$this->collector->collect($integrityMock);
41+
42+
$result = $this->collector->release();
43+
$this->assertCount(1, $result);
44+
$this->assertSame($integrityMock, $result[0]);
45+
}
46+
47+
/**
48+
* Test that multiple collect calls accumulate objects
49+
*/
50+
public function testMultipleCollectCallsAccumulate(): void
51+
{
52+
$integrity1 = $this->createMock(SubresourceIntegrity::class);
53+
$integrity2 = $this->createMock(SubresourceIntegrity::class);
54+
$integrity3 = $this->createMock(SubresourceIntegrity::class);
55+
56+
$this->collector->collect($integrity1);
57+
$this->collector->collect($integrity2);
58+
$this->collector->collect($integrity3);
59+
60+
$result = $this->collector->release();
61+
$this->assertCount(3, $result);
62+
$this->assertSame($integrity1, $result[0]);
63+
$this->assertSame($integrity2, $result[1]);
64+
$this->assertSame($integrity3, $result[2]);
65+
}
66+
67+
/**
68+
* Test that release returns empty array when no objects collected
69+
*/
70+
public function testReleaseReturnsEmptyArrayWhenEmpty(): void
71+
{
72+
$result = $this->collector->release();
73+
74+
$this->assertIsArray($result);
75+
$this->assertEmpty($result);
76+
}
77+
78+
/**
79+
* Test that release does not clear the internal data
80+
*/
81+
public function testReleaseDoesNotClearData(): void
82+
{
83+
$integrityMock = $this->createMock(SubresourceIntegrity::class);
84+
85+
$this->collector->collect($integrityMock);
86+
87+
// Call release multiple times
88+
$result1 = $this->collector->release();
89+
$result2 = $this->collector->release();
90+
91+
$this->assertCount(1, $result1);
92+
$this->assertCount(1, $result2);
93+
$this->assertSame($integrityMock, $result1[0]);
94+
$this->assertSame($integrityMock, $result2[0]);
95+
}
96+
97+
/**
98+
* Test that clear method empties the internal storage
99+
*/
100+
public function testClearEmptiesInternalStorage(): void
101+
{
102+
$integrity1 = $this->createMock(SubresourceIntegrity::class);
103+
$integrity2 = $this->createMock(SubresourceIntegrity::class);
104+
105+
// Add some objects
106+
$this->collector->collect($integrity1);
107+
$this->collector->collect($integrity2);
108+
109+
// Verify they're there
110+
$resultBeforeClear = $this->collector->release();
111+
$this->assertCount(2, $resultBeforeClear);
112+
113+
// Clear the data
114+
$this->collector->clear();
115+
116+
// Verify it's empty
117+
$resultAfterClear = $this->collector->release();
118+
$this->assertEmpty($resultAfterClear);
119+
}
120+
121+
/**
122+
* Test that collector works properly after clear
123+
*/
124+
public function testCollectorWorksAfterClear(): void
125+
{
126+
$integrity1 = $this->createMock(SubresourceIntegrity::class);
127+
$integrity2 = $this->createMock(SubresourceIntegrity::class);
128+
129+
// Add and clear
130+
$this->collector->collect($integrity1);
131+
$this->collector->clear();
132+
133+
// Add new data
134+
$this->collector->collect($integrity2);
135+
136+
$result = $this->collector->release();
137+
$this->assertCount(1, $result);
138+
$this->assertSame($integrity2, $result[0]);
139+
}
140+
141+
/**
142+
* Test collect, release, clear cycle
143+
*/
144+
public function testCompleteCollectReleaseClearCycle(): void
145+
{
146+
$integrity1 = $this->createMock(SubresourceIntegrity::class);
147+
$integrity2 = $this->createMock(SubresourceIntegrity::class);
148+
149+
// Initially empty
150+
$this->assertEmpty($this->collector->release());
151+
152+
// Collect objects
153+
$this->collector->collect($integrity1);
154+
$this->collector->collect($integrity2);
155+
156+
// Release should return collected objects
157+
$released = $this->collector->release();
158+
$this->assertCount(2, $released);
159+
$this->assertSame($integrity1, $released[0]);
160+
$this->assertSame($integrity2, $released[1]);
161+
162+
// Data should still be there after release
163+
$this->assertCount(2, $this->collector->release());
164+
165+
// Clear should empty everything
166+
$this->collector->clear();
167+
$this->assertEmpty($this->collector->release());
168+
}
169+
}

0 commit comments

Comments
 (0)