Skip to content
This repository was archived by the owner on Jun 8, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
wip
  • Loading branch information
djaiss committed Mar 13, 2022
commit 337e0b95caa1f3d7ef4a833ef896d4653f2cfa59
5 changes: 5 additions & 0 deletions app/Jobs/ProcessScheduledContactReminders.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Jobs\Notifications\SendEmailNotification;
use App\Services\Contact\ManageReminder\RescheduleContactReminder;

class ProcessScheduledContactReminders implements ShouldQueue
{
Expand Down Expand Up @@ -47,6 +48,10 @@ public function handle()
if ($scheduledReminder->userNotificationChannel->type == UserNotificationChannel::TYPE_EMAIL) {
SendEmailNotification::dispatch($scheduledReminder)->onQueue('low');
}

(new RescheduleContactReminder)->execute([
'scheduled_contact_reminder_id' => $scheduledReminder->id,
]);
}
}
}
75 changes: 75 additions & 0 deletions app/Services/Contact/ManageReminder/RescheduleContactReminder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace App\Services\Contact\ManageReminder;

use Carbon\Carbon;
use App\Services\BaseService;
use App\Models\ContactReminder;
use App\Interfaces\ServiceInterface;
use App\Models\ScheduledContactReminder;

class RescheduleContactReminder extends BaseService implements ServiceInterface
{
private ScheduledContactReminder $scheduledContactReminder;
private array $data;
private Carbon $upcomingDate;

/**
* Get the validation rules that apply to the service.
*
* @return array
*/
public function rules(): array
{
return [
'scheduled_contact_reminder_id' => 'required|integer|exists:scheduled_contact_reminders,id',
];
}

/**
* Schedule another occurence of the scheduled contact reminder, as the
* previous iteration has been sent.
* Before sending this occurence, we need to make the user notification
* channel is still active.
*
* @param array $data
* @return void
*/
public function execute(array $data): void
{
$this->validateRules($data);
$this->data = $data;

$this->scheduledContactReminder = ScheduledContactReminder::with('reminder')
->findOrFail($this->data['scheduled_contact_reminder_id']);

if (! $this->scheduledContactReminder->userNotificationChannel->active) {
return;
}

if ($this->scheduledContactReminder->reminder->type !== ContactReminder::TYPE_ONE_TIME) {
$this->schedule();
}
}

private function schedule(): void
{
if ($this->scheduledContactReminder->reminder->type === ContactReminder::TYPE_RECURRING_DAY) {
$this->upcomingDate = $this->scheduledContactReminder->scheduled_at->addDay();
}

if ($this->scheduledContactReminder->reminder->type === ContactReminder::TYPE_RECURRING_MONTH) {
$this->upcomingDate = $this->scheduledContactReminder->scheduled_at->addMonth();
}

if ($this->scheduledContactReminder->reminder->type === ContactReminder::TYPE_RECURRING_YEAR) {
$this->upcomingDate = $this->scheduledContactReminder->scheduled_at->addYear();
}

ScheduledContactReminder::create([
'contact_reminder_id' => $this->scheduledContactReminder->contact_reminder_id,
'user_notification_channel_id' => $this->scheduledContactReminder->user_notification_channel_id,
'scheduled_at' => $this->upcomingDate,
]);
}
}
2 changes: 1 addition & 1 deletion resources/js/Shared/Modules/Reminders.vue
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ select {
</div>

<!-- edit reminder modal -->
<form v-if="editedReminderId == reminder.id" class="mb-6 bg-white" @submit.prevent="update(reminder)">
<form v-if="editedReminderId == reminder.id" class="bg-white" @submit.prevent="update(reminder)">
<div class="border-b border-gray-200">
<div v-if="form.errors.length > 0" class="p-5">
<errors :errors="form.errors" />
Expand Down
10 changes: 8 additions & 2 deletions tests/Unit/Jobs/ProcessScheduledContactRemindersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ public function it_processes_all_the_scheduled_contact_reminders(): void
Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 0));

$contactReminder = ContactReminder::factory()->create([
'type' => UserNotificationChannel::TYPE_EMAIL,
'type' => ContactReminder::TYPE_RECURRING_DAY,
]);

ScheduledContactReminder::factory()->create([
$scheduledContactReminder = ScheduledContactReminder::factory()->create([
'contact_reminder_id' => $contactReminder->id,
'scheduled_at' => Carbon::now(),
'triggered_at' => null,
Expand All @@ -38,6 +38,12 @@ public function it_processes_all_the_scheduled_contact_reminders(): void
$job->handle();

Bus::assertDispatched(SendEmailNotification::class);

$this->assertDatabaseHas('scheduled_contact_reminders', [
'user_notification_channel_id' => $scheduledContactReminder->user_notification_channel_id,
'scheduled_at' => '2018-01-02 00:00:00',
'triggered_at' => null,
]);
}

/** @test */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<?php

namespace Tests\Unit\Services\Contact\ManageReminder;

use Carbon\Carbon;
use Tests\TestCase;
use App\Models\Vault;
use App\Models\Contact;
use App\Models\ContactReminder;
use App\Models\ScheduledContactReminder;
use App\Models\UserNotificationChannel;
use App\Services\Contact\ManageReminder\RescheduleContactReminder;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Services\Contact\ManageReminder\ScheduleContactReminder;

class RescheduleContactReminderTest extends TestCase
{
use DatabaseTransactions;

/** @test */
public function it_doesnt_schedules_a_one_time_contact_reminder_again(): void
{
Carbon::setTestNow(Carbon::create(2018, 1, 1));

$contactReminder = ContactReminder::factory()->create([
'type' => ContactReminder::TYPE_ONE_TIME,
'day' => 2,
'month' => 10,
'year' => 2000,
]);
$scheduledContactReminder = ScheduledContactReminder::factory()->create([
'contact_reminder_id' => $contactReminder->id,
]);

(new RescheduleContactReminder)->execute([
'scheduled_contact_reminder_id' => $scheduledContactReminder->id,
]);

$this->assertDatabaseMissing('scheduled_contact_reminders', [
'user_notification_channel_id' => $scheduledContactReminder->user_notification_channel_id,
'scheduled_at' => '2018-10-02 00:00:00',
'triggered_at' => null,
]);
}

/** @test */
public function it_schedules_a_daily_contact_reminder_again(): void
{
Carbon::setTestNow(Carbon::create(2018, 1, 1));

$contactReminder = ContactReminder::factory()->create([
'type' => ContactReminder::TYPE_RECURRING_DAY,
'day' => 2,
'month' => 10,
'year' => 2000,
]);
$scheduledContactReminder = ScheduledContactReminder::factory()->create([
'contact_reminder_id' => $contactReminder->id,
'scheduled_at' => '2018-01-01 00:00:00',
]);

(new RescheduleContactReminder)->execute([
'scheduled_contact_reminder_id' => $scheduledContactReminder->id,
]);

$this->assertDatabaseHas('scheduled_contact_reminders', [
'user_notification_channel_id' => $scheduledContactReminder->user_notification_channel_id,
'scheduled_at' => '2018-01-02 00:00:00',
'triggered_at' => null,
]);
}

/** @test */
public function it_schedules_a_monthly_contact_reminder_again(): void
{
Carbon::setTestNow(Carbon::create(2018, 1, 1));

$contactReminder = ContactReminder::factory()->create([
'type' => ContactReminder::TYPE_RECURRING_MONTH,
'day' => 2,
'month' => 10,
'year' => 2000,
]);
$scheduledContactReminder = ScheduledContactReminder::factory()->create([
'contact_reminder_id' => $contactReminder->id,
'scheduled_at' => '2018-01-01 00:00:00',
]);

(new RescheduleContactReminder)->execute([
'scheduled_contact_reminder_id' => $scheduledContactReminder->id,
]);

$this->assertDatabaseHas('scheduled_contact_reminders', [
'user_notification_channel_id' => $scheduledContactReminder->user_notification_channel_id,
'scheduled_at' => '2018-02-01 00:00:00',
'triggered_at' => null,
]);
}

/** @test */
public function it_schedules_a_yearly_contact_reminder_again(): void
{
Carbon::setTestNow(Carbon::create(2018, 1, 1));

$contactReminder = ContactReminder::factory()->create([
'type' => ContactReminder::TYPE_RECURRING_YEAR,
'day' => 2,
'month' => 10,
'year' => 2000,
]);
$scheduledContactReminder = ScheduledContactReminder::factory()->create([
'contact_reminder_id' => $contactReminder->id,
'scheduled_at' => '2018-01-01 00:00:00',
]);

(new RescheduleContactReminder)->execute([
'scheduled_contact_reminder_id' => $scheduledContactReminder->id,
]);

$this->assertDatabaseHas('scheduled_contact_reminders', [
'user_notification_channel_id' => $scheduledContactReminder->user_notification_channel_id,
'scheduled_at' => '2019-01-01 00:00:00',
'triggered_at' => null,
]);
}

/** @test */
public function it_doesnt_schedules_a_yearly_contact_reminder_again_if_channel_is_inactive(): void
{
Carbon::setTestNow(Carbon::create(2018, 1, 1));

$contactReminder = ContactReminder::factory()->create([
'type' => ContactReminder::TYPE_RECURRING_YEAR,
'day' => 2,
'month' => 10,
'year' => 2000,
]);
$scheduledContactReminder = ScheduledContactReminder::factory()->create([
'contact_reminder_id' => $contactReminder->id,
'scheduled_at' => '2018-01-01 00:00:00',
]);
$scheduledContactReminder->userNotificationChannel->update([
'active' => false,
]);

(new RescheduleContactReminder)->execute([
'scheduled_contact_reminder_id' => $scheduledContactReminder->id,
]);

$this->assertDatabaseMissing('scheduled_contact_reminders', [
'user_notification_channel_id' => $scheduledContactReminder->user_notification_channel_id,
'scheduled_at' => '2018-10-02 00:00:00',
'triggered_at' => null,
]);
}
}