| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- <?php
- namespace Tests\Feature;
- use App\Enums\ApprovalStatusEnum;
- use App\Enums\PushNotificationCategoryEnum;
- use App\Enums\PushNotificationTargetEnum;
- use App\Enums\UserTypeEnum;
- use App\Models\DeviceToken;
- use App\Models\Provider;
- use App\Models\PushNotificationLog;
- use App\Models\User;
- use App\Notifications\Push\Prestador\Transacional\CadastroAprovadoPush;
- use App\Services\ProviderService;
- use App\Services\PushNotificationService;
- use Illuminate\Foundation\Testing\RefreshDatabase;
- use Illuminate\Support\Facades\Mail;
- use Mockery\MockInterface;
- use Tests\TestCase;
- class ProviderApprovalPushTest extends TestCase
- {
- use RefreshDatabase;
- private ProviderService $service;
- protected function setUp(): void
- {
- parent::setUp();
- Mail::fake();
- $this->service = app(ProviderService::class);
- }
- public function test_aprovar_prestador_dispara_push_de_cadastro_aprovado(): void
- {
- $provider = $this->makeProvider();
- $this->withDeviceToken($provider->user);
- $push = $this->mockPushService();
- $push->shouldReceive('sendToUser')
- ->once()
- ->withArgs(function (User $user, $notification) use ($provider) {
- return $user->is($provider->user)
- && $notification instanceof CadastroAprovadoPush;
- });
- $approved = $this->service->approve($provider->id);
- $this->assertSame(ApprovalStatusEnum::ACCEPTED->value, $approved->approval_status->value);
- }
- public function test_update_para_accepted_dispara_push(): void
- {
- $provider = $this->makeProvider();
- $this->withDeviceToken($provider->user);
- $push = $this->mockPushService();
- $push->shouldReceive('sendToUser')->once();
- $this->service->update($provider->id, [
- 'approval_status' => ApprovalStatusEnum::ACCEPTED->value,
- ]);
- }
- public function test_update_que_nao_muda_o_status_nao_dispara_push(): void
- {
- $provider = $this->makeProvider();
- $this->withDeviceToken($provider->user);
- $push = $this->mockPushService();
- $push->shouldNotReceive('sendToUser');
- $this->service->update($provider->id, ['birth_date' => '1991-02-02']);
- }
- public function test_aprovar_prestador_ja_aprovado_nao_reenvia_push(): void
- {
- $provider = $this->makeProvider(ApprovalStatusEnum::ACCEPTED);
- $this->withDeviceToken($provider->user);
- $push = $this->mockPushService();
- $push->shouldNotReceive('sendToUser');
- $this->service->approve($provider->id);
- }
- /**
- * Rede de seguranca extra: mesmo que a transicao seja detectada de novo
- * (reprovar e reaprovar, por exemplo), o log impede o envio duplicado.
- */
- public function test_push_ja_registrada_no_log_nao_e_reenviada(): void
- {
- $provider = $this->makeProvider();
- $this->withDeviceToken($provider->user);
- PushNotificationLog::query()->create([
- 'label' => (new CadastroAprovadoPush)->label(),
- 'user_id' => $provider->user->id,
- 'target' => PushNotificationTargetEnum::PRESTADOR->value,
- 'category' => PushNotificationCategoryEnum::TRANSACIONAL->value,
- 'sent_at' => now()->subDay(),
- ]);
- $push = $this->mockPushService();
- $push->shouldNotReceive('sendToUser');
- $this->service->approve($provider->id);
- }
- public function test_prestador_sem_device_token_ativo_nao_dispara_push(): void
- {
- $provider = $this->makeProvider();
- $this->withDeviceToken($provider->user, active: false);
- $push = $this->mockPushService();
- $push->shouldNotReceive('sendToUser');
- $approved = $this->service->approve($provider->id);
- $this->assertSame(ApprovalStatusEnum::ACCEPTED->value, $approved->approval_status->value);
- }
- public function test_token_de_outro_app_nao_dispara_push_do_prestador(): void
- {
- $provider = $this->makeProvider();
- $this->withDeviceToken($provider->user, appType: PushNotificationTargetEnum::CLIENTE);
- $push = $this->mockPushService();
- $push->shouldNotReceive('sendToUser');
- $this->service->approve($provider->id);
- }
- public function test_falha_no_envio_da_push_nao_impede_a_aprovacao(): void
- {
- $provider = $this->makeProvider();
- $this->withDeviceToken($provider->user);
- $push = $this->mockPushService();
- $push->shouldReceive('sendToUser')
- ->once()
- ->andThrow(new \RuntimeException('FCM indisponivel'));
- $approved = $this->service->approve($provider->id);
- $this->assertSame(ApprovalStatusEnum::ACCEPTED->value, $approved->approval_status->value);
- }
- //
- private function mockPushService(): MockInterface
- {
- return $this->mock(PushNotificationService::class);
- }
- private function makeProvider(?ApprovalStatusEnum $status = null): Provider
- {
- $user = User::query()->create([
- 'name' => 'Prestador Teste',
- 'email' => 'prestador'.uniqid().'@teste.com',
- 'password' => 'secret',
- 'type' => UserTypeEnum::PROVIDER->value,
- ]);
- $provider = Provider::query()->create([
- 'user_id' => $user->id,
- 'document' => '06767310905',
- 'birth_date' => '1990-01-01',
- 'approval_status' => ($status ?? ApprovalStatusEnum::PENDING)->value,
- ]);
- return $provider->load('user');
- }
- private function withDeviceToken(
- User $user,
- bool $active = true,
- ?PushNotificationTargetEnum $appType = null,
- ): DeviceToken {
- return DeviceToken::query()->create([
- 'user_id' => $user->id,
- 'token' => 'tok_'.uniqid(),
- 'platform' => 'android',
- 'app_type' => ($appType ?? PushNotificationTargetEnum::PRESTADOR)->value,
- 'active' => $active,
- ]);
- }
- }
|