From d60e24ff64947a8d516cb5ba5e6a06318fb221cf Mon Sep 17 00:00:00 2001 From: philipp lang Date: Sun, 20 Oct 2024 21:19:07 +0200 Subject: [PATCH] Add mailgateway --- app/Setting/SettingServiceProvider.php | 2 - modules/Mailgateway/Components/Form.php | 119 ++++++++++++++++ .../Mailgateway/Components/SettingView.php | 21 +++ .../Components/setting-view.blade.php | 37 +++++ modules/Mailgateway/IndexTest.php | 39 ++++++ .../MailgatewayServiceProvider.php | 37 +++++ modules/Mailgateway/MailgatewaySettings.php | 26 ++++ modules/Mailgateway/StoreTest.php | 128 ++++++++++++++++++ modules/Mailgateway/UpdateTest.php | 104 ++++++++++++++ resources/js/components/ui/BooleanDisplay.vue | 32 ----- 10 files changed, 511 insertions(+), 34 deletions(-) create mode 100644 modules/Mailgateway/Components/Form.php create mode 100644 modules/Mailgateway/Components/SettingView.php create mode 100644 modules/Mailgateway/Components/setting-view.blade.php create mode 100644 modules/Mailgateway/IndexTest.php create mode 100644 modules/Mailgateway/MailgatewayServiceProvider.php create mode 100644 modules/Mailgateway/MailgatewaySettings.php create mode 100644 modules/Mailgateway/StoreTest.php create mode 100644 modules/Mailgateway/UpdateTest.php delete mode 100644 resources/js/components/ui/BooleanDisplay.vue diff --git a/app/Setting/SettingServiceProvider.php b/app/Setting/SettingServiceProvider.php index 4889a3f9..c452886b 100644 --- a/app/Setting/SettingServiceProvider.php +++ b/app/Setting/SettingServiceProvider.php @@ -4,7 +4,6 @@ namespace App\Setting; use App\Fileshare\FileshareSettings; use App\Form\FormSettings; -use App\Mailgateway\MailgatewaySettings; use Modules\Module\ModuleSettings; use App\Prevention\PreventionSettings; use App\Setting\Data\SettingSynthesizer; @@ -35,7 +34,6 @@ class SettingServiceProvider extends ServiceProvider { app(SettingFactory::class)->register(ModuleSettings::class); app(SettingFactory::class)->register(InvoiceSettings::class); - app(SettingFactory::class)->register(MailgatewaySettings::class); app(SettingFactory::class)->register(NamiSettings::class); app(SettingFactory::class)->register(FormSettings::class); app(SettingFactory::class)->register(FileshareSettings::class); diff --git a/modules/Mailgateway/Components/Form.php b/modules/Mailgateway/Components/Form.php new file mode 100644 index 00000000..9eb57979 --- /dev/null +++ b/modules/Mailgateway/Components/Form.php @@ -0,0 +1,119 @@ + 'required|string|max:255', + 'domain' => 'required|string|max:255', + 'cls' => ['required', 'string', 'max:255', Rule::in(app('mail-gateways'))], + 'params' => 'present|array', + ...$this->cls ? collect($this->cls::rules($this->id ? 'updateValidator' : 'storeValidator'))->mapWithKeys(fn ($rules, $key) => ["params.{$key}" => $rules]) : [], + ]; + } + + public function validationAttributes(): array + { + return [ + 'cls' => 'Typ', + 'name' => 'Beschreibung', + 'domain' => 'Domain', + ...$this->cls ? collect($this->cls::fieldNames())->mapWithKeys(fn ($attribute, $key) => ["params.{$key}" => $attribute]) : [], + ]; + } + + public function mount(?string $model = null): void + { + $this->types = app('mail-gateways')->map(fn ($gateway) => [ + 'name' => $gateway::name(), + 'id' => $gateway, + ]); + + $model = Mailgateway::find($model); + + if ($model) { + $this->id = $model->id; + $this->name = $model->name; + $this->domain = $model->domain; + $this->cls = get_class($model->type); + $this->params = (array) $model->type; + } + } + + public function updatedType(string $type): void + { + $this->params = $type::defaults(); + } + + public function fields(): array + { + return $this->cls ? $this->cls::fields() : []; + } + + #[On('onStoreFromModal')] + public function onSave(): void + { + $this->validate(); + + if (!app($this->cls)->setParams($this->params)->works()) { + throw ValidationException::withMessages(['connection' => 'Verbindung fehlgeschlagen.']); + } + + $payload = [ + 'name' => $this->name, + 'domain' => $this->domain, + 'type' => ['cls' => $this->cls, 'params' => $this->params], + ]; + if ($this->id) { + Mailgateway::find($this->id)->update($payload); + } else { + Mailgateway::create($payload); + } + $this->dispatch('closeModal'); + $this->dispatch('refresh'); + $this->dispatch('success', 'Erfolgreich gespeichert.'); + } + + public function render() + { + return <<<'HTML' +
+
+ + + + @foreach($this->fields() as $index => $field) + + @endforeach + +
+ HTML; + } +} diff --git a/modules/Mailgateway/Components/SettingView.php b/modules/Mailgateway/Components/SettingView.php new file mode 100644 index 00000000..2ec0c789 --- /dev/null +++ b/modules/Mailgateway/Components/SettingView.php @@ -0,0 +1,21 @@ + '$refresh']; + + public function render() + { + return view('mailgateway::setting-view', [ + 'data' => Mailgateway::get(), + ]); + } +} diff --git a/modules/Mailgateway/Components/setting-view.blade.php b/modules/Mailgateway/Components/setting-view.blade.php new file mode 100644 index 00000000..d4b2c45f --- /dev/null +++ b/modules/Mailgateway/Components/setting-view.blade.php @@ -0,0 +1,37 @@ + +
+ + + Bezeichnung + Domain + Typ + Prüfung + Aktion + + + Neu + + @foreach ($data as $index => $gateway) + + {{ $gateway->name }} + {{ $gateway->domain }} + {{ $gateway->type::name() }} + + + + + Bearbeiten + + + @endforeach + +
+
diff --git a/modules/Mailgateway/IndexTest.php b/modules/Mailgateway/IndexTest.php new file mode 100644 index 00000000..31419d47 --- /dev/null +++ b/modules/Mailgateway/IndexTest.php @@ -0,0 +1,39 @@ +login()->loginNami(); + test()->get('/setting/mailgateway')->assertSeeLivewire(SettingView::class); +}); + +it('test it displays local gateways', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + Mailgateway::factory()->type(LocalType::class, [])->name('Lore')->domain('example.com')->create(); + + Livewire::test(SettingView::class) + ->assertSeeHtml('example.com') + ->assertSeeHtml('Lore') + ->assertSeeHtml('Lokal') + ->assertSeeHtml('Verbindung erfolgreich'); +}); + +it('displays mailman gateways', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + $typeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner']); + Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(); + + Livewire::test(SettingView::class)->assertSeeHtml('Verbindung erfolgreich'); +}); diff --git a/modules/Mailgateway/MailgatewayServiceProvider.php b/modules/Mailgateway/MailgatewayServiceProvider.php new file mode 100644 index 00000000..f0f2b64a --- /dev/null +++ b/modules/Mailgateway/MailgatewayServiceProvider.php @@ -0,0 +1,37 @@ +register(MailgatewaySettings::class); + + app(Router::class)->middleware(['web', 'auth:web'])->group(function ($router) { + $router->get('/setting/mailgateway', SettingView::class)->name('setting.mailgateway'); + }); + + View::addNamespace('mailgateway', __DIR__ . '/Components'); + } +} diff --git a/modules/Mailgateway/MailgatewaySettings.php b/modules/Mailgateway/MailgatewaySettings.php new file mode 100644 index 00000000..419fa797 --- /dev/null +++ b/modules/Mailgateway/MailgatewaySettings.php @@ -0,0 +1,26 @@ +withoutExceptionHandling()->login()->loginNami(); + + Livewire::test(Form::class) + ->set('name', 'lala') + ->set('domain', 'example.com') + ->set('cls', LocalType::class) + ->call('onSave') + ->assertDispatched('closeModal') + ->assertDispatched('refresh') + ->assertDispatched('success'); + + $this->assertDatabaseHas('mailgateways', [ + 'domain' => 'example.com', + 'name' => 'lala', + 'type' => json_encode([ + 'cls' => LocalType::class, + 'params' => [], + ]), + ]); +}); + +it('validates type', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + Livewire::test(Form::class) + ->set('cls', '') + ->assertHasErrors(['cls' => 'required']); +}); + +it('test it validates mail gateway', function (array $attributes, array $errors) { + test()->withoutExceptionHandling()->login()->loginNami(); + + Livewire::test(Form::class) + ->set('name', 'lala') + ->set('domain', 'example.com') + ->set('cls', LocalType::class) + ->setArray($attributes) + ->call('onSave') + ->assertHasErrors($errors) + ->assertNotDispatched('closeModal') + ->assertNotDispatched('refresh') + ->assertNotDispatched('success'); +})->with([ + [['name' => ''], ['name' => 'required']], + [['domain' => ''], ['domain' => 'required']], +]); + +it('test it validates mailman type', function (array $attributes, array $errors) { + test()->withoutExceptionHandling()->login()->loginNami(); + + Livewire::test(Form::class) + ->set('name', 'lala') + ->set('domain', 'example.com') + ->set('cls', MailmanType::class) + ->set('params.url', 'exampl.com') + ->set('params.user', '::user::') + ->set('params.password', 'password') + ->setArray($attributes) + ->call('onSave') + ->assertHasErrors($errors) + ->assertNotDispatched('closeModal'); +})->with([ + [['params.url' => ''], ['params.url' => 'required']], + [['params.user' => ''], ['params.user' => 'required']], + [['params.password' => ''], ['params.password' => 'required']], + [['params.owner' => ''], ['params.owner' => 'required']], + [['params.owner' => 'aaa'], ['params.owner' => 'email']], +]); + +it('test it stores mailman gateway', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + $typeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://example.com', 'user' => 'user', 'password' => 'secret', 'owner' => 'owner@example.com']); + + Livewire::test(Form::class) + ->setArray([ + 'name' => 'lala', + 'domain' => 'https://example.com', + 'cls' => MailmanType::class, + 'params' => $typeParams + ]) + ->call('onSave') + ->assertDispatched('closeModal'); + + $this->assertDatabaseHas('mailgateways', [ + 'type' => json_encode([ + 'cls' => MailmanType::class, + 'params' => $typeParams, + ]), + 'name' => 'lala', + 'domain' => 'https://example.com', + ]); +}); + +it('test it checks mailman connection', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + $typeParams = MailmanTypeRequest::new()->fails()->create(['url' => 'https://example.com', 'user' => 'user', 'password' => 'secret', 'owner' => 'owner@example.com']); + + Livewire::test(Form::class) + ->setArray([ + 'name' => 'lala', + 'domain' => 'https://example.com', + 'cls' => MailmanType::class, + 'params' => $typeParams + ]) + ->call('onSave') + ->assertHasErrors('connection') + ->assertNotDispatched('closeModal'); + + $this->assertDatabaseCount('mailgateways', 0); +}); diff --git a/modules/Mailgateway/UpdateTest.php b/modules/Mailgateway/UpdateTest.php new file mode 100644 index 00000000..790af3fb --- /dev/null +++ b/modules/Mailgateway/UpdateTest.php @@ -0,0 +1,104 @@ +withoutExceptionHandling()->login()->loginNami(); + + $typeParams = MailmanTypeRequest::new()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner']); + $mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(['name' => '::name::', 'domain' => 'example.com']); + + Livewire::test(Form::class, ['model' => $mailgateway->id]) + ->assertSet('id', $mailgateway->id) + ->assertSet('name', '::name::') + ->assertSet('domain', 'example.com') + ->assertSet('cls', MailmanType::class) + ->assertSet('params.url', 'https://mailman.example.com') + ->assertSet('params.user', 'user') + ->assertSet('params.password', 'password') + ->assertSet('params.owner', 'owner'); +}); + +it('test it sets attributes for local', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + $mailgateway = Mailgateway::factory()->type(LocalType::class, [])->create(['name' => '::name::', 'domain' => 'example.com']); + + Livewire::test(Form::class, ['model' => $mailgateway->id]) + ->assertSet('name', '::name::') + ->assertSet('domain', 'example.com') + ->assertSet('cls', LocalType::class) + ->assertSet('params', []); +}); + +it('test it validates type', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + $mailgateway = Mailgateway::factory()->type(LocalType::class, [])->create(['name' => '::name::', 'domain' => 'example.com']); + + Livewire::test(Form::class, ['model' => $mailgateway->id]) + ->set('cls', '') + ->assertHasErrors(['cls' => 'required']); +}); + +it('test it updates a mailman gateway without updating password', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + $typeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']); + $mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(['name' => '::name::', 'domain' => 'example.com']); + + Livewire::test(Form::class, ['model' => $mailgateway->id]) + ->set('name', '::newname::') + ->call('onSave') + ->assertHasNoErrors(); + + $this->assertDatabaseCount('mailgateways', 1); + $this->assertDatabaseHas('mailgateways', [ + 'name' => '::newname::', + 'type' => json_encode(['cls' => MailmanType::class, 'params' => $typeParams]), + ]); +}); + +it('test it updates a mailman gateway with password', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + $typeParams = MailmanTypeRequest::new()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']); + $newTypeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'newuser', 'password' => 'password', 'owner' => 'owner@example.com']); + $mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(); + + Livewire::test(Form::class, ['model' => $mailgateway->id]) + ->set('params.user', 'newuser') + ->call('onSave') + ->assertHasNoErrors(); + + $this->assertDatabaseCount('mailgateways', 1); + $this->assertDatabaseHas('mailgateways', [ + 'type' => json_encode(['cls' => MailmanType::class, 'params' => $newTypeParams]), + ]); +}); + +it('test it checks mailgateway connection when updating', function () { + test()->withoutExceptionHandling()->login()->loginNami(); + + $typeParams = MailmanTypeRequest::new()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']); + MailmanTypeRequest::new()->fails()->create(['url' => 'https://mailman.example.com', 'user' => 'newuser', 'password' => 'password', 'owner' => 'owner@example.com']); + $mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(); + + Livewire::test(Form::class, ['model' => $mailgateway->id]) + ->set('params.user', 'newuser') + ->call('onSave') + ->assertHasErrors('connection'); +}); diff --git a/resources/js/components/ui/BooleanDisplay.vue b/resources/js/components/ui/BooleanDisplay.vue deleted file mode 100644 index 4536b3ed..00000000 --- a/resources/js/components/ui/BooleanDisplay.vue +++ /dev/null @@ -1,32 +0,0 @@ - - -