Compare commits

..

23 Commits

Author SHA1 Message Date
philipp lang e807aff3e6 Remove default arch tests
continuous-integration/drone/push Build is passing Details
2024-10-28 23:54:21 +01:00
philipp lang 096224fe98 Lint
continuous-integration/drone/push Build is passing Details
2024-09-23 02:01:35 +02:00
philipp lang 646ce647da Move Dashboard Route to DashboardServiceProvider 2024-09-23 01:53:46 +02:00
philipp lang f858716e57 Add Arch tests
continuous-integration/drone/push Build is passing Details
2024-09-22 22:58:31 +02:00
philipp lang 1521aba1f8 Fix drone
continuous-integration/drone/push Build is passing Details
2024-09-22 19:39:36 +02:00
philipp lang 664b88564d Fix phpstan
continuous-integration/drone/push Build is failing Details
2024-09-22 18:25:42 +02:00
philipp lang d30a2336cf Fix tests
continuous-integration/drone/push Build is failing Details
2024-09-22 17:32:29 +02:00
philipp lang a5f1c90003 Fix tests
continuous-integration/drone/push Build is failing Details
2024-09-22 12:28:10 +02:00
philipp lang c3908b714b Update laravel-nami
continuous-integration/drone/push Build is failing Details
2024-09-22 03:02:15 +02:00
philipp lang 2f1e02151f Fix tests 2024-09-22 03:02:10 +02:00
philipp lang eaf014b7c7 Touch env file while testing with drone
continuous-integration/drone/push Build is failing Details
2024-09-22 02:30:25 +02:00
philipp lang 94d34d1afa Add Pail 2024-09-22 02:15:59 +02:00
philipp lang 9b700be889 Update laravel-nami
continuous-integration/drone/push Build was killed Details
2024-09-22 02:13:12 +02:00
philipp lang e1ec6ad9df update composer in drone
continuous-integration/drone/push Build is failing Details
2024-09-22 02:03:58 +02:00
philipp lang aaa236fcd5 Fix tests
continuous-integration/drone/push Build is failing Details
2024-09-22 01:41:56 +02:00
philipp lang 4d74e53fc2 Update Activity UpdateTest 2024-09-22 00:06:03 +02:00
philipp lang b8d389bdb9 Lint Activity EditTest 2024-09-21 23:43:51 +02:00
philipp lang 3a4c99f154 Add Laravel 11 support
continuous-integration/drone/push Build was killed Details
2024-09-21 22:46:38 +02:00
philipp lang fca7fc463e Update php to 8.3
continuous-integration/drone/push Build is passing Details
2024-09-21 21:55:16 +02:00
philipp lang 767df11e4f Fix tests
continuous-integration/drone/push Build is passing Details
2024-09-21 18:56:53 +02:00
philipp lang 295d85f4f8 Add Pestphp
continuous-integration/drone/push Build is failing Details
2024-09-21 18:29:47 +02:00
philipp lang 42ccd32740 Fix tests
continuous-integration/drone/push Build is failing Details
2024-09-21 17:46:07 +02:00
philipp lang bbcf2fd768 Update to laravel 10
continuous-integration/drone/push Build is failing Details
2024-09-21 17:42:11 +02:00
84 changed files with 3205 additions and 2859 deletions

View File

@ -1,4 +1,4 @@
FROM php:8.1.6-fpm as php FROM php:8.3.11-fpm as php
WORKDIR /app WORKDIR /app
RUN ls /app RUN ls /app
RUN apt-get update RUN apt-get update

View File

@ -12,7 +12,7 @@ steps:
- git submodule update --init --recursive - git submodule update --init --recursive
- name: composer_dev - name: composer_dev
image: composer:2.2.7 image: composer:2.7.9
commands: commands:
- composer install --ignore-platform-reqs --dev - composer install --ignore-platform-reqs --dev
@ -39,6 +39,7 @@ steps:
- name: tests - name: tests
image: zoomyboy/adrema-base:latest image: zoomyboy/adrema-base:latest
commands: commands:
- touch .env
- php artisan migrate - php artisan migrate
- php artisan test - php artisan test
- rm -f .env - rm -f .env
@ -135,7 +136,7 @@ steps:
event: push event: push
- name: composer_no_dev - name: composer_no_dev
image: composer:2.2.7 image: composer:2.7.9
commands: commands:
- composer install --ignore-platform-reqs --no-dev - composer install --ignore-platform-reqs --no-dev

View File

@ -4,12 +4,14 @@ namespace App;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use Cviebrock\EloquentSluggable\Sluggable; use Cviebrock\EloquentSluggable\Sluggable;
use Database\Factories\ActivityFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Activity extends Model class Activity extends Model
{ {
/** @use HasFactory<ActivityFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;
use Sluggable; use Sluggable;

View File

@ -2,11 +2,13 @@
namespace App; namespace App;
use Database\Factories\ConfessionFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Confession extends Model class Confession extends Model
{ {
/** @use HasFactory<ConfessionFactory> */
use HasFactory; use HasFactory;
public $fillable = ['name', 'nami_id', 'is_null']; public $fillable = ['name', 'nami_id', 'is_null'];

View File

@ -29,7 +29,7 @@ class MemberData extends Data
*/ */
public static function fromModels(array $ids): Collection public static function fromModels(array $ids): Collection
{ {
return Member::whereIn('id', $ids)->orderByRaw('lastname, firstname')->get()->map(fn ($member) => self::withoutMagicalCreationFrom([ return Member::whereIn('id', $ids)->orderByRaw('lastname, firstname')->get()->map(fn ($member) => self::factory()->withoutMagicalCreation()->from([
...$member->toArray(), ...$member->toArray(),
'birthday' => $member->birthday->toAtomString(), 'birthday' => $member->birthday->toAtomString(),
'isLeader' => $member->isLeader(), 'isLeader' => $member->isLeader(),
@ -44,7 +44,7 @@ class MemberData extends Data
*/ */
public static function fromApi(array $data): Collection public static function fromApi(array $data): Collection
{ {
return collect($data)->map(fn ($member) => self::withoutMagicalCreationFrom([ return collect($data)->map(fn ($member) => self::factory()->withoutMagicalCreation()->from([
...$member, ...$member,
'birthday' => Carbon::parse($member['birthday'])->toAtomString(), 'birthday' => Carbon::parse($member['birthday'])->toAtomString(),
'gender' => Gender::fromString($member['gender']), 'gender' => Gender::fromString($member['gender']),
@ -54,22 +54,22 @@ class MemberData extends Data
public function fullname(): string public function fullname(): string
{ {
return $this->firstname.' '.$this->lastname; return $this->firstname . ' ' . $this->lastname;
} }
public function separatedName(): string public function separatedName(): string
{ {
return $this->lastname.', '.$this->firstname; return $this->lastname . ', ' . $this->firstname;
} }
public function fullAddress(): string public function fullAddress(): string
{ {
return $this->address.', '.$this->zip.' '.$this->location; return $this->address . ', ' . $this->zip . ' ' . $this->location;
} }
public function city(): string public function city(): string
{ {
return $this->zip.' '.$this->location; return $this->zip . ' ' . $this->location;
} }
public function age(): string public function age(): string

View File

@ -74,7 +74,7 @@ class BdkjHesse extends ContributionDocument
public function durationDays(): int public function durationDays(): int
{ {
return Carbon::parse($this->dateUntil)->diffInDays(Carbon::parse($this->dateFrom)) + 1; return intVal(Carbon::parse($this->dateUntil)->diffInDays(Carbon::parse($this->dateFrom))) + 1;
} }
/** /**

View File

@ -3,11 +3,13 @@
namespace App; namespace App;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use Database\Factories\CountryFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Country extends Model class Country extends Model
{ {
/** @use HasFactory<CountryFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;

View File

@ -3,11 +3,13 @@
namespace App\Course\Models; namespace App\Course\Models;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use Database\Factories\Course\Models\CourseFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Course extends Model class Course extends Model
{ {
/** @use HasFactory<CourseFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;

View File

@ -3,12 +3,14 @@
namespace App\Course\Models; namespace App\Course\Models;
use App\Member\Member; use App\Member\Member;
use Database\Factories\Course\Models\CourseMemberFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class CourseMember extends Model class CourseMember extends Model
{ {
/** @use HasFactory<CourseMemberFactory> */
use HasFactory; use HasFactory;
/** @var array<int, string> */ /** @var array<int, string> */

View File

@ -2,7 +2,9 @@
namespace App\Dashboard; namespace App\Dashboard;
use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use App\Dashboard\Actions\IndexAction as DashboardIndexAction;
class DashboardServiceProvider extends ServiceProvider class DashboardServiceProvider extends ServiceProvider
{ {
@ -23,5 +25,8 @@ class DashboardServiceProvider extends ServiceProvider
*/ */
public function boot() public function boot()
{ {
app(Router::class)->middleware(['web', 'auth:web'])->group(function ($router) {
$router->get('/', DashboardIndexAction::class)->name('home');
});
} }
} }

View File

@ -4,12 +4,14 @@ namespace App;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use App\Payment\Subscription; use App\Payment\Subscription;
use Database\Factories\FeeFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
class Fee extends Model class Fee extends Model
{ {
/** @use HasFactory<FeeFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;

View File

@ -17,6 +17,6 @@ class ListFilesAction
*/ */
public function handle(ActionRequest $request, Fileshare $fileshare): DataCollection public function handle(ActionRequest $request, Fileshare $fileshare): DataCollection
{ {
return ResourceData::collection($fileshare->type->getSubDirectories($request->input('parent')))->wrap('data'); return ResourceData::collect($fileshare->type->getSubDirectories($request->input('parent')), DataCollection::class)->wrap('data');
} }
} }

View File

@ -3,11 +3,13 @@
namespace App\Fileshare\Models; namespace App\Fileshare\Models;
use App\Fileshare\ConnectionTypes\ConnectionType; use App\Fileshare\ConnectionTypes\ConnectionType;
use Database\Factories\Fileshare\Models\FileshareFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Fileshare extends Model class Fileshare extends Model
{ {
/** @use HasFactory<FileshareFactory> */
use HasFactory; use HasFactory;
public $guarded = []; public $guarded = [];

View File

@ -6,6 +6,7 @@ use App\Form\Fields\Field;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Spatie\LaravelData\Casts\Cast; use Spatie\LaravelData\Casts\Cast;
use Spatie\LaravelData\Data; use Spatie\LaravelData\Data;
use Spatie\LaravelData\Support\Creation\CreationContext;
use Spatie\LaravelData\Support\DataProperty; use Spatie\LaravelData\Support\DataProperty;
class CollectionCast implements Cast class CollectionCast implements Cast
@ -20,10 +21,9 @@ class CollectionCast implements Cast
/** /**
* @param array<int, array<string, mixed>> $value * @param array<int, array<string, mixed>> $value
* @param array<string, mixed> $context
* @return Collection<int, Data> * @return Collection<int, Data>
*/ */
public function cast(DataProperty $property, mixed $value, array $context): mixed public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): mixed
{ {
return collect($value)->map(fn ($item) => $this->target::from($item)); return collect($value)->map(fn ($item) => $this->target::from($item));
} }

View File

@ -5,16 +5,16 @@ namespace App\Form\Casts;
use App\Form\Data\FieldCollection; use App\Form\Data\FieldCollection;
use App\Form\Fields\Field; use App\Form\Fields\Field;
use Spatie\LaravelData\Casts\Cast; use Spatie\LaravelData\Casts\Cast;
use Spatie\LaravelData\Support\Creation\CreationContext;
use Spatie\LaravelData\Support\DataProperty; use Spatie\LaravelData\Support\DataProperty;
class FieldCollectionCast implements Cast class FieldCollectionCast implements Cast
{ {
/** /**
* @param array<int, array<string, string>> $value * @param array<int, array<string, string>> $value
* @param array<string, mixed> $context
* @return FieldCollection * @return FieldCollection
*/ */
public function cast(DataProperty $property, mixed $value, array $context): mixed public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): mixed
{ {
return new FieldCollection(collect($value)->map(fn ($value) => Field::classFromType($value['type'])::from($value))->all()); return new FieldCollection(collect($value)->map(fn ($value) => Field::classFromType($value['type'])::from($value))->all());
} }

View File

@ -48,7 +48,7 @@ enum NamiType: string
static::LOCATION => $member->location, static::LOCATION => $member->location,
static::NICKNAME => $member->nickname, static::NICKNAME => $member->nickname,
static::GENDER => $member->gender?->name, static::GENDER => $member->gender?->name,
static::AGE => $member->birthday->diffInYears(now()), static::AGE => intVal($member->birthday->diffInYears(now())),
static::AGEEVENT => $member->birthday->diffInYears($form->from), static::AGEEVENT => $member->birthday->diffInYears($form->from),
static::MOBILEPHONE => $member->mobile_phone, static::MOBILEPHONE => $member->mobile_phone,
}; };

View File

@ -8,10 +8,12 @@ use App\Form\Data\FormConfigData;
use App\Lib\Editor\Condition; use App\Lib\Editor\Condition;
use App\Lib\Editor\EditorData; use App\Lib\Editor\EditorData;
use Cviebrock\EloquentSluggable\Sluggable; use Cviebrock\EloquentSluggable\Sluggable;
use Database\Factories\Form\Models\FormFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Laravel\Scout\Searchable; use Laravel\Scout\Searchable;
use Spatie\Image\Enums\Fit;
use Spatie\Image\Manipulations; use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia; use Spatie\MediaLibrary\InteractsWithMedia;
@ -21,6 +23,7 @@ use Zoomyboy\MedialibraryHelper\DefersUploads;
/** @todo replace editor content with EditorData cast */ /** @todo replace editor content with EditorData cast */
class Form extends Model implements HasMedia class Form extends Model implements HasMedia
{ {
/** @use HasFactory<FormFactory> */
use HasFactory; use HasFactory;
use Sluggable; use Sluggable;
use InteractsWithMedia; use InteractsWithMedia;
@ -41,11 +44,12 @@ class Form extends Model implements HasMedia
'needs_prevention' => 'boolean', 'needs_prevention' => 'boolean',
'prevention_text' => EditorData::class, 'prevention_text' => EditorData::class,
'prevention_conditions' => Condition::class, 'prevention_conditions' => Condition::class,
'from' => 'datetime',
'to' => 'datetime',
'registration_from' => 'datetime',
'registration_until' => 'datetime',
]; ];
/** @var array<int, string> */
public $dates = ['from', 'to', 'registration_from', 'registration_until'];
/** /**
* @return SluggableConfig * @return SluggableConfig
*/ */
@ -73,7 +77,7 @@ class Form extends Model implements HasMedia
->forceFileName(fn (Form $model, string $name) => $model->slug) ->forceFileName(fn (Form $model, string $name) => $model->slug)
->convert(fn () => 'jpg') ->convert(fn () => 'jpg')
->registerMediaConversions(function (Media $media) { ->registerMediaConversions(function (Media $media) {
$this->addMediaConversion('square')->fit(Manipulations::FIT_CROP, 400, 400); $this->addMediaConversion('square')->fit(Fit::Crop, 400, 400);
}); });
$this->addMediaCollection('mailattachments') $this->addMediaCollection('mailattachments')
->withDefaultProperties(fn () => [ ->withDefaultProperties(fn () => [

View File

@ -4,6 +4,7 @@ namespace App\Form\Models;
use App\Form\Data\FormConfigData; use App\Form\Data\FormConfigData;
use App\Lib\Editor\EditorData; use App\Lib\Editor\EditorData;
use Database\Factories\Form\Models\FormtemplateFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -12,6 +13,7 @@ use Illuminate\Database\Eloquent\Model;
*/ */
class Formtemplate extends Model class Formtemplate extends Model
{ {
/** @use HasFactory<FormtemplateFactory> */
use HasFactory; use HasFactory;
public $guarded = []; public $guarded = [];

View File

@ -8,6 +8,7 @@ use App\Form\Mails\ConfirmRegistrationMail;
use App\Form\Scopes\ParticipantFilterScope; use App\Form\Scopes\ParticipantFilterScope;
use App\Member\Member; use App\Member\Member;
use App\Prevention\Contracts\Preventable; use App\Prevention\Contracts\Preventable;
use Database\Factories\Form\Models\ParticipantFactory;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -18,6 +19,8 @@ use stdClass;
class Participant extends Model implements Preventable class Participant extends Model implements Preventable
{ {
/** @use HasFactory<ParticipantFactory> */
use HasFactory; use HasFactory;
public $guarded = []; public $guarded = [];

View File

@ -5,6 +5,7 @@ namespace App\Form\Transformers;
use App\Form\Fields\Field; use App\Form\Fields\Field;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Spatie\LaravelData\Support\DataProperty; use Spatie\LaravelData\Support\DataProperty;
use Spatie\LaravelData\Support\Transformation\TransformationContext;
use Spatie\LaravelData\Transformers\Transformer; use Spatie\LaravelData\Transformers\Transformer;
class CollectionTransformer implements Transformer class CollectionTransformer implements Transformer
@ -18,7 +19,7 @@ class CollectionTransformer implements Transformer
* @param Collection<int, Field> $value * @param Collection<int, Field> $value
* @return array<string, mixed> * @return array<string, mixed>
*/ */
public function transform(DataProperty $property, mixed $value): mixed public function transform(DataProperty $property, mixed $value, TransformationContext $context): mixed
{ {
return $value->toArray(); return $value->toArray();
} }

View File

@ -5,6 +5,7 @@ namespace App\Form\Transformers;
use App\Form\Fields\Field; use App\Form\Fields\Field;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Spatie\LaravelData\Support\DataProperty; use Spatie\LaravelData\Support\DataProperty;
use Spatie\LaravelData\Support\Transformation\TransformationContext;
use Spatie\LaravelData\Transformers\Transformer; use Spatie\LaravelData\Transformers\Transformer;
class FieldCollectionTransformer implements Transformer class FieldCollectionTransformer implements Transformer
@ -14,7 +15,7 @@ class FieldCollectionTransformer implements Transformer
* @param Collection<int, Field> $value * @param Collection<int, Field> $value
* @return array<string, mixed> * @return array<string, mixed>
*/ */
public function transform(DataProperty $property, mixed $value): mixed public function transform(DataProperty $property, mixed $value, TransformationContext $context): mixed
{ {
return $value->map(fn ($field) => [ return $value->map(fn ($field) => [
...$field->toArray(), ...$field->toArray(),

View File

@ -3,12 +3,15 @@
namespace App; namespace App;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use Database\Factories\GenderFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Gender extends Model class Gender extends Model
{ {
use HasNamiField; use HasNamiField;
/** @use HasFactory<GenderFactory> */
use HasFactory; use HasFactory;
public $fillable = ['name', 'nami_id']; public $fillable = ['name', 'nami_id'];

View File

@ -5,6 +5,7 @@ namespace App;
use App\Fileshare\Data\FileshareResourceData; use App\Fileshare\Data\FileshareResourceData;
use App\Group\Enums\Level; use App\Group\Enums\Level;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use Database\Factories\GroupFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -12,6 +13,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class Group extends Model class Group extends Model
{ {
/** @use HasFactory<GroupFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;
@ -24,11 +26,11 @@ class Group extends Model
]; ];
/** /**
* @return BelongsTo<static, self> * @return BelongsTo<self, self>
*/ */
public function parent(): BelongsTo public function parent(): BelongsTo
{ {
return $this->belongsTo(static::class, 'parent_id'); return $this->belongsTo(self::class, 'parent_id');
} }
/** /**
@ -36,7 +38,7 @@ class Group extends Model
*/ */
public function children(): HasMany public function children(): HasMany
{ {
return $this->hasMany(static::class, 'parent_id'); return $this->hasMany(self::class, 'parent_id');
} }
public static function booted(): void public static function booted(): void

View File

@ -36,7 +36,7 @@ abstract class InvoiceDocument extends Document
public static function fromInvoice(Invoice $invoice): self public static function fromInvoice(Invoice $invoice): self
{ {
return static::withoutMagicalCreationFrom([ return static::factory()->withoutMagicalCreation()->from([
'toName' => $invoice->to['name'], 'toName' => $invoice->to['name'],
'toAddress' => $invoice->to['address'], 'toAddress' => $invoice->to['address'],
'toZip' => $invoice->to['zip'], 'toZip' => $invoice->to['zip'],

View File

@ -11,6 +11,7 @@ use App\Invoice\RememberDocument;
use App\Invoice\Scopes\InvoiceFilterScope; use App\Invoice\Scopes\InvoiceFilterScope;
use App\Member\Member; use App\Member\Member;
use App\Payment\Subscription; use App\Payment\Subscription;
use Database\Factories\Invoice\Models\InvoiceFactory;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -20,6 +21,7 @@ use stdClass;
class Invoice extends Model class Invoice extends Model
{ {
/** @use HasFactory<InvoiceFactory> */
use HasFactory; use HasFactory;
public $guarded = []; public $guarded = [];
@ -28,12 +30,8 @@ class Invoice extends Model
'to' => 'json', 'to' => 'json',
'status' => InvoiceStatus::class, 'status' => InvoiceStatus::class,
'via' => BillKind::class, 'via' => BillKind::class,
]; 'sent_at' => 'datetime',
'last_remembered_at' => 'datetime',
/** @var array<int, string> */
public $dates = [
'sent_at',
'last_remembered_at',
]; ];
/** /**

View File

@ -3,12 +3,14 @@
namespace App\Invoice\Models; namespace App\Invoice\Models;
use App\Member\Member; use App\Member\Member;
use Database\Factories\Invoice\Models\InvoicePositionFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class InvoicePosition extends Model class InvoicePosition extends Model
{ {
/** @use HasFactory<InvoicePositionFactory> */
use HasFactory; use HasFactory;
public $guarded = []; public $guarded = [];

View File

@ -20,12 +20,12 @@ class Condition extends Data
public static function fromMedia(Media $media): self public static function fromMedia(Media $media): self
{ {
return $media->getCustomProperty('conditions') ? static::withoutMagicalCreationFrom($media->getCustomProperty('conditions')) : static::defaults(); return $media->getCustomProperty('conditions') ? static::factory()->withoutMagicalCreation()->from($media->getCustomProperty('conditions')) : static::defaults();
} }
public static function defaults(): self public static function defaults(): self
{ {
return static::withoutMagicalCreationFrom(['mode' => 'any', 'ifs' => []]); return static::factory()->withoutMagicalCreation()->from(['mode' => 'any', 'ifs' => []]);
} }
public function hasStatements(): bool public function hasStatements(): bool

View File

@ -20,7 +20,7 @@ abstract class ConditionResolver
*/ */
public function filterBlock(array $block): bool public function filterBlock(array $block): bool
{ {
return $this->filterCondition(Condition::withoutMagicalCreationFrom([ return $this->filterCondition(Condition::factory()->withoutMagicalCreation()->from([
'mode' => data_get($block, 'tunes.condition.mode', 'any'), 'mode' => data_get($block, 'tunes.condition.mode', 'any'),
'ifs' => data_get($block, 'tunes.condition.ifs', []), 'ifs' => data_get($block, 'tunes.condition.ifs', []),
])); ]));

View File

@ -36,7 +36,7 @@ abstract class Filter extends Data
*/ */
public static function fromPost(?array $post = null): static public static function fromPost(?array $post = null): static
{ {
return static::withoutMagicalCreationFrom($post ?: [])->toDefault(); return static::factory()->withoutMagicalCreation()->from($post ?: [])->toDefault();
} }
/** /**

View File

@ -14,9 +14,11 @@ abstract class ScoutFilter extends Data
{ {
/** /**
* @return Builder * @return Builder<T>
*/ */
abstract public function getQuery(): Builder; abstract public function getQuery(): Builder;
/** @var Builder<T> */
protected Builder $query; protected Builder $query;
/** /**
@ -36,6 +38,6 @@ abstract class ScoutFilter extends Data
*/ */
public static function fromPost(?array $post = null): static public static function fromPost(?array $post = null): static
{ {
return static::withoutMagicalCreationFrom($post ?: []); return static::factory()->withoutMagicalCreation()->from($post ?: []);
} }
} }

View File

@ -8,7 +8,6 @@ use Illuminate\Database\Eloquent\Model;
class Localmaildispatcher extends Model class Localmaildispatcher extends Model
{ {
use HasFactory;
use HasUuids; use HasUuids;
public $guarded = []; public $guarded = [];

View File

@ -3,6 +3,7 @@
namespace App\Maildispatcher\Models; namespace App\Maildispatcher\Models;
use App\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Database\Factories\Maildispatcher\Models\MaildispatcherFactory;
use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -10,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Maildispatcher extends Model class Maildispatcher extends Model
{ {
/** @use HasFactory<MaildispatcherFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;

View File

@ -3,12 +3,14 @@
namespace App\Mailgateway\Models; namespace App\Mailgateway\Models;
use App\Mailgateway\Casts\TypeCast; use App\Mailgateway\Casts\TypeCast;
use Database\Factories\Mailgateway\Models\MailgatewayFactory;
use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Mailgateway extends Model class Mailgateway extends Model
{ {
/** @use HasFactory<MailgatewayFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;

View File

@ -26,7 +26,7 @@ class MailingList extends Data
) { ) {
} }
public static function factory(): MailinglistFactory public static function toFactory(): MailinglistFactory
{ {
return MailinglistFactory::new(); return MailinglistFactory::new();
} }

View File

@ -5,7 +5,6 @@ namespace App\Member\Data;
use App\Group; use App\Group;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Spatie\LaravelData\Data; use Spatie\LaravelData\Data;
use Spatie\LaravelData\DataCollection;
class NestedGroup extends Data class NestedGroup extends Data
{ {
@ -23,7 +22,7 @@ class NestedGroup extends Data
$groups = collect([]); $groups = collect([]);
foreach (Group::where('parent_id', $parentId)->orderBy('name')->get()->toBase() as $group) { foreach (Group::where('parent_id', $parentId)->orderBy('name')->get()->toBase() as $group) {
$groups->push(['name' => str_repeat('- ', $level).$group->name, 'id' => $group->id]); $groups->push(['name' => str_repeat('- ', $level) . $group->name, 'id' => $group->id]);
$groups = $groups->merge(static::forSelect($group->id, $level + 1)); $groups = $groups->merge(static::forSelect($group->id, $level + 1));
} }
@ -31,10 +30,10 @@ class NestedGroup extends Data
} }
/** /**
* @return DataCollection<int, static> * @return Collection<int, static>
*/ */
public static function cacheForSelect(): DataCollection public static function cacheForSelect(): Collection
{ {
return static::collection(static::forSelect()); return static::collect(static::forSelect());
} }
} }

View File

@ -33,6 +33,7 @@ use Zoomyboy\Osm\Geolocatable;
use Zoomyboy\Osm\HasGeolocation; use Zoomyboy\Osm\HasGeolocation;
use Zoomyboy\Phone\HasPhoneNumbers; use Zoomyboy\Phone\HasPhoneNumbers;
use App\Prevention\Enums\Prevention; use App\Prevention\Enums\Prevention;
use Database\Factories\Member\MemberFactory;
/** /**
* @property string $subscription_name * @property string $subscription_name
@ -42,6 +43,7 @@ class Member extends Model implements Geolocatable
{ {
use Notifiable; use Notifiable;
use HasNamiField; use HasNamiField;
/** @use HasFactory<MemberFactory> */
use HasFactory; use HasFactory;
use Sluggable; use Sluggable;
use Searchable; use Searchable;
@ -58,11 +60,6 @@ class Member extends Model implements Geolocatable
*/ */
public static array $namiFields = ['firstname', 'lastname', 'joined_at', 'birthday', 'send_newspaper', 'address', 'zip', 'location', 'nickname', 'other_country', 'further_address', 'main_phone', 'mobile_phone', 'work_phone', 'fax', 'email', 'email_parents', 'gender_id', 'confession_id', 'region_id', 'country_id', 'fee_id', 'nationality_id', 'slug', 'subscription_id']; public static array $namiFields = ['firstname', 'lastname', 'joined_at', 'birthday', 'send_newspaper', 'address', 'zip', 'location', 'nickname', 'other_country', 'further_address', 'main_phone', 'mobile_phone', 'work_phone', 'fax', 'email', 'email_parents', 'gender_id', 'confession_id', 'region_id', 'country_id', 'fee_id', 'nationality_id', 'slug', 'subscription_id'];
/**
* @var array<int, string>
*/
public $dates = ['try_created_at', 'recertified_at', 'joined_at', 'birthday', 'efz', 'ps_at', 'more_ps_at', 'without_education_at', 'without_efz_at'];
/** /**
* @var array<string, string> * @var array<string, string>
*/ */
@ -82,6 +79,16 @@ class Member extends Model implements Geolocatable
'is_leader' => 'boolean', 'is_leader' => 'boolean',
'bill_kind' => BillKind::class, 'bill_kind' => BillKind::class,
'mitgliedsnr' => 'integer', 'mitgliedsnr' => 'integer',
'try_created_at' => 'datetime',
'recertified_at' => 'datetime',
'joined_at' => 'datetime',
'birthday' => 'datetime',
'efz' => 'datetime',
'ps_at' => 'datetime',
'more_ps_at' => 'datetime',
'without_education_at' => 'datetime',
'without_efz_at' => 'datetime',
]; ];
/** /**
@ -177,7 +184,7 @@ class Member extends Model implements Geolocatable
public function getAge(): ?int public function getAge(): ?int
{ {
return $this->birthday?->diffInYears(now()); return $this->birthday ? intval($this->birthday->diffInYears(now())) : null;
} }
protected function getAusstand(): int protected function getAusstand(): int
@ -401,14 +408,14 @@ class Member extends Model implements Geolocatable
return $query->where('group_id', $group->id); return $query->where('group_id', $group->id);
} }
public static function fromVcard(string $url, string $data): static public static function fromVcard(string $url, string $data): self
{ {
$settings = app(NamiSettings::class); $settings = app(NamiSettings::class);
$card = Reader::read($data); $card = Reader::read($data);
[$lastname, $firstname] = $card->N->getParts(); [$lastname, $firstname] = $card->N->getParts();
[$deprecated1, $deprecated2, $address, $location, $region, $zip, $country] = $card->ADR->getParts(); [$deprecated1, $deprecated2, $address, $location, $region, $zip, $country] = $card->ADR->getParts();
return new static([ return new self([
'joined_at' => now(), 'joined_at' => now(),
'send_newspaper' => false, 'send_newspaper' => false,
'firstname' => $firstname, 'firstname' => $firstname,

View File

@ -6,6 +6,7 @@ use App\Activity;
use App\Group; use App\Group;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use App\Subactivity; use App\Subactivity;
use Database\Factories\Member\MembershipFactory;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -16,6 +17,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
*/ */
class Membership extends Model class Membership extends Model
{ {
/** @use HasFactory<MembershipFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;

View File

@ -3,11 +3,13 @@
namespace App; namespace App;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use Database\Factories\NationalityFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Nationality extends Model class Nationality extends Model
{ {
/** @use HasFactory<NationalityFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;

View File

@ -3,6 +3,7 @@
namespace App\Payment; namespace App\Payment;
use App\Fee; use App\Fee;
use Database\Factories\Payment\SubscriptionFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -10,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class Subscription extends Model class Subscription extends Model
{ {
/** @use HasFactory<SubscriptionFactory> */
use HasFactory; use HasFactory;
/** /**

View File

@ -2,12 +2,14 @@
namespace App\Payment; namespace App\Payment;
use Database\Factories\Payment\SubscriptionChildFactory;
use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class SubscriptionChild extends Model class SubscriptionChild extends Model
{ {
/** @use HasFactory<SubscriptionChildFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;

View File

@ -21,7 +21,6 @@ class AppServiceProvider extends ServiceProvider
public function register() public function register()
{ {
JsonResource::withoutWrapping(); JsonResource::withoutWrapping();
Telescope::ignoreMigrations();
\Inertia::share('search', request()->query('search', '')); \Inertia::share('search', request()->query('search', ''));

View File

@ -2,12 +2,14 @@
namespace App; namespace App;
use Database\Factories\RegionFactory;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Region extends Model class Region extends Model
{ {
/** @use HasFactory<RegionFactory> */
use HasFactory; use HasFactory;
public $timestamps = false; public $timestamps = false;

View File

@ -4,12 +4,14 @@ namespace App;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
use Cviebrock\EloquentSluggable\Sluggable; use Cviebrock\EloquentSluggable\Sluggable;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Subactivity extends Model class Subactivity extends Model
{ {
/** @use HasFactory<UserFactory> */
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;
use Sluggable; use Sluggable;

View File

@ -3,12 +3,14 @@
namespace App; namespace App;
use App\Auth\ResetPassword; use App\Auth\ResetPassword;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
class User extends Authenticatable class User extends Authenticatable
{ {
/** @use HasFactory<UserFactory> */
use HasFactory; use HasFactory;
use Notifiable; use Notifiable;

View File

@ -45,35 +45,34 @@
], ],
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^8.1", "php": "^8.3",
"barryvdh/laravel-debugbar": "^3.9", "barryvdh/laravel-debugbar": "^3.9",
"beyondcode/laravel-dump-server": "^1.8", "cviebrock/eloquent-sluggable": "^11.0",
"cviebrock/eloquent-sluggable": "^9.0",
"doctrine/dbal": "^3.1", "doctrine/dbal": "^3.1",
"guzzlehttp/guzzle": "^7.0.1", "guzzlehttp/guzzle": "^7.0.1",
"inertiajs/inertia-laravel": "^0.6.9", "inertiajs/inertia-laravel": "^1.0",
"laravel/framework": "^9.0", "laravel/framework": "^11.0",
"laravel/horizon": "^5.0", "laravel/horizon": "^5.0",
"laravel/passport": "^11.8", "laravel/pail": "^1.1",
"laravel/scout": "^9.8", "laravel/passport": "^12.8",
"laravel/telescope": "^4.13", "laravel/scout": "^10.8",
"laravel/telescope": "^5.0",
"laravel/tinker": "^2.0", "laravel/tinker": "^2.0",
"laravel/ui": "^3.0", "laravel/ui": "^4.0",
"league/csv": "^9.9", "league/csv": "^9.9",
"league/flysystem-webdav": "dev-master as 3.28.0",
"lorisleiva/laravel-actions": "^2.4", "lorisleiva/laravel-actions": "^2.4",
"meilisearch/meilisearch-php": "^1.6", "meilisearch/meilisearch-php": "^1.6",
"monicahq/laravel-sabre": "^1.6", "monicahq/laravel-sabre": "^1.6",
"nunomaduro/collision": "^6.1", "nunomaduro/collision": "^8.1",
"phake/phake": "^4.2", "phake/phake": "^4.2",
"pusher/pusher-php-server": "^7.2", "pusher/pusher-php-server": "^7.2",
"spatie/laravel-data": "^3.0", "spatie/laravel-data": "^4.0",
"spatie/laravel-ignition": "^1.0", "spatie/laravel-ignition": "^2.0",
"spatie/laravel-medialibrary": "^10.0", "spatie/laravel-settings": "^3.0",
"spatie/laravel-settings": "^2.2", "worksome/request-factories": "^3.0",
"worksome/request-factories": "^2.5",
"zoomyboy/laravel-nami": "dev-master", "zoomyboy/laravel-nami": "dev-master",
"zoomyboy/medialibrary-helper": "dev-master as 1.0", "zoomyboy/medialibrary-helper": "dev-master as 1.0",
"league/flysystem-webdav": "dev-master as 3.28.0",
"zoomyboy/osm": "1.0.3", "zoomyboy/osm": "1.0.3",
"zoomyboy/phone": "^1.0", "zoomyboy/phone": "^1.0",
"zoomyboy/table-document": "dev-master as 1.0", "zoomyboy/table-document": "dev-master as 1.0",
@ -81,12 +80,12 @@
}, },
"require-dev": { "require-dev": {
"fakerphp/faker": "^1.9.1", "fakerphp/faker": "^1.9.1",
"larastan/larastan": "^2.0",
"laravel/envoy": "^2.8", "laravel/envoy": "^2.8",
"mockery/mockery": "^1.4.4", "mockery/mockery": "^1.4.4",
"larastan/larastan": "^2.0", "orchestra/testbench": "^9.0",
"orchestra/testbench": "^7.0", "pestphp/pest": "^3.0",
"phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-mockery": "^1.1"
"phpunit/phpunit": "^9.5.10"
}, },
"config": { "config": {
"optimize-autoloader": true, "optimize-autoloader": true,

4582
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('settings', function (Blueprint $table): void {
$table->boolean('locked')->default(false)->change();
$table->unique(['group', 'name']);
$table->dropIndex(['group']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('settings', function (Blueprint $table): void {
$table->boolean('locked')->default(null)->change();
$table->dropUnique(['group', 'name']);
$table->index('group');
});
}
};

@ -1 +1 @@
Subproject commit 84103d40521d77f936635a7f992cf1ae4b01dafe Subproject commit bc61530e510b3d41048984b7cf20b6d82c4f85fb

@ -1 +1 @@
Subproject commit 59d7647720ab2791e954944b38c986143db9de8e Subproject commit 77cfe9bbc7a11ee6494b205458ac5c75ff5c166d

@ -1 +1 @@
Subproject commit 8aefd17b06ee3c26d00b472a154a48898b884d15 Subproject commit 7304963370ff64fb5accf08da4864981cc424301

View File

@ -10,7 +10,6 @@ parameters:
paths: paths:
- app - app
- tests
- database - database
- packages/tex/src - packages/tex/src
- packages/laravel-nami/src - packages/laravel-nami/src
@ -29,6 +28,11 @@ parameters:
AddressBookCard: 'array{lastmodified: int, etag: string, uri: string, id: int, size: int}' AddressBookCard: 'array{lastmodified: int, etag: string, uri: string, id: int, size: int}'
ignoreErrors: ignoreErrors:
-
message: "#but does not specify its types: TData#"
-
message: "#cast\\(\\) has parameter \\$properties#"
- -
message: "#^Method App\\\\Activity\\:\\:sluggable\\(\\) return type has no value type specified in iterable type array\\.$#" message: "#^Method App\\\\Activity\\:\\:sluggable\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1 count: 1
@ -59,11 +63,6 @@ parameters:
count: 1 count: 1
path: app/Member/Member.php path: app/Member/Member.php
-
message: "#^Unsafe usage of new static\\(\\)\\.$#"
count: 1
path: app/Member/Member.php
- -
message: "#^Method App\\\\Member\\\\MemberRequest\\:\\:rules\\(\\) return type has no value type specified in iterable type array\\.$#" message: "#^Method App\\\\Member\\\\MemberRequest\\:\\:rules\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1 count: 1
@ -394,16 +393,6 @@ parameters:
count: 1 count: 1
path: tests/Feature/Member/DavTest.php path: tests/Feature/Member/DavTest.php
-
message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$email\\.$#"
count: 2
path: app/Maildispatcher/Actions/ResyncAction.php
-
message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$email_parents\\.$#"
count: 2
path: app/Maildispatcher/Actions/ResyncAction.php
- -
message: "#^Unable to resolve the template type TKey in call to function collect$#" message: "#^Unable to resolve the template type TKey in call to function collect$#"
count: 2 count: 2
@ -513,3 +502,8 @@ parameters:
message: "#^Call to an undefined method Phake\\\\Proxies\\\\VerifierProxy\\:\\:handle\\(\\)\\.$#" message: "#^Call to an undefined method Phake\\\\Proxies\\\\VerifierProxy\\:\\:handle\\(\\)\\.$#"
count: 2 count: 2
path: tests/Feature/Member/NamiPutMemberActionTest.php path: tests/Feature/Member/NamiPutMemberActionTest.php
-
message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\Relation\\<\\*, \\*, \\*\\>\\:\\:isTrying\\(\\)\\.$#"
count: 1
path: app/Membership/TestersBlock.php

View File

@ -1,38 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" cacheDirectory=".phpunit.cache">
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd" <testsuites>
bootstrap="vendor/autoload.php" <testsuite name="Unit">
colors="true"> <directory suffix="Test.php">./tests/Unit</directory>
<testsuites> </testsuite>
<testsuite name="Unit"> <testsuite name="Feature">
<directory suffix="Test.php">./tests/Unit</directory> <directory suffix="Test.php">./tests/Feature</directory>
</testsuite> </testsuite>
<testsuite name="Feature"> <testsuite name="Fileshare">
<directory suffix="Test.php">./tests/Feature</directory> <directory suffix="Test.php">./tests/Fileshare</directory>
</testsuite> </testsuite>
<testsuite name="Fileshare"> <testsuite name="Arch">
<directory suffix="Test.php">./tests/Fileshare</directory> <file>tests/Arch.php</file>
</testsuite> </testsuite>
<testsuite name="NamiUnit"> <testsuite name="NamiUnit">
<directory suffix="Test.php">./packages/laravel-nami/tests/Unit</directory> <directory suffix="Test.php">./packages/laravel-nami/tests/Unit</directory>
</testsuite> </testsuite>
<testsuite name="EndToEnd"> <testsuite name="EndToEnd">
<directory suffix="Test.php">./tests/EndToEnd</directory> <directory suffix="Test.php">./tests/EndToEnd</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<filter> <php>
<whitelist processUncoveredFilesFromWhitelist="true"> <server name="APP_ENV" value="testing"/>
<directory suffix=".php">./app</directory> <server name="BCRYPT_ROUNDS" value="4"/>
</whitelist> <server name="CACHE_DRIVER" value="array"/>
</filter> <server name="BROADCAST_DRIVER" value="log"/>
<php> <server name="MAIL_MAILER" value="array"/>
<server name="APP_ENV" value="testing"/> <server name="QUEUE_CONNECTION" value="sync"/>
<server name="BCRYPT_ROUNDS" value="4"/> <server name="SESSION_DRIVER" value="array"/>
<server name="CACHE_DRIVER" value="array"/> <server name="TELESCOPE_ENABLED" value="false"/>
<server name="BROADCAST_DRIVER" value="log"/> </php>
<server name="MAIL_MAILER" value="array"/> <source>
<server name="QUEUE_CONNECTION" value="sync"/> <include>
<server name="SESSION_DRIVER" value="array"/> <directory suffix=".php">./app</directory>
<server name="TELESCOPE_ENABLED" value="false"/> </include>
</php> </source>
</phpunit> </phpunit>

View File

@ -2,7 +2,7 @@
<page-layout> <page-layout>
<div class="gap-6 md:grid-cols-2 xl:grid-cols-4 grid p-6"> <div class="gap-6 md:grid-cols-2 xl:grid-cols-4 grid p-6">
<v-block v-for="(block, index) in blocks" :key="index" :title="block.title"> <v-block v-for="(block, index) in blocks" :key="index" :title="block.title">
<component :data="block.data" :is="block.component"></component> <component :is="block.component" :data="block.data"></component>
</v-block> </v-block>
</div> </div>
</page-layout> </page-layout>

View File

@ -17,7 +17,6 @@ use App\Course\Actions\CourseIndexAction;
use App\Course\Actions\CourseStoreAction; use App\Course\Actions\CourseStoreAction;
use App\Invoice\Actions\InvoiceStoreAction; use App\Invoice\Actions\InvoiceStoreAction;
use App\Course\Actions\CourseUpdateAction; use App\Course\Actions\CourseUpdateAction;
use App\Dashboard\Actions\IndexAction as DashboardIndexAction;
use App\Efz\ShowEfzDocumentAction; use App\Efz\ShowEfzDocumentAction;
use App\Fileshare\Actions\FileshareApiIndexAction; use App\Fileshare\Actions\FileshareApiIndexAction;
use App\Fileshare\Actions\FileshareStoreAction; use App\Fileshare\Actions\FileshareStoreAction;
@ -84,7 +83,6 @@ Route::group(['namespace' => 'App\\Http\\Controllers'], function (): void {
}); });
Route::group(['middleware' => 'auth:web'], function (): void { Route::group(['middleware' => 'auth:web'], function (): void {
Route::get('/', DashboardIndexAction::class)->name('home');
Route::post('/nami/login-check', NamiLoginCheckAction::class)->name('nami.login-check'); Route::post('/nami/login-check', NamiLoginCheckAction::class)->name('nami.login-check');
Route::post('/nami/get-search-layer', NamiGetSearchLayerAction::class)->name('nami.get-search-layer'); Route::post('/nami/get-search-layer', NamiGetSearchLayerAction::class)->name('nami.get-search-layer');
Route::post('/nami/search', NamiSearchAction::class)->name('nami.search'); Route::post('/nami/search', NamiSearchAction::class)->name('nami.search');

6
tests/Arch.php Normal file
View File

@ -0,0 +1,6 @@
<?php
arch()
->expect('App')
->not->toUse(['die', 'dd', 'dump'])
->not->toHaveFileSystemPermissions('0777');

View File

@ -3,134 +3,126 @@
namespace Tests\EndToEnd\Form; namespace Tests\EndToEnd\Form;
use App\Form\Models\Form; use App\Form\Models\Form;
use App\Membership\TestersBlock;
use App\Subactivity; use App\Subactivity;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Tests\Feature\Form\FormtemplateSectionRequest; use Tests\Feature\Form\FormtemplateSectionRequest;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
use Tests\TestCase;
class FormApiListActionTest extends FormTestCase uses(FormTestCase::class);
{ uses(DatabaseTransactions::class);
use DatabaseTransactions; it('testItDisplaysForms', function () {
Carbon::setTestNow(Carbon::parse('2023-03-02'));
Storage::fake('temp');
$this->loginNami()->withoutExceptionHandling();
$form = Form::factory()
->name('lala 2')
->excerpt('fff')
->withImage('headerImage', 'lala-2.jpg')
->description(EditorRequestFactory::new()->text(10, 'desc'))
->from('2023-05-05')
->to('2023-06-07')
->sections([FormtemplateSectionRequest::new()->name('sname')])
->create();
public function testItDisplaysForms(): void sleep(1);
{ $this->get('/api/form?perPage=15')
Carbon::setTestNow(Carbon::parse('2023-03-02')); ->assertOk()
Storage::fake('temp'); ->assertJsonPath('data.0.name', 'lala 2')
$this->loginNami()->withoutExceptionHandling(); ->assertJsonPath('data.0.config.sections.0.name', 'sname')
$form = Form::factory() ->assertJsonPath('data.0.id', $form->id)
->name('lala 2') ->assertJsonPath('data.0.excerpt', 'fff')
->excerpt('fff') ->assertJsonPath('data.0.description.blocks.0.data.text', 'desc')
->withImage('headerImage', 'lala-2.jpg') ->assertJsonPath('data.0.slug', 'lala-2')
->description(EditorRequestFactory::new()->text(10, 'desc')) ->assertJsonPath('data.0.image', $form->getMedia('headerImage')->first()->getFullUrl('square'))
->from('2023-05-05') ->assertJsonPath('data.0.dates', '05.05.2023 - 07.06.2023')
->to('2023-06-07') ->assertJsonPath('data.0.from_human', '05.05.2023')
->sections([FormtemplateSectionRequest::new()->name('sname')]) ->assertJsonPath('data.0.to_human', '07.06.2023')
->create(); ->assertJsonPath('meta.per_page', 15)
->assertJsonPath('meta.base_url', url(''))
->assertJsonPath('meta.total', 1);
});
sleep(1); it('testItDisplaysDefaultValueOfField', function () {
$this->get('/api/form?perPage=15') Storage::fake('temp');
->assertOk() $this->loginNami()->withoutExceptionHandling();
->assertJsonPath('data.0.name', 'lala 2') Form::factory()->withImage('headerImage', 'lala-2.jpg')
->assertJsonPath('data.0.config.sections.0.name', 'sname') ->sections([FormtemplateSectionRequest::new()->fields([$this->textField()])])
->assertJsonPath('data.0.id', $form->id) ->create();
->assertJsonPath('data.0.excerpt', 'fff')
->assertJsonPath('data.0.description.blocks.0.data.text', 'desc')
->assertJsonPath('data.0.slug', 'lala-2')
->assertJsonPath('data.0.image', $form->getMedia('headerImage')->first()->getFullUrl('square'))
->assertJsonPath('data.0.dates', '05.05.2023 - 07.06.2023')
->assertJsonPath('data.0.from_human', '05.05.2023')
->assertJsonPath('data.0.to_human', '07.06.2023')
->assertJsonPath('meta.per_page', 15)
->assertJsonPath('meta.base_url', url(''))
->assertJsonPath('meta.total', 1);
}
public function testItDisplaysDefaultValueOfField(): void sleep(1);
{ $this->get('/api/form?perPage=15')->assertJsonPath('data.0.config.sections.0.fields.0.value', null);
Storage::fake('temp'); });
$this->loginNami()->withoutExceptionHandling();
Form::factory()->withImage('headerImage', 'lala-2.jpg')
->sections([FormtemplateSectionRequest::new()->fields([$this->textField()])])
->create();
sleep(1); it('testItDisplaysRemoteGroups', function () {
$this->get('/api/form?perPage=15')->assertJsonPath('data.0.config.sections.0.fields.0.value', null); $this->loginNami()->withoutExceptionHandling();
} Subactivity::factory()->inNami(1)->name('Wölfling')->ageGroup(true)->create();
Subactivity::factory()->inNami(50)->name('Biber')->ageGroup(false)->create();
Subactivity::factory()->name('Lager')->ageGroup(true)->create();
public function testItDisplaysRemoteGroups(): void sleep(1);
{ $this->get('/api/form?perPage=15')
$this->loginNami()->withoutExceptionHandling(); ->assertJsonPath('meta.agegroups.0', ['id' => 1, 'name' => 'Wölfling'])
Subactivity::factory()->inNami(1)->name('Wölfling')->ageGroup(true)->create(); ->assertJsonCount(1, 'meta.agegroups');
Subactivity::factory()->inNami(50)->name('Biber')->ageGroup(false)->create(); });
Subactivity::factory()->name('Lager')->ageGroup(true)->create();
sleep(1); it('testItDoesntDisplayInactiveForms', function () {
$this->get('/api/form?perPage=15') $this->loginNami()->withoutExceptionHandling();
->assertJsonPath('meta.agegroups.0', ['id' => 1, 'name' => 'Wölfling'])
->assertJsonCount(1, 'meta.agegroups');
}
public function testItDoesntDisplayInactiveForms(): void Form::factory()->isActive(false)->withImage('headerImage', 'lala-2.jpg')->count(1)->create();
{ Form::factory()->isActive(true)->withImage('headerImage', 'lala-2.jpg')->count(2)->create();
$this->loginNami()->withoutExceptionHandling();
Form::factory()->isActive(false)->withImage('headerImage', 'lala-2.jpg')->count(1)->create(); sleep(1);
Form::factory()->isActive(true)->withImage('headerImage', 'lala-2.jpg')->count(2)->create(); $this->get('/api/form?perPage=15&filter=' . $this->filterString(['inactive' => true]))->assertJsonCount(3, 'data');
$this->get('/api/form?perPage=15&filter=' . $this->filterString(['inactive' => false]))->assertJsonCount(2, 'data');
$this->get('/api/form?perPage=15&filter=' . $this->filterString([]))->assertJsonCount(2, 'data')
->assertJsonPath('data.0.is_active', true)
->assertJsonPath('data.0.is_private', false);
});
sleep(1); it('testItDisplaysDailyForms', function () {
$this->get('/api/form?perPage=15&filter=' . $this->filterString(['inactive' => true]))->assertJsonCount(3, 'data'); Carbon::setTestNow(Carbon::parse('2023-03-02'));
$this->get('/api/form?perPage=15&filter=' . $this->filterString(['inactive' => false]))->assertJsonCount(2, 'data'); $this->loginNami()->withoutExceptionHandling();
$this->get('/api/form?perPage=15&filter=' . $this->filterString([]))->assertJsonCount(2, 'data') Form::factory()
->assertJsonPath('data.0.is_active', true) ->withImage('headerImage', 'lala-2.jpg')
->assertJsonPath('data.0.is_private', false); ->from('2023-05-05')
} ->to('2023-05-05')
->create();
public function testItDisplaysDailyForms(): void sleep(1);
{ $this->get('/api/form')
Carbon::setTestNow(Carbon::parse('2023-03-02')); ->assertJsonPath('data.0.dates', '05.05.2023');
$this->loginNami()->withoutExceptionHandling(); });
Form::factory()
->withImage('headerImage', 'lala-2.jpg')
->from('2023-05-05')
->to('2023-05-05')
->create();
sleep(1); it('testItDisplaysPastEvents', function () {
$this->get('/api/form') Carbon::setTestNow(Carbon::parse('2023-05-10'));
->assertJsonPath('data.0.dates', '05.05.2023'); $this->loginNami()->withoutExceptionHandling();
} Form::factory()
->withImage('headerImage', 'lala-2.jpg')
->from('2023-05-05')
->to('2023-05-05')
->create();
public function testItDisplaysPastEvents(): void sleep(1);
{ $this->get('/api/form?filter=' . $this->filterString(['past' => true]))
Carbon::setTestNow(Carbon::parse('2023-05-10')); ->assertJsonCount(1, 'data');
$this->loginNami()->withoutExceptionHandling(); });
Form::factory()
->withImage('headerImage', 'lala-2.jpg')
->from('2023-05-05')
->to('2023-05-05')
->create();
sleep(1); it('testItDisplaysAllForms', function () {
$this->get('/api/form?filter=' . $this->filterString(['past' => true])) Carbon::setTestNow(Carbon::parse('2023-03-02'));
->assertJsonCount(1, 'data'); Storage::fake('temp');
} $this->loginNami()->withoutExceptionHandling();
Form::factory()
->withImage('headerImage', 'lala-2.jpg')
->from('2023-05-05')
->to('2023-06-07')
->count(20)
->create();
public function testItDisplaysAllForms(): void sleep(1);
{ $this->get('/api/form')->assertJsonCount(20, 'data');
Carbon::setTestNow(Carbon::parse('2023-03-02')); });
Storage::fake('temp');
$this->loginNami()->withoutExceptionHandling();
Form::factory()
->withImage('headerImage', 'lala-2.jpg')
->from('2023-05-05')
->to('2023-06-07')
->count(20)
->create();
sleep(1);
$this->get('/api/form')->assertJsonCount(20, 'data');
}
}

View File

@ -13,7 +13,7 @@ abstract class EndToEndTestCase extends TestCase
{ {
use DatabaseMigrations; use DatabaseMigrations;
public function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();

View File

@ -5,43 +5,38 @@ namespace Tests\Feature\Activity;
use App\Activity; use App\Activity;
use App\Subactivity; use App\Subactivity;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
class EditTest extends TestCase uses(DatabaseTransactions::class);
{
use DatabaseTransactions;
public function testItEditsAnActivity(): void it('testItEditsAnActivity', function () {
{ $this->login()->loginNami()->withoutExceptionHandling();
$this->login()->loginNami()->withoutExceptionHandling(); $activity = Activity::factory()->name('Asas')->hasAttached(Subactivity::factory()->name('Pupu')->filterable())->create();
$activity = Activity::factory()->name('Asas')->hasAttached(Subactivity::factory()->name('Pupu')->filterable())->create();
$response = $this->get(route('activity.edit', ['activity' => $activity])); $response = $this->get(route('activity.edit', ['activity' => $activity]));
$this->assertInertiaHas([ $this->assertInertiaHas([
'name' => 'Asas', 'name' => 'Asas',
'is_filterable' => false,
'subactivities' => [$activity->subactivities->first()->id],
'subactivity_model' => [
'activities' => [$activity->id],
'is_age_group' => false,
'is_filterable' => false, 'is_filterable' => false,
'subactivities' => [$activity->subactivities->first()->id], 'name' => '',
'subactivity_model' => [ ],
'activities' => [$activity->id], ], $response, 'data');
'is_age_group' => false, $this->assertInertiaHas([
'is_filterable' => false, 'id' => $activity->subactivities->first()->id,
'name' => '', 'name' => 'Pupu',
], 'is_filterable' => true,
], $response, 'data'); ], $response, 'meta.subactivities.0');
$this->assertInertiaHas([ $this->assertInertiaHas([
'id' => $activity->subactivities->first()->id, 'id' => $activity->subactivities->first()->id,
'name' => 'Pupu', 'name' => 'Pupu',
'is_filterable' => true, 'is_filterable' => true,
], $response, 'meta.subactivities.0'); 'links' => [
$this->assertInertiaHas([ 'show' => route('api.subactivity.show', ['subactivity' => $activity->subactivities->first()->id]),
'id' => $activity->subactivities->first()->id, 'update' => route('api.subactivity.update', ['subactivity' => $activity->subactivities->first()->id]),
'name' => 'Pupu', ],
'is_filterable' => true, ], $response, 'meta.subactivities.0');
'links' => [ });
'show' => route('api.subactivity.show', ['subactivity' => $activity->subactivities->first()->id]),
'update' => route('api.subactivity.update', ['subactivity' => $activity->subactivities->first()->id]),
],
], $response, 'meta.subactivities.0');
}
}

View File

@ -3,178 +3,210 @@
namespace Tests\Feature\Activity; namespace Tests\Feature\Activity;
use App\Activity; use App\Activity;
use App\Activity\Actions\ActivityUpdateAction;
use App\Member\Member; use App\Member\Member;
use App\Member\Membership; use App\Member\Membership;
use App\Subactivity; use App\Subactivity;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
class UpdateTest extends TestCase covers(ActivityUpdateAction::class);
{
use DatabaseTransactions;
public function testItCannotUpdateAnActivityFromNami(): void uses(DatabaseTransactions::class);
{
$this->login()->loginNami();
$activity = Activity::factory()->inNami(67)->name('abc')->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [ it('testItCannotUpdateAnActivityFromNami', function () {
'name' => 'Lorem', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()->inNami(67)->name('abc')->create();
'subactivities' => [],
]);
$response->assertSessionHasErrors(['nami_id' => 'Aktivität ist in NaMi. Update des Namens nicht möglich.']); $response = $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'Lorem',
'is_filterable' => false,
'subactivities' => [],
]);
public function testItCanUpdateSubactivitiesOfNamiActivity(): void $response->assertSessionHasErrors(['nami_id' => 'Aktivität ist in NaMi. Update des Namens nicht möglich.']);
{ });
$this->login()->loginNami();
$activity = Activity::factory()->inNami(67)->name('abc')->create();
$subactivity = Subactivity::factory()->create();
$this->patch(route('activity.update', ['activity' => $activity]), [ it('testItCanUpdateSubactivitiesOfNamiActivity', function () {
'name' => 'abc', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()->inNami(67)->name('abc')->create();
'subactivities' => [$subactivity->id], $subactivity = Subactivity::factory()->create();
]);
$this->assertDatabaseHas('activity_subactivity', ['activity_id' => $activity->id, 'subactivity_id' => $subactivity->id]); $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'abc',
'is_filterable' => false,
'subactivities' => [$subactivity->id],
]);
public function testItCannotRemoveANamiSubactivityFromANamiActivity(): void $this->assertDatabaseHas('activity_subactivity', ['activity_id' => $activity->id, 'subactivity_id' => $subactivity->id]);
{ });
$this->login()->loginNami();
$activity = Activity::factory()->inNami(67)->name('abc')->has(Subactivity::factory()->inNami(69))->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [ it('testItCannotRemoveANamiSubactivityFromANamiActivity', function () {
'name' => 'abc', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()->inNami(67)->name('abc')->has(Subactivity::factory()->inNami(69))->create();
'subactivities' => [],
]);
$response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht entfernt werden.']); $response = $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'abc',
'is_filterable' => false,
'subactivities' => [],
]);
public function testItCannotAddANamiSubactivityToANamiActivity(): void $response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht entfernt werden.']);
{ });
$this->login()->loginNami();
$activity = Activity::factory()->inNami(67)->name('abc')->create();
$subactivity = Subactivity::factory()->inNami(60)->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [ it('testItCannotAddANamiSubactivityToANamiActivity', function () {
'name' => 'abc', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()->inNami(67)->name('abc')->create();
'subactivities' => [$subactivity->id], $subactivity = Subactivity::factory()->inNami(60)->create();
]);
$response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht hinzugefügt werden.']); $response = $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'abc',
'is_filterable' => false,
'subactivities' => [$subactivity->id],
]);
public function testItCannotRemoveANamiSubactivityFromANamiActivityAndSetAnother(): void $response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht hinzugefügt werden.']);
{ });
$this->login()->loginNami();
$activity = Activity::factory()->inNami(67)->name('abc')->has(Subactivity::factory()->inNami(69))->create();
$otherSubactivity = Subactivity::factory()->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [ it('test it cannot set subactivity to a string', function () {
'name' => 'abc', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()->create();
'subactivities' => [$otherSubactivity->id],
]);
$response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht entfernt werden.']); $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'abc',
'is_filterable' => false,
'subactivities' => ['AAA'],
])->assertSessionHasErrors('subactivities.0');
});
public function testNameIsRequired(): void
{
$this->login()->loginNami();
$activity = Activity::factory()->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [ it('testItCannotRemoveANamiSubactivityFromANamiActivityAndSetAnother', function () {
'name' => '', $this->login()->loginNami();
'is_filterable' => true, $activity = Activity::factory()->inNami(67)->name('abc')->has(Subactivity::factory()->inNami(69))->create();
]); $otherSubactivity = Subactivity::factory()->create();
$response->assertSessionHasErrors(['name' => 'Name ist erforderlich.']); $response = $this->patch(route('activity.update', ['activity' => $activity]), [
$response->assertSessionHasErrors(['subactivities' => 'Untergliederungen muss vorhanden sein.']); 'name' => 'abc',
} 'is_filterable' => false,
'subactivities' => [$otherSubactivity->id],
]);
public function testItUpdatesName(): void $response->assertSessionHasErrors(['nami_id' => 'Untertätigkeit kann nicht entfernt werden.']);
{ });
$this->login()->loginNami();
$activity = Activity::factory()->name('UUU')->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [ it('testNameIsRequired', function () {
'name' => 'Lorem', $this->login()->loginNami();
'is_filterable' => true, $activity = Activity::factory()->create();
'subactivities' => [],
]);
$response->assertRedirect('/activity'); $response = $this->patch(route('activity.update', ['activity' => $activity]), [
$this->assertDatabaseHas('activities', ['name' => 'Lorem', 'is_filterable' => true]); 'name' => '',
} 'is_filterable' => true,
]);
public function testItSetsSubactivities(): void $response->assertSessionHasErrors(['name' => 'Name ist erforderlich.']);
{ $response->assertSessionHasErrors(['subactivities' => 'Untergliederungen muss vorhanden sein.']);
$this->login()->loginNami(); });
$activity = Activity::factory()->create();
$subactivity = Subactivity::factory()->create();
$this->patch(route('activity.update', ['activity' => $activity]), [ it('testItUpdatesName', function () {
'name' => 'Lorem', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()->name('UUU')->create();
'subactivities' => [$subactivity->id],
]);
$this->assertDatabaseHas('activity_subactivity', ['activity_id' => $activity->id, 'subactivity_id' => $subactivity->id]); $response = $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'Lorem',
'is_filterable' => true,
'subactivities' => [],
]);
public function testItCannotSetNamiId(): void $response->assertRedirect('/activity');
{ $this->assertDatabaseHas('activities', ['name' => 'Lorem', 'is_filterable' => true]);
$this->login()->loginNami(); });
$activity = Activity::factory()->create();
$this->patch(route('activity.update', ['activity' => $activity]), [ it('testItSetsSubactivities', function () {
'name' => 'Lorem', $this->login()->loginNami();
'nami_id' => 66, $activity = Activity::factory()->create();
'is_filterable' => false, $subactivity = Subactivity::factory()->create();
'subactivities' => [],
]);
$this->assertDatabaseHas('activities', ['nami_id' => null]); $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'Lorem',
'is_filterable' => false,
'subactivities' => [$subactivity->id],
]);
public function testItUnsetsSubactivities(): void $this->assertDatabaseHas('activity_subactivity', ['activity_id' => $activity->id, 'subactivity_id' => $subactivity->id]);
{ });
$this->login()->loginNami();
$activity = Activity::factory()
->hasAttached(Subactivity::factory())
->create();
$this->patch(route('activity.update', ['activity' => $activity]), [ it('testItCannotSetNamiId', function () {
'name' => 'Lorem', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()->create();
'subactivities' => [],
]);
$this->assertDatabaseEmpty('activity_subactivity'); $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'Lorem',
'nami_id' => 66,
'is_filterable' => false,
'subactivities' => [],
]);
public function testItCannotSetSubactivityIfItStillHasMembers(): void $this->assertDatabaseHas('activities', ['nami_id' => null]);
{ });
$this->login()->loginNami();
$activity = Activity::factory()->create();
$subactivity = Subactivity::factory()->hasAttached($activity)->create();
$newSubactivity = Subactivity::factory()->create();
Member::factory()->defaults()->has(Membership::factory()->for($activity)->for($subactivity))->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [ it('testItUnsetsSubactivities', function () {
'name' => 'abc', $this->login()->loginNami();
'is_filterable' => false, $activity = Activity::factory()
'subactivities' => [$newSubactivity->id], ->hasAttached(Subactivity::factory())
]); ->create();
$response->assertSessionHasErrors(['subactivities' => 'Untergliederung hat noch Mitglieder.']); $this->patch(route('activity.update', ['activity' => $activity]), [
} 'name' => 'Lorem',
} 'is_filterable' => false,
'subactivities' => [],
]);
$this->assertDatabaseEmpty('activity_subactivity');
});
it('testItCannotSetSubactivityIfItStillHasMembers', function () {
$this->login()->loginNami();
$activity = Activity::factory()
->hasAttached(Subactivity::factory())
->create();
Member::factory()->defaults()->has(Membership::factory()->for($activity)->for($activity->subactivities->first()))->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [
'name' => 'abc',
'is_filterable' => false,
'subactivities' => [],
]);
$response->assertSessionHasErrors(['subactivities' => 'Untergliederung hat noch Mitglieder.']);
});
it('test it succeeds when membership is not of removing subactivity', function () {
$this->login()->loginNami();
$activity = Activity::factory()
->hasAttached(Subactivity::factory())
->create();
Member::factory()->defaults()->has(Membership::factory()->for($activity)->for(Subactivity::factory()))->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [
'name' => 'abc',
'is_filterable' => false,
'subactivities' => [],
]);
$response->assertSessionDoesntHaveErrors();
});
it('test it succeeds when membership is not of removing activity', function () {
$this->login()->loginNami();
$activity = Activity::factory()
->hasAttached(Subactivity::factory())
->create();
Member::factory()->defaults()->has(Membership::factory()->for(Activity::factory())->for($activity->subactivities->first()))->create();
$response = $this->patch(route('activity.update', ['activity' => $activity]), [
'name' => 'abc',
'is_filterable' => false,
'subactivities' => [],
]);
$response->assertSessionDoesntHaveErrors();
});

View File

@ -13,6 +13,7 @@ use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Laravel\Passport\Client; use Laravel\Passport\Client;
use Laravel\Passport\Passport; use Laravel\Passport\Passport;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\ContributionMemberApiRequestFactory; use Tests\RequestFactories\ContributionMemberApiRequestFactory;
use Tests\RequestFactories\ContributionRequestFactory; use Tests\RequestFactories\ContributionRequestFactory;
use Tests\TestCase; use Tests\TestCase;
@ -112,8 +113,8 @@ class StoreTest extends TestCase
/** /**
* @param array<string, string> $input * @param array<string, string> $input
* @param class-string<ContributionDocument> $documentClass * @param class-string<ContributionDocument> $documentClass
* @dataProvider validationDataProvider
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesInput(array $input, string $documentClass, string $errorField): void public function testItValidatesInput(array $input, string $documentClass, string $errorField): void
{ {
$this->login()->loginNami(); $this->login()->loginNami();
@ -127,8 +128,8 @@ class StoreTest extends TestCase
/** /**
* @param array<string, string> $input * @param array<string, string> $input
* @param class-string<ContributionDocument> $documentClass * @param class-string<ContributionDocument> $documentClass
* @dataProvider validationDataProvider
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesInputBeforeGeneration(array $input, string $documentClass, string $errorField): void public function testItValidatesInputBeforeGeneration(array $input, string $documentClass, string $errorField): void
{ {
$this->login()->loginNami(); $this->login()->loginNami();
@ -140,7 +141,7 @@ class StoreTest extends TestCase
])->assertSessionHasErrors($errorField); ])->assertSessionHasErrors($errorField);
} }
protected function validationDataProvider(): Generator public static function validationDataProvider(): Generator
{ {
yield [ yield [
['type' => 'aaa'], ['type' => 'aaa'],

View File

@ -5,6 +5,7 @@ namespace Tests\Feature\Course;
use App\Course\Models\Course; use App\Course\Models\Course;
use App\Member\Member; use App\Member\Member;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase; use Tests\TestCase;
use Zoomyboy\LaravelNami\Fakes\CourseFake; use Zoomyboy\LaravelNami\Fakes\CourseFake;
@ -15,7 +16,7 @@ class StoreTest extends TestCase
/** /**
* @return array<string, array{payload: array<string, mixed>, errors: array<string, mixed>}> * @return array<string, array{payload: array<string, mixed>, errors: array<string, mixed>}>
*/ */
public function validationDataProvider(): array public static function validationDataProvider(): array
{ {
return [ return [
'course_id_missing' => [ 'course_id_missing' => [
@ -48,8 +49,8 @@ class StoreTest extends TestCase
/** /**
* @param array<string, string> $payload * @param array<string, string> $payload
* @param array<string, string> $errors * @param array<string, string> $errors
* @dataProvider validationDataProvider
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesInput(array $payload, array $errors): void public function testItValidatesInput(array $payload, array $errors): void
{ {
$this->login()->withNamiSettings(); $this->login()->withNamiSettings();

View File

@ -6,6 +6,7 @@ use App\Course\Models\Course;
use App\Course\Models\CourseMember; use App\Course\Models\CourseMember;
use App\Member\Member; use App\Member\Member;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase; use Tests\TestCase;
use Zoomyboy\LaravelNami\Fakes\CourseFake; use Zoomyboy\LaravelNami\Fakes\CourseFake;
@ -16,7 +17,7 @@ class UpdateTest extends TestCase
/** /**
* @return array<string, array{payload: array<string, mixed>, errors: array<string, mixed>}> * @return array<string, array{payload: array<string, mixed>, errors: array<string, mixed>}>
*/ */
public function validationDataProvider(): array public static function validationDataProvider(): array
{ {
return [ return [
'course_id_missing' => [ 'course_id_missing' => [
@ -49,8 +50,8 @@ class UpdateTest extends TestCase
/** /**
* @param array<string, string> $payload * @param array<string, string> $payload
* @param array<string, string> $errors * @param array<string, string> $errors
* @dataProvider validationDataProvider
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesInput(array $payload, array $errors): void public function testItValidatesInput(array $payload, array $errors): void
{ {
$this->login()->loginNami(); $this->login()->loginNami();

View File

@ -17,6 +17,7 @@ use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use Illuminate\Testing\TestResponse; use Illuminate\Testing\TestResponse;
use PHPUnit\Framework\Attributes\DataProvider;
class FormRegisterActionTest extends FormTestCase class FormRegisterActionTest extends FormTestCase
{ {
@ -86,10 +87,10 @@ class FormRegisterActionTest extends FormTestCase
} }
/** /**
* @dataProvider validationDataProvider
* @param array<string, mixed> $payload * @param array<string, mixed> $payload
* @param ?array<string, mixed> $messages * @param ?array<string, mixed> $messages
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesInput(FormtemplateFieldRequest $fieldGenerator, array $payload, ?array $messages): void public function testItValidatesInput(FormtemplateFieldRequest $fieldGenerator, array $payload, ?array $messages): void
{ {
Carbon::setTestNow(Carbon::parse('2024-02-15 06:00:00')); Carbon::setTestNow(Carbon::parse('2024-02-15 06:00:00'));
@ -105,226 +106,226 @@ class FormRegisterActionTest extends FormTestCase
} }
} }
public function validationDataProvider(): Generator public static function validationDataProvider(): Generator
{ {
yield [ yield [
$this->dateField('birthday')->name('Geburtsdatum')->maxToday(false), static::dateField('birthday')->name('Geburtsdatum')->maxToday(false),
['birthday' => 'aa'], ['birthday' => 'aa'],
['birthday' => 'Geburtsdatum muss ein gültiges Datum sein.'] ['birthday' => 'Geburtsdatum muss ein gültiges Datum sein.']
]; ];
yield [ yield [
$this->dateField('birthday')->name('Geburtsdatum')->maxToday(false), static::dateField('birthday')->name('Geburtsdatum')->maxToday(false),
['birthday' => '2021-05-06'], ['birthday' => '2021-05-06'],
null, null,
]; ];
yield [ yield [
$this->dateField('birthday')->name('Geburtsdatum')->maxToday(true), static::dateField('birthday')->name('Geburtsdatum')->maxToday(true),
['birthday' => '2024-02-16'], ['birthday' => '2024-02-16'],
['birthday' => 'Geburtsdatum muss ein Datum vor oder gleich dem 15.02.2024 sein.'], ['birthday' => 'Geburtsdatum muss ein Datum vor oder gleich dem 15.02.2024 sein.'],
]; ];
yield [ yield [
$this->dateField('birthday')->name('Geburtsdatum')->maxToday(true), static::dateField('birthday')->name('Geburtsdatum')->maxToday(true),
['birthday' => '2024-02-15'], ['birthday' => '2024-02-15'],
null, null,
]; ];
yield [ yield [
$this->textField('vorname')->name('Vorname der Mutter')->required(true), static::textField('vorname')->name('Vorname der Mutter')->required(true),
['vorname' => ''], ['vorname' => ''],
['vorname' => 'Vorname der Mutter ist erforderlich.'] ['vorname' => 'Vorname der Mutter ist erforderlich.']
]; ];
yield [ yield [
$this->textField('vorname')->name('Vorname der Mutter')->required(true), static::textField('vorname')->name('Vorname der Mutter')->required(true),
['vorname' => 5], ['vorname' => 5],
['vorname' => 'Vorname der Mutter muss ein String sein.'] ['vorname' => 'Vorname der Mutter muss ein String sein.']
]; ];
yield [ yield [
$this->radioField('yes_or_no')->name('Ja oder Nein')->required(true), static::radioField('yes_or_no')->name('Ja oder Nein')->required(true),
['yes_or_no' => null], ['yes_or_no' => null],
['yes_or_no' => 'Ja oder Nein ist erforderlich.'] ['yes_or_no' => 'Ja oder Nein ist erforderlich.']
]; ];
yield [ yield [
$this->radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(false)->allowcustom(false), static::radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(false)->allowcustom(false),
['letter' => 'Z'], ['letter' => 'Z'],
['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.'] ['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.']
]; ];
yield [ yield [
$this->radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false), static::radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false),
['letter' => 'Z'], ['letter' => 'Z'],
['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.'] ['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.']
]; ];
yield [ yield [
$this->radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(true), static::radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(true),
['letter' => 'lalalaa'], ['letter' => 'lalalaa'],
null, null,
]; ];
yield [ yield [
$this->radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false), static::radioField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false),
['letter' => 'A'], ['letter' => 'A'],
null null
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']),
['letter' => ['Z']], ['letter' => ['Z']],
['letter.0' => 'Der gewählte Wert für Buchstabe ist ungültig.'], ['letter.0' => 'Der gewählte Wert für Buchstabe ist ungültig.'],
]; ];
yield [ yield [
$this->dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->allowcustom(true), static::dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->allowcustom(true),
['letter' => 'Z'], ['letter' => 'Z'],
null, null,
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']),
['letter' => 77], ['letter' => 77],
['letter' => 'Buchstabe muss ein Array sein.'], ['letter' => 'Buchstabe muss ein Array sein.'],
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']),
['letter' => ['A']], ['letter' => ['A']],
null, null,
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B']),
['letter' => []], ['letter' => []],
null, null,
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(0)->max(2), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(0)->max(2),
['letter' => ['A', 'B', 'C']], ['letter' => ['A', 'B', 'C']],
['letter' => 'Buchstabe darf maximal 2 Elemente haben.'], ['letter' => 'Buchstabe darf maximal 2 Elemente haben.'],
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(2)->max(0), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(2)->max(0),
['letter' => ['A']], ['letter' => ['A']],
['letter' => 'Buchstabe muss mindestens 2 Elemente haben.'], ['letter' => 'Buchstabe muss mindestens 2 Elemente haben.'],
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(1)->max(0), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(1)->max(0),
['letter' => []], ['letter' => []],
['letter' => 'Buchstabe muss mindestens 1 Elemente haben.'], ['letter' => 'Buchstabe muss mindestens 1 Elemente haben.'],
]; ];
yield [ yield [
$this->checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(0)->max(1), static::checkboxesField('letter')->name('Buchstabe')->options(['A', 'B', 'C', 'D'])->min(0)->max(1),
['letter' => ['A', 'B']], ['letter' => ['A', 'B']],
['letter' => 'Buchstabe darf maximal 1 Elemente haben.'], ['letter' => 'Buchstabe darf maximal 1 Elemente haben.'],
]; ];
yield [ yield [
$this->checkboxField('data')->name('Datenschutz')->required(false), static::checkboxField('data')->name('Datenschutz')->required(false),
['data' => 5], ['data' => 5],
['data' => 'Datenschutz muss ein Wahrheitswert sein.'], ['data' => 'Datenschutz muss ein Wahrheitswert sein.'],
]; ];
yield [ yield [
$this->checkboxField('data')->name('Datenschutz')->required(false), static::checkboxField('data')->name('Datenschutz')->required(false),
['data' => false], ['data' => false],
null null
]; ];
yield [ yield [
$this->checkboxField('data')->name('Datenschutz')->required(true), static::checkboxField('data')->name('Datenschutz')->required(true),
['data' => false], ['data' => false],
['data' => 'Datenschutz muss akzeptiert werden.'], ['data' => 'Datenschutz muss akzeptiert werden.'],
]; ];
yield [ yield [
$this->checkboxField('data')->name('Datenschutz')->required(true), static::checkboxField('data')->name('Datenschutz')->required(true),
['data' => true], ['data' => true],
null, null,
]; ];
yield [ yield [
$this->dropdownField('yes_or_no')->name('Ja oder Nein')->required(true), static::dropdownField('yes_or_no')->name('Ja oder Nein')->required(true),
['yes_or_no' => null], ['yes_or_no' => null],
['yes_or_no' => 'Ja oder Nein ist erforderlich.'] ['yes_or_no' => 'Ja oder Nein ist erforderlich.']
]; ];
yield [ yield [
$this->dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->required(false)->allowcustom(false), static::dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->required(false)->allowcustom(false),
['letter' => 'Z'], ['letter' => 'Z'],
['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.'] ['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.']
]; ];
yield [ yield [
$this->dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false), static::dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false),
['letter' => 'Z'], ['letter' => 'Z'],
['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.'] ['letter' => 'Der gewählte Wert für Buchstabe ist ungültig.']
]; ];
yield [ yield [
$this->dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false), static::dropdownField('letter')->name('Buchstabe')->options(['A', 'B'])->required(true)->allowcustom(false),
['letter' => 'A'], ['letter' => 'A'],
null null
]; ];
yield [ yield [
$this->textareaField('vorname')->name('Vorname der Mutter')->required(true), static::textareaField('vorname')->name('Vorname der Mutter')->required(true),
['vorname' => ''], ['vorname' => ''],
['vorname' => 'Vorname der Mutter ist erforderlich.'] ['vorname' => 'Vorname der Mutter ist erforderlich.']
]; ];
yield [ yield [
$this->textareaField('vorname')->name('Vorname der Mutter')->required(true), static::textareaField('vorname')->name('Vorname der Mutter')->required(true),
['vorname' => 5], ['vorname' => 5],
['vorname' => 'Vorname der Mutter muss ein String sein.'] ['vorname' => 'Vorname der Mutter muss ein String sein.']
]; ];
yield [ yield [
$this->textareaField('vorname')->name('Vorname der Mutter')->required(true), static::textareaField('vorname')->name('Vorname der Mutter')->required(true),
['vorname' => 5], ['vorname' => 5],
['vorname' => 'Vorname der Mutter muss ein String sein.'] ['vorname' => 'Vorname der Mutter muss ein String sein.']
]; ];
yield [ yield [
$this->emailField('email')->name('Mail')->required(true), static::emailField('email')->name('Mail')->required(true),
['email' => 'alaaa'], ['email' => 'alaaa'],
['email' => 'Mail muss eine gültige E-Mail-Adresse sein.'] ['email' => 'Mail muss eine gültige E-Mail-Adresse sein.']
]; ];
yield [ yield [
$this->emailField('email')->name('Mail')->required(false), static::emailField('email')->name('Mail')->required(false),
['email' => 'alaaa'], ['email' => 'alaaa'],
['email' => 'Mail muss eine gültige E-Mail-Adresse sein.'] ['email' => 'Mail muss eine gültige E-Mail-Adresse sein.']
]; ];
yield [ yield [
$this->numberField('numb')->name('Nummer')->required(false)->min(10)->max(20), static::numberField('numb')->name('Nummer')->required(false)->min(10)->max(20),
['numb' => 21], ['numb' => 21],
['numb' => 'Nummer muss kleiner oder gleich 20 sein.'] ['numb' => 'Nummer muss kleiner oder gleich 20 sein.']
]; ];
yield [ yield [
$this->numberField('numb')->name('Nummer')->required(false)->min(10)->max(20), static::numberField('numb')->name('Nummer')->required(false)->min(10)->max(20),
['numb' => 9], ['numb' => 9],
['numb' => 'Nummer muss größer oder gleich 10 sein.'] ['numb' => 'Nummer muss größer oder gleich 10 sein.']
]; ];
yield [ yield [
$this->numberField('numb')->name('Nummer')->required(false)->min(10)->max(20), static::numberField('numb')->name('Nummer')->required(false)->min(10)->max(20),
['numb' => 'asss'], ['numb' => 'asss'],
['numb' => 'Nummer muss eine ganze Zahl sein.'] ['numb' => 'Nummer muss eine ganze Zahl sein.']
]; ];
yield [ yield [
$this->numberField('numb')->name('Nummer')->required(true), static::numberField('numb')->name('Nummer')->required(true),
['numb' => ''], ['numb' => ''],
['numb' => 'Nummer ist erforderlich.'] ['numb' => 'Nummer ist erforderlich.']
]; ];
@ -456,7 +457,7 @@ class FormRegisterActionTest extends FormTestCase
$this->assertEquals($form->participants->get(0)->id, $form->participants->get(1)->parent_id); $this->assertEquals($form->participants->get(0)->id, $form->participants->get(1)->parent_id);
} }
protected function memberMatchingDataProvider(): Generator public static function memberMatchingDataProvider(): Generator
{ {
yield [ yield [
['email' => 'max@muster.de'], ['email' => 'max@muster.de'],
@ -539,10 +540,10 @@ class FormRegisterActionTest extends FormTestCase
} }
/** /**
* @dataProvider memberMatchingDataProvider
* @param array<string, string> $memberAttributes * @param array<string, string> $memberAttributes
* @param mixed $participantValue * @param mixed $participantValue
*/ */
#[DataProvider('memberMatchingDataProvider')]
public function testItSynchsMemberAttributes(array $memberAttributes, NamiType $type, mixed $participantValue, ?callable $factory = null): void public function testItSynchsMemberAttributes(array $memberAttributes, NamiType $type, mixed $participantValue, ?callable $factory = null): void
{ {
Carbon::setTestNow(Carbon::parse('2023-05-04')); Carbon::setTestNow(Carbon::parse('2023-05-04'));

View File

@ -8,6 +8,7 @@ use App\Form\Models\Form;
use App\Form\Models\Participant; use App\Form\Models\Participant;
use Generator; use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
class FormRegisterMailTest extends FormTestCase class FormRegisterMailTest extends FormTestCase
@ -77,25 +78,25 @@ class FormRegisterMailTest extends FormTestCase
$mail->assertHasAttachedData('content2', 'beispiel2.pdf', ['mime' => 'application/pdf']); $mail->assertHasAttachedData('content2', 'beispiel2.pdf', ['mime' => 'application/pdf']);
} }
public function blockDataProvider(): Generator public static function blockDataProvider(): Generator
{ {
yield [ yield [
['mode' => 'all', 'ifs' => []], ['mode' => 'all', 'ifs' => []],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
yield [ yield [
['mode' => 'any', 'ifs' => []], ['mode' => 'any', 'ifs' => []],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
yield [ yield [
['mode' => 'any', 'ifs' => []], ['mode' => 'any', 'ifs' => []],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
@ -104,7 +105,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'any', 'ifs' => [ ['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A'] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
@ -113,7 +114,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'any', 'ifs' => [ ['mode' => 'any', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B']
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
false, false,
]; ];
@ -123,7 +124,7 @@ class FormRegisterMailTest extends FormTestCase
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'], ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A'] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
@ -133,7 +134,7 @@ class FormRegisterMailTest extends FormTestCase
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'], ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A'] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'], ['fieldkey' => 'B'],
true, true,
]; ];
@ -143,7 +144,7 @@ class FormRegisterMailTest extends FormTestCase
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'], ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'],
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A'] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'A']
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'], ['fieldkey' => 'B'],
false, false,
]; ];
@ -152,7 +153,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'all', 'ifs' => [ ['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B'] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => 'B']
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'], ['fieldkey' => 'B'],
true, true,
]; ];
@ -161,7 +162,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'all', 'ifs' => [ ['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotEqual', 'value' => 'A'] ['field' => 'fieldkey', 'comparator' => 'isNotEqual', 'value' => 'A']
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'B'], ['fieldkey' => 'B'],
true, true,
]; ];
@ -170,7 +171,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'all', 'ifs' => [ ['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isIn', 'value' => ['A']] ['field' => 'fieldkey', 'comparator' => 'isIn', 'value' => ['A']]
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
@ -179,7 +180,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'all', 'ifs' => [ ['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']] ['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']]
]], ]],
$this->dropdownField('fieldkey')->options(['A', 'B']), static::dropdownField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
@ -188,7 +189,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'all', 'ifs' => [ ['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']] ['field' => 'fieldkey', 'comparator' => 'isNotIn', 'value' => ['B']]
]], ]],
$this->radioField('fieldkey')->options(['A', 'B']), static::radioField('fieldkey')->options(['A', 'B']),
['fieldkey' => 'A'], ['fieldkey' => 'A'],
true, true,
]; ];
@ -197,7 +198,7 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'all', 'ifs' => [ ['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => true] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => true]
]], ]],
$this->checkboxField('fieldkey'), static::checkboxField('fieldkey'),
['fieldkey' => true], ['fieldkey' => true],
true, true,
]; ];
@ -206,17 +207,17 @@ class FormRegisterMailTest extends FormTestCase
['mode' => 'all', 'ifs' => [ ['mode' => 'all', 'ifs' => [
['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => false] ['field' => 'fieldkey', 'comparator' => 'isEqual', 'value' => false]
]], ]],
$this->checkboxField('fieldkey'), static::checkboxField('fieldkey'),
['fieldkey' => true], ['fieldkey' => true],
false, false,
]; ];
} }
/** /**
* @dataProvider blockDataProvider
* @param array<string, mixed> $conditions * @param array<string, mixed> $conditions
* @param array<string, mixed> $participantValues * @param array<string, mixed> $participantValues
*/ */
#[DataProvider('blockDataProvider')]
public function testItFiltersForBlockConditions(array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result): void public function testItFiltersForBlockConditions(array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result): void
{ {
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();
@ -242,10 +243,10 @@ class FormRegisterMailTest extends FormTestCase
} }
/** /**
* @dataProvider blockDataProvider
* @param array<string, mixed> $conditions * @param array<string, mixed> $conditions
* @param array<string, mixed> $participantValues * @param array<string, mixed> $participantValues
*/ */
#[DataProvider('blockDataProvider')]
public function testItFiltersForAttachments(array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result): void public function testItFiltersForAttachments(array $conditions, FormtemplateFieldRequest $field, array $participantValues, bool $result): void
{ {
$this->login()->loginNami()->withoutExceptionHandling(); $this->login()->loginNami()->withoutExceptionHandling();

View File

@ -10,6 +10,7 @@ use App\Lib\Events\Succeeded;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Generator; use Generator;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
class FormStoreActionTest extends FormTestCase class FormStoreActionTest extends FormTestCase
@ -80,7 +81,7 @@ class FormStoreActionTest extends FormTestCase
$this->assertEquals(2, $form->export->root->connectionId); $this->assertEquals(2, $form->export->root->connectionId);
} }
public function validationDataProvider(): Generator public static function validationDataProvider(): Generator
{ {
yield [FormRequest::new()->name(''), ['name' => 'Name ist erforderlich.']]; yield [FormRequest::new()->name(''), ['name' => 'Name ist erforderlich.']];
yield [FormRequest::new()->excerpt(''), ['excerpt' => 'Auszug ist erforderlich.']]; yield [FormRequest::new()->excerpt(''), ['excerpt' => 'Auszug ist erforderlich.']];
@ -92,9 +93,9 @@ class FormStoreActionTest extends FormTestCase
/** /**
* @dataProvider validationDataProvider
* @param array<string, string> $messages * @param array<string, string> $messages
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesRequests(FormRequest $request, array $messages): void public function testItValidatesRequests(FormRequest $request, array $messages): void
{ {
$this->login()->loginNami(); $this->login()->loginNami();

View File

@ -14,7 +14,7 @@ class FormTestCase extends TestCase
private string $clearCacheUrl = 'http://event.com/clear-cache'; private string $clearCacheUrl = 'http://event.com/clear-cache';
public function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();

View File

@ -10,6 +10,7 @@ use App\Lib\Events\Succeeded;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Generator; use Generator;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
class FormtemplateStoreActionTest extends FormTestCase class FormtemplateStoreActionTest extends FormTestCase
@ -51,12 +52,12 @@ class FormtemplateStoreActionTest extends FormTestCase
Event::assertDispatched(Succeeded::class, fn (Succeeded $event) => $event->message === 'Vorlage gespeichert.'); Event::assertDispatched(Succeeded::class, fn (Succeeded $event) => $event->message === 'Vorlage gespeichert.');
} }
public function validationDataProvider(): Generator public static function validationDataProvider(): Generator
{ {
yield [FormtemplateRequest::new()->name(''), ['name' => 'Name ist erforderlich.']]; yield [FormtemplateRequest::new()->name(''), ['name' => 'Name ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->name('')]), ['config.sections.0.name' => 'Sektionsname ist erforderlich.']]; yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->name('')]), ['config.sections.0.name' => 'Sektionsname ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([ yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
$this->textField()->name(''), static::textField()->name(''),
])]), ['config.sections.0.fields.0.name' => 'Feldname ist erforderlich.']]; ])]), ['config.sections.0.fields.0.name' => 'Feldname ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([ yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
FormtemplateFieldRequest::type('') FormtemplateFieldRequest::type('')
@ -65,20 +66,20 @@ class FormtemplateStoreActionTest extends FormTestCase
FormtemplateFieldRequest::type('aaaaa'), FormtemplateFieldRequest::type('aaaaa'),
])]), ['config.sections.0.fields.0.type' => 'Feldtyp ist ungültig.']]; ])]), ['config.sections.0.fields.0.type' => 'Feldtyp ist ungültig.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([ yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
$this->textField(''), static::textField(''),
])]), ['config.sections.0.fields.0.key' => 'Feldkey ist erforderlich.']]; ])]), ['config.sections.0.fields.0.key' => 'Feldkey ist erforderlich.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([ yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
$this->textField('a b'), static::textField('a b'),
])]), ['config.sections.0.fields.0.key' => 'Feldkey Format ist ungültig.']]; ])]), ['config.sections.0.fields.0.key' => 'Feldkey Format ist ungültig.']];
yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([ yield [FormtemplateRequest::new()->sections([FormtemplateSectionRequest::new()->fields([
$this->textField()->required('la') static::textField()->required('la')
])]), ['config.sections.0.fields.0.required' => 'Erforderlich muss ein Wahrheitswert sein.']]; ])]), ['config.sections.0.fields.0.required' => 'Erforderlich muss ein Wahrheitswert sein.']];
} }
/** /**
* @dataProvider validationDataProvider
* @param array<string, string> $messages * @param array<string, string> $messages
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesRequests(FormtemplateRequest $request, array $messages): void public function testItValidatesRequests(FormtemplateRequest $request, array $messages): void
{ {
$this->login()->loginNami(); $this->login()->loginNami();

View File

@ -8,6 +8,7 @@ use App\Setting\NamiSettings;
use App\Subactivity; use App\Subactivity;
use Generator; use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase; use Tests\TestCase;
use Zoomyboy\LaravelNami\Fakes\ActivityFake; use Zoomyboy\LaravelNami\Fakes\ActivityFake;
use Zoomyboy\LaravelNami\Fakes\GroupFake; use Zoomyboy\LaravelNami\Fakes\GroupFake;
@ -54,7 +55,7 @@ class InitializeActivitiesTest extends TestCase
]); ]);
} }
public function activityDataProvider(): Generator public static function activityDataProvider(): Generator
{ {
yield [ yield [
fn (ActivityFake $fake) => $fake->fetches(1000, [ fn (ActivityFake $fake) => $fake->fetches(1000, [
@ -82,11 +83,10 @@ class InitializeActivitiesTest extends TestCase
} }
/** /**
* @dataProvider activityDataProvider
*
* @param array<string, string|null> $activityCheck * @param array<string, string|null> $activityCheck
* @param array<string, string|null> $subactivityCheck * @param array<string, string|null> $subactivityCheck
*/ */
#[DataProvider('activityDataProvider')]
public function testItInitsOtherFields(callable $activityFake, array $activityCheck, ?array $subactivityCheck = null): void public function testItInitsOtherFields(callable $activityFake, array $activityCheck, ?array $subactivityCheck = null): void
{ {
app(GroupFake::class) app(GroupFake::class)

View File

@ -20,7 +20,7 @@ class InitializeMembersTest extends TestCase
$this->loginNami(); $this->loginNami();
$api = app(NamiSettings::class)->login(); $api = app(NamiSettings::class)->login();
app(SearchFake::class)->fetches(1, 0, 100, [ app(SearchFake::class)->fetches(1, 0, 100, [
MemberEntry::factory()->toMember(['groupId' => 100, 'id' => 20]), MemberEntry::toFactory()->toMember(['groupId' => 100, 'id' => 20]),
]); ]);
FullMemberAction::partialMock()->shouldReceive('configureJob')->once(); FullMemberAction::partialMock()->shouldReceive('configureJob')->once();
FullMemberAction::partialMock()->shouldReceive('handle')->once(); FullMemberAction::partialMock()->shouldReceive('handle')->once();
@ -32,7 +32,7 @@ class InitializeMembersTest extends TestCase
{ {
$this->loginNami(); $this->loginNami();
app(SearchFake::class)->fetches(1, 0, 100, [ app(SearchFake::class)->fetches(1, 0, 100, [
MemberEntry::factory()->toMember(['groupId' => 100, 'id' => 20]), MemberEntry::toFactory()->toMember(['groupId' => 100, 'id' => 20]),
]); ]);
FullMemberAction::partialMock()->shouldReceive('configureJob')->once(); FullMemberAction::partialMock()->shouldReceive('configureJob')->once();
FullMemberAction::partialMock()->shouldReceive('handle')->once(); FullMemberAction::partialMock()->shouldReceive('handle')->once();

View File

@ -23,8 +23,8 @@ class SearchTest extends TestCase
{ {
$this->withoutExceptionHandling(); $this->withoutExceptionHandling();
app(SearchFake::class)->fetches(1, 0, 10, [ app(SearchFake::class)->fetches(1, 0, 10, [
MemberEntry::factory()->state(['id' => 2, 'groupId' => 100, 'firstname' => 'Max', 'lastname' => 'Muster', 'birthday' => '2013-07-04 00:00:00'])->toMember(), MemberEntry::toFactory()->state(['id' => 2, 'groupId' => 100, 'firstname' => 'Max', 'lastname' => 'Muster', 'birthday' => '2013-07-04 00:00:00'])->toMember(),
MemberEntry::factory()->state(['id' => 2, 'groupId' => 150, 'firstname' => 'Jane', 'lastname' => 'Muster', 'birthday' => '2013-07-04 00:00:00'])->toMember(), MemberEntry::toFactory()->state(['id' => 2, 'groupId' => 150, 'firstname' => 'Jane', 'lastname' => 'Muster', 'birthday' => '2013-07-04 00:00:00'])->toMember(),
]); ]);
Auth::success(333, 'secret'); Auth::success(333, 'secret');
@ -53,7 +53,7 @@ class SearchTest extends TestCase
{ {
$this->withoutExceptionHandling(); $this->withoutExceptionHandling();
app(SearchFake::class)->fetches(1, 0, 10, [ app(SearchFake::class)->fetches(1, 0, 10, [
MemberEntry::factory()->noFirstname()->toMember(), MemberEntry::toFactory()->noFirstname()->toMember(),
]); ]);
Auth::success(333, 'secret'); Auth::success(333, 'secret');
@ -70,8 +70,8 @@ class SearchTest extends TestCase
{ {
$this->withoutExceptionHandling(); $this->withoutExceptionHandling();
app(SearchFake::class)->fetches(2, 10, 10, [ app(SearchFake::class)->fetches(2, 10, 10, [
MemberEntry::factory()->toMember(), MemberEntry::toFactory()->toMember(),
MemberEntry::factory()->toMember(), MemberEntry::toFactory()->toMember(),
]); ]);
Auth::success(333, 'secret'); Auth::success(333, 'secret');

View File

@ -5,20 +5,14 @@ namespace Tests\Feature\Invoice;
use App\Invoice\Models\Invoice; use App\Invoice\Models\Invoice;
use App\Invoice\Models\InvoicePosition; use App\Invoice\Models\InvoicePosition;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
class InvoiceDestroyActionTest extends TestCase uses(DatabaseTransactions::class);
{
use DatabaseTransactions; it('testItDestroysInvoice', function () {
$this->login()->loginNami()->withoutExceptionHandling();
$invoice = Invoice::factory()->has(InvoicePosition::factory()->withMember(), 'positions')->create();
public function testItDestroysInvoice(): void $this->delete(route('invoice.destroy', ['invoice' => $invoice]))->assertOk();
{ $this->assertDatabaseCount('invoices', 0);
$this->login()->loginNami()->withoutExceptionHandling(); $this->assertDatabaseCount('invoice_positions', 0);
$invoice = Invoice::factory()->has(InvoicePosition::factory()->withMember(), 'positions')->create(); });
$this->delete(route('invoice.destroy', ['invoice' => $invoice]))->assertOk();
$this->assertDatabaseCount('invoices', 0);
$this->assertDatabaseCount('invoice_positions', 0);
}
}

View File

@ -9,96 +9,88 @@ use App\Invoice\Models\InvoicePosition;
use App\Member\Member; use App\Member\Member;
use App\Payment\Subscription; use App\Payment\Subscription;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
class InvoiceIndexActionTest extends TestCase uses(DatabaseTransactions::class);
{
use DatabaseTransactions; it('testItDisplaysInvoices', function () {
$this->login()->loginNami()->withoutExceptionHandling();
$subscription = Subscription::factory()->forFee()->name('Beitrag')->create();
$member = Member::factory()->defaults()->create(['firstname' => 'Aaaa', 'lastname' => 'Aaab']);
$invoice = Invoice::factory()
->has(InvoicePosition::factory()->price(1100)->for($member)->state(['description' => 'lala']), 'positions')
->has(InvoicePosition::factory()->price(2200)->withMember(), 'positions')
->to(ReceiverRequestFactory::new()->name('Familie Blabla'))
->sentAt(now()->subDay())
->via(BillKind::POST)
->status(InvoiceStatus::SENT)
->create(['usage' => 'Usa', 'mail_email' => 'a@b.de']);
public function testItDisplaysInvoices(): void test()->get(route('invoice.index'))
{ ->assertInertiaPath('data.data.0.to.name', 'Familie Blabla')
$this->login()->loginNami()->withoutExceptionHandling(); ->assertInertiaPath('data.data.0.id', $invoice->id)
$subscription = Subscription::factory()->forFee()->name('Beitrag')->create(); ->assertInertiaPath('data.data.0.sum_human', '33,00 €')
$member = Member::factory()->defaults()->create(['firstname' => 'Aaaa', 'lastname' => 'Aaab']); ->assertInertiaPath('data.data.0.sent_at_human', now()->subDay()->format('d.m.Y'))
$invoice = Invoice::factory() ->assertInertiaPath('data.data.0.status', 'Rechnung gestellt')
->has(InvoicePosition::factory()->price(1100)->for($member)->state(['description' => 'lala']), 'positions') ->assertInertiaPath('data.data.0.via', 'Post')
->has(InvoicePosition::factory()->price(2200)->withMember(), 'positions') ->assertInertiaPath('data.data.0.mail_email', 'a@b.de')
->to(ReceiverRequestFactory::new()->name('Familie Blabla')) ->assertInertiaPath('data.data.0.usage', 'Usa')
->sentAt(now()->subDay()) ->assertInertiaPath('data.data.0.greeting', $invoice->greeting)
->via(BillKind::POST) ->assertInertiaPath('data.data.0.positions.0.price', 1100)
->status(InvoiceStatus::SENT) ->assertInertiaPath('data.data.0.positions.0.member_id', $member->id)
->create(['usage' => 'Usa', 'mail_email' => 'a@b.de']); ->assertInertiaPath('data.data.0.positions.0.description', 'lala')
->assertInertiaPath('data.data.0.positions.0.id', $invoice->positions->first()->id)
->assertInertiaPath('data.data.0.links.pdf', route('invoice.pdf', ['invoice' => $invoice]))
->assertInertiaPath('data.data.0.links.rememberpdf', route('invoice.rememberpdf', ['invoice' => $invoice]))
->assertInertiaPath('data.data.0.links.update', route('invoice.update', ['invoice' => $invoice]))
->assertInertiaPath('data.data.0.links.destroy', route('invoice.destroy', ['invoice' => $invoice]))
->assertInertiaPath('data.meta.links.mass-store', route('invoice.mass-store'))
->assertInertiaPath('data.meta.links.newInvoiceAttributes', route('invoice.new-invoice-attributes'))
->assertInertiaPath('data.meta.links.store', route('invoice.store'))
->assertInertiaPath('data.meta.links.masspdf', route('invoice.masspdf'))
->assertInertiaPath('data.meta.vias.0', ['id' => 'E-Mail', 'name' => 'E-Mail'])
->assertInertiaPath('data.meta.statuses.0', ['id' => 'Neu', 'name' => 'Neu'])
->assertInertiaPath('data.meta.members.0', ['id' => $member->id, 'name' => 'Aaaa Aaab'])
->assertInertiaPath('data.meta.subscriptions.0', ['name' => 'Beitrag', 'id' => $subscription->id])
->assertInertiaPath('data.meta.filter.statuses', ['Neu', 'Rechnung gestellt'])
->assertInertiaPath('data.meta.default', [
'to' => [
'name' => '',
'address' => '',
'zip' => '',
'location' => '',
],
'positions' => [],
'greeting' => '',
'status' => InvoiceStatus::NEW->value,
'via' => null,
'usage' => '',
'mail_email' => '',
])
->assertInertiaPath('data.meta.default_position', [
'id' => null,
'price' => 0,
'description' => '',
'member_id' => null,
]);
});
$this->get(route('invoice.index')) it('testValuesCanBeNull', function () {
->assertInertiaPath('data.data.0.to.name', 'Familie Blabla') test()->login()->loginNami()->withoutExceptionHandling();
->assertInertiaPath('data.data.0.id', $invoice->id) Invoice::factory()->create();
->assertInertiaPath('data.data.0.sum_human', '33,00 €')
->assertInertiaPath('data.data.0.sent_at_human', now()->subDay()->format('d.m.Y'))
->assertInertiaPath('data.data.0.status', 'Rechnung gestellt')
->assertInertiaPath('data.data.0.via', 'Post')
->assertInertiaPath('data.data.0.mail_email', 'a@b.de')
->assertInertiaPath('data.data.0.usage', 'Usa')
->assertInertiaPath('data.data.0.greeting', $invoice->greeting)
->assertInertiaPath('data.data.0.positions.0.price', 1100)
->assertInertiaPath('data.data.0.positions.0.member_id', $member->id)
->assertInertiaPath('data.data.0.positions.0.description', 'lala')
->assertInertiaPath('data.data.0.positions.0.id', $invoice->positions->first()->id)
->assertInertiaPath('data.data.0.links.pdf', route('invoice.pdf', ['invoice' => $invoice]))
->assertInertiaPath('data.data.0.links.rememberpdf', route('invoice.rememberpdf', ['invoice' => $invoice]))
->assertInertiaPath('data.data.0.links.update', route('invoice.update', ['invoice' => $invoice]))
->assertInertiaPath('data.data.0.links.destroy', route('invoice.destroy', ['invoice' => $invoice]))
->assertInertiaPath('data.meta.links.mass-store', route('invoice.mass-store'))
->assertInertiaPath('data.meta.links.newInvoiceAttributes', route('invoice.new-invoice-attributes'))
->assertInertiaPath('data.meta.links.store', route('invoice.store'))
->assertInertiaPath('data.meta.links.masspdf', route('invoice.masspdf'))
->assertInertiaPath('data.meta.vias.0', ['id' => 'E-Mail', 'name' => 'E-Mail'])
->assertInertiaPath('data.meta.statuses.0', ['id' => 'Neu', 'name' => 'Neu'])
->assertInertiaPath('data.meta.members.0', ['id' => $member->id, 'name' => 'Aaaa Aaab'])
->assertInertiaPath('data.meta.subscriptions.0', ['name' => 'Beitrag', 'id' => $subscription->id])
->assertInertiaPath('data.meta.filter.statuses', ['Neu', 'Rechnung gestellt'])
->assertInertiaPath('data.meta.default', [
'to' => [
'name' => '',
'address' => '',
'zip' => '',
'location' => '',
],
'positions' => [],
'greeting' => '',
'status' => InvoiceStatus::NEW->value,
'via' => null,
'usage' => '',
'mail_email' => '',
])
->assertInertiaPath('data.meta.default_position', [
'id' => null,
'price' => 0,
'description' => '',
'member_id' => null,
]);
}
public function testValuesCanBeNull(): void test()->get(route('invoice.index'))
{ ->assertInertiaPath('data.data.0.sent_at_human', '');
$this->login()->loginNami()->withoutExceptionHandling(); });
Invoice::factory()->create();
$this->get(route('invoice.index')) it('testItFiltersForInvoiceStatus', function () {
->assertInertiaPath('data.data.0.sent_at_human', ''); test()->login()->loginNami()->withoutExceptionHandling();
} Invoice::factory()->status(InvoiceStatus::NEW)->create();
Invoice::factory()->status(InvoiceStatus::SENT)->count(2)->create();
Invoice::factory()->status(InvoiceStatus::PAID)->count(3)->create();
public function testItFiltersForInvoiceStatus(): void test()->callFilter('invoice.index', [])->assertInertiaCount('data.data', 3);
{ test()->callFilter('invoice.index', ['statuses' => []])->assertInertiaCount('data.data', 0);
$this->login()->loginNami()->withoutExceptionHandling(); test()->callFilter('invoice.index', ['statuses' => ['Neu']])->assertInertiaCount('data.data', 1);
Invoice::factory()->status(InvoiceStatus::NEW)->create(); test()->callFilter('invoice.index', ['statuses' => ['Neu', 'Rechnung beglichen']])->assertInertiaCount('data.data', 4);
Invoice::factory()->status(InvoiceStatus::SENT)->count(2)->create(); test()->callFilter('invoice.index', ['statuses' => ['Neu', 'Rechnung beglichen', 'Rechnung gestellt']])->assertInertiaCount('data.data', 6);
Invoice::factory()->status(InvoiceStatus::PAID)->count(3)->create(); });
$this->callFilter('invoice.index', [])->assertInertiaCount('data.data', 3);
$this->callFilter('invoice.index', ['statuses' => []])->assertInertiaCount('data.data', 0);
$this->callFilter('invoice.index', ['statuses' => ['Neu']])->assertInertiaCount('data.data', 1);
$this->callFilter('invoice.index', ['statuses' => ['Neu', 'Rechnung beglichen']])->assertInertiaCount('data.data', 4);
$this->callFilter('invoice.index', ['statuses' => ['Neu', 'Rechnung beglichen', 'Rechnung gestellt']])->assertInertiaCount('data.data', 6);
}
}

View File

@ -8,6 +8,7 @@ use App\Invoice\Models\Invoice;
use App\Member\Member; use App\Member\Member;
use Generator; use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase; use Tests\TestCase;
class InvoiceStoreActionTest extends TestCase class InvoiceStoreActionTest extends TestCase
@ -55,7 +56,7 @@ class InvoiceStoreActionTest extends TestCase
], $invoice->to); ], $invoice->to);
} }
public function validationDataProvider(): Generator public static function validationDataProvider(): Generator
{ {
yield [ yield [
['to.address' => ''], ['to.address' => ''],
@ -106,8 +107,8 @@ class InvoiceStoreActionTest extends TestCase
/** /**
* @param array<string, mixed> $input * @param array<string, mixed> $input
* @param array<string, string> $errors * @param array<string, string> $errors
* @dataProvider validationDataProvider
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesInput(array $input, array $errors): void public function testItValidatesInput(array $input, array $errors): void
{ {
$this->login()->loginNami(); $this->login()->loginNami();

View File

@ -9,6 +9,7 @@ use App\Invoice\Models\InvoicePosition;
use App\Member\Member; use App\Member\Member;
use Generator; use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase; use Tests\TestCase;
class InvoiceUpdateActionTest extends TestCase class InvoiceUpdateActionTest extends TestCase
@ -98,7 +99,7 @@ class InvoiceUpdateActionTest extends TestCase
$this->assertDatabaseCount('invoice_positions', 0); $this->assertDatabaseCount('invoice_positions', 0);
} }
public function validationDataProvider(): Generator public static function validationDataProvider(): Generator
{ {
yield [ yield [
['to.address' => ''], ['to.address' => ''],
@ -144,8 +145,8 @@ class InvoiceUpdateActionTest extends TestCase
/** /**
* @param array<string, mixed> $input * @param array<string, mixed> $input
* @param array<string, string> $errors * @param array<string, string> $errors
* @dataProvider validationDataProvider
*/ */
#[DataProvider('validationDataProvider')]
public function testItValidatesInput(array $input, array $errors): void public function testItValidatesInput(array $input, array $errors): void
{ {
$this->login()->loginNami(); $this->login()->loginNami();

View File

@ -17,6 +17,7 @@ use App\Prevention\PreventionSettings;
use Generator; use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\Lib\CreatesFormFields; use Tests\Lib\CreatesFormFields;
use Tests\RequestFactories\EditorRequestFactory; use Tests\RequestFactories\EditorRequestFactory;
use Tests\TestCase; use Tests\TestCase;
@ -108,7 +109,7 @@ class PreventionTest extends TestCase
$this->assertNotNull($participant->fresh()->last_remembered_at); $this->assertNotNull($participant->fresh()->last_remembered_at);
} }
protected function attributes(): Generator public static function attributes(): Generator
{ {
yield [ yield [
'attrs' => ['has_vk' => true, 'efz' => null, 'ps_at' => now()], 'attrs' => ['has_vk' => true, 'efz' => null, 'ps_at' => now()],
@ -169,14 +170,14 @@ class PreventionTest extends TestCase
/** /**
* @param array<int, Prevention> $preventions * @param array<int, Prevention> $preventions
* @param array<string, mixed> $memberAttributes * @param array<string, mixed> $memberAttributes
* @dataProvider attributes
*/ */
public function testItRemembersMember(array $memberAttributes, array $preventions): void #[DataProvider('attributes')]
public function testItRemembersMember(array $attrs, array $preventions): void
{ {
Mail::fake(); Mail::fake();
$form = $this->createForm(); $form = $this->createForm();
$participant = $this->createParticipant($form); $participant = $this->createParticipant($form);
$participant->member->update($memberAttributes); $participant->member->update($attrs);
PreventionRememberAction::run(); PreventionRememberAction::run();

View File

@ -7,7 +7,6 @@ use App\Activity;
use App\Country; use App\Country;
use App\Course\Models\Course; use App\Course\Models\Course;
use App\Course\Models\CourseMember; use App\Course\Models\CourseMember;
use App\Fee;
use App\Gender; use App\Gender;
use App\Group; use App\Group;
use App\Member\Member; use App\Member\Member;
@ -48,7 +47,7 @@ class PullCoursesActionTest extends TestCase
$activity = Activity::factory()->inNami(1003)->name('Tätigkeit')->create(); $activity = Activity::factory()->inNami(1003)->name('Tätigkeit')->create();
$member = Member::factory()->defaults()->for(Group::factory()->inNami(1000)->name('SG Wald'))->inNami(1001)->create(); $member = Member::factory()->defaults()->for(Group::factory()->inNami(1000)->name('SG Wald'))->inNami(1001)->create();
$course = Course::factory()->name('BS')->inNami(11)->create(); $course = Course::factory()->name('BS')->inNami(11)->create();
app(CourseFake::class)->fetches(1001, [50])->shows(1001, NamiCourse::factory()->toCourse([ app(CourseFake::class)->fetches(1001, [50])->shows(1001, NamiCourse::toFactory()->toCourse([
'courseId' => 11, 'courseId' => 11,
'organizer' => 'TTT', 'organizer' => 'TTT',
'eventName' => 'Schulung', 'eventName' => 'Schulung',
@ -93,7 +92,7 @@ class PullCoursesActionTest extends TestCase
->has(CourseMember::factory()->for(Course::factory()->inNami(50))->inNami(55), 'courses') ->has(CourseMember::factory()->for(Course::factory()->inNami(50))->inNami(55), 'courses')
->inNami(1001) ->inNami(1001)
->create(); ->create();
app(CourseFake::class)->fetches(1001, [55])->shows(1001, NamiCourse::factory()->toCourse(['id' => 55, 'courseId' => 50, 'organizer' => 'ZZU'])); app(CourseFake::class)->fetches(1001, [55])->shows(1001, NamiCourse::toFactory()->toCourse(['id' => 55, 'courseId' => 50, 'organizer' => 'ZZU']));
app(PullCoursesAction::class)->handle($member); app(PullCoursesAction::class)->handle($member);

View File

@ -17,6 +17,7 @@ use App\Region;
use Carbon\Carbon; use Carbon\Carbon;
use Generator; use Generator;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase; use Tests\TestCase;
class ShowTest extends TestCase class ShowTest extends TestCase
@ -170,16 +171,14 @@ class ShowTest extends TestCase
], $response, 'data'); ], $response, 'data');
} }
public function membershipDataProvider(): Generator public static function membershipDataProvider(): Generator
{ {
yield [now()->subMonths(2), null, true]; yield [now()->subMonths(2), null, true];
yield [now()->subMonths(2), now()->subDay(), false]; yield [now()->subMonths(2), now()->subDay(), false];
yield [now()->addDays(2), null, false]; yield [now()->addDays(2), null, false];
} }
/** #[DataProvider('membershipDataProvider')]
* @dataProvider membershipDataProvider
*/
public function testItShowsIfMembershipIsActive(Carbon $from, ?Carbon $to, bool $isActive): void public function testItShowsIfMembershipIsActive(Carbon $from, ?Carbon $to, bool $isActive): void
{ {
$this->withoutExceptionHandling()->login()->loginNami(); $this->withoutExceptionHandling()->login()->loginNami();

View File

@ -62,7 +62,7 @@ class StoreTest extends TestCase
'address' => 'Bavert 50', 'address' => 'Bavert 50',
'bill_kind' => 'Post', 'bill_kind' => 'Post',
'birthday' => '2013-02-19', 'birthday' => '2013-02-19',
'children_phone' => '+49 176 8574112', 'children_phone' => '+49 176 70512778',
'country_id' => $country->id, 'country_id' => $country->id,
'email_parents' => 'osloot@aol.com', 'email_parents' => 'osloot@aol.com',
'firstname' => 'Joe', 'firstname' => 'Joe',
@ -71,8 +71,8 @@ class StoreTest extends TestCase
'lastname' => 'Muster', 'lastname' => 'Muster',
'letter_address' => null, 'letter_address' => null,
'location' => 'Solingen', 'location' => 'Solingen',
'main_phone' => '+49 212 2334322', 'main_phone' => '+49 212 337056',
'mobile_phone' => '+49 176 3033053', 'mobile_phone' => '+49 176 70512774',
'nationality_id' => $nationality->id, 'nationality_id' => $nationality->id,
'region_id' => $region->id, 'region_id' => $region->id,
'send_newspaper' => '1', 'send_newspaper' => '1',
@ -230,7 +230,7 @@ class StoreTest extends TestCase
return [ return [
'address' => 'Bavert 50', 'address' => 'Bavert 50',
'birthday' => '2013-02-19', 'birthday' => '2013-02-19',
'children_phone' => '+49 176 8574112', 'children_phone' => '+49 176 70512778',
'efz' => '', 'efz' => '',
'email' => '', 'email' => '',
'email_parents' => 'osloot@aol.com', 'email_parents' => 'osloot@aol.com',
@ -244,8 +244,8 @@ class StoreTest extends TestCase
'lastname' => 'Muster', 'lastname' => 'Muster',
'letter_address' => '', 'letter_address' => '',
'location' => 'Solingen', 'location' => 'Solingen',
'main_phone' => '+49 212 2334322', 'main_phone' => '+49 212 337056',
'mobile_phone' => '+49 176 3033053', 'mobile_phone' => '+49 176 70512774',
'more_ps_at' => '', 'more_ps_at' => '',
'multiply_more_pv' => false, 'multiply_more_pv' => false,
'multiply_pv' => false, 'multiply_pv' => false,

View File

@ -8,6 +8,7 @@ use App\Member\Membership;
use Generator; use Generator;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase; use Tests\TestCase;
class IndexTest extends TestCase class IndexTest extends TestCase
@ -45,16 +46,14 @@ class IndexTest extends TestCase
->assertJsonPath('meta.links.store', route('member.membership.store', ['member' => $member])); ->assertJsonPath('meta.links.store', route('member.membership.store', ['member' => $member]));
} }
public function membershipDataProvider(): Generator public static function membershipDataProvider(): Generator
{ {
yield [now()->subMonths(2), null, true]; yield [now()->subMonths(2), null, true];
yield [now()->subMonths(2), now()->subDay(), false]; yield [now()->subMonths(2), now()->subDay(), false];
yield [now()->addDays(2), null, false]; yield [now()->addDays(2), null, false];
} }
/** #[DataProvider('membershipDataProvider')]
* @dataProvider membershipDataProvider
*/
public function testItShowsIfMembershipIsActive(Carbon $from, ?Carbon $to, bool $isActive): void public function testItShowsIfMembershipIsActive(Carbon $from, ?Carbon $to, bool $isActive): void
{ {
$this->withoutExceptionHandling()->login()->loginNami(); $this->withoutExceptionHandling()->login()->loginNami();

View File

@ -30,7 +30,7 @@ class RemoteSearchTest extends TestCase
{ {
Auth::success(90100, 'secret'); Auth::success(90100, 'secret');
app(SearchFake::class)->fetches(1, 0, 50, [ app(SearchFake::class)->fetches(1, 0, 50, [
MemberEntry::factory()->toMember(['groupId' => 100, 'id' => 20, 'memberId' => 56, 'firstname' => 'Max', 'lastname' => 'Muster']), MemberEntry::toFactory()->toMember(['groupId' => 100, 'id' => 20, 'memberId' => 56, 'firstname' => 'Max', 'lastname' => 'Muster']),
]); ]);
$accessToken = $this->loginRemotely()->json('access_token'); $accessToken = $this->loginRemotely()->json('access_token');

View File

@ -18,62 +18,62 @@ use Tests\Feature\Form\FormtemplateFieldRequest;
trait CreatesFormFields trait CreatesFormFields
{ {
protected function namiField(?string $key = null): FormtemplateFieldRequest protected static function namiField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(NamiField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(NamiField::class)->key($key ?? static::randomKey());
} }
protected function textField(?string $key = null): FormtemplateFieldRequest protected static function textField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(TextField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(TextField::class)->key($key ?? static::randomKey());
} }
protected function numberField(?string $key = null): FormtemplateFieldRequest protected static function numberField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(NumberField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(NumberField::class)->key($key ?? static::randomKey());
} }
protected function emailField(?string $key = null): FormtemplateFieldRequest protected static function emailField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(EmailField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(EmailField::class)->key($key ?? static::randomKey());
} }
protected function checkboxesField(?string $key = null): FormtemplateFieldRequest protected static function checkboxesField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(CheckboxesField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(CheckboxesField::class)->key($key ?? static::randomKey());
} }
protected function textareaField(?string $key = null): FormtemplateFieldRequest protected static function textareaField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(TextareaField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(TextareaField::class)->key($key ?? static::randomKey());
} }
protected function dropdownField(?string $key = null): FormtemplateFieldRequest protected static function dropdownField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(DropdownField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(DropdownField::class)->key($key ?? static::randomKey());
} }
protected function dateField(?string $key = null): FormtemplateFieldRequest protected static function dateField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(DateField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(DateField::class)->key($key ?? static::randomKey());
} }
protected function radioField(?string $key = null): FormtemplateFieldRequest protected static function radioField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(RadioField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(RadioField::class)->key($key ?? static::randomKey());
} }
protected function checkboxField(?string $key = null): FormtemplateFieldRequest protected static function checkboxField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(CheckboxField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(CheckboxField::class)->key($key ?? static::randomKey());
} }
protected function groupField(?string $key = null): FormtemplateFieldRequest protected static function groupField(?string $key = null): FormtemplateFieldRequest
{ {
return FormtemplateFieldRequest::type(GroupField::class)->key($key ?? $this->randomKey()); return FormtemplateFieldRequest::type(GroupField::class)->key($key ?? static::randomKey());
} }
protected function randomKey(): string protected static function randomKey(): string
{ {
return preg_replace('/[\-0-9]/', '', str()->uuid() . str()->uuid()); return preg_replace('/[\-0-9]/', '', str()->uuid() . str()->uuid());
} }

54
tests/Pest.php Normal file
View File

@ -0,0 +1,54 @@
<?php
/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "uses()" function to bind a different classes or traits.
|
*/
use Symfony\Component\Finder\Finder;
uses(
Tests\TestCase::class,
// Illuminate\Foundation\Testing\RefreshDatabase::class,
)->in('Feature');
/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| When you're writing tests, you often need to check that values meet certain conditions. The
| "expect()" function gives you access to a set of "expectations" methods that you can use
| to assert different things. Of course, you may extend the Expectation API at any time.
|
*/
// expect()->extend('toBeOne', function () {
// return $this->toBe(1);
// });
/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/
function globArch(string $pattern)
{
$files = iterator_to_array(Finder::create()->files()->in(str($pattern)->replaceStart('App', './app')->replace('\\', '/'))->name('*.php'));
return collect($files)->map(
fn ($file) => str($file->getPathname())->replaceStart('./app', 'App')->replace('/', '\\')->replaceEnd('.php', '')->toString()
)->values()->toArray();
}

View File

@ -19,7 +19,7 @@ use Tests\Lib\TestsInertia;
use Zoomyboy\LaravelNami\Authentication\Auth; use Zoomyboy\LaravelNami\Authentication\Auth;
use Zoomyboy\TableDocument\TestsExcelDocuments; use Zoomyboy\TableDocument\TestsExcelDocuments;
abstract class TestCase extends BaseTestCase class TestCase extends BaseTestCase
{ {
use CreatesApplication; use CreatesApplication;
use TestsInertia; use TestsInertia;
@ -28,7 +28,7 @@ abstract class TestCase extends BaseTestCase
protected User $me; protected User $me;
public function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
Auth::fake(); Auth::fake();

View File

@ -7,6 +7,7 @@ use App\Mailman\Exceptions\MailmanServiceException;
use App\Mailman\Support\MailmanService; use App\Mailman\Support\MailmanService;
use Generator; use Generator;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\RequestFactories\MailmanListRequestFactory; use Tests\RequestFactories\MailmanListRequestFactory;
use Tests\TestCase; use Tests\TestCase;
@ -23,7 +24,7 @@ class ServiceTest extends TestCase
$this->assertTrue($result); $this->assertTrue($result);
Http::assertSentCount(1); Http::assertSentCount(1);
Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/system/versions' === $request->url() && $request->header('Authorization') === ['Basic '.base64_encode('user:secret')]); Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/system/versions' === $request->url() && $request->header('Authorization') === ['Basic ' . base64_encode('user:secret')]);
} }
public function testItFailsWhenChckingCredentials(): void public function testItFailsWhenChckingCredentials(): void
@ -37,7 +38,7 @@ class ServiceTest extends TestCase
$this->assertFalse($result); $this->assertFalse($result);
Http::assertSentCount(1); Http::assertSentCount(1);
Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/system/versions' === $request->url() && $request->header('Authorization') === ['Basic '.base64_encode('user:secret')]); Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/system/versions' === $request->url() && $request->header('Authorization') === ['Basic ' . base64_encode('user:secret')]);
} }
public function testItGetsMembersFromList(): void public function testItGetsMembersFromList(): void
@ -51,12 +52,12 @@ class ServiceTest extends TestCase
]), 200), ]), 200),
]); ]);
$result = app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members(MailingList::factory()->id('listid')->toData())->first(); $result = app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members(MailingList::toFactory()->id('listid')->toData())->first();
$this->assertEquals(994, $result->memberId); $this->assertEquals(994, $result->memberId);
$this->assertEquals('test@example.com', $result->email); $this->assertEquals('test@example.com', $result->email);
Http::assertSentCount(1); Http::assertSentCount(1);
Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/lists/listid/roster/member?page=1&count=10' === $request->url() && $request->header('Authorization') === ['Basic '.base64_encode('user:secret')]); Http::assertSent(fn ($request) => 'GET' === $request->method() && 'http://mailman.test/api/lists/listid/roster/member?page=1&count=10' === $request->url() && $request->header('Authorization') === ['Basic ' . base64_encode('user:secret')]);
} }
public function testItThrowsExceptionWhenLoginFailed(): void public function testItThrowsExceptionWhenLoginFailed(): void
@ -66,7 +67,7 @@ class ServiceTest extends TestCase
'http://mailman.test/api/lists/listid/roster/member?page=1&count=10' => Http::response('', 401), 'http://mailman.test/api/lists/listid/roster/member?page=1&count=10' => Http::response('', 401),
]); ]);
app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members(MailingList::factory()->id('listid')->toData())->first(); app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members(MailingList::toFactory()->id('listid')->toData())->first();
} }
public function testItCanGetLists(): void public function testItCanGetLists(): void
@ -89,33 +90,31 @@ class ServiceTest extends TestCase
$this->assertEquals('Eltern', $lists[0]->displayName); $this->assertEquals('Eltern', $lists[0]->displayName);
} }
public function listDataProvider(): Generator public static function listDataProvider(): Generator
{ {
foreach (range(3, 40) as $i) { foreach (range(3, 40) as $i) {
yield [ yield [
collect(range(1, $i)) collect(range(1, $i))
->map(fn ($num) => ['email' => 'test'.$num.'@example.com', 'self_link' => 'https://example.com/994']) ->map(fn ($num) => ['email' => 'test' . $num . '@example.com', 'self_link' => 'https://example.com/994'])
->toArray(), ->toArray(),
]; ];
} }
} }
/** #[DataProvider('listDataProvider')]
* @dataProvider listDataProvider
*/
public function testItReturnsMoreThanOneResult(array $totals): void public function testItReturnsMoreThanOneResult(array $totals): void
{ {
$totals = collect($totals); $totals = collect($totals);
foreach ($totals->chunk(10) as $n => $chunk) { foreach ($totals->chunk(10) as $n => $chunk) {
Http::fake([ Http::fake([
'http://mailman.test/api/lists/listid/roster/member?page='.($n + 1).'&count=10' => Http::response(json_encode([ 'http://mailman.test/api/lists/listid/roster/member?page=' . ($n + 1) . '&count=10' => Http::response(json_encode([
'entries' => $chunk, 'entries' => $chunk,
'total_size' => $totals->count(), 'total_size' => $totals->count(),
]), 200), ]), 200),
]); ]);
} }
$result = app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members(MailingList::factory()->id('listid')->toData()); $result = app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->members(MailingList::toFactory()->id('listid')->toData());
$this->assertCount($totals->count(), $result->toArray()); $this->assertCount($totals->count(), $result->toArray());
Http::assertSentCount($totals->chunk(10)->count()); Http::assertSentCount($totals->chunk(10)->count());