Add: Store new mailgateway

This commit is contained in:
Philipp Lang 2023-06-01 15:45:02 +02:00
parent 27c61ff8af
commit f75201dfaa
7 changed files with 153 additions and 17 deletions

View File

@ -0,0 +1,33 @@
<?php
namespace App\Mailgateway\Actions;
use App\Mailgateway\Models\Mailgateway;
use Illuminate\Validation\Rule;
use Lorisleiva\Actions\ActionRequest;
use Lorisleiva\Actions\Concerns\AsAction;
class StoreAction
{
use AsAction;
public function handle(array $input)
{
Mailgateway::create($input);
}
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'domain' => 'required|string|max:255',
'type.class' => ['required', 'string', 'max:255', Rule::in(app('mail-gateways'))],
'type.params' => 'present',
];
}
public function asController(ActionRequest $request): void
{
$this->handle($request->validated());
}
}

View File

@ -36,6 +36,18 @@ class MailgatewayResource extends JsonResource
'links' => [
'store' => route('api.mailgateway.store'),
],
'types' => app('mail-gateways')->map(fn ($gateway) => [
'id' => $gateway,
'name' => $gateway::name(),
]),
'default' => [
'domain' => '',
'name' => '',
'type' => [
'params' => [],
'class' => null,
],
],
];
}
}

View File

@ -1,21 +1,18 @@
<template>
<page-layout>
<template #toolbar>
<page-toolbar-button @click.prevent="popup = true" color="primary" icon="plus">Neue Verbindung</page-toolbar-button>
<page-toolbar-button @click.prevent="model = data.meta.default" color="primary" icon="plus">Neue Verbindung</page-toolbar-button>
</template>
<ui-popup heading="Neue Verbindung" v-if="popup === true" @close="popup = false">
<ui-popup heading="Neue Verbindung" v-if="model !== null && !model.id" @close="model = null">
<div>
<div class="grid grid-cols-2 gap-3 mt-6">
<f-text v-model="model.name" name="name" id="name" label="Bezeichnung" required></f-text>
<f-text v-model="model.domain" name="domain" id="domain" label="Domain" required></f-text>
<f-select :value="model.type.class" @input="model.type.class = $event" label="Typ" name="type" id="type" :options="data.meta.types"></f-select>
</div>
<div class="flex mt-4 space-x-2">
<a href="#" @click.prevent="submit" class="text-center btn btn-danger">Speichern</a>
<a
href="#"
@click.prevent="
value = {};
popup = false;
"
class="text-center btn btn-primary"
>Abbrechen</a
>
<a href="#" @click.prevent="model = null" class="text-center btn btn-primary">Abbrechen</a>
</div>
</div>
</ui-popup>
@ -23,14 +20,14 @@
<div class="w-full h-full pb-6">
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm hidden md:table">
<thead>
<th>Name</th>
<th>Bezeichnung</th>
<th>Domain</th>
<th>Typ</th>
<th>Prüfung</th>
<th>Aktion</th>
</thead>
<tr v-for="(gateway, index) in inner" :key="index">
<tr v-for="(gateway, index) in inner.data" :key="index">
<td v-text="gateway.name"></td>
<td v-text="gateway.domain"></td>
<td v-text="gateway.type_human"></td>
@ -55,18 +52,33 @@
<script>
import SettingLayout from '../setting/Layout.vue';
import indexHelpers from '../../mixins/indexHelpers.js';
export default {
mixins: [indexHelpers],
data: function () {
return {
popup: false,
inner: [...this.data.data],
meta: {...this.data.meta},
model: null,
inner: {...this.data},
};
},
props: {
data: {},
},
methods: {
async submit() {
try {
await this.axios.post(this.data.meta.links.store, this.model);
this.reload();
this.model = null;
} catch (e) {
this.errorsFromException(e);
}
},
},
components: {
SettingLayout,
},

View File

@ -20,6 +20,7 @@ use App\Initialize\Actions\InitializeFormAction;
use App\Initialize\Actions\NamiGetSearchLayerAction;
use App\Initialize\Actions\NamiLoginCheckAction;
use App\Initialize\Actions\NamiSearchAction;
use App\Mailgateway\Actions\StoreAction;
use App\Member\Actions\ExportAction;
use App\Member\Actions\MemberResyncAction;
use App\Member\Actions\MemberShowAction;
@ -80,5 +81,5 @@ Route::group(['middleware' => 'auth:web'], function (): void {
Route::post('/contribution-validate', ContributionValidateAction::class)->name('contribution.validate');
// -------------------------------- Mailgateway --------------------------------
Route::post('/api/mailgateway', fn () => '')->name('api.mailgateway.store');
Route::post('/api/mailgateway', StoreAction::class)->name('api.mailgateway.store');
});

View File

@ -45,5 +45,9 @@ class IndexTest extends TestCase
$response = $this->get('/setting/mailgateway');
$this->assertInertiaHas(route('api.mailgateway.store'), $response, 'data.meta.links.store');
$this->assertInertiaHas([
'id' => LocalType::class,
'name' => 'Lokal',
], $response, 'data.meta.types.0');
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Tests\Feature\Mailgateway;
use App\Mailgateway\Types\LocalType;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\RequestFactories\MailgatewayRequestFactory;
use Tests\TestCase;
class StoreTest extends TestCase
{
use DatabaseTransactions;
public function setUp(): void
{
parent::setUp();
$this->login()->loginNami();
}
public function testItCanStoreALocalGateway(): void
{
$response = $this->post('/api/mailgateway', MailgatewayRequestFactory::new()->name('lala')->type(LocalType::class, [])->domain('example.com')->create());
$response->assertOk();
$this->assertDatabaseHas('mailgateways', [
'domain' => 'example.com',
'name' => 'lala',
]);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace Tests\RequestFactories;
use Worksome\RequestFactories\RequestFactory;
class MailgatewayRequestFactory extends RequestFactory
{
public function definition(): array
{
return [
'name' => $this->faker->words(5, true),
'type' => [
'class' => app('mail-gateways')->random(),
'params' => [],
],
'domain' => $this->faker->safeEmailDomain(),
];
}
public function name(string $name): self
{
return $this->state(['name' => $name]);
}
public function domain(string $domain): self
{
return $this->state(['domain' => $domain]);
}
/**
* @param class-string<Type> $type
* @param array<string, mixed> $params
*/
public function type(string $type, array $params): self
{
return $this->state(['type' => [
'class' => $type,
'params' => $params,
]]);
}
}