Skip to content

Commit 28b0ce1

Browse files
authored
Organizers unable to message attendees awaiting payment (#520)
1 parent aa2c1bb commit 28b0ce1

File tree

2 files changed

+174
-2
lines changed

2 files changed

+174
-2
lines changed

backend/app/Services/Application/Handlers/Message/SendMessageHandler.php

-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Carbon\Carbon;
66
use HiEvents\DomainObjects\MessageDomainObject;
7-
use HiEvents\DomainObjects\Status\AttendeeStatus;
87
use HiEvents\DomainObjects\Status\MessageStatus;
98
use HiEvents\Exceptions\AccountNotVerifiedException;
109
use HiEvents\Jobs\Event\SendMessagesJob;
@@ -98,7 +97,6 @@ private function getAttendeeIds(SendMessageDTO $messageData): Collection
9897
values: $messageData->attendee_ids,
9998
additionalWhere: [
10099
'event_id' => $messageData->event_id,
101-
'status' => AttendeeStatus::ACTIVE->name,
102100
],
103101
columns: ['id']
104102
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<?php
2+
3+
namespace Tests\Unit\Services\Application\Handlers\Message;
4+
5+
use Carbon\Carbon;
6+
use HiEvents\DomainObjects\AccountDomainObject;
7+
use HiEvents\DomainObjects\AttendeeDomainObject;
8+
use HiEvents\DomainObjects\Enums\MessageTypeEnum;
9+
use HiEvents\DomainObjects\MessageDomainObject;
10+
use HiEvents\DomainObjects\OrderDomainObject;
11+
use HiEvents\DomainObjects\ProductDomainObject;
12+
use HiEvents\Exceptions\AccountNotVerifiedException;
13+
use HiEvents\Jobs\Event\SendMessagesJob;
14+
use HiEvents\Repository\Interfaces\AccountRepositoryInterface;
15+
use HiEvents\Repository\Interfaces\AttendeeRepositoryInterface;
16+
use HiEvents\Repository\Interfaces\MessageRepositoryInterface;
17+
use HiEvents\Repository\Interfaces\OrderRepositoryInterface;
18+
use HiEvents\Repository\Interfaces\ProductRepositoryInterface;
19+
use HiEvents\Services\Application\Handlers\Message\DTO\SendMessageDTO;
20+
use HiEvents\Services\Application\Handlers\Message\SendMessageHandler;
21+
use HiEvents\Services\Infrastructure\HtmlPurifier\HtmlPurifierService;
22+
use Illuminate\Config\Repository;
23+
use Illuminate\Support\Facades\Bus;
24+
use Mockery as m;
25+
use Tests\TestCase;
26+
27+
class SendMessageHandlerTest extends TestCase
28+
{
29+
private OrderRepositoryInterface $orderRepository;
30+
private AttendeeRepositoryInterface $attendeeRepository;
31+
private ProductRepositoryInterface $productRepository;
32+
private MessageRepositoryInterface $messageRepository;
33+
private AccountRepositoryInterface $accountRepository;
34+
private HtmlPurifierService $purifier;
35+
private Repository $config;
36+
37+
private SendMessageHandler $handler;
38+
39+
protected function setUp(): void
40+
{
41+
parent::setUp();
42+
43+
$this->orderRepository = m::mock(OrderRepositoryInterface::class);
44+
$this->attendeeRepository = m::mock(AttendeeRepositoryInterface::class);
45+
$this->productRepository = m::mock(ProductRepositoryInterface::class);
46+
$this->messageRepository = m::mock(MessageRepositoryInterface::class);
47+
$this->accountRepository = m::mock(AccountRepositoryInterface::class);
48+
$this->purifier = m::mock(HtmlPurifierService::class);
49+
$this->config = m::mock(Repository::class);
50+
51+
$this->handler = new SendMessageHandler(
52+
$this->orderRepository,
53+
$this->attendeeRepository,
54+
$this->productRepository,
55+
$this->messageRepository,
56+
$this->accountRepository,
57+
$this->purifier,
58+
$this->config
59+
);
60+
}
61+
62+
public function testThrowsIfAccountNotVerified(): void
63+
{
64+
$dto = new SendMessageDTO(
65+
account_id: 1,
66+
event_id: 1,
67+
subject: 'Subject',
68+
message: 'Message',
69+
type: MessageTypeEnum::INDIVIDUAL_ATTENDEES,
70+
is_test: false,
71+
send_copy_to_current_user: false,
72+
sent_by_user_id: 1,
73+
order_statuses: [],
74+
order_id: null,
75+
attendee_ids: [],
76+
product_ids: []
77+
);
78+
79+
$account = m::mock(AccountDomainObject::class);
80+
$account->shouldReceive('getAccountVerifiedAt')->andReturn(null);
81+
82+
$this->accountRepository->shouldReceive('findById')->with(1)->andReturn($account);
83+
84+
$this->expectException(AccountNotVerifiedException::class);
85+
86+
$this->handler->handle($dto);
87+
}
88+
89+
public function testThrowsIfSaasModeEnabledAndNotManuallyVerified(): void
90+
{
91+
$dto = new SendMessageDTO(
92+
account_id: 1,
93+
event_id: 1,
94+
subject: 'Subject',
95+
message: 'Message',
96+
type: MessageTypeEnum::INDIVIDUAL_ATTENDEES,
97+
is_test: false,
98+
send_copy_to_current_user: false,
99+
sent_by_user_id: 1,
100+
order_statuses: [],
101+
order_id: null,
102+
attendee_ids: [],
103+
product_ids: []
104+
);
105+
106+
$account = m::mock(AccountDomainObject::class);
107+
$account->shouldReceive('getAccountVerifiedAt')->andReturn(Carbon::now());
108+
$account->shouldReceive('getIsManuallyVerified')->andReturn(false);
109+
110+
$this->accountRepository->shouldReceive('findById')->with(1)->andReturn($account);
111+
$this->config->shouldReceive('get')->with('app.saas_mode_enabled')->andReturn(true);
112+
$this->config->shouldReceive('get')->with('app.platform_support_email')->andReturn('[email protected]');
113+
114+
$this->expectException(AccountNotVerifiedException::class);
115+
116+
$this->handler->handle($dto);
117+
}
118+
119+
public function testHandleCreatesMessageAndDispatchesJob(): void
120+
{
121+
$dto = new SendMessageDTO(
122+
account_id: 1,
123+
event_id: 101,
124+
subject: 'Hello',
125+
message: '<p>Test</p>',
126+
type: MessageTypeEnum::INDIVIDUAL_ATTENDEES,
127+
is_test: false,
128+
send_copy_to_current_user: false,
129+
sent_by_user_id: 99,
130+
order_statuses: [],
131+
order_id: 5,
132+
attendee_ids: [10],
133+
product_ids: [20],
134+
);
135+
136+
$account = m::mock(AccountDomainObject::class);
137+
$account->shouldReceive('getAccountVerifiedAt')->andReturn(Carbon::now());
138+
$account->shouldReceive('getIsManuallyVerified')->andReturn(true);
139+
140+
$this->accountRepository->shouldReceive('findById')->with(1)->andReturn($account);
141+
$this->config->shouldReceive('get')->with('app.saas_mode_enabled')->andReturn(false);
142+
143+
$this->purifier->shouldReceive('purify')->with('<p>Test</p>')->andReturn('<p>Test</p>');
144+
145+
$attendee = new AttendeeDomainObject();
146+
$attendee->setId(10);
147+
148+
$product = new ProductDomainObject();
149+
$product->setId(20);
150+
151+
$order = new OrderDomainObject();
152+
$order->setId(5);
153+
154+
$this->attendeeRepository->shouldReceive('findWhereIn')->andReturn(collect([$attendee]));
155+
$this->productRepository->shouldReceive('findWhereIn')->andReturn(collect([$product]));
156+
$this->orderRepository->shouldReceive('findFirstWhere')->andReturn($order);
157+
158+
$message = m::mock(MessageDomainObject::class);
159+
$message->shouldReceive('getId')->andReturn(1);
160+
$message->shouldReceive('getOrderId')->andReturn(5);
161+
$message->shouldReceive('getAttendeeIds')->andReturn([10]);
162+
$message->shouldReceive('getProductIds')->andReturn([20]);
163+
164+
$this->messageRepository->shouldReceive('create')->andReturn($message);
165+
166+
Bus::fake();
167+
168+
$result = $this->handler->handle($dto);
169+
170+
$this->assertSame($message, $result);
171+
172+
Bus::assertDispatched(SendMessagesJob::class);
173+
}
174+
}

0 commit comments

Comments
 (0)