ldc-crm/tests/CRM/ApiV4/SingleOptinTest.php

268 lines
9 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Tests\CRM\ApiV4;
use App\Enums\ApiError;
use App\Enums\ApiStatus;
use App\Enums\Country;
use App\Models\CustomerInfo;
use App\Models\ModelAnswer;
use App\Models\Question;
use App\Models\Service;
use App\Models\SingleOptin;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\CreatesApplication;
class SingleOptinTest extends ApiBase
{
use CreatesApplication;
use DatabaseTransactions;
/** @var string $email */
private $email = 'singleoptin@hotmail.fr';
/**
2025-04-17 11:32:43 +02:00
* Test set single optin on.
* route: apiV4.optin
*
* @return void
*/
2025-04-17 11:32:43 +02:00
public function testSetSingleOptinOn(): void
{
$service = Service::firstOrFail();
$response = $this->callApiWithToken($service, 'post', route('apiV4.optin'), [
'email' => $this->email,
'opt_in' => 1,
]);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::OK);
$this->assertTrue(
SingleOptin::query()->where('email', $this->email)->exists(),
'Single optin should have been set for email "singleoptin@hotmail.fr"'
);
}
/**
* Test set single optin on with answer associated.
* route: apiV4.optin
*
* @return void
*/
public function testSetSingleOptinOnWithAnswerAssociated(): void
{
$service = Service::firstOrFail();
/** @var \Illuminate\Database\Eloquent\Collection $questions */
$questions = Question::query()->whereHas('brand', function ($q) use ($service) {
$q->whereId($service->brand->getKey());
})->with('answers')->get()->keyBy('id');
// * Make sure a customer answer is set.
$firstAnswer = $questions->first()->answers->first();
$response = $this->callApiWithToken($service, 'post', route('apiV4.optin'), [
'email' => $this->email,
'opt_in' => 1,
'answer_id' => [$firstAnswer->getkey()],
]);
$singleOptin = SingleOptin::query()->where('email', $this->email);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::OK);
$this->assertTrue(
$singleOptin->exists() && ModelAnswer::query()->where([
['answer_id', $firstAnswer->getkey()],
['model_id', !is_null($singleOptin->first()) ? $singleOptin->first()->getKey() : null],
['model_type', SingleOptin::class],
])->exists(),
'Single optin should have been set for email "singleoptin@hotmail.fr"'
);
}
/**
2025-04-17 11:32:43 +02:00
* Test set single optin off.
* route: apiV4.optin
*
* @return void
*/
2025-04-17 11:32:43 +02:00
public function testSetSingleOptinOff(): void
{
$service = Service::firstOrFail();
$response = $this->callApiWithToken($service, 'post', route('apiV4.optin'), [
'email' => $this->email,
'opt_in' => 0,
]);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::OK);
$this->assertFalse(
SingleOptin::query()->where('email', $this->email)->exists(),
'Single optin should have been removed for email "singleoptin@hotmail.fr"'
);
}
/**
* Test set single optin on when customer exist.
* route: apiV4.optin
*
* @return void
*/
public function testSetSingleOptinWhenCustomerExist(): void
{
$service = Service::firstOrFail();
$this->storeCustomer($service);
$response = $this->callApiWithToken($service, 'post', route('apiV4.optin'), [
'email' => $this->email,
'opt_in' => 1,
]);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::OK);
$this->assertFalse(SingleOptin::query()->where('email', 'singleoptout@hotmail.fr')->exists());
$crmCustomer = CustomerInfo::query()->whereHas('customer', function (Builder $query) {
$query->where('email', $this->email);
})->first();
$this->assertTrue(
$crmCustomer->opt_in,
'Single optin should have been set for customer with email "singleoptin@hotmail.fr"'
);
}
/**
* Test set single optin on with anexisting answer associated.
*
* @return void
*/
public function testSingleOptinShouldFailIfAnswerIdDoesntExist(): void
{
$service = Service::query()->firstOrFail();
$response = $this->callApiWithToken($service, 'post', route('apiV4.optin'), [
'email' => $this->email,
'opt_in' => 1,
'answer_id' => [0],
]);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::KO);
$this->assertEquals(ApiError::validationFailed->value(), $json->json('data.code'));
}
/**
2025-04-17 11:32:43 +02:00
* Test set single optin off using hashcode.
* route: apiV4.optout-hashcode
*
* @return void
*/
2025-04-17 11:32:43 +02:00
public function testSetSingleOptoutWithHashcode(): void
{
$service = Service::firstOrFail();
// * Make sure a single optin exists.
$singleOptin = SingleOptin::query()->where('email', 'singleoptout@hotmail.fr')->firstOrNew();
$singleOptin->brand()->associate($service->brand);
$singleOptin->email = 'singleoptout@hotmail.fr';
$singleOptin->saveOrFail();
$singleOptin->refresh();
$response = $this->callApiWithToken($service, 'post', route('apiV4.optout-hashcode'), [
'hashcode' => $singleOptin->hashcode,
]);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::OK);
$this->assertFalse(
SingleOptin::query()->where('email', 'singleoptout@hotmail.fr')->exists(),
'Single optin should have been removed for email "singleoptout@hotmail.fr"'
);
}
/**
2025-04-17 11:32:43 +02:00
* Test set single optin off using hashcode fails if does not exists.
* route: apiV4.optout-hashcode
*
* @return void
*/
2025-04-17 11:32:43 +02:00
public function testSetSingleOptoutWithHashcodeFailsIfDoesNotExists(): void
{
$service = Service::firstOrFail();
// * Make sure a single optin exists.
$singleOptin = SingleOptin::query()->where('email', 'singleoptout@hotmail.fr')->firstOrNew();
$singleOptin->brand()->associate($service->brand);
$singleOptin->email = 'singleoptout@hotmail.fr';
$singleOptin->saveOrFail();
$singleOptin->refresh();
// * Make sure a single optin does exists.
$singleOptin->delete();
$response = $this->callApiWithToken($service, 'post', route('apiV4.optout-hashcode'), [
'hashcode' => $singleOptin->hashcode,
]);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::KO);
$this->assertEquals(ApiError::modelNotFound->value, $json->json('data.code'));
}
/**
* Test set single optin off using hashcode.
* route: apiV4.optout-hashcode
*
* @return void
*/
public function testSetSingleOptoutWithHashcodeWhenCustomerExists(): void
{
$service = Service::firstOrFail();
$this->storeCustomer($service);
$crmCustomer = CustomerInfo::query()
->whereHas('customer', fn(Builder $query) => $query->where('email', $this->email))
->firstOrFail();
$response = $this->callApiWithToken($service, 'post', route('apiV4.optout-hashcode'), [
'hashcode' => $crmCustomer->hashcode,
]);
$json = $response->decodeResponseJson();
$this->assertApiResponseStatusIs($json, ApiStatus::OK);
$this->assertFalse(
SingleOptin::query()->where('email', $this->email)->exists(),
'A SingleOptin record should not exist for this email.'
);
$updatedCustomer = CustomerInfo::query()
->whereHas('customer', fn(Builder $query) => $query->where('email', $this->email))
->firstOrFail();
$this->assertFalse(
$updatedCustomer->opt_in,
'Customer "opt_in" field should be set to false after opt-out with hashcode.'
);
}
/**
2025-04-17 11:32:43 +02:00
* Store a customer in DB.
*
* @param \App\Models\Service $service
* @return void
*/
2025-04-17 11:32:43 +02:00
private function storeCustomer(Service $service): void
{
$data = [
2025-04-17 11:32:43 +02:00
'firstname' => 'Jean',
'lastname' => 'Bond',
'birth_date' => \date('1992-03-08'),
2025-04-17 11:32:43 +02:00
'address' => '10 rue des totos',
'email' => $this->email,
2025-04-17 11:32:43 +02:00
'password' => '123.Mot.De.P4sse',
'phone' => '+33654821562',
'country' => Country::france->value,
'city' => 'Connerré',
'postcode' => '72160',
'opt_in' => true,
];
$this->callApiWithToken($service, 'post', route('apiV4.customers.store'), $data);
}
}