Skip to content

Commit

Permalink
Updates following PR comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
denis-getopensocial committed Oct 30, 2024
1 parent 85bf835 commit cf40d65
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,4 @@ services:
social_group.current_group:
class: Drupal\social_group\CurrentGroupService
arguments:
- '@entity_type.manager'
- '@group.group_route_context'
- '@context.repository'
52 changes: 14 additions & 38 deletions modules/social_features/social_group/src/CurrentGroupService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

namespace Drupal\social_group;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\group\Entity\GroupInterface;

/**
Expand All @@ -14,63 +13,40 @@
class CurrentGroupService {

/**
* The entity type manager.
* The context repository interface.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
* @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
*/
private EntityTypeManagerInterface $entityTypeManager;

/**
* The group route context.
*
* @var \Drupal\Core\Plugin\Context\ContextProviderInterface
*/
private ContextProviderInterface $groupRouteContext;
private ContextRepositoryInterface $contextRepository;

/**
* Constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Plugin\Context\ContextProviderInterface $group_route_context
* The group route context.
* @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository
* The context repository.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
ContextProviderInterface $group_route_context,
ContextRepositoryInterface $context_repository,
) {
$this->entityTypeManager = $entity_type_manager;
$this->groupRouteContext = $group_route_context;
$this->contextRepository = $context_repository;
}

/**
* Get group from runtime contexts.
*
* @return \Drupal\group\Entity\GroupInterface|null
* The current group or NULL.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function fromRunTimeContexts(): ?GroupInterface {
$runtime_context = $this->groupRouteContext->getRuntimeContexts([]);
if (isset($runtime_context['group']) === FALSE) {
return NULL;
}
$group_runtime_context = $this->contextRepository->getRuntimeContexts(['@group.group_route_context:group']);

$group = $runtime_context['group']->getContextData()->getValue();
if ($group instanceof GroupInterface) {
return $group;
}

if (is_int($group) === TRUE) {
/** @var \Drupal\group\Entity\GroupInterface $loadedGroup */
$loadedGroup = $this->entityTypeManager
->getStorage('group')->load($group);
return $loadedGroup;
$group = $group_runtime_context['@group.group_route_context:group']->getContextData()->getValue();
if ($group === NULL) {
return NULL;
}

return NULL;
assert($group instanceof GroupInterface, "The group context resolver returned a context value that is not a GroupInterface instance which violates the services contract.");
return $group;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace Drupal\Tests\social_group\Unit;

use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Context\ContextInterface;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\group\Entity\GroupInterface;
use Drupal\social_group\CurrentGroupService;
Expand All @@ -20,142 +18,74 @@
class CurrentGroupServiceTest extends UnitTestCase {

/**
* The mocked EntityTypeManagerInterface.
* The mocked context repository interface.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit\Framework\MockObject\MockObject
* @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject
*/
private EntityTypeManagerInterface|MockObject $entityTypeManager;

/**
* The mocked ContextProviderInterface.
*
* @var \Drupal\Core\Plugin\Context\ContextProviderInterface|\PHPUnit\Framework\MockObject\MockObject
*/
private ContextProviderInterface|MockObject $groupRouteContext;
protected ContextRepositoryInterface|MockObject $contextRepository;

/**
* The service under test.
*
* @var \Drupal\social_group\CurrentGroupService
*/
private CurrentGroupService $currentGroupService;
protected CurrentGroupService $currentGroupService;

/**
* Set up the test case.
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->contextRepository = $this->createMock(ContextRepositoryInterface::class);

$this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
$this->groupRouteContext = $this->createMock(ContextProviderInterface::class);

$this->currentGroupService = new CurrentGroupService(
$this->entityTypeManager,
$this->groupRouteContext
);
}

/**
* Helper function to create a mock context.
*
* @param mixed $value
* The value returned by typeDataInterface.
*
* @return \Drupal\Core\Plugin\Context\ContextInterface
* The updated mock context.
*/
private function createContextWithValue(mixed $value): ContextInterface {
$typeDataInterface = $this->createMock(TypedDataInterface::class);
$typeDataInterface->expects($this->once())
->method('getValue')
->willReturn($value);

$context = $this->createMock(ContextInterface::class);
$context->expects($this->once())
->method('getContextData')
->willReturn($typeDataInterface);

return $context;
}

/**
* Test that fromRunTimeContexts() returns NULL when no group context is set.
*/
public function testFromRunTimeContextsNoGroupContext(): void {
$this->groupRouteContext
->expects($this->once())
->method('getRuntimeContexts')
->willReturn([]);

$group = $this->currentGroupService->fromRunTimeContexts();

$this->assertNull($group, 'No group context should return NULL.');
$this->currentGroupService = new CurrentGroupService($this->contextRepository);
}

/**
* Test that fromRunTimeContexts() returns a GroupInterface when available.
* Test that fromRunTimeContexts() returns a Group when a group is present.
*/
public function testFromRunTimeContextsWithGroup(): void {
$group = $this->createMock(GroupInterface::class);
$context = $this->createContextWithValue($group);

$this->groupRouteContext
->expects($this->once())
->method('getRuntimeContexts')
->willReturn(['group' => $context]);
$this->mockContext($group);

// Call the method and assert the group is returned.
$result = $this->currentGroupService->fromRunTimeContexts();

$this->assertSame($group, $result, 'Group should be returned when found in context.');
$this->assertSame($group, $result, 'Group context should return a GroupInterface instance.');
}

/**
* Test that fromRunTimeContexts() loads a group by ID.
* Test that fromRunTimeContexts() returns NULL when group is not present.
*/
public function testFromRunTimeContextsWithGroupId(): void {
$groupId = 1;
$group = $this->createMock(GroupInterface::class);

$context = $this->createContextWithValue($groupId);

$this->groupRouteContext
->expects($this->once())
->method('getRuntimeContexts')
->willReturn(['group' => $context]);

$storage = $this->createMock(EntityStorageInterface::class);
$this->entityTypeManager
->expects($this->once())
->method('getStorage')
->with('group')
->willReturn($storage);

$storage
->expects($this->once())
->method('load')
->with($groupId)
->willReturn($group);
public function testFromRunTimeContextsWithoutGroup(): void {
$this->mockContext(NULL);

// Call the method and assert NULL is returned.
$result = $this->currentGroupService->fromRunTimeContexts();

$this->assertSame($group, $result, 'Group should be loaded by ID and returned.');
$this->assertNull($result, 'Group context should return NULL.');
}

/**
* Test that fromRunTimeContexts() returns NULL when no valid group found.
* Mock the context.
*
* @param \PHPUnit\Framework\MockObject\MockObject|\Drupal\group\Entity\GroupInterface|null $group
* The mocked group or NULL.
*/
public function testFromRunTimeContextsInvalidGroup(): void {
$invalidValue = 'invalid';
$context = $this->createContextWithValue($invalidValue);
private function mockContext(MockObject|GroupInterface|NULL $group): void {
$typedData = $this->createMock(TypedDataInterface::class);
$typedData->expects($this->once())
->method('getValue')
->willReturn($group);

$context = $this->createMock(ContextInterface::class);
$context->expects($this->once())
->method('getContextData')
->willReturn($typedData);

$this->groupRouteContext
$this->contextRepository
->expects($this->once())
->method('getRuntimeContexts')
->willReturn(['group' => $context]);

$result = $this->currentGroupService->fromRunTimeContexts();

$this->assertNull($result, 'Invalid group value should return NULL.');
->with(['@group.group_route_context:group'])
->willReturn(['@group.group_route_context:group' => $context]);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class PostPhotoBlock extends PostBlock {
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
$plugin_id,
$plugin_definition,
EntityTypeManagerInterface $entity_type_manager,
AccountProxyInterface $current_user,
FormBuilderInterface $form_builder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class PostPhotoProfileBlock extends PostProfileBlock {
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
$plugin_id,
$plugin_definition,
EntityTypeManagerInterface $entity_type_manager,
AccountProxyInterface $current_user,
FormBuilderInterface $form_builder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\hux\Attribute\Alter;
use Drupal\social_post\Service\SocialPostHelperInterface;

Expand Down Expand Up @@ -59,16 +58,12 @@ public function __construct(
*/
#[Alter('form_post_form')]
public function formPostFormAlter(array &$form, FormStateInterface $form_state): void {
$content = $this->socialPostHelper->buildCurrentUserImage();
$form_object = $form_state->getFormObject();
assert($form_object instanceof ContentEntityForm, 'Expected $form_object to be an instance of ContentEntityForm.');

if ($form_object instanceof ContentEntityForm === FALSE) {
return;
}

if ($form_object->getEntity()->isNew()
&& $content !== NULL) {
$form['current_user_image'] = $content;
if ($this->socialPostHelper->buildCurrentUserImage() !== NULL
&& $form_object->getEntity()->isNew()) {
$form['current_user_image'] = $this->socialPostHelper->buildCurrentUserImage();
}

// Reset title display.
Expand All @@ -77,42 +72,24 @@ public function formPostFormAlter(array &$form, FormStateInterface $form_state):
// Set submit button caption to Post instead of Save.
$form['actions']['submit']['#value'] = t('Post', [], ['context' => 'Post button']);

if (empty($form['field_post']) || empty($form['field_post']['widget'][0])) {
return;
}

// Default value.
$form = $this->setFormTitleAndPlaceholder($form, t('Say something to the Community'));
$titleAndPlaceholderValue = t('Say something to the Community');

if ($form_state->get('currentGroup') !== NULL) {
$form = $this->setFormTitleAndPlaceholder($form, t('Say something to the group'));
$titleAndPlaceholderValue = t('Say something to the group');
}

// $user_profile = $this->routeMatch->getParameter('user');
$user_profile = $form_state->get('recipientUser');
if ($user_profile !== NULL
&& $user_profile->id() !== $this->currentUser->id()) {
$form = $this->setFormTitleAndPlaceholder($form, t('Leave a message to @name', [
$titleAndPlaceholderValue = t('Leave a message to @name', [
'@name' => $user_profile->getDisplayName(),
]));
]);
}
}

/**
* Set form title and placeholder value.
*
* @param array $form
* The drupal form.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup $displayedValue
* The translatable markup value to display.
*
* @return array
* The updated form title and placeholder.
*/
private function setFormTitleAndPlaceholder(array $form, TranslatableMarkup $displayedValue): array {
$form['field_post']['widget'][0]['#title'] = $displayedValue;
$form['field_post']['widget'][0]['#placeholder'] = $displayedValue;
return $form;
// Set the title and placeholder value.
$form['field_post']['widget'][0]['#title'] = $titleAndPlaceholderValue;
$form['field_post']['widget'][0]['#placeholder'] = $titleAndPlaceholderValue;
}

}
Loading

0 comments on commit cf40d65

Please sign in to comment.