|
11 | 11 | use Magento\Framework\Acl; |
12 | 12 | use Magento\Framework\Acl\Data\CacheInterface; |
13 | 13 | use Magento\Framework\Acl\RootResource; |
| 14 | +use Magento\Framework\Acl\Role\CurrentRoleContext; |
14 | 15 | use Magento\Framework\App\ResourceConnection; |
15 | 16 | use Magento\Framework\Serialize\Serializer\Json; |
16 | 17 | use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; |
@@ -54,8 +55,8 @@ protected function setUp(): void |
54 | 55 | { |
55 | 56 | $this->rootResource = new RootResource('Magento_Backend::all'); |
56 | 57 | $this->resourceMock = $this->getMockBuilder(ResourceConnection::class) |
| 58 | + ->onlyMethods(['getConnection', 'getTableName']) |
57 | 59 | ->addMethods(['getTable']) |
58 | | - ->onlyMethods(['getConnection']) |
59 | 60 | ->disableOriginalConstructor() |
60 | 61 | ->getMock(); |
61 | 62 | $this->aclDataCacheMock = $this->getMockForAbstractClass(CacheInterface::class); |
@@ -147,4 +148,81 @@ public function testPopulateAclFromCache(): void |
147 | 148 |
|
148 | 149 | $this->model->populateAcl($aclMock); |
149 | 150 | } |
| 151 | + |
| 152 | + /** |
| 153 | + * Ensure that when a role context is present, rules are loaded from the role-specific cache key |
| 154 | + * and applied accordingly. |
| 155 | + */ |
| 156 | + public function testPopulateAclForSpecificRoleFromCache(): void |
| 157 | + { |
| 158 | + $roleId = 10; |
| 159 | + $rules = [ |
| 160 | + ['role_id' => $roleId, 'resource_id' => 'Magento_Backend::all', 'permission' => 'allow'], |
| 161 | + ['role_id' => $roleId, 'resource_id' => 'Magento_Backend::admin', 'permission' => 'allow'], |
| 162 | + ]; |
| 163 | + |
| 164 | + $roleContext = $this->createMock(CurrentRoleContext::class); |
| 165 | + $roleContext->method('getRoleId')->willReturn($roleId); |
| 166 | + |
| 167 | + // Expect the role-specific cache key to be read |
| 168 | + $this->aclDataCacheMock->expects($this->once()) |
| 169 | + ->method('load') |
| 170 | + ->with(Rule::ACL_RULE_CACHE_KEY . '_' . $roleId) |
| 171 | + ->willReturn(json_encode($rules)); |
| 172 | + |
| 173 | + // ACL expectations: allow for root, then for specific resource |
| 174 | + $aclMock = $this->createMock(Acl::class); |
| 175 | + $aclMock->method('hasResource')->willReturn(true); |
| 176 | + $calls = []; |
| 177 | + $aclMock->method('allow') |
| 178 | + ->willReturnCallback(function ($role, $resource, $privilege) use (&$calls) { |
| 179 | + $calls[] = [$role, $resource, $privilege]; |
| 180 | + return null; |
| 181 | + }); |
| 182 | + |
| 183 | + $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) |
| 184 | + ->disableOriginalConstructor() |
| 185 | + ->getMock(); |
| 186 | + $connectionMock->method('fetchRow')->willReturn([]); // Return empty array for any DB fetchRow() call |
| 187 | + |
| 188 | + $selectMock = $this->getMockBuilder('stdClass') |
| 189 | + ->addMethods(['from', 'where', 'limit']) |
| 190 | + ->getMock(); |
| 191 | + $selectMock->method('from')->willReturnSelf(); |
| 192 | + $selectMock->method('where')->willReturnSelf(); |
| 193 | + $selectMock->method('limit')->willReturnSelf(); |
| 194 | + $connectionMock->method('select')->willReturn($selectMock); |
| 195 | + $this->resourceMock->method('getConnection')->willReturn($connectionMock); |
| 196 | + $this->resourceMock->method('getTableName')->willReturn('authorization_role'); // Return dummy table name |
| 197 | + |
| 198 | + $objectManager = new ObjectManager($this); |
| 199 | + $model = $objectManager->getObject( |
| 200 | + Rule::class, |
| 201 | + [ |
| 202 | + 'rootResource' => $this->rootResource, |
| 203 | + 'resource' => $this->resourceMock, |
| 204 | + 'aclDataCache' => $this->aclDataCacheMock, |
| 205 | + 'serializer' => $this->serializerMock, |
| 206 | + 'roleContext' => $roleContext, |
| 207 | + ] |
| 208 | + ); |
| 209 | + |
| 210 | + $model->populateAcl($aclMock); |
| 211 | + |
| 212 | + $foundRootResourceAllow = false; |
| 213 | + $foundAdminResourceAllow = false; |
| 214 | + foreach ($calls as $call) { |
| 215 | + [$role, $resource, $privilege] = $call; |
| 216 | + if ($privilege === null && (int)$role === $roleId) { |
| 217 | + if ($resource === 'Magento_Backend::all') { |
| 218 | + $foundRootResourceAllow = true; |
| 219 | + } |
| 220 | + if ($resource === 'Magento_Backend::admin') { |
| 221 | + $foundAdminResourceAllow = true; |
| 222 | + } |
| 223 | + } |
| 224 | + } |
| 225 | + $this->assertTrue($foundRootResourceAllow, 'Expected allow() call for Magento_Backend::all with given role'); |
| 226 | + $this->assertTrue($foundAdminResourceAllow, 'Expected allow() call for Magento_Backend::admin with given role'); |
| 227 | + } |
150 | 228 | } |
0 commit comments