feat(integration): add requires_tenant_configuration field and update related logic and tests
This commit is contained in:
@@ -13,10 +13,12 @@ class Integration extends Model
|
|||||||
'name',
|
'name',
|
||||||
'url',
|
'url',
|
||||||
'integration_data_schema',
|
'integration_data_schema',
|
||||||
|
'requires_tenant_configuration',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'integration_data_schema' => 'array',
|
'integration_data_schema' => 'array',
|
||||||
|
'requires_tenant_configuration' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function tenantIntegrations()
|
public function tenantIntegrations()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class StoreIntegrationRequest extends FormRequest
|
|||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
'url' => ['nullable', 'url', 'max:255'],
|
'url' => ['nullable', 'url', 'max:255'],
|
||||||
'integration_data_schema' => ['nullable', 'array'],
|
'integration_data_schema' => ['nullable', 'array'],
|
||||||
|
'requires_tenant_configuration' => ['sometimes', 'boolean'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class UpdateIntegrationRequest extends FormRequest
|
|||||||
'name' => ['sometimes', 'required', 'string', 'max:255'],
|
'name' => ['sometimes', 'required', 'string', 'max:255'],
|
||||||
'url' => ['nullable', 'url', 'max:255'],
|
'url' => ['nullable', 'url', 'max:255'],
|
||||||
'integration_data_schema' => ['nullable', 'array'],
|
'integration_data_schema' => ['nullable', 'array'],
|
||||||
|
'requires_tenant_configuration' => ['sometimes', 'boolean'],
|
||||||
// the code shouldn't ideally be updatable, but if it is:
|
// the code shouldn't ideally be updatable, but if it is:
|
||||||
'integration_code' => ['sometimes', 'required', 'string', 'unique:integrations,integration_code,' . ($integration->id ?? '')],
|
'integration_code' => ['sometimes', 'required', 'string', 'unique:integrations,integration_code,' . ($integration->id ?? '')],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ abstract class BaseIntegrationService
|
|||||||
->where('integration_code', $this->integrationCode)
|
->where('integration_code', $this->integrationCode)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if (!$this->tenantIntegration) {
|
if (!$this->tenantIntegration && $this->integration->requires_tenant_configuration) {
|
||||||
throw new Exception("Tenant '{$this->tenantCode}' does not have integration '{$this->integrationCode}' configured.");
|
throw new Exception("Tenant '{$this->tenantCode}' does not have integration '{$this->integrationCode}' configured.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ class MailService extends BaseIntegrationService
|
|||||||
|
|
||||||
private ?Tenant $tenant = null;
|
private ?Tenant $tenant = null;
|
||||||
|
|
||||||
|
private bool $usesTenantMailer = false;
|
||||||
|
|
||||||
public function __construct(?MailFactory $mailFactory = null)
|
public function __construct(?MailFactory $mailFactory = null)
|
||||||
{
|
{
|
||||||
$this->mailFactory = $mailFactory ?? app(MailFactory::class);
|
$this->mailFactory = $mailFactory ?? app(MailFactory::class);
|
||||||
@@ -41,7 +43,14 @@ class MailService extends BaseIntegrationService
|
|||||||
$this->tenant = Tenant::query()
|
$this->tenant = Tenant::query()
|
||||||
->where('codigo', $tenantCode)
|
->where('codigo', $tenantCode)
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
|
|
||||||
|
if ($this->tenantIntegration) {
|
||||||
$this->mailer = $this->resolveMailer();
|
$this->mailer = $this->resolveMailer();
|
||||||
|
$this->usesTenantMailer = true;
|
||||||
|
} else {
|
||||||
|
$this->mailer = $this->mailFactory->mailer();
|
||||||
|
$this->usesTenantMailer = false;
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -82,7 +91,9 @@ class MailService extends BaseIntegrationService
|
|||||||
|
|
||||||
public function mailerName(): string
|
public function mailerName(): string
|
||||||
{
|
{
|
||||||
return 'tenant-smtp';
|
return $this->usesTenantMailer
|
||||||
|
? 'tenant-smtp'
|
||||||
|
: (string) config('mail.default');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onSetup(): void
|
public function onSetup(): void
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('integrations', function (Blueprint $table) {
|
||||||
|
$table->boolean('requires_tenant_configuration')->default(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('integrations')
|
||||||
|
->where('integration_code', 'email')
|
||||||
|
->update(['requires_tenant_configuration' => false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('integrations', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('requires_tenant_configuration');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -17,6 +17,7 @@ class EmailIntegrationSeeder extends Seeder
|
|||||||
[
|
[
|
||||||
'name' => 'Email',
|
'name' => 'Email',
|
||||||
'url' => null,
|
'url' => null,
|
||||||
|
'requires_tenant_configuration' => false,
|
||||||
'integration_data_schema' => [
|
'integration_data_schema' => [
|
||||||
'MAIL_MAILER' => 'required|string|in:smtp',
|
'MAIL_MAILER' => 'required|string|in:smtp',
|
||||||
'MAIL_SCHEME' => 'required|string|in:smtp',
|
'MAIL_SCHEME' => 'required|string|in:smtp',
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class TelepagosIntegrationSeeder extends Seeder
|
|||||||
[
|
[
|
||||||
'name' => 'Telepagos',
|
'name' => 'Telepagos',
|
||||||
'url' => 'https://api.telepagos.com.ar',
|
'url' => 'https://api.telepagos.com.ar',
|
||||||
|
'requires_tenant_configuration' => true,
|
||||||
'integration_data_schema' => [
|
'integration_data_schema' => [
|
||||||
'username' => 'required|string',
|
'username' => 'required|string',
|
||||||
'password' => 'required|string',
|
'password' => 'required|string',
|
||||||
@@ -29,6 +30,7 @@ class TelepagosIntegrationSeeder extends Seeder
|
|||||||
[
|
[
|
||||||
'name' => 'Telepagos Homologación',
|
'name' => 'Telepagos Homologación',
|
||||||
'url' => 'https://api.homo.telepagos.com.ar',
|
'url' => 'https://api.homo.telepagos.com.ar',
|
||||||
|
'requires_tenant_configuration' => true,
|
||||||
'integration_data_schema' => [
|
'integration_data_schema' => [
|
||||||
'username' => 'required|string',
|
'username' => 'required|string',
|
||||||
'password' => 'required|string',
|
'password' => 'required|string',
|
||||||
|
|||||||
@@ -57,6 +57,28 @@ class MailServiceTest extends TestCase
|
|||||||
$this->assertSame('tenant-smtp', $service->mailerName());
|
$this->assertSame('tenant-smtp', $service->mailerName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_uses_the_default_mailer_when_tenant_configuration_is_not_required(): void
|
||||||
|
{
|
||||||
|
Mail::fake();
|
||||||
|
config(['mail.default' => 'array']);
|
||||||
|
$tenant = $this->createTenant();
|
||||||
|
Integration::create([
|
||||||
|
'integration_code' => 'email',
|
||||||
|
'name' => 'Email',
|
||||||
|
'requires_tenant_configuration' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$service = (new MailService)->forTenant($tenant->codigo);
|
||||||
|
$service->send('customer@example.com', 'Default mailer', '<p>Fallback</p>');
|
||||||
|
|
||||||
|
$this->assertSame('array', $service->mailerName());
|
||||||
|
Mail::assertSent(Mailable::class, function (Mailable $mail): bool {
|
||||||
|
return $mail->hasTo('customer@example.com')
|
||||||
|
&& $mail->subject === 'Default mailer'
|
||||||
|
&& str_contains($mail->render(), 'Fallback');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function test_on_setup_sends_a_branded_test_email_to_the_configured_sender(): void
|
public function test_on_setup_sends_a_branded_test_email_to_the_configured_sender(): void
|
||||||
{
|
{
|
||||||
Mail::fake();
|
Mail::fake();
|
||||||
|
|||||||
Reference in New Issue
Block a user