diff --git a/core/modules/user/tests/src/Unit/Plugin/Validation/Constraint/UserMailRequiredValidatorTest.php b/core/modules/user/tests/src/Unit/Plugin/Validation/Constraint/UserMailRequiredValidatorTest.php new file mode 100644 index 0000000000..c36ff97d73 --- /dev/null +++ b/core/modules/user/tests/src/Unit/Plugin/Validation/Constraint/UserMailRequiredValidatorTest.php @@ -0,0 +1,152 @@ +prophesize(UserInterface::class); + $unchanged_account->getEmail()->willReturn(NULL); + + $user_storage = $this->prophesize(UserStorageInterface::class); + $user_storage->loadUnchanged('current-user')->willReturn($unchanged_account->reveal()); + + $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class); + $entity_type_manager->getStorage('user')->willReturn($user_storage->reveal()); + + $current_user = $this->prophesize(AccountInterface::class); + $current_user->id()->willReturn('current-user'); + $current_user->hasPermission("administer users")->willReturn($is_admin); + $container = new ContainerBuilder(); + $container->set('entity_type.manager', $entity_type_manager->reveal()); + $container->set('current_user', $current_user->reveal()); + \Drupal::setContainer($container); + return new UserMailRequiredValidator(); + } + + /** + * @covers ::validate + * + * @dataProvider providerTestValidate + */ + public function testValidate($items, $expected_violation, $is_admin = FALSE) { + $constraint = new UserMailRequired(); + + // If a violation is expected, then the context's addViolation method will + // be called, otherwise it should not be called. + $context = $this->prophesize(ExecutionContextInterface::class); + + if ($expected_violation) { + $context->addViolation('@name field is required.', ["@name" => "label"])->shouldBeCalledTimes(1); + } + else { + $context->addViolation()->shouldNotBeCalled(1); + } + + $validator = $this->createValidator($is_admin); + $validator->initialize($context->reveal()); + $validator->validate($items, $constraint); + } + + /** + * Data provider for ::testValidate(). + */ + public function providerTestValidate() { + $cases = []; + + // Case 1: Empty user should be ignored. + $items = $this->prophesize(FieldItemListInterface::class); + $items->getEntity()->willReturn(NULL)->shouldBeCalledTimes(1); + $cases['Empty user should be ignored'] = [$items->reveal(), FALSE]; + + // Case 2: New users without an email should add a violation. + $items = $this->prophesize(FieldItemListInterface::class); + $account = $this->prophesize(UserInterface::class); + $account->isNew()->willReturn(TRUE); + $account->id()->shouldNotBeCalled(); + $field_definition = $this->prophesize(FieldDefinitionInterface::class); + $field_definition->getLabel()->willReturn('label'); + $account->getFieldDefinition("mail")->willReturn($field_definition->reveal())->shouldBeCalledTimes(1); + $items->getEntity()->willReturn($account->reveal())->shouldBeCalledTimes(1); + $items->isEmpty()->willReturn(TRUE); + $cases['New users without an email should add a violation'] = [$items->reveal(), TRUE]; + + // Case 3: Existing users without an email should add a violation. + $items = $this->prophesize(FieldItemListInterface::class); + $account = $this->prophesize(UserInterface::class); + $account->isNew()->willReturn(FALSE); + $account->id()->willReturn('current-user'); + $field_definition = $this->prophesize(FieldDefinitionInterface::class); + $field_definition->getLabel()->willReturn('label'); + $account->getFieldDefinition("mail")->willReturn($field_definition->reveal())->shouldBeCalledTimes(1); + $items->getEntity()->willReturn($account->reveal())->shouldBeCalledTimes(1); + $items->isEmpty()->willReturn(TRUE); + $cases['Existing users without an email should add a violation'] = [$items->reveal(), TRUE]; + + // Case 4: New users with an email should be ignored. + $items = $this->prophesize(FieldItemListInterface::class); + $account = $this->prophesize(UserInterface::class); + $account->isNew()->willReturn(TRUE); + $account->id()->shouldNotBeCalled(); + $field_definition = $this->prophesize(FieldDefinitionInterface::class); + $field_definition->getLabel()->willReturn('label'); + $account->getFieldDefinition("mail")->willReturn($field_definition->reveal())->shouldBeCalledTimes(1); + $items->getEntity()->willReturn($account->reveal())->shouldBeCalledTimes(1); + $items->isEmpty()->willReturn(FALSE); + $cases['New users with an email should be ignored'] = [$items->reveal(), FALSE]; + + // Case 5: Existing users with an email should be ignored. + $items = $this->prophesize(FieldItemListInterface::class); + $account = $this->prophesize(UserInterface::class); + $account->isNew()->willReturn(FALSE); + $account->id()->willReturn('current-user'); + $field_definition = $this->prophesize(FieldDefinitionInterface::class); + $field_definition->getLabel()->willReturn('label'); + $account->getFieldDefinition("mail")->willReturn($field_definition->reveal())->shouldBeCalledTimes(1); + $items->getEntity()->willReturn($account->reveal())->shouldBeCalledTimes(1); + $items->isEmpty()->willReturn(FALSE); + $cases['Existing users with an email should be ignored'] = [$items->reveal(), FALSE]; + + // Case 6: Existing users without an email should be ignored if the current + // user is an administrator. + $items = $this->prophesize(FieldItemListInterface::class); + $account = $this->prophesize(UserInterface::class); + $account->isNew()->willReturn(FALSE); + $account->id()->willReturn('current-user'); + $field_definition = $this->prophesize(FieldDefinitionInterface::class); + $field_definition->getLabel()->willReturn('label'); + $account->getFieldDefinition("mail")->willReturn($field_definition->reveal())->shouldBeCalledTimes(1); + $items->getEntity()->willReturn($account->reveal())->shouldBeCalledTimes(1); + $items->isEmpty()->willReturn(TRUE); + $cases['Existing users without an email should be ignored if the current user is an administrator.'] = [$items->reveal(), FALSE, TRUE]; + + return $cases; + } + +}