Chris@0: stringTranslation = new TestTranslationManager(); Chris@0: $this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Provides an extension object for a given module with a human name. Chris@0: * Chris@0: * @param string $module Chris@0: * The module machine name. Chris@0: * @param string $name Chris@0: * The module human name. Chris@0: * Chris@0: * @return \Drupal\Core\Extension\Extension Chris@0: * The extension object. Chris@0: */ Chris@0: protected function mockModuleExtension($module, $name) { Chris@0: $extension = new Extension($this->root, $module, "modules/$module"); Chris@0: $extension->info['name'] = $name; Chris@0: return $extension; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests permissions provided by YML files. Chris@0: * Chris@0: * @covers ::__construct Chris@0: * @covers ::getPermissions Chris@0: * @covers ::buildPermissionsYaml Chris@0: * @covers ::moduleProvidesPermissions Chris@0: */ Chris@0: public function testBuildPermissionsYaml() { Chris@0: vfsStreamWrapper::register(); Chris@0: $root = new vfsStreamDirectory('modules'); Chris@0: vfsStreamWrapper::setRoot($root); Chris@0: Chris@0: $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); Chris@0: $this->moduleHandler->expects($this->once()) Chris@0: ->method('getModuleDirectories') Chris@0: ->willReturn([ Chris@0: 'module_a' => vfsStream::url('modules/module_a'), Chris@0: 'module_b' => vfsStream::url('modules/module_b'), Chris@0: 'module_c' => vfsStream::url('modules/module_c'), Chris@0: ]); Chris@0: Chris@0: $url = vfsStream::url('modules'); Chris@0: mkdir($url . '/module_a'); Chris@0: file_put_contents($url . '/module_a/module_a.permissions.yml', "access_module_a: single_description"); Chris@0: mkdir($url . '/module_b'); Chris@0: file_put_contents($url . '/module_b/module_b.permissions.yml', << $this->mockModuleExtension('module_a', 'Module a'), Chris@0: 'module_b' => $this->mockModuleExtension('module_b', 'Module b'), Chris@0: 'module_c' => $this->mockModuleExtension('module_c', 'Module c'), Chris@0: ]; Chris@0: $this->moduleHandler->expects($this->any()) Chris@0: ->method('getImplementations') Chris@0: ->with('permission') Chris@0: ->willReturn([]); Chris@0: Chris@0: $this->moduleHandler->expects($this->any()) Chris@0: ->method('getModuleList') Chris@0: ->willReturn(array_flip($modules)); Chris@0: Chris@0: $this->controllerResolver->expects($this->never()) Chris@0: ->method('getControllerFromDefinition'); Chris@0: Chris@0: $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver); Chris@0: Chris@0: // Setup system_rebuild_module_data(). Chris@0: $this->permissionHandler->setSystemRebuildModuleData($extensions); Chris@0: Chris@0: $actual_permissions = $this->permissionHandler->getPermissions(); Chris@0: $this->assertPermissions($actual_permissions); Chris@0: Chris@0: $this->assertTrue($this->permissionHandler->moduleProvidesPermissions('module_a')); Chris@0: $this->assertTrue($this->permissionHandler->moduleProvidesPermissions('module_b')); Chris@0: $this->assertTrue($this->permissionHandler->moduleProvidesPermissions('module_c')); Chris@0: $this->assertFalse($this->permissionHandler->moduleProvidesPermissions('module_d')); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests permissions sort inside a module. Chris@0: * Chris@0: * @covers ::__construct Chris@0: * @covers ::getPermissions Chris@0: * @covers ::buildPermissionsYaml Chris@0: * @covers ::sortPermissions Chris@0: */ Chris@0: public function testBuildPermissionsSortPerModule() { Chris@0: vfsStreamWrapper::register(); Chris@0: $root = new vfsStreamDirectory('modules'); Chris@0: vfsStreamWrapper::setRoot($root); Chris@0: Chris@0: $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); Chris@0: $this->moduleHandler->expects($this->once()) Chris@0: ->method('getModuleDirectories') Chris@0: ->willReturn([ Chris@0: 'module_a' => vfsStream::url('modules/module_a'), Chris@0: 'module_b' => vfsStream::url('modules/module_b'), Chris@0: 'module_c' => vfsStream::url('modules/module_c'), Chris@0: ]); Chris@0: $this->moduleHandler->expects($this->exactly(3)) Chris@0: ->method('getName') Chris@0: ->will($this->returnValueMap([ Chris@0: ['module_a', 'Module a'], Chris@0: ['module_b', 'Module b'], Chris@0: ['module_c', 'A Module'], Chris@0: ])); Chris@0: Chris@0: $url = vfsStream::url('modules'); Chris@0: mkdir($url . '/module_a'); Chris@0: file_put_contents($url . '/module_a/module_a.permissions.yml', <<moduleHandler->expects($this->once()) Chris@0: ->method('getModuleList') Chris@0: ->willReturn(array_flip($modules)); Chris@0: Chris@0: $permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver); Chris@0: $actual_permissions = $permissionHandler->getPermissions(); Chris@0: $this->assertEquals(['access_module_a4', 'access_module_a1', 'access_module_a2', 'access_module_a3'], Chris@0: array_keys($actual_permissions)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests dynamic callback permissions provided by YML files. Chris@0: * Chris@0: * @covers ::__construct Chris@0: * @covers ::getPermissions Chris@0: * @covers ::buildPermissionsYaml Chris@0: */ Chris@0: public function testBuildPermissionsYamlCallback() { Chris@0: vfsStreamWrapper::register(); Chris@0: $root = new vfsStreamDirectory('modules'); Chris@0: vfsStreamWrapper::setRoot($root); Chris@0: Chris@0: $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); Chris@0: $this->moduleHandler->expects($this->once()) Chris@0: ->method('getModuleDirectories') Chris@0: ->willReturn([ Chris@0: 'module_a' => vfsStream::url('modules/module_a'), Chris@0: 'module_b' => vfsStream::url('modules/module_b'), Chris@0: 'module_c' => vfsStream::url('modules/module_c'), Chris@0: ]); Chris@0: Chris@0: $url = vfsStream::url('modules'); Chris@0: mkdir($url . '/module_a'); Chris@0: file_put_contents($url . '/module_a/module_a.permissions.yml', << $this->mockModuleExtension('module_a', 'Module a'), Chris@0: 'module_b' => $this->mockModuleExtension('module_b', 'Module b'), Chris@0: 'module_c' => $this->mockModuleExtension('module_c', 'Module c'), Chris@0: ]; Chris@0: Chris@0: $this->moduleHandler->expects($this->any()) Chris@0: ->method('getImplementations') Chris@0: ->with('permission') Chris@0: ->willReturn([]); Chris@0: Chris@0: $this->moduleHandler->expects($this->any()) Chris@0: ->method('getModuleList') Chris@0: ->willReturn(array_flip($modules)); Chris@0: Chris@0: $this->controllerResolver->expects($this->at(0)) Chris@0: ->method('getControllerFromDefinition') Chris@0: ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::singleDescription') Chris@0: ->willReturn([new TestPermissionCallbacks(), 'singleDescription']); Chris@0: $this->controllerResolver->expects($this->at(1)) Chris@0: ->method('getControllerFromDefinition') Chris@0: ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription') Chris@0: ->willReturn([new TestPermissionCallbacks(), 'titleDescription']); Chris@0: $this->controllerResolver->expects($this->at(2)) Chris@0: ->method('getControllerFromDefinition') Chris@0: ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleProvider') Chris@0: ->willReturn([new TestPermissionCallbacks(), 'titleProvider']); Chris@0: $this->controllerResolver->expects($this->at(3)) Chris@0: ->method('getControllerFromDefinition') Chris@0: ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescriptionRestrictAccess') Chris@0: ->willReturn([new TestPermissionCallbacks(), 'titleDescriptionRestrictAccess']); Chris@0: Chris@0: $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver); Chris@0: Chris@0: // Setup system_rebuild_module_data(). Chris@0: $this->permissionHandler->setSystemRebuildModuleData($extensions); Chris@0: Chris@0: $actual_permissions = $this->permissionHandler->getPermissions(); Chris@0: $this->assertPermissions($actual_permissions); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests a YAML file containing both static permissions and a callback. Chris@0: */ Chris@0: public function testPermissionsYamlStaticAndCallback() { Chris@0: vfsStreamWrapper::register(); Chris@0: $root = new vfsStreamDirectory('modules'); Chris@0: vfsStreamWrapper::setRoot($root); Chris@0: Chris@0: $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); Chris@0: $this->moduleHandler->expects($this->once()) Chris@0: ->method('getModuleDirectories') Chris@0: ->willReturn([ Chris@0: 'module_a' => vfsStream::url('modules/module_a'), Chris@0: ]); Chris@0: Chris@0: $url = vfsStream::url('modules'); Chris@0: mkdir($url . '/module_a'); Chris@0: file_put_contents($url . '/module_a/module_a.permissions.yml', << $this->mockModuleExtension('module_a', 'Module a'), Chris@0: ]; Chris@0: Chris@0: $this->moduleHandler->expects($this->any()) Chris@0: ->method('getImplementations') Chris@0: ->with('permission') Chris@0: ->willReturn([]); Chris@0: Chris@0: $this->moduleHandler->expects($this->any()) Chris@0: ->method('getModuleList') Chris@0: ->willReturn(array_flip($modules)); Chris@0: Chris@0: $this->controllerResolver->expects($this->once()) Chris@0: ->method('getControllerFromDefinition') Chris@0: ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription') Chris@0: ->willReturn([new TestPermissionCallbacks(), 'titleDescription']); Chris@0: Chris@0: $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver); Chris@0: Chris@0: // Setup system_rebuild_module_data(). Chris@0: $this->permissionHandler->setSystemRebuildModuleData($extensions); Chris@0: Chris@0: $actual_permissions = $this->permissionHandler->getPermissions(); Chris@0: Chris@0: $this->assertCount(2, $actual_permissions); Chris@0: $this->assertEquals($actual_permissions['access module a']['title'], 'Access A'); Chris@0: $this->assertEquals($actual_permissions['access module a']['provider'], 'module_a'); Chris@0: $this->assertEquals($actual_permissions['access module a']['description'], 'bla bla'); Chris@0: $this->assertEquals($actual_permissions['access module b']['title'], 'Access B'); Chris@0: $this->assertEquals($actual_permissions['access module b']['provider'], 'module_a'); Chris@0: $this->assertEquals($actual_permissions['access module b']['description'], 'bla bla'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Checks that the permissions are like expected. Chris@0: * Chris@0: * @param array $actual_permissions Chris@0: * The actual permissions Chris@0: */ Chris@0: protected function assertPermissions(array $actual_permissions) { Chris@0: $this->assertCount(4, $actual_permissions); Chris@0: $this->assertEquals($actual_permissions['access_module_a']['title'], 'single_description'); Chris@0: $this->assertEquals($actual_permissions['access_module_a']['provider'], 'module_a'); Chris@0: $this->assertEquals($actual_permissions['access module b']['title'], 'Access B'); Chris@0: $this->assertEquals($actual_permissions['access module b']['provider'], 'module_b'); Chris@0: $this->assertEquals($actual_permissions['access_module_c']['title'], 'Access C'); Chris@0: $this->assertEquals($actual_permissions['access_module_c']['provider'], 'module_c'); Chris@0: $this->assertEquals($actual_permissions['access_module_c']['restrict access'], TRUE); Chris@0: $this->assertEquals($actual_permissions['access module a via module b']['provider'], 'module_a'); Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestPermissionHandler extends PermissionHandler { Chris@0: Chris@0: /** Chris@0: * Test module data. Chris@0: * Chris@0: * @var array Chris@0: */ Chris@0: protected $systemModuleData; Chris@0: Chris@0: protected function systemRebuildModuleData() { Chris@0: return $this->systemModuleData; Chris@0: } Chris@0: Chris@0: public function setSystemRebuildModuleData(array $extensions) { Chris@0: $this->systemModuleData = $extensions; Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: class TestPermissionCallbacks { Chris@0: Chris@0: public function singleDescription() { Chris@0: return [ Chris@17: 'access_module_a' => 'single_description', Chris@0: ]; Chris@0: } Chris@0: Chris@0: public function titleDescription() { Chris@0: return [ Chris@0: 'access module b' => [ Chris@0: 'title' => 'Access B', Chris@0: 'description' => 'bla bla', Chris@0: ], Chris@0: ]; Chris@0: } Chris@0: Chris@0: public function titleDescriptionRestrictAccess() { Chris@0: return [ Chris@0: 'access_module_c' => [ Chris@0: 'title' => 'Access C', Chris@0: 'description' => 'bla bla', Chris@0: 'restrict access' => TRUE, Chris@0: ], Chris@0: ]; Chris@0: } Chris@0: Chris@0: public function titleProvider() { Chris@0: return [ Chris@0: 'access module a via module b' => [ Chris@0: 'title' => 'Access A via B', Chris@0: 'provider' => 'module_a', Chris@0: ], Chris@0: ]; Chris@0: } Chris@0: Chris@0: } Chris@0: Chris@0: /** Chris@0: * Implements a translation manager in tests. Chris@0: */ Chris@0: class TestTranslationManager implements TranslationInterface { Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function translate($string, array $args = [], array $options = []) { Chris@0: return new TranslatableMarkup($string, $args, $options, $this); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function translateString(TranslatableMarkup $translated_string) { Chris@0: return $translated_string->getUntranslatedString(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function formatPlural($count, $singular, $plural, array $args = [], array $options = []) { Chris@0: return new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $this); Chris@0: } Chris@0: Chris@0: }