Lots of linting
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Philipp Lang 2023-02-17 18:57:11 +01:00
parent b5dfa80a1c
commit ef537b919e
38 changed files with 408 additions and 1426 deletions

View File

@ -30,6 +30,9 @@ class Activity extends Model
]; ];
} }
/**
* @return BelongsToMany<Subactivity>
*/
public function subactivities(): BelongsToMany public function subactivities(): BelongsToMany
{ {
return $this->belongsToMany(Subactivity::class); return $this->belongsToMany(Subactivity::class);

View File

@ -5,19 +5,21 @@ namespace App\Contribution\Documents;
use App\Country; use App\Country;
use App\Member\Member; use App\Member\Member;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Collection;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Zoomyboy\Tex\Engine; use Zoomyboy\Tex\Engine;
use Zoomyboy\Tex\Template; use Zoomyboy\Tex\Template;
class DvDocument extends ContributionDocument class DvDocument extends ContributionDocument
{ {
/**
* @param Collection<int, Collection<int, Member>> $members
*/
public function __construct( public function __construct(
public string $dateFrom, public string $dateFrom,
public string $dateUntil, public string $dateUntil,
public string $zipLocation, public string $zipLocation,
public ?Country $country, public ?Country $country,
/* @var Collection<int, Collection<int, Member>> */
public Collection $members, public Collection $members,
public ?string $filename = '', public ?string $filename = '',
public string $type = 'F', public string $type = 'F',
@ -38,7 +40,7 @@ class DvDocument extends ContributionDocument
dateUntil: $request->dateUntil, dateUntil: $request->dateUntil,
zipLocation: $request->zipLocation, zipLocation: $request->zipLocation,
country: Country::where('id', $request->country)->firstOrFail(), country: Country::where('id', $request->country)->firstOrFail(),
members: Member::whereIn('id', $request->members)->orderByRaw('lastname, firstname')->get()->chunk(17), members: Member::whereIn('id', $request->members)->orderByRaw('lastname, firstname')->get()->toBase()->chunk(17),
); );
} }

View File

@ -5,21 +5,23 @@ namespace App\Contribution\Documents;
use App\Country; use App\Country;
use App\Member\Member; use App\Member\Member;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Collection;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Zoomyboy\Tex\Engine; use Zoomyboy\Tex\Engine;
use Zoomyboy\Tex\Template; use Zoomyboy\Tex\Template;
class RemscheidDocument extends ContributionDocument class RemscheidDocument extends ContributionDocument
{ {
/**
* @param Collection<int, Collection<int, Member>> $leaders
* @param Collection<int, Collection<int, Member>> $children
*/
public function __construct( public function __construct(
public string $dateFrom, public string $dateFrom,
public string $dateUntil, public string $dateUntil,
public string $zipLocation, public string $zipLocation,
public ?Country $country, public ?Country $country,
/* @var Collection<int, Collection<int, Member>> */
public Collection $leaders, public Collection $leaders,
/* @var Collection<int, Collection<int, Member>> */
public Collection $children, public Collection $children,
public ?string $filename = '', public ?string $filename = '',
public string $type = 'F', public string $type = 'F',
@ -45,8 +47,8 @@ class RemscheidDocument extends ContributionDocument
dateUntil: $request->dateUntil, dateUntil: $request->dateUntil,
zipLocation: $request->zipLocation, zipLocation: $request->zipLocation,
country: Country::where('id', $request->country)->firstOrFail(), country: Country::where('id', $request->country)->firstOrFail(),
leaders: $leaders->values()->chunk(6), leaders: $leaders->values()->toBase()->chunk(6),
children: $children->values()->chunk(20), children: $children->values()->toBase()->chunk(20),
); );
} }

View File

@ -4,7 +4,7 @@ namespace App\Contribution\Documents;
use App\Member\Member; use App\Member\Member;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Collection;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Zoomyboy\Tex\Engine; use Zoomyboy\Tex\Engine;
@ -12,11 +12,13 @@ use Zoomyboy\Tex\Template;
class SolingenDocument extends ContributionDocument class SolingenDocument extends ContributionDocument
{ {
/**
* @param array<int, int> $members
*/
final private function __construct( final private function __construct(
public string $dateFrom, public string $dateFrom,
public string $dateUntil, public string $dateUntil,
public string $zipLocation, public string $zipLocation,
/** @var array<int, int> */
public array $members, public array $members,
public string $eventName, public string $eventName,
public string $type = 'F', public string $type = 'F',
@ -35,11 +37,11 @@ class SolingenDocument extends ContributionDocument
} }
/** /**
* @return Collection<Collection<Member>> * @return Collection<int, Collection<int, Member>>
*/ */
public function memberModels(): Collection public function memberModels(): Collection
{ {
return Member::whereIn('id', $this->members)->orderByRaw('lastname, firstname')->get()->chunk(14); return Member::whereIn('id', $this->members)->orderByRaw('lastname, firstname')->get()->toBase()->chunk(14);
} }
public function niceEventFrom(): string public function niceEventFrom(): string

View File

@ -10,8 +10,12 @@ class CourseMember extends Model
{ {
use HasFactory; use HasFactory;
/** @var array<int, string> */
public $guarded = []; public $guarded = [];
/**
* @return BelongsTo<Course, self>
*/
public function course(): BelongsTo public function course(): BelongsTo
{ {
return $this->belongsTo(Course::class); return $this->belongsTo(Course::class);

View File

@ -14,7 +14,7 @@ class CourseResource extends JsonResource
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* *
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable * @return array<string, mixed>
*/ */
public function toArray($request) public function toArray($request)
{ {

View File

@ -11,9 +11,15 @@ class Fee extends Model
{ {
use HasFactory; use HasFactory;
/** @var array<int, string> */
public $fillable = ['name', 'nami_id']; public $fillable = ['name', 'nami_id'];
/** @var bool */
public $timestamps = false; public $timestamps = false;
/**
* @return HasMany<Subscription>
*/
public function subscriptions(): HasMany public function subscriptions(): HasMany
{ {
return $this->hasMany(Subscription::class); return $this->hasMany(Subscription::class);

View File

@ -15,6 +15,9 @@ class Group extends Model
public $fillable = ['nami_id', 'name', 'parent_id']; public $fillable = ['nami_id', 'name', 'parent_id'];
public $timestamps = false; public $timestamps = false;
/**
* @return BelongsTo<static, self>
*/
public function parent(): BelongsTo public function parent(): BelongsTo
{ {
return $this->belongsTo(static::class, 'parent_id'); return $this->belongsTo(static::class, 'parent_id');

View File

@ -4,13 +4,12 @@ namespace App\Letter;
use App\Member\Member; use App\Member\Member;
use App\Payment\Payment; use App\Payment\Payment;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Collection as BaseCollection;
class Page class Page
{ {
/** /**
* @var Collection<Member> * @var Collection<int, Member>
*/ */
private Collection $members; private Collection $members;
public string $familyName; public string $familyName;
@ -26,7 +25,7 @@ class Page
public array $positions; public array $positions;
/** /**
* @param Collection<Member> $members * @param Collection<int, Member> $members
*/ */
public function __construct(Collection $members) public function __construct(Collection $members)
{ {
@ -63,9 +62,9 @@ class Page
} }
/** /**
* @return BaseCollection<int, Payment> * @return Collection<int, Payment>
*/ */
public function getPayments(): BaseCollection public function getPayments(): Collection
{ {
return $this->members->pluck('payments')->flatten(1); return $this->members->pluck('payments')->flatten(1);
} }

View File

@ -34,7 +34,7 @@ abstract class LetterMemberQuery
/** /**
* @param class-string<Letter> $type * @param class-string<Letter> $type
* *
* @return EloquentCollection<Member> * @return EloquentCollection<int, Member>
*/ */
private function get(string $type): EloquentCollection private function get(string $type): EloquentCollection
{ {

View File

@ -68,6 +68,9 @@ class MailmanService
return Http::withBasicAuth($this->username, $this->password)->withOptions(['base_uri' => $this->baseUrl]); return Http::withBasicAuth($this->username, $this->password)->withOptions(['base_uri' => $this->baseUrl]);
} }
/**
* @return LazyCollection<int, MailingList>
*/
public function getLists(): LazyCollection public function getLists(): LazyCollection
{ {
return app(Paginator::class)->result( return app(Paginator::class)->result(

View File

@ -5,6 +5,7 @@ namespace App\Member;
use App\Confession; use App\Confession;
use App\Country; use App\Country;
use App\Course\Models\CourseMember; use App\Course\Models\CourseMember;
use App\Gender;
use App\Group; use App\Group;
use App\Letter\BillKind; use App\Letter\BillKind;
use App\Nami\HasNamiField; use App\Nami\HasNamiField;
@ -82,13 +83,17 @@ class Member extends Model
]; ];
} }
public function scopeSearch(Builder $q, ?string $text): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeSearch(Builder $query, ?string $text): Builder
{ {
if (is_null($text)) { if (is_null($text)) {
return $q; return $query;
} }
return $q->where('firstname', 'LIKE', '%'.$text.'%') return $query->where('firstname', 'LIKE', '%'.$text.'%')
->orWhere('lastname', 'LIKE', '%'.$text.'%') ->orWhere('lastname', 'LIKE', '%'.$text.'%')
->orWhere('address', 'LIKE', '%'.$text.'%') ->orWhere('address', 'LIKE', '%'.$text.'%')
->orWhere('zip', 'LIKE', '%'.$text.'%') ->orWhere('zip', 'LIKE', '%'.$text.'%')
@ -179,16 +184,25 @@ class Member extends Model
} }
// ---------------------------------- Relations ---------------------------------- // ---------------------------------- Relations ----------------------------------
/**
* @return BelongsTo<Country, self>
*/
public function country(): BelongsTo public function country(): BelongsTo
{ {
return $this->belongsTo(Country::class); return $this->belongsTo(Country::class);
} }
/**
* @return BelongsTo<Gender, self>
*/
public function gender(): BelongsTo public function gender(): BelongsTo
{ {
return $this->belongsTo(\App\Gender::class); return $this->belongsTo(Gender::class);
} }
/**
* @return BelongsTo<Region, self>
*/
public function region(): BelongsTo public function region(): BelongsTo
{ {
return $this->belongsTo(Region::class)->withDefault([ return $this->belongsTo(Region::class)->withDefault([
@ -197,41 +211,62 @@ class Member extends Model
]); ]);
} }
/**
* @return BelongsTo<Confession, self>
*/
public function confession(): BelongsTo public function confession(): BelongsTo
{ {
return $this->belongsTo(Confession::class); return $this->belongsTo(Confession::class);
} }
public function payments(): HasMany /**
{ * @return BelongsTo<Nationality, self>
return $this->hasMany(Payment::class)->orderBy('nr'); */
}
public function nationality(): BelongsTo public function nationality(): BelongsTo
{ {
return $this->belongsTo(Nationality::class); return $this->belongsTo(Nationality::class);
} }
public function memberships(): HasMany /**
{ * @return BelongsTo<Subscription, self>
return $this->hasMany(Membership::class); */
}
public function subscription(): BelongsTo public function subscription(): BelongsTo
{ {
return $this->belongsTo(Subscription::class); return $this->belongsTo(Subscription::class);
} }
/**
* @return BelongsTo<Group, self>
*/
public function group(): BelongsTo public function group(): BelongsTo
{ {
return $this->belongsTo(Group::class); return $this->belongsTo(Group::class);
} }
/**
* @return HasMany<CourseMember>
*/
public function courses(): HasMany public function courses(): HasMany
{ {
return $this->hasMany(CourseMember::class); return $this->hasMany(CourseMember::class);
} }
/**
* @return HasMany<Membership>
*/
public function memberships(): HasMany
{
return $this->hasMany(Membership::class);
}
/**
* @return HasMany<Payment>
*/
public function payments(): HasMany
{
return $this->hasMany(Payment::class)->orderBy('nr');
}
/** /**
* @return HasMany<Membership> * @return HasMany<Membership>
*/ */
@ -257,19 +292,31 @@ class Member extends Model
} }
// ---------------------------------- Scopes ----------------------------------- // ---------------------------------- Scopes -----------------------------------
public function scopeOrdered(Builder $q): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeOrdered(Builder $query): Builder
{ {
return $q->orderByRaw('lastname, firstname'); return $query->orderByRaw('lastname, firstname');
} }
public function scopeSlangOrdered(Builder $q): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeSlangOrdered(Builder $query): Builder
{ {
return $q->orderByRaw('firstname, lastname'); return $query->orderByRaw('firstname, lastname');
} }
public function scopeWithPendingPayment(Builder $q): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeWithPendingPayment(Builder $query): Builder
{ {
return $q->addSelect([ return $query->addSelect([
'pending_payment' => Payment::selectRaw('SUM(subscription_children.amount)') 'pending_payment' => Payment::selectRaw('SUM(subscription_children.amount)')
->whereColumn('payments.member_id', 'members.id') ->whereColumn('payments.member_id', 'members.id')
->whereNeedsPayment() ->whereNeedsPayment()
@ -278,47 +325,73 @@ class Member extends Model
]); ]);
} }
public function scopeWhereHasPendingPayment(Builder $q): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeWhereHasPendingPayment(Builder $query): Builder
{ {
return $q->whereHas('payments', function (Builder $q): void { return $query->whereHas('payments', function (Builder $q): void {
$q->whereNeedsPayment(); $q->whereNeedsPayment();
}); });
} }
public function scopeWhereAusstand(Builder $q): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeWhereAusstand(Builder $query): Builder
{ {
return $q->whereHas('payments', function ($q) { return $query->whereHas('payments', function ($q) {
return $q->whereHas('status', fn ($q) => $q->where('is_remember', true)); return $q->whereHas('status', fn ($q) => $q->where('is_remember', true));
}); });
} }
public function scopePayable(Builder $q): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopePayable(Builder $query): Builder
{ {
return $q->where('bill_kind', '!=', null)->where('subscription_id', '!=', null); return $query->where('bill_kind', '!=', null)->where('subscription_id', '!=', null);
} }
public function scopeWhereNoPayment(Builder $q, int $year): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeWhereNoPayment(Builder $query, int $year): Builder
{ {
return $q->whereDoesntHave('payments', function (Builder $q) use ($year) { return $query->whereDoesntHave('payments', function (Builder $q) use ($year) {
$q->where('nr', '=', $year); $q->where('nr', '=', $year);
}); });
} }
public function scopeForDashboard(Builder $q): Builder /**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeForDashboard(Builder $query): Builder
{ {
return $q->selectRaw('SUM(id)'); return $query->selectRaw('SUM(id)');
} }
public function scopeFilter(Builder $q, array $filter): Builder /**
* @todo refactor this to an actual filter model
* @param Builder<self> $query
* @param array<string, mixed> $filter
* @return Builder<self>
*/
public function scopeFilter(Builder $query, array $filter): Builder
{ {
if (true === data_get($filter, 'ausstand', false)) { if (true === data_get($filter, 'ausstand', false)) {
$q->whereAusstand(); $query->whereAusstand();
} }
if (data_get($filter, 'bill_kind', false)) { if (data_get($filter, 'bill_kind', false)) {
$q->where('bill_kind', BillKind::fromValue($filter['bill_kind'])); $query->where('bill_kind', BillKind::fromValue($filter['bill_kind']));
} }
if (data_get($filter, 'subactivity_id', false) || data_get($filter, 'activity_id', false)) { if (data_get($filter, 'subactivity_id', false) || data_get($filter, 'activity_id', false)) {
$q->whereHas('memberships', function ($q) use ($filter) { $query->whereHas('memberships', function ($q) use ($filter) {
if (data_get($filter, 'subactivity_id', false)) { if (data_get($filter, 'subactivity_id', false)) {
$q->where('subactivity_id', $filter['subactivity_id']); $q->where('subactivity_id', $filter['subactivity_id']);
} }
@ -328,7 +401,7 @@ class Member extends Model
}); });
} }
return $q; return $query;
} }
public static function fromVcard(string $url, string $data): static public static function fromVcard(string $url, string $data): static

View File

@ -20,7 +20,7 @@ class MemberResource extends JsonResource
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* *
* @return array * @return array<string, mixed>
*/ */
public function toArray($request) public function toArray($request)
{ {

View File

@ -18,22 +18,27 @@ class Membership extends Model
use HasFactory; use HasFactory;
use HasNamiField; use HasNamiField;
/** @var array<int, string> */
public $fillable = ['subactivity_id', 'activity_id', 'group_id', 'member_id', 'nami_id', 'from', 'to', 'promised_at']; public $fillable = ['subactivity_id', 'activity_id', 'group_id', 'member_id', 'nami_id', 'from', 'to', 'promised_at'];
/** /** @var array<string, string> */
* @var array<string, string>
*/
public $casts = [ public $casts = [
'from' => 'date', 'from' => 'date',
'to' => 'date', 'to' => 'date',
'promised_at' => 'date', 'promised_at' => 'date',
]; ];
/**
* @return BelongsTo<Activity, self>
*/
public function activity(): BelongsTo public function activity(): BelongsTo
{ {
return $this->belongsTo(Activity::class); return $this->belongsTo(Activity::class);
} }
/**
* @return BelongsTo<Subactivity, self>
*/
public function subactivity(): BelongsTo public function subactivity(): BelongsTo
{ {
return $this->belongsTo(Subactivity::class); return $this->belongsTo(Subactivity::class);

View File

@ -7,6 +7,9 @@ use Illuminate\Support\Collection;
class ActionFactory class ActionFactory
{ {
/**
* @return Collection<int, array{link: array{href: string, label: mixed}, text: mixed}>
*/
public function allLinks(): Collection public function allLinks(): Collection
{ {
return app(DocumentFactory::class)->getTypes()->map(function ($repo) { return app(DocumentFactory::class)->getTypes()->map(function ($repo) {

View File

@ -67,7 +67,7 @@ class AllpaymentStoreAction
} }
/** /**
* @return Collection<Membership> * @return Collection<int, Membership>
*/ */
public function promisedMemberships(Member $member, int $year): Collection public function promisedMemberships(Member $member, int $year): Collection
{ {

View File

@ -14,38 +14,62 @@ class Payment extends Model
public $fillable = ['member_id', 'subscription_id', 'nr', 'status_id', 'last_remembered_at']; public $fillable = ['member_id', 'subscription_id', 'nr', 'status_id', 'last_remembered_at'];
/**
* @return BelongsTo<Member, self>
*/
public function member(): BelongsTo public function member(): BelongsTo
{ {
return $this->belongsTo(Member::class); return $this->belongsTo(Member::class);
} }
/**
* @return BelongsTo<Subscription, self>
*/
public function subscription(): BelongsTo public function subscription(): BelongsTo
{ {
return $this->belongsTo(Subscription::class); return $this->belongsTo(Subscription::class);
} }
/**
* @return BelongsTo<Status, self>
*/
public function status(): BelongsTo public function status(): BelongsTo
{ {
return $this->belongsTo(Status::class); return $this->belongsTo(Status::class);
} }
public function scopeWhereNeedsPayment(Builder $q): Builder /**
* @param Builder<self> $query
*
* @return Builder<self>
*/
public function scopeWhereNeedsPayment(Builder $query): Builder
{ {
return $q->whereHas('status', function ($q) { return $query->whereHas('status', function ($q) {
return $q->needsPayment(); return $q->needsPayment();
}); });
} }
public function scopeWhereNeedsBill(Builder $q): Builder /**
* @param Builder<self> $query
*
* @return Builder<self>
*/
public function scopeWhereNeedsBill(Builder $query): Builder
{ {
return $q->whereHas('status', function ($q) { return $query->whereHas('status', function ($q) {
return $q->where('is_bill', true); return $q->where('is_bill', true);
}); });
} }
public function scopeWhereNeedsRemember(Builder $q): Builder /**
* @param Builder<self> $query
*
* @return Builder<self>
*/
public function scopeWhereNeedsRemember(Builder $query): Builder
{ {
return $q->whereHas('status', function ($q) { return $query->whereHas('status', function ($q) {
return $q->where('is_remember', true); return $q->where('is_remember', true);
})->where(fn ($query) => $query->whereNull('last_remembered_at')->orWhere('last_remembered_at', '<=', now()->subMonths(3))); })->where(fn ($query) => $query->whereNull('last_remembered_at')->orWhere('last_remembered_at', '<=', now()->subMonths(3)));
} }

View File

@ -28,6 +28,10 @@ class Status extends Model
} }
// ---------------------------------- Scopes ----------------------------------- // ---------------------------------- Scopes -----------------------------------
/**
* @param Builder<self> $query
* @return Builder<self>
*/
public function scopeNeedsPayment(Builder $query): Builder public function scopeNeedsPayment(Builder $query): Builder
{ {
return $query->where(function (Builder $query): Builder { return $query->where(function (Builder $query): Builder {

View File

@ -30,11 +30,17 @@ class Subscription extends Model
return $this->children->sum('amount'); return $this->children->sum('amount');
} }
/**
* @return BelongsTo<Fee, self>
*/
public function fee(): BelongsTo public function fee(): BelongsTo
{ {
return $this->belongsTo(Fee::class); return $this->belongsTo(Fee::class);
} }
/**
* @return HasMany<SubscriptionChild>
*/
public function children(): HasMany public function children(): HasMany
{ {
return $this->hasMany(SubscriptionChild::class, 'parent_id'); return $this->hasMany(SubscriptionChild::class, 'parent_id');

View File

@ -2,7 +2,7 @@
namespace App; namespace App;
use Illuminate\Database\Eloquent\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;
@ -17,6 +17,9 @@ class Region extends Model
'is_null' => 'boolean', 'is_null' => 'boolean',
]; ];
/**
* @return Collection<int, array{id: int, name: string}>
*/
public static function forSelect(): Collection public static function forSelect(): Collection
{ {
return static::select('id', 'name')->get(); return static::select('id', 'name')->get();

View File

@ -31,6 +31,9 @@ class Subactivity extends Model
]; ];
} }
/**
* @return BelongsToMany<Activity>
*/
public function activities(): BelongsToMany public function activities(): BelongsToMany
{ {
return $this->belongsToMany(Activity::class); return $this->belongsToMany(Activity::class);

View File

@ -39,7 +39,7 @@
"fakerphp/faker": "^1.9.1", "fakerphp/faker": "^1.9.1",
"laravel/sail": "^1.0.1", "laravel/sail": "^1.0.1",
"mockery/mockery": "^1.4.4", "mockery/mockery": "^1.4.4",
"nunomaduro/larastan": "^1.0", "nunomaduro/larastan": "*",
"orchestra/testbench": "^7.0", "orchestra/testbench": "^7.0",
"phpstan/phpstan": "^1.8.10", "phpstan/phpstan": "^1.8.10",
"phpunit/phpunit": "^9.5.10" "phpunit/phpunit": "^9.5.10"

1419
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,9 @@ namespace Database\Factories;
use App\Confession; use App\Confession;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Confession>
*/
class ConfessionFactory extends Factory class ConfessionFactory extends Factory
{ {
protected $model = Confession::class; protected $model = Confession::class;

View File

@ -5,6 +5,9 @@ namespace Database\Factories\Course\Models;
use App\Course\Models\CourseMember; use App\Course\Models\CourseMember;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<CourseMember>
*/
class CourseMemberFactory extends Factory class CourseMemberFactory extends Factory
{ {
public $model = CourseMember::class; public $model = CourseMember::class;

View File

@ -2,10 +2,11 @@
namespace Database\Factories; namespace Database\Factories;
use App\Gender;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
/** /**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Gender> * @extends Factory<Gender>
*/ */
class GenderFactory extends Factory class GenderFactory extends Factory
{ {

View File

@ -9,6 +9,9 @@ use App\Payment\Subscription;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
use Tests\RequestFactories\Child; use Tests\RequestFactories\Child;
/**
* @extends Factory<Payment>
*/
class PaymentFactory extends Factory class PaymentFactory extends Factory
{ {
protected $model = Payment::class; protected $model = Payment::class;

View File

@ -5,6 +5,9 @@ namespace Database\Factories\Payment;
use App\Payment\Status; use App\Payment\Status;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Status>
*/
class StatusFactory extends Factory class StatusFactory extends Factory
{ {
public $model = Status::class; public $model = Status::class;

View File

@ -8,6 +8,9 @@ use App\Payment\SubscriptionChild;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
use Tests\RequestFactories\Child; use Tests\RequestFactories\Child;
/**
* @extends Factory<Subscription>
*/
class SubscriptionFactory extends Factory class SubscriptionFactory extends Factory
{ {
protected $model = Subscription::class; protected $model = Subscription::class;

@ -1 +1 @@
Subproject commit 3c3d0df50e56ce09a09f8624e9491fdd43369dfa Subproject commit 0ee77550774715324e2fa66ca2b821d8a0e19880

@ -1 +1 @@
Subproject commit f075f67526bf0650a04fd2d3dd60ebbd74d43675 Subproject commit 6f162102ef7ceca41822d18c3e694abd926f550b

View File

@ -20,11 +20,6 @@ parameters:
count: 1 count: 1
path: app/Activity.php path: app/Activity.php
-
message: "#^Property App\\\\Activity\\:\\:\\$casts type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Activity.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: 1 count: 1
@ -35,11 +30,6 @@ parameters:
count: 1 count: 1
path: app/Course/Requests/StoreRequest.php path: app/Course/Requests/StoreRequest.php
-
message: "#^Method App\\\\Course\\\\Resources\\\\CourseResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Course/Resources/CourseResource.php
- -
message: "#^Method App\\\\Dav\\\\AddressBookBackend\\:\\:getCard\\(\\) should return M of array\\{lastmodified\\: int, etag\\: string, uri\\: string, id\\: int, size\\: int\\} but returns false\\.$#" message: "#^Method App\\\\Dav\\\\AddressBookBackend\\:\\:getCard\\(\\) should return M of array\\{lastmodified\\: int, etag\\: string, uri\\: string, id\\: int, size\\: int\\} but returns false\\.$#"
count: 1 count: 1
@ -140,11 +130,6 @@ parameters:
count: 1 count: 1
path: app/Member/Member.php path: app/Member/Member.php
-
message: "#^Method App\\\\Member\\\\Member\\:\\:scopeFilter\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#"
count: 1
path: app/Member/Member.php
- -
message: "#^Unsafe usage of new static\\(\\)\\.$#" message: "#^Unsafe usage of new static\\(\\)\\.$#"
count: 1 count: 1
@ -160,11 +145,6 @@ parameters:
count: 1 count: 1
path: app/Member/MemberRequest.php path: app/Member/MemberRequest.php
-
message: "#^Method App\\\\Member\\\\MemberResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Member/MemberResource.php
- -
message: "#^Method App\\\\Membership\\\\MembershipResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" message: "#^Method App\\\\Membership\\\\MembershipResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1 count: 1
@ -175,11 +155,6 @@ parameters:
count: 1 count: 1
path: app/Payment/PaymentResource.php path: app/Payment/PaymentResource.php
-
message: "#^Property App\\\\Payment\\\\Status\\:\\:\\$casts type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Payment/Status.php
- -
message: "#^Method App\\\\Payment\\\\SubscriptionResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" message: "#^Method App\\\\Payment\\\\SubscriptionResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1 count: 1
@ -195,21 +170,11 @@ parameters:
count: 1 count: 1
path: app/Providers/AuthServiceProvider.php path: app/Providers/AuthServiceProvider.php
-
message: "#^Property App\\\\Region\\:\\:\\$casts type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Region.php
- -
message: "#^Method App\\\\Subactivity\\:\\:sluggable\\(\\) return type has no value type specified in iterable type array\\.$#" message: "#^Method App\\\\Subactivity\\:\\:sluggable\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1 count: 1
path: app/Subactivity.php path: app/Subactivity.php
-
message: "#^Property App\\\\Subactivity\\:\\:\\$casts type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Subactivity.php
- -
message: "#^Method Database\\\\Factories\\\\ActivityFactory\\:\\:definition\\(\\) return type has no value type specified in iterable type array\\.$#" message: "#^Method Database\\\\Factories\\\\ActivityFactory\\:\\:definition\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1 count: 1
@ -279,11 +244,6 @@ parameters:
count: 1 count: 1
path: tests/TestCase.php path: tests/TestCase.php
-
message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$nami_id\\.$#"
count: 1
path: tests/Unit/InitializeGroupsTest.php
- -
message: "#^Parameter \\#1 \\$api of class App\\\\Initialize\\\\InitializeGroups constructor expects Zoomyboy\\\\LaravelNami\\\\Api, PHPUnit\\\\Framework\\\\MockObject\\\\Stub given\\.$#" message: "#^Parameter \\#1 \\$api of class App\\\\Initialize\\\\InitializeGroups constructor expects Zoomyboy\\\\LaravelNami\\\\Api, PHPUnit\\\\Framework\\\\MockObject\\\\Stub given\\.$#"
count: 6 count: 6
@ -294,46 +254,6 @@ parameters:
count: 1 count: 1
path: tests/Unit/Mailman/ServiceTest.php path: tests/Unit/Mailman/ServiceTest.php
-
message: "#^Property Zoomyboy\\\\LaravelNami\\\\Authentication\\\\FakeCookie\\:\\:\\$authenticated type has no value type specified in iterable type array\\.$#"
count: 1
path: packages/laravel-nami/src/Authentication/FakeCookie.php
-
message: "#^Property Zoomyboy\\\\LaravelNami\\\\Authentication\\\\FakeCookie\\:\\:\\$invalidAccounts type has no value type specified in iterable type array\\.$#"
count: 1
path: packages/laravel-nami/src/Authentication/FakeCookie.php
-
message: "#^Property Zoomyboy\\\\LaravelNami\\\\Authentication\\\\FakeCookie\\:\\:\\$validAccounts type has no value type specified in iterable type array\\.$#"
count: 1
path: packages/laravel-nami/src/Authentication/FakeCookie.php
-
message: "#^Method Zoomyboy\\\\LaravelNami\\\\Backend\\\\FakeBackend\\:\\:fakeSingleMembership\\(\\) has no return type specified\\.$#"
count: 1
path: packages/laravel-nami/src/Backend/FakeBackend.php
-
message: "#^Method Zoomyboy\\\\LaravelNami\\\\Backend\\\\FakeBackend\\:\\:fakeSingleMembership\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: packages/laravel-nami/src/Backend/FakeBackend.php
-
message: "#^Return type of call to function collect contains unresolvable type\\.$#"
count: 1
path: packages/laravel-nami/src/Backend/FakeBackend.php
-
message: "#^Unable to resolve the template type TKey in call to function collect$#"
count: 1
path: packages/laravel-nami/src/Backend/FakeBackend.php
-
message: "#^Unable to resolve the template type TValue in call to function collect$#"
count: 1
path: packages/laravel-nami/src/Backend/FakeBackend.php
- -
message: "#^Method Zoomyboy\\\\LaravelNami\\\\Confession\\:\\:fromNami\\(\\) has no return type specified\\.$#" message: "#^Method Zoomyboy\\\\LaravelNami\\\\Confession\\:\\:fromNami\\(\\) has no return type specified\\.$#"
count: 1 count: 1

View File

@ -49,7 +49,7 @@ class SettingTest extends TestCase
$response = $this->get('/setting/bill'); $response = $this->get('/setting/bill');
/** @var array<int, array{url: string, is_active: bool}> */ /** @var array<int, array{url: string, title: string, is_active: bool}> */
$menus = $this->inertia($response, 'setting_menu'); $menus = $this->inertia($response, 'setting_menu');
$this->assertTrue( $this->assertTrue(
collect($menus) collect($menus)

View File

@ -98,7 +98,7 @@ class StoreTest extends TestCase
public function testItThrowsErrorWhenLoginIsWrong(): void public function testItThrowsErrorWhenLoginIsWrong(): void
{ {
$this->login()->failedNami(); $this->login()->withNamiSettings();
$member = Member::factory()->defaults()->inNami(123)->createOne(); $member = Member::factory()->defaults()->inNami(123)->createOne();
$course = Course::factory()->inNami(456)->createOne(); $course = Course::factory()->inNami(456)->createOne();

View File

@ -100,7 +100,7 @@ class UpdateTest extends TestCase
public function testItThrowsErrorWhenLoginIsWrong(): void public function testItThrowsErrorWhenLoginIsWrong(): void
{ {
$this->login()->failedNami(); $this->login()->withNamiSettings();
$member = Member::factory()->defaults()->inNami(123)->has(CourseMember::factory()->inNami(999)->for(Course::factory()), 'courses')->createOne(); $member = Member::factory()->defaults()->inNami(123)->has(CourseMember::factory()->inNami(999)->for(Course::factory()), 'courses')->createOne();
$newCourse = Course::factory()->inNami(789)->create(); $newCourse = Course::factory()->inNami(789)->create();

View File

@ -53,7 +53,6 @@ class InitializeActionTest extends TestCase
public function testItValidatesLogin(): void public function testItValidatesLogin(): void
{ {
$this->login(); $this->login();
Auth::fails(12345, 'secret');
$response = $this->post('/initialize', $this->factory()->withCredentials(12345, 'secret')->create()); $response = $this->post('/initialize', $this->factory()->withCredentials(12345, 'secret')->create());

View File

@ -117,17 +117,22 @@ class UpdateTest extends TestCase
private function fakeRequest(): void private function fakeRequest(): void
{ {
Http::fake(function ($request) { Http::fake(function ($request) {
if ($request->url() === app(FakeBackend::class)->singleMemberUrl(10, 135) && 'GET' === $request->method()) { if ($request->url() === $this->singleMemberUrl(10, 135) && 'GET' === $request->method()) {
return Http::response('{ "success": true, "data": {"missingkey": "missingvalue", "kontoverbindung": {"a": "b"} } }', 200); return Http::response('{ "success": true, "data": {"missingkey": "missingvalue", "kontoverbindung": {"a": "b"} } }', 200);
} }
if ($request->url() === app(FakeBackend::class)->singleMemberUrl(10, 135) && 'PUT' === $request->method() && 43 === $request['version']) { if ($request->url() === $this->singleMemberUrl(10, 135) && 'PUT' === $request->method() && 43 === $request['version']) {
return Http::response('{ "success": false, "message": "Update nicht möglich. Der Datensatz wurde zwischenzeitlich verändert." }', 200); return Http::response('{ "success": false, "message": "Update nicht möglich. Der Datensatz wurde zwischenzeitlich verändert." }', 200);
} }
if ($request->url() === app(FakeBackend::class)->singleMemberUrl(10, 135) && 'PUT' === $request->method()) { if ($request->url() === $this->singleMemberUrl(10, 135) && 'PUT' === $request->method()) {
return Http::response('{ "success": true, "data": { "version": 44 } }', 200); return Http::response('{ "success": true, "data": { "version": 44 } }', 200);
} }
}); });
} }
private function singleMemberUrl(int $gruppierungId, int $memberId): string
{
return "https://nami.dpsg.de/ica/rest/nami/mitglied/filtered-for-navigation/gruppierung/gruppierung/{$gruppierungId}/{$memberId}";
}
} }

View File

@ -47,18 +47,6 @@ abstract class TestCase extends BaseTestCase
return $this; return $this;
} }
public function failedNami(int $mglnr = 12345, string $password = 'password'): self
{
Auth::fails($mglnr, $password);
NamiSettings::fake([
'mglnr' => $mglnr,
'password' => $password,
'default_group_id' => 55,
]);
return $this;
}
public function login(): self public function login(): self
{ {
$this->be($user = User::factory()->create()); $this->be($user = User::factory()->create());