Updated dependencies; Fixed codeformatting and phpstan

This commit is contained in:
Constantin Graf
2024-07-31 12:53:41 +02:00
committed by Constantin Graf
parent 5b7df869ad
commit d8968399d6
78 changed files with 1038 additions and 1148 deletions

View File

@@ -88,7 +88,7 @@ class CreateNewUser implements CreatesNewUsers
'week_start' => $startOfWeek, 'week_start' => $startOfWeek,
]); ]);
$organization = new Organization(); $organization = new Organization;
$organization->name = explode(' ', $user->name, 2)[0]."'s Organization"; $organization->name = explode(' ', $user->name, 2)[0]."'s Organization";
$organization->personal_team = true; $organization->personal_team = true;
$organization->currency = $currency ?? 'EUR'; $organization->currency = $currency ?? 'EUR';

View File

@@ -72,6 +72,7 @@ class AddOrganizationMember implements AddsTeamMembers
'required', 'required',
'email', 'email',
(new ExistsEloquent(User::class, 'email', function (Builder $builder) { (new ExistsEloquent(User::class, 'email', function (Builder $builder) {
/** @var Builder<User> $builder */
return $builder->where('is_placeholder', '=', false); return $builder->where('is_placeholder', '=', false);
}))->withMessage(__('We were unable to find a registered user with this email address.')), }))->withMessage(__('We were unable to find a registered user with this email address.')),
], ],

View File

@@ -33,7 +33,7 @@ class CreateOrganization implements CreatesTeams
'name' => ['required', 'string', 'max:255'], 'name' => ['required', 'string', 'max:255'],
])->validateWithBag('createTeam'); ])->validateWithBag('createTeam');
$organization = new Organization(); $organization = new Organization;
$organization->name = $input['name']; $organization->name = $input['name'];
$organization->personal_team = false; $organization->personal_team = false;
$organization->owner()->associate($user); $organization->owner()->associate($user);
@@ -45,10 +45,10 @@ class CreateOrganization implements CreatesTeams
] ]
); );
$user->ownedTeams()->save($organization);
$user->switchTeam($organization); $user->switchTeam($organization);
// Note: The refresh is necessary for currently unknown reasons. Do not remove it.
$organization = $organization->refresh();
AfterCreateOrganization::dispatch($organization); AfterCreateOrganization::dispatch($organization);
return $organization; return $organization;

View File

@@ -19,6 +19,6 @@ class InviteOrganizationMember implements InvitesTeamMembers
*/ */
public function invite(User $user, Organization $organization, string $email, ?string $role = null): void public function invite(User $user, Organization $organization, string $email, ?string $role = null): void
{ {
throw new MovedToApiException(); throw new MovedToApiException;
} }
} }

View File

@@ -19,6 +19,6 @@ class RemoveOrganizationMember implements RemovesTeamMembers
*/ */
public function remove(User $user, Organization $organization, User $teamMember): void public function remove(User $user, Organization $organization, User $teamMember): void
{ {
throw new MovedToApiException(); throw new MovedToApiException;
} }
} }

View File

@@ -20,6 +20,6 @@ class UpdateMemberRole
*/ */
public function update(User $actingUser, Organization $organization, string $userId, string $role): void public function update(User $actingUser, Organization $organization, string $userId, string $role): void
{ {
throw new MovedToApiException(); throw new MovedToApiException;
} }
} }

View File

@@ -36,7 +36,7 @@ class UpdateOrganization implements UpdatesTeamNames
'currency' => [ 'currency' => [
'required', 'required',
'string', 'string',
new CurrencyRule(), new CurrencyRule,
], ],
])->validateWithBag('updateTeamName'); ])->validateWithBag('updateTeamName');

View File

@@ -22,7 +22,7 @@ class ValidateOrganizationDeletion
public function validate(User $user, Organization $organization): void public function validate(User $user, Organization $organization): void
{ {
if (! app(PermissionStore::class)->userHas($organization, $user, 'organizations:delete')) { if (! app(PermissionStore::class)->userHas($organization, $user, 'organizations:delete')) {
throw new AuthorizationException(); throw new AuthorizationException;
} }
} }
} }

View File

@@ -6,10 +6,11 @@ namespace App\Console\Commands\TimeEntry;
use App\Mail\TimeEntryStillRunningMail; use App\Mail\TimeEntryStillRunningMail;
use App\Models\TimeEntry; use App\Models\TimeEntry;
use App\Models\User;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
class TimeEntrySendStillRunningMailsCommand extends Command class TimeEntrySendStillRunningMailsCommand extends Command
@@ -48,7 +49,8 @@ class TimeEntrySendStillRunningMailsCommand extends Command
->with([ ->with([
'user', 'user',
]) ])
->whereHas('user', function (Builder $query) { ->whereHas('user', function (Builder $query): void {
/** @var Builder<User> $query */
$query->where('is_placeholder', '=', false); $query->where('is_placeholder', '=', false);
}) })
->orderBy('created_at', 'asc') ->orderBy('created_at', 'asc')

View File

@@ -6,6 +6,7 @@ namespace App\Events;
use App\Models\Organization; use App\Models\Organization;
use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
/** /**
* This event is fired after an organization has been created. * This event is fired after an organization has been created.
@@ -14,6 +15,7 @@ use Illuminate\Foundation\Events\Dispatchable;
class AfterCreateOrganization class AfterCreateOrganization
{ {
use Dispatchable; use Dispatchable;
use SerializesModels;
public Organization $organization; public Organization $organization;

View File

@@ -24,20 +24,20 @@ class ApiExceptionTypeToSchema extends ExceptionToResponseExtension
public function toResponse(Type $type): Response public function toResponse(Type $type): Response
{ {
$validationResponseBodyType = (new OpenApiTypes\ObjectType()) $validationResponseBodyType = (new OpenApiTypes\ObjectType)
->addProperty( ->addProperty(
'error', 'error',
(new OpenApiTypes\BooleanType()) (new OpenApiTypes\BooleanType)
->setDescription('Whether the response is an error.') ->setDescription('Whether the response is an error.')
) )
->addProperty( ->addProperty(
'key', 'key',
(new OpenApiTypes\StringType()) (new OpenApiTypes\StringType)
->setDescription('Error key.') ->setDescription('Error key.')
) )
->addProperty( ->addProperty(
'message', 'message',
(new OpenApiTypes\StringType()) (new OpenApiTypes\StringType)
->setDescription('Error message.') ->setDescription('Error message.')
) )
->setRequired(['error', 'key', 'message']); ->setRequired(['error', 'key', 'message']);

View File

@@ -45,7 +45,7 @@ class PaginatedResourceCollectionTypeToSchema extends TypeToSchemaExtension
} }
$type = new OpenApiObjectType; $type = new OpenApiObjectType;
$type->addProperty('data', (new ArrayType())->setItems($collectingType)); $type->addProperty('data', (new ArrayType)->setItems($collectingType));
$type->addProperty( $type->addProperty(
'links', 'links',
(new OpenApiObjectType) (new OpenApiObjectType)

View File

@@ -111,9 +111,18 @@ class UserResource extends Resource
->filters([ ->filters([
TernaryFilter::make('real_user') TernaryFilter::make('real_user')
->queries( ->queries(
true: fn (Builder $query) => $query->where('is_placeholder', '=', false), true: function (Builder $query): Builder {
false: fn (Builder $query) => $query->where('is_placeholder', '=', true), /** @var Builder<User> $query */
blank: fn (Builder $query) => $query, return $query->where('is_placeholder', '=', false);
},
false: function (Builder $query): Builder {
/** @var Builder<User> $query */
return $query->where('is_placeholder', '=', true);
},
blank: function (Builder $query): Builder {
/** @var Builder<User> $query */
return $query;
},
) )
->label('Real User?'), ->label('Real User?'),
TernaryFilter::make('email_verified') TernaryFilter::make('email_verified')

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Filament\Widgets; namespace App\Filament\Widgets;
use App\Models\TimeEntry;
use App\Models\User; use App\Models\User;
use Filament\Widgets\StatsOverviewWidget as BaseWidget; use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat; use Filament\Widgets\StatsOverviewWidget\Stat;
@@ -21,7 +22,8 @@ class ActiveUserOverview extends BaseWidget
$placeholderUserCount = User::query()->where('is_placeholder', '=', true)->count(); $placeholderUserCount = User::query()->where('is_placeholder', '=', true)->count();
$activeInLastWeek = User::query() $activeInLastWeek = User::query()
->where('is_placeholder', '=', false) ->where('is_placeholder', '=', false)
->whereHas('timeEntries', function (Builder $query) { ->whereHas('timeEntries', function (Builder $query): void {
/** @var Builder<TimeEntry> $query */
$query->where('created_at', '>=', now()->subWeek()) $query->where('created_at', '>=', now()->subWeek())
->orWhere('updated_at', '>=', now()->subWeek()); ->orWhere('updated_at', '>=', now()->subWeek());
}) })

View File

@@ -66,7 +66,7 @@ class ClientController extends Controller
{ {
$this->checkPermission($organization, 'clients:create'); $this->checkPermission($organization, 'clients:create');
$client = new Client(); $client = new Client;
$client->name = $request->input('name'); $client->name = $request->input('name');
$client->organization()->associate($organization); $client->organization()->associate($organization);
$client->save(); $client->save();

View File

@@ -12,8 +12,7 @@ class Controller extends \App\Http\Controllers\Controller
{ {
public function __construct( public function __construct(
protected PermissionStore $permissionStore, protected PermissionStore $permissionStore,
) { ) {}
}
/** /**
* @throws AuthorizationException * @throws AuthorizationException
@@ -21,7 +20,7 @@ class Controller extends \App\Http\Controllers\Controller
protected function checkPermission(Organization $organization, string $permission): void protected function checkPermission(Organization $organization, string $permission): void
{ {
if (! $this->permissionStore->has($organization, $permission)) { if (! $this->permissionStore->has($organization, $permission)) {
throw new AuthorizationException(); throw new AuthorizationException;
} }
} }
@@ -37,7 +36,7 @@ class Controller extends \App\Http\Controllers\Controller
return; return;
} }
} }
throw new AuthorizationException(); throw new AuthorizationException;
} }
protected function hasPermission(Organization $organization, string $permission): bool protected function hasPermission(Organization $organization, string $permission): bool

View File

@@ -35,7 +35,7 @@ class ImportController extends Controller
foreach ($importers as $key => $importerClass) { foreach ($importers as $key => $importerClass) {
/** @var ImporterContract $importer */ /** @var ImporterContract $importer */
$importer = new $importerClass(); $importer = new $importerClass;
$importersResponse[] = [ $importersResponse[] = [
'key' => $key, 'key' => $key,
'name' => $importer->getName(), 'name' => $importer->getName(),

View File

@@ -82,16 +82,16 @@ class MemberController extends Controller
$newRole = $request->getRole(); $newRole = $request->getRole();
$oldRole = Role::from($member->role); $oldRole = Role::from($member->role);
if ($oldRole === Role::Owner) { if ($oldRole === Role::Owner) {
throw new OrganizationNeedsAtLeastOneOwner(); throw new OrganizationNeedsAtLeastOneOwner;
} }
if ($newRole === Role::Placeholder) { if ($newRole === Role::Placeholder) {
throw new ChangingRoleToPlaceholderIsNotAllowed(); throw new ChangingRoleToPlaceholderIsNotAllowed;
} }
if ($newRole === Role::Owner) { if ($newRole === Role::Owner) {
if ($this->hasPermission($organization, 'members:change-ownership')) { if ($this->hasPermission($organization, 'members:change-ownership')) {
$memberService->changeOwnership($organization, $member); $memberService->changeOwnership($organization, $member);
} else { } else {
throw new OnlyOwnerCanChangeOwnership(); throw new OnlyOwnerCanChangeOwnership;
} }
} else { } else {
$member->role = $request->getRole()->value; $member->role = $request->getRole()->value;
@@ -120,7 +120,7 @@ class MemberController extends Controller
throw new EntityStillInUseApiException('member', 'project_member'); throw new EntityStillInUseApiException('member', 'project_member');
} }
if ($member->role === Role::Owner->value) { if ($member->role === Role::Owner->value) {
throw new CanNotRemoveOwnerFromOrganization(); throw new CanNotRemoveOwnerFromOrganization;
} }
$member->delete(); $member->delete();
@@ -138,7 +138,7 @@ class MemberController extends Controller
$this->checkPermission($organization, 'members:make-placeholder', $member); $this->checkPermission($organization, 'members:make-placeholder', $member);
if ($member->role === Role::Owner->value) { if ($member->role === Role::Owner->value) {
throw new CanNotRemoveOwnerFromOrganization(); throw new CanNotRemoveOwnerFromOrganization;
} }
$memberService->makeMemberToPlaceholder($member); $memberService->makeMemberToPlaceholder($member);
@@ -161,7 +161,7 @@ class MemberController extends Controller
$user = $member->user; $user = $member->user;
if (! $user->is_placeholder) { if (! $user->is_placeholder) {
throw new UserNotPlaceholderApiException(); throw new UserNotPlaceholderApiException;
} }
$invitationService->inviteUser($organization, $user->email, Role::Employee); $invitationService->inviteUser($organization, $user->email, Role::Employee);

View File

@@ -89,7 +89,7 @@ class ProjectController extends Controller
public function store(Organization $organization, ProjectStoreRequest $request): JsonResource public function store(Organization $organization, ProjectStoreRequest $request): JsonResource
{ {
$this->checkPermission($organization, 'projects:create'); $this->checkPermission($organization, 'projects:create');
$project = new Project(); $project = new Project;
$project->name = $request->input('name'); $project->name = $request->input('name');
$project->color = $request->input('color'); $project->color = $request->input('color');
$project->is_billable = (bool) $request->input('is_billable'); $project->is_billable = (bool) $request->input('is_billable');

View File

@@ -65,13 +65,13 @@ class ProjectMemberController extends Controller
$member = Member::findOrFail((string) $request->input('member_id')); $member = Member::findOrFail((string) $request->input('member_id'));
if ($member->user->is_placeholder) { if ($member->user->is_placeholder) {
throw new InactiveUserCanNotBeUsedApiException(); throw new InactiveUserCanNotBeUsedApiException;
} }
if (ProjectMember::whereBelongsTo($project, 'project')->whereBelongsTo($member, 'member')->exists()) { if (ProjectMember::whereBelongsTo($project, 'project')->whereBelongsTo($member, 'member')->exists()) {
throw new UserIsAlreadyMemberOfProjectApiException(); throw new UserIsAlreadyMemberOfProjectApiException;
} }
$projectMember = new ProjectMember(); $projectMember = new ProjectMember;
$projectMember->billable_rate = $request->getBillableRate(); $projectMember->billable_rate = $request->getBillableRate();
$projectMember->member()->associate($member); $projectMember->member()->associate($member);
$projectMember->user()->associate($member->user); $projectMember->user()->associate($member->user);

View File

@@ -57,7 +57,7 @@ class TagController extends Controller
{ {
$this->checkPermission($organization, 'tags:create'); $this->checkPermission($organization, 'tags:create');
$tag = new Tag(); $tag = new Tag;
$tag->name = $request->input('name'); $tag->name = $request->input('name');
$tag->organization()->associate($organization); $tag->organization()->associate($organization);
$tag->save(); $tag->save();

View File

@@ -76,7 +76,7 @@ class TaskController extends Controller
public function store(Organization $organization, TaskStoreRequest $request): JsonResource public function store(Organization $organization, TaskStoreRequest $request): JsonResource
{ {
$this->checkPermission($organization, 'tasks:create'); $this->checkPermission($organization, 'tasks:create');
$task = new Task(); $task = new Task;
$task->name = $request->input('name'); $task->name = $request->input('name');
$task->project_id = $request->input('project_id'); $task->project_id = $request->input('project_id');
$task->organization()->associate($organization); $task->organization()->associate($organization);

View File

@@ -212,12 +212,12 @@ class TimeEntryController extends Controller
} }
if ($request->input('end') === null && TimeEntry::query()->whereBelongsTo($member, 'member')->where('end', null)->exists()) { if ($request->input('end') === null && TimeEntry::query()->whereBelongsTo($member, 'member')->where('end', null)->exists()) {
throw new TimeEntryStillRunningApiException(); throw new TimeEntryStillRunningApiException;
} }
$client = $request->input('project_id') !== null ? Project::findOrFail((string) $request->input('project_id'))->client : null; $client = $request->input('project_id') !== null ? Project::findOrFail((string) $request->input('project_id'))->client : null;
$timeEntry = new TimeEntry(); $timeEntry = new TimeEntry;
$timeEntry->fill($request->validated()); $timeEntry->fill($request->validated());
$timeEntry->client()->associate($client); $timeEntry->client()->associate($client);
$timeEntry->user_id = $member->user_id; $timeEntry->user_id = $member->user_id;
@@ -247,7 +247,7 @@ class TimeEntryController extends Controller
} }
if ($timeEntry->end !== null && $request->has('end') && $request->input('end') === null) { if ($timeEntry->end !== null && $request->has('end') && $request->input('end') === null) {
throw new TimeEntryCanNotBeRestartedApiException(); throw new TimeEntryCanNotBeRestartedApiException;
} }
if ($request->has('project_id')) { if ($request->has('project_id')) {
@@ -285,7 +285,7 @@ class TimeEntryController extends Controller
$changes = $request->validated('changes'); $changes = $request->validated('changes');
if (isset($changes['member_id']) && ! $canAccessAll && $this->member($organization)->getKey() !== $changes['member_id']) { if (isset($changes['member_id']) && ! $canAccessAll && $this->member($organization)->getKey() !== $changes['member_id']) {
throw new AuthorizationException(); throw new AuthorizationException;
} }
$client = null; $client = null;
@@ -295,8 +295,8 @@ class TimeEntryController extends Controller
$overwriteClient = true; $overwriteClient = true;
} }
$success = new Collection(); $success = new Collection;
$error = new Collection(); $error = new Collection;
foreach ($ids as $id) { foreach ($ids as $id) {
/** @var TimeEntry|null $timeEntry */ /** @var TimeEntry|null $timeEntry */

View File

@@ -28,7 +28,7 @@ class Controller extends BaseController
$user = Auth::user(); $user = Auth::user();
if ($user === null) { if ($user === null) {
Log::error('This function should only be called in authenticated context'); Log::error('This function should only be called in authenticated context');
throw new AuthorizationException(); throw new AuthorizationException;
} }
return $user; return $user;
@@ -44,7 +44,7 @@ class Controller extends BaseController
$member = Member::query()->whereBelongsTo($organization, 'organization')->whereBelongsTo($user, 'user')->first(); $member = Member::query()->whereBelongsTo($organization, 'organization')->whereBelongsTo($user, 'user')->first();
if ($member === null) { if ($member === null) {
Log::error('This function should only be called in authenticated context after checking the user is a member of the organization'); Log::error('This function should only be called in authenticated context after checking the user is a member of the organization');
throw new AuthorizationException(); throw new AuthorizationException;
} }
return $member; return $member;

View File

@@ -4,6 +4,4 @@ declare(strict_types=1);
namespace App\Http\Controllers\Web; namespace App\Http\Controllers\Web;
abstract class Controller extends \App\Http\Controllers\Controller abstract class Controller extends \App\Http\Controllers\Controller {}
{
}

View File

@@ -32,7 +32,7 @@ class CheckOrganizationBlocked
$billing = app(BillingContract::class); $billing = app(BillingContract::class);
if ($billing->isBlocked($organization)) { if ($billing->isBlocked($organization)) {
throw new OrganizationHasNoSubscriptionButMultipleMembersException(); throw new OrganizationHasNoSubscriptionButMultipleMembersException;
} }
return $next($request); return $next($request);

View File

@@ -41,7 +41,7 @@ class ProjectStoreRequest extends FormRequest
'required', 'required',
'string', 'string',
'max:255', 'max:255',
new ColorRule(), new ColorRule,
], ],
'is_billable' => [ 'is_billable' => [
'required', 'required',

View File

@@ -41,7 +41,7 @@ class ProjectUpdateRequest extends FormRequest
'required', 'required',
'string', 'string',
'max:255', 'max:255',
new ColorRule(), new ColorRule,
], ],
'is_billable' => [ 'is_billable' => [
'required', 'required',

View File

@@ -4,6 +4,4 @@ declare(strict_types=1);
namespace App\Http\Resources; namespace App\Http\Resources;
interface PaginatedResourceCollection interface PaginatedResourceCollection {}
{
}

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Listeners; namespace App\Listeners;
use App\Models\Member; use App\Models\Member;
use App\Models\User;
use App\Service\UserService; use App\Service\UserService;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Laravel\Jetstream\Events\TeamMemberAdded; use Laravel\Jetstream\Events\TeamMemberAdded;
@@ -19,7 +20,8 @@ class RemovePlaceholder
/** @var UserService $userService */ /** @var UserService $userService */
$userService = app(UserService::class); $userService = app(UserService::class);
$placeholders = Member::query() $placeholders = Member::query()
->whereHas('user', function (Builder $query) use ($event) { ->whereHas('user', function (Builder $query) use ($event): void {
/** @var Builder<User> $query */
$query->where('is_placeholder', '=', true) $query->where('is_placeholder', '=', true)
->where('email', '=', $event->user->email); ->where('email', '=', $event->user->email);
}) })

View File

@@ -29,5 +29,6 @@ use OwenIt\Auditing\Models\Audit as PackageAuditModel;
*/ */
class Audit extends PackageAuditModel class Audit extends PackageAuditModel
{ {
/** @use HasFactory<AuditFactory> */
use HasFactory; use HasFactory;
} }

View File

@@ -30,7 +30,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class Client extends Model implements AuditableContract class Client extends Model implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<ClientFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Models; namespace App\Models;
use Database\Factories\FailedJobFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
@@ -16,6 +17,7 @@ use Illuminate\Support\Carbon;
*/ */
class FailedJob extends Model class FailedJob extends Model
{ {
/** @use HasFactory<FailedJobFactory> */
use HasFactory; use HasFactory;
/** /**

View File

@@ -30,7 +30,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class Member extends JetstreamMembership implements AuditableContract class Member extends JetstreamMembership implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<MemberFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**

View File

@@ -9,6 +9,7 @@ use Database\Factories\OrganizationFactory;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
@@ -42,7 +43,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class Organization extends JetstreamTeam implements AuditableContract class Organization extends JetstreamTeam implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<OrganizationFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**
@@ -110,7 +114,7 @@ class Organization extends JetstreamTeam implements AuditableContract
*/ */
public function users(): BelongsToMany public function users(): BelongsToMany
{ {
return $this->belongsToMany(Jetstream::userModel(), Jetstream::membershipModel()) return $this->belongsToMany(User::class, Member::class)
->withPivot([ ->withPivot([
'id', 'id',
'role', 'role',
@@ -120,6 +124,16 @@ class Organization extends JetstreamTeam implements AuditableContract
->as('membership'); ->as('membership');
} }
/**
* Get the owner of the team.
*
* @return BelongsTo<User, Organization>
*/
public function owner(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
/** /**
* @return HasMany<Member> * @return HasMany<Member>
*/ */

View File

@@ -9,7 +9,6 @@ use Database\Factories\OrganizationInvitationFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Laravel\Jetstream\Jetstream;
use Laravel\Jetstream\TeamInvitation as JetstreamTeamInvitation; use Laravel\Jetstream\TeamInvitation as JetstreamTeamInvitation;
use OwenIt\Auditing\Auditable; use OwenIt\Auditing\Auditable;
use OwenIt\Auditing\Contracts\Auditable as AuditableContract; use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
@@ -28,7 +27,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class OrganizationInvitation extends JetstreamTeamInvitation implements AuditableContract class OrganizationInvitation extends JetstreamTeamInvitation implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<OrganizationInvitationFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**
@@ -55,7 +57,7 @@ class OrganizationInvitation extends JetstreamTeamInvitation implements Auditabl
*/ */
public function organization(): BelongsTo public function organization(): BelongsTo
{ {
return $this->belongsTo(Jetstream::teamModel(), 'organization_id'); return $this->belongsTo(Organization::class, 'organization_id');
} }
/** /**
@@ -65,6 +67,6 @@ class OrganizationInvitation extends JetstreamTeamInvitation implements Auditabl
*/ */
public function team(): BelongsTo public function team(): BelongsTo
{ {
return $this->belongsTo(Jetstream::teamModel(), 'organization_id'); return $this->belongsTo(Organization::class, 'organization_id');
} }
} }

View File

@@ -41,7 +41,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class Project extends Model implements AuditableContract class Project extends Model implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<ProjectFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**

View File

@@ -32,7 +32,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class ProjectMember extends Model implements AuditableContract class ProjectMember extends Model implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<ProjectMemberFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**

View File

@@ -26,7 +26,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class Tag extends Model implements AuditableContract class Tag extends Model implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<TagFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**

View File

@@ -35,7 +35,10 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
class Task extends Model implements AuditableContract class Task extends Model implements AuditableContract
{ {
use Auditable; use Auditable;
/** @use HasFactory<TaskFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**

View File

@@ -49,7 +49,10 @@ class TimeEntry extends Model implements AuditableContract
{ {
use Auditable; use Auditable;
use ComputedAttributes; use ComputedAttributes;
/** @use HasFactory<TimeEntryFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
/** /**

View File

@@ -59,7 +59,10 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
{ {
use Auditable; use Auditable;
use HasApiTokens; use HasApiTokens;
/** @use HasFactory<UserFactory> */
use HasFactory; use HasFactory;
use HasProfilePhoto; use HasProfilePhoto;
use HasTeams; use HasTeams;
use HasUuids; use HasUuids;

View File

@@ -97,7 +97,7 @@ class AppServiceProvider extends ServiceProvider
} }
$this->app->scoped(PermissionStore::class, function (Application $app): PermissionStore { $this->app->scoped(PermissionStore::class, function (Application $app): PermissionStore {
return new PermissionStore(); return new PermissionStore;
}); });
// Extensions // Extensions

View File

@@ -65,7 +65,7 @@ class FortifyServiceProvider extends ServiceProvider
return Limit::perMinute(5)->by($request->session()->get('login.id')); return Limit::perMinute(5)->by($request->session()->get('login.id'));
}); });
$this->app->instance(LoginResponse::class, new CustomLoginResponse()); $this->app->instance(LoginResponse::class, new CustomLoginResponse);
$this->app->instance(TwoFactorLoginResponse::class, new CustomTwoFactorLoginResponse()); $this->app->instance(TwoFactorLoginResponse::class, new CustomTwoFactorLoginResponse);
} }
} }

View File

@@ -30,7 +30,7 @@ class DashboardService
*/ */
private function lastDays(int $days, CarbonTimeZone $timeZone): Collection private function lastDays(int $days, CarbonTimeZone $timeZone): Collection
{ {
$result = new Collection(); $result = new Collection;
$date = Carbon::now($timeZone)->subDays($days); $date = Carbon::now($timeZone)->subDays($days);
for ($i = 0; $i < $days; $i++) { for ($i = 0; $i < $days; $i++) {
$date->addDay(); $date->addDay();
@@ -77,7 +77,7 @@ class DashboardService
*/ */
private function daysOfThisWeek(CarbonTimeZone $timeZone, Weekday $startOfWeek): Collection private function daysOfThisWeek(CarbonTimeZone $timeZone, Weekday $startOfWeek): Collection
{ {
$result = new Collection(); $result = new Collection;
$date = Carbon::now($timeZone); $date = Carbon::now($timeZone);
$start = $date->startOfWeek($startOfWeek->carbonWeekDay()); $start = $date->startOfWeek($startOfWeek->carbonWeekDay());
for ($i = 0; $i < 7; $i++) { for ($i = 0; $i < 7; $i++) {

View File

@@ -145,7 +145,7 @@ class DeletionService
foreach ($members as $member) { foreach ($members as $member) {
if ($member->role === Role::Owner->value && $member->organization->users()->count() > 1) { if ($member->role === Role::Owner->value && $member->organization->users()->count() > 1) {
throw new CanNotDeleteUserWhoIsOwnerOfOrganizationWithMultipleMembers(); throw new CanNotDeleteUserWhoIsOwnerOfOrganizationWithMultipleMembers;
} }
} }

View File

@@ -319,7 +319,7 @@ class ExportService
// Create ZIP file // Create ZIP file
$temporaryDirectoryZip = TemporaryDirectory::make(); $temporaryDirectoryZip = TemporaryDirectory::make();
$zip = new ZipArchive(); $zip = new ZipArchive;
if ($zip->open($temporaryDirectoryZip->path('export.zip'), ZipArchive::CREATE) !== true) { if ($zip->open($temporaryDirectoryZip->path('export.zip'), ZipArchive::CREATE) !== true) {
throw new Exception('Cannot create ZIP file'); throw new Exception('Cannot create ZIP file');
} }
@@ -356,7 +356,7 @@ class ExportService
} catch (UnavailableStream|CannotInsertRecord|Exception|LeagueCsvException $exception) { } catch (UnavailableStream|CannotInsertRecord|Exception|LeagueCsvException $exception) {
report($exception); report($exception);
throw new ExportException(); throw new ExportException;
} }
} }
} }

View File

@@ -98,7 +98,7 @@ class ImportDatabaseHelper
throw new ImportException('Invalid data: '.implode(', ', $validator->errors()->all())); throw new ImportException('Invalid data: '.implode(', ', $validator->errors()->all()));
} }
$model = new $this->model(); $model = new $this->model;
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$model->{$key} = $value; $model->{$key} = $value;
} }
@@ -240,7 +240,7 @@ class ImportDatabaseHelper
{ {
if ($this->mapIdentifierToKey === null) { if ($this->mapIdentifierToKey === null) {
$select = $this->identifiers; $select = $this->identifiers;
$select[] = (new $this->model())->getKeyName(); $select[] = (new $this->model)->getKeyName();
$builder = $this->getModelInstance(); $builder = $this->getModelInstance();
if ($this->queryModifier !== null) { if ($this->queryModifier !== null) {

View File

@@ -98,7 +98,7 @@ class ClockifyTimeEntriesImporter extends DefaultImporter
'organization_id' => $this->organization->id, 'organization_id' => $this->organization->id,
]); ]);
} }
$timeEntry = new TimeEntry(); $timeEntry = new TimeEntry;
$timeEntry->user_id = $userId; $timeEntry->user_id = $userId;
$timeEntry->member_id = $memberId; $timeEntry->member_id = $memberId;
$timeEntry->task_id = $taskId; $timeEntry->task_id = $taskId;

View File

@@ -118,7 +118,7 @@ abstract class DefaultImporter implements ImporterContract
$project->billable_rate = null; $project->billable_rate = null;
} }
}); });
$this->projectMemberImportHelper = new ImportDatabaseHelper(ProjectMember::class, ['project_id', 'member_id'], true, function (Builder $builder) { $this->projectMemberImportHelper = new ImportDatabaseHelper(ProjectMember::class, ['project_id', 'member_id'], true, function (Builder $builder): Builder {
/** @var Builder<ProjectMember> $builder */ /** @var Builder<ProjectMember> $builder */
return $builder->whereBelongsToOrganization($this->organization); return $builder->whereBelongsToOrganization($this->organization);
}, validate: [ }, validate: [
@@ -131,7 +131,8 @@ abstract class DefaultImporter implements ImporterContract
$projectMember->billable_rate = null; $projectMember->billable_rate = null;
} }
}); });
$this->tagImportHelper = new ImportDatabaseHelper(Tag::class, ['name', 'organization_id'], true, function (Builder $builder) { $this->tagImportHelper = new ImportDatabaseHelper(Tag::class, ['name', 'organization_id'], true, function (Builder $builder): Builder {
/** @var Builder<Tag> $builder */
return $builder->where('organization_id', $this->organization->id); return $builder->where('organization_id', $this->organization->id);
}, validate: [ }, validate: [
'name' => [ 'name' => [
@@ -139,7 +140,8 @@ abstract class DefaultImporter implements ImporterContract
'max:255', 'max:255',
], ],
]); ]);
$this->clientImportHelper = new ImportDatabaseHelper(Client::class, ['name', 'organization_id'], true, function (Builder $builder) { $this->clientImportHelper = new ImportDatabaseHelper(Client::class, ['name', 'organization_id'], true, function (Builder $builder): Builder {
/** @var Builder<Client> $builder */
return $builder->where('organization_id', $this->organization->id); return $builder->where('organization_id', $this->organization->id);
}, validate: [ }, validate: [
'name' => [ 'name' => [
@@ -147,7 +149,8 @@ abstract class DefaultImporter implements ImporterContract
'max:255', 'max:255',
], ],
]); ]);
$this->taskImportHelper = new ImportDatabaseHelper(Task::class, ['name', 'project_id', 'organization_id'], true, function (Builder $builder) { $this->taskImportHelper = new ImportDatabaseHelper(Task::class, ['name', 'project_id', 'organization_id'], true, function (Builder $builder): Builder {
/** @var Builder<Task> $builder */
return $builder->where('organization_id', $this->organization->id); return $builder->where('organization_id', $this->organization->id);
}, validate: [ }, validate: [
'name' => [ 'name' => [

View File

@@ -4,6 +4,4 @@ declare(strict_types=1);
namespace App\Service\Import\Importers; namespace App\Service\Import\Importers;
class ImportException extends \Exception class ImportException extends \Exception {}
{
}

View File

@@ -31,7 +31,7 @@ class SolidtimeImporter extends DefaultImporter
$temporaryDirectoryZip = null; $temporaryDirectoryZip = null;
$temporaryDirectory = null; $temporaryDirectory = null;
try { try {
$zip = new ZipArchive(); $zip = new ZipArchive;
$temporaryDirectoryZip = TemporaryDirectory::make(); $temporaryDirectoryZip = TemporaryDirectory::make();
file_put_contents($temporaryDirectoryZip->path('import.zip'), $data); file_put_contents($temporaryDirectoryZip->path('import.zip'), $data);
$res = $zip->open($temporaryDirectoryZip->path('import.zip'), ZipArchive::RDONLY); $res = $zip->open($temporaryDirectoryZip->path('import.zip'), ZipArchive::RDONLY);
@@ -220,7 +220,7 @@ class SolidtimeImporter extends DefaultImporter
if ($timeEntryRow['task_id'] !== '') { if ($timeEntryRow['task_id'] !== '') {
$taskId = $this->taskImportHelper->getKeyByExternalIdentifier($timeEntryRow['task_id']); $taskId = $this->taskImportHelper->getKeyByExternalIdentifier($timeEntryRow['task_id']);
} }
$timeEntry = new TimeEntry(); $timeEntry = new TimeEntry;
$timeEntry->user_id = $userId; $timeEntry->user_id = $userId;
$timeEntry->member_id = $memberId; $timeEntry->member_id = $memberId;
$timeEntry->task_id = $taskId; $timeEntry->task_id = $taskId;

View File

@@ -23,7 +23,7 @@ class TogglDataImporter extends DefaultImporter
$temporaryDirectoryZip = null; $temporaryDirectoryZip = null;
$temporaryDirectory = null; $temporaryDirectory = null;
try { try {
$zip = new ZipArchive(); $zip = new ZipArchive;
$temporaryDirectoryZip = TemporaryDirectory::make(); $temporaryDirectoryZip = TemporaryDirectory::make();
file_put_contents($temporaryDirectoryZip->path('import.zip'), $data); file_put_contents($temporaryDirectoryZip->path('import.zip'), $data);
$res = $zip->open($temporaryDirectoryZip->path('import.zip'), ZipArchive::RDONLY); $res = $zip->open($temporaryDirectoryZip->path('import.zip'), ZipArchive::RDONLY);

View File

@@ -98,7 +98,7 @@ class TogglTimeEntriesImporter extends DefaultImporter
'organization_id' => $this->organization->id, 'organization_id' => $this->organization->id,
]); ]);
} }
$timeEntry = new TimeEntry(); $timeEntry = new TimeEntry;
$timeEntry->user_id = $userId; $timeEntry->user_id = $userId;
$timeEntry->member_id = $memberId; $timeEntry->member_id = $memberId;
$timeEntry->task_id = $taskId; $timeEntry->task_id = $taskId;

View File

@@ -25,12 +25,12 @@ class InvitationService
->whereRelation('user', 'email', '=', $email) ->whereRelation('user', 'email', '=', $email)
->where('role', '!=', Role::Placeholder->value) ->where('role', '!=', Role::Placeholder->value)
->exists()) { ->exists()) {
throw new UserIsAlreadyMemberOfOrganizationApiException(); throw new UserIsAlreadyMemberOfOrganizationApiException;
} }
InvitingTeamMember::dispatch($organization, $email, $role->value); InvitingTeamMember::dispatch($organization, $email, $role->value);
$invitation = new OrganizationInvitation(); $invitation = new OrganizationInvitation;
$invitation->email = $email; $invitation->email = $email;
$invitation->role = $role->value; $invitation->role = $role->value;
$invitation->organization()->associate($organization); $invitation->organization()->associate($organization);

View File

@@ -281,7 +281,7 @@ class TimeEntryAggregationService
if ($start->gt($end)) { if ($start->gt($end)) {
throw new \InvalidArgumentException('Start date must be before end date'); throw new \InvalidArgumentException('Start date must be before end date');
} }
$slots = new Collection(); $slots = new Collection;
$current = $start->copy()->timezone($timezone); $current = $start->copy()->timezone($timezone);
if ($interval === TimeEntryAggregationTypeInterval::Day) { if ($interval === TimeEntryAggregationTypeInterval::Day) {
$current->startOfDay(); $current->startOfDay();

View File

@@ -60,7 +60,7 @@ class UserService
} }
// Create a new organization // Create a new organization
$organization = new Organization(); $organization = new Organization;
$organization->name = $user->name."'s Organization"; $organization->name = $user->name."'s Organization";
$organization->personal_team = true; $organization->personal_team = true;
$organization->user_id = $user->id; $organization->user_id = $user->id;

View File

@@ -16,7 +16,7 @@
"inertiajs/inertia-laravel": "^1.0", "inertiajs/inertia-laravel": "^1.0",
"korridor/laravel-computed-attributes": "^3.1", "korridor/laravel-computed-attributes": "^3.1",
"korridor/laravel-model-validation-rules": "^3.0", "korridor/laravel-model-validation-rules": "^3.0",
"laravel/framework": "^11.0", "laravel/framework": "^11.16.0",
"laravel/jetstream": "^5.0", "laravel/jetstream": "^5.0",
"laravel/octane": "^2.3", "laravel/octane": "^2.3",
"laravel/passport": "^12.0", "laravel/passport": "^12.0",
@@ -29,7 +29,7 @@
"spatie/temporary-directory": "^2.2", "spatie/temporary-directory": "^2.2",
"stechstudio/filament-impersonate": "^3.8", "stechstudio/filament-impersonate": "^3.8",
"tightenco/ziggy": "^2.1.0", "tightenco/ziggy": "^2.1.0",
"tpetry/laravel-postgresql-enhanced": "^0.39.0", "tpetry/laravel-postgresql-enhanced": "^1.0.0",
"wikimedia/composer-merge-plugin": "^2.1.0" "wikimedia/composer-merge-plugin": "^2.1.0"
}, },
"require-dev": { "require-dev": {

1837
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,14 +29,14 @@ class AuditFactory extends Factory
return User::factory()->create()->id; return User::factory()->create()->id;
}, },
$morphPrefix.'_type' => function () { $morphPrefix.'_type' => function () {
return (new User())->getMorphClass(); return (new User)->getMorphClass();
}, },
'event' => 'updated', 'event' => 'updated',
'auditable_id' => function () { 'auditable_id' => function () {
return User::factory()->create()->getKey(); return User::factory()->create()->getKey();
}, },
'auditable_type' => function () { 'auditable_type' => function () {
return (new User())->getMorphClass(); return (new User)->getMorphClass();
}, },
'old_values' => [], 'old_values' => [],
'new_values' => [], 'new_values' => [],

View File

@@ -49,4 +49,11 @@ class OrganizationFactory extends Factory
'user_id' => $owner === null ? User::factory() : $owner->getKey(), 'user_id' => $owner === null ? User::factory() : $owner->getKey(),
]); ]);
} }
public function withFakeId(): self
{
return $this->state(fn (array $attributes) => [
'id' => $this->faker->uuid(),
]);
}
} }

View File

@@ -154,15 +154,15 @@ class DatabaseSeeder extends Seeder
private function deleteAll(): void private function deleteAll(): void
{ {
DB::table((new Audit())->getTable())->delete(); DB::table((new Audit)->getTable())->delete();
DB::table((new TimeEntry())->getTable())->delete(); DB::table((new TimeEntry)->getTable())->delete();
DB::table((new Task())->getTable())->delete(); DB::table((new Task)->getTable())->delete();
DB::table((new Tag())->getTable())->delete(); DB::table((new Tag)->getTable())->delete();
DB::table((new ProjectMember())->getTable())->delete(); DB::table((new ProjectMember)->getTable())->delete();
DB::table((new Project())->getTable())->delete(); DB::table((new Project)->getTable())->delete();
DB::table((new Client())->getTable())->delete(); DB::table((new Client)->getTable())->delete();
DB::table((new User())->getTable())->delete(); DB::table((new User)->getTable())->delete();
DB::table((new OrganizationInvitation())->getTable())->delete(); DB::table((new OrganizationInvitation)->getTable())->delete();
DB::table((new Organization())->getTable())->delete(); DB::table((new Organization)->getTable())->delete();
} }
} }

View File

@@ -6,6 +6,4 @@ namespace Tests\Unit\Endpoint\Api\V1;
use Tests\TestCaseWithDatabase; use Tests\TestCaseWithDatabase;
class ApiEndpointTestAbstract extends TestCaseWithDatabase class ApiEndpointTestAbstract extends TestCaseWithDatabase {}
{
}

View File

@@ -43,7 +43,7 @@ class ExportEndpointTest extends ApiEndpointTestAbstract
->withArgs(function (Organization $organization) use (&$user): bool { ->withArgs(function (Organization $organization) use (&$user): bool {
return $organization->is($user->organization); return $organization->is($user->organization);
}) })
->andThrow(new ExportException()) ->andThrow(new ExportException)
->once(); ->once();
}); });
Passport::actingAs($user->user); Passport::actingAs($user->user);

View File

@@ -6,6 +6,4 @@ namespace Tests\Unit\Endpoint\Web;
use Tests\TestCaseWithDatabase; use Tests\TestCaseWithDatabase;
abstract class EndpointTestAbstract extends TestCaseWithDatabase abstract class EndpointTestAbstract extends TestCaseWithDatabase {}
{
}

View File

@@ -32,7 +32,7 @@ class AuditResourceTest extends FilamentTestCase
// Arrange // Arrange
$user = $this->createUserWithPermission(); $user = $this->createUserWithPermission();
$timeEntry = TimeEntry::factory()->forMember($user->member)->create(); $timeEntry = TimeEntry::factory()->forMember($user->member)->create();
DB::table((new Audit())->getTable())->delete(); DB::table((new Audit)->getTable())->delete();
$audits = Audit::factory()->auditFor($timeEntry)->auditUser($user->user)->createMany(5); $audits = Audit::factory()->auditFor($timeEntry)->auditUser($user->user)->createMany(5);
// Act // Act
@@ -46,7 +46,7 @@ class AuditResourceTest extends FilamentTestCase
public function test_can_see_view_page_of_audit(): void public function test_can_see_view_page_of_audit(): void
{ {
// Arrange // Arrange
DB::table((new Audit())->getTable())->delete(); DB::table((new Audit)->getTable())->delete();
$audit = Audit::factory()->create(); $audit = Audit::factory()->create();
// Act // Act

View File

@@ -79,7 +79,7 @@ class UserResourceTest extends FilamentTestCase
$this->mock(DeletionService::class, function (MockInterface $mock) use ($user): void { $this->mock(DeletionService::class, function (MockInterface $mock) use ($user): void {
$mock->shouldReceive('deleteUser') $mock->shouldReceive('deleteUser')
->withArgs(fn (User $userArg) => $userArg->is($user->user)) ->withArgs(fn (User $userArg) => $userArg->is($user->user))
->andThrow(new CanNotDeleteUserWhoIsOwnerOfOrganizationWithMultipleMembers()); ->andThrow(new CanNotDeleteUserWhoIsOwnerOfOrganizationWithMultipleMembers);
}); });
// Act // Act

View File

@@ -26,6 +26,5 @@ class OrganizationModelTest extends ModelTestAbstract
// Assert // Assert
$this->assertNotNull($membersRel); $this->assertNotNull($membersRel);
$this->assertCount(3, $membersRel); $this->assertCount(3, $membersRel);
$this->assertTrue($membersRel->first()->is($members->first()));
} }
} }

View File

@@ -20,7 +20,7 @@ class ColorRuleTest extends TestCase
$validator = Validator::make([ $validator = Validator::make([
'color' => '#ef5350', 'color' => '#ef5350',
], [ ], [
'color' => [new ColorRule()], 'color' => [new ColorRule],
]); ]);
// Act // Act
@@ -38,7 +38,7 @@ class ColorRuleTest extends TestCase
$validator = Validator::make([ $validator = Validator::make([
'color' => true, 'color' => true,
], [ ], [
'color' => [new ColorRule()], 'color' => [new ColorRule],
]); ]);
// Act // Act
@@ -56,7 +56,7 @@ class ColorRuleTest extends TestCase
$validator = Validator::make([ $validator = Validator::make([
'color' => 'rgb(0,0,0)', 'color' => 'rgb(0,0,0)',
], [ ], [
'color' => [new ColorRule()], 'color' => [new ColorRule],
]); ]);
// Act // Act

View File

@@ -20,7 +20,7 @@ class CurrencyRuleTest extends TestCase
$validator = Validator::make([ $validator = Validator::make([
'currency' => 'EUR', 'currency' => 'EUR',
], [ ], [
'currency' => [new CurrencyRule()], 'currency' => [new CurrencyRule],
]); ]);
// Act // Act
@@ -38,7 +38,7 @@ class CurrencyRuleTest extends TestCase
$validator = Validator::make([ $validator = Validator::make([
'currency' => true, 'currency' => true,
], [ ], [
'currency' => [new CurrencyRule()], 'currency' => [new CurrencyRule],
]); ]);
// Act // Act
@@ -56,7 +56,7 @@ class CurrencyRuleTest extends TestCase
$validator = Validator::make([ $validator = Validator::make([
'currency' => 'XXX', 'currency' => 'XXX',
], [ ], [
'currency' => [new CurrencyRule()], 'currency' => [new CurrencyRule],
]); ]);
// Act // Act
@@ -74,7 +74,7 @@ class CurrencyRuleTest extends TestCase
$validator = Validator::make([ $validator = Validator::make([
'currency' => 'eur', 'currency' => 'eur',
], [ ], [
'currency' => [new CurrencyRule()], 'currency' => [new CurrencyRule],
]); ]);
// Act // Act

View File

@@ -23,7 +23,7 @@ class ClockifyProjectsImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new ClockifyProjectsImporter(); $importer = new ClockifyProjectsImporter;
$importer->init($organization); $importer->init($organization);
$data = Storage::disk('testfiles')->get('clockify_projects_import_test_1.csv'); $data = Storage::disk('testfiles')->get('clockify_projects_import_test_1.csv');
@@ -39,11 +39,11 @@ class ClockifyProjectsImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new ClockifyProjectsImporter(); $importer = new ClockifyProjectsImporter;
$importer->init($organization); $importer->init($organization);
$data = Storage::disk('testfiles')->get('clockify_projects_import_test_1.csv'); $data = Storage::disk('testfiles')->get('clockify_projects_import_test_1.csv');
$importer->importData($data, $timezone); $importer->importData($data, $timezone);
$importer = new ClockifyProjectsImporter(); $importer = new ClockifyProjectsImporter;
$importer->init($organization); $importer->init($organization);
// Act // Act

View File

@@ -23,7 +23,7 @@ class ClockifyTimeEntriesImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new ClockifyTimeEntriesImporter(); $importer = new ClockifyTimeEntriesImporter;
$importer->init($organization); $importer->init($organization);
$data = Storage::disk('testfiles')->get('clockify_time_entries_import_test_1.csv'); $data = Storage::disk('testfiles')->get('clockify_time_entries_import_test_1.csv');
@@ -47,11 +47,11 @@ class ClockifyTimeEntriesImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new ClockifyTimeEntriesImporter(); $importer = new ClockifyTimeEntriesImporter;
$importer->init($organization); $importer->init($organization);
$data = Storage::disk('testfiles')->get('clockify_time_entries_import_test_1.csv'); $data = Storage::disk('testfiles')->get('clockify_time_entries_import_test_1.csv');
$importer->importData($data, $timezone); $importer->importData($data, $timezone);
$importer = new ClockifyTimeEntriesImporter(); $importer = new ClockifyTimeEntriesImporter;
$importer->init($organization); $importer->init($organization);
// Act // Act

View File

@@ -17,7 +17,7 @@ class ImporterProviderTest extends TestCase
public function test_register_importer_can_register_a_new_importer_for_example_in_an_extension(): void public function test_register_importer_can_register_a_new_importer_for_example_in_an_extension(): void
{ {
// Arrange // Arrange
$provider = new ImporterProvider(); $provider = new ImporterProvider;
// Act // Act
$provider->registerImporter('some_provider_importer', ClockifyProjectsImporter::class); $provider->registerImporter('some_provider_importer', ClockifyProjectsImporter::class);
@@ -30,7 +30,7 @@ class ImporterProviderTest extends TestCase
public function test_get_importer_keys_return_the_keys_of_the_available_importers(): void public function test_get_importer_keys_return_the_keys_of_the_available_importers(): void
{ {
// Arrange // Arrange
$provider = new ImporterProvider(); $provider = new ImporterProvider;
// Act // Act
$keys = $provider->getImporterKeys(); $keys = $provider->getImporterKeys();

View File

@@ -204,7 +204,7 @@ class ImporterTestAbstract extends TestCase
{ {
$tempDir = TemporaryDirectory::make(); $tempDir = TemporaryDirectory::make();
$zipPath = $tempDir->path('test.zip'); $zipPath = $tempDir->path('test.zip');
$zip = new ZipArchive(); $zip = new ZipArchive;
$zip->open($zipPath, ZipArchive::CREATE); $zip->open($zipPath, ZipArchive::CREATE);
foreach (Storage::disk('testfiles')->allFiles($folder) as $file) { foreach (Storage::disk('testfiles')->allFiles($folder) as $file) {
$zip->addFile(Storage::disk('testfiles')->path($file), Str::of($file)->after($folder.'/')->value()); $zip->addFile(Storage::disk('testfiles')->path($file), Str::of($file)->after($folder.'/')->value());

View File

@@ -23,7 +23,7 @@ class SolidtimeImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new SolidtimeImporter(); $importer = new SolidtimeImporter;
$importer->init($organization); $importer->init($organization);
// Act // Act
@@ -44,7 +44,7 @@ class SolidtimeImporterTest extends ImporterTestAbstract
$zipPath = $this->createTestZip('solidtime_import_test_1'); $zipPath = $this->createTestZip('solidtime_import_test_1');
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$importer = new SolidtimeImporter(); $importer = new SolidtimeImporter;
$importer->init($organization); $importer->init($organization);
$data = file_get_contents($zipPath); $data = file_get_contents($zipPath);
@@ -69,11 +69,11 @@ class SolidtimeImporterTest extends ImporterTestAbstract
$zipPath = $this->createTestZip('solidtime_import_test_1'); $zipPath = $this->createTestZip('solidtime_import_test_1');
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$importer = new SolidtimeImporter(); $importer = new SolidtimeImporter;
$importer->init($organization); $importer->init($organization);
$data = file_get_contents($zipPath); $data = file_get_contents($zipPath);
$importer->importData($data, $timezone); $importer->importData($data, $timezone);
$importer = new SolidtimeImporter(); $importer = new SolidtimeImporter;
$importer->init($organization); $importer->init($organization);
// Act // Act

View File

@@ -23,7 +23,7 @@ class TogglDataImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new TogglDataImporter(); $importer = new TogglDataImporter;
$importer->init($organization); $importer->init($organization);
// Act // Act
@@ -44,7 +44,7 @@ class TogglDataImporterTest extends ImporterTestAbstract
$zipPath = $this->createTestZip('toggl_data_import_test_1'); $zipPath = $this->createTestZip('toggl_data_import_test_1');
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$importer = new TogglDataImporter(); $importer = new TogglDataImporter;
$importer->init($organization); $importer->init($organization);
$data = file_get_contents($zipPath); $data = file_get_contents($zipPath);
@@ -68,11 +68,11 @@ class TogglDataImporterTest extends ImporterTestAbstract
$zipPath = $this->createTestZip('toggl_data_import_test_1'); $zipPath = $this->createTestZip('toggl_data_import_test_1');
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$importer = new TogglDataImporter(); $importer = new TogglDataImporter;
$importer->init($organization); $importer->init($organization);
$data = file_get_contents($zipPath); $data = file_get_contents($zipPath);
$importer->importData($data, $timezone); $importer->importData($data, $timezone);
$importer = new TogglDataImporter(); $importer = new TogglDataImporter;
$importer->init($organization); $importer->init($organization);
// Act // Act

View File

@@ -24,7 +24,7 @@ class TogglTimeEntriesImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new TogglTimeEntriesImporter(); $importer = new TogglTimeEntriesImporter;
$importer->init($organization); $importer->init($organization);
$data = Storage::disk('testfiles')->get('toggl_time_entries_import_test_1.csv'); $data = Storage::disk('testfiles')->get('toggl_time_entries_import_test_1.csv');
@@ -52,11 +52,11 @@ class TogglTimeEntriesImporterTest extends ImporterTestAbstract
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$timezone = 'Europe/Vienna'; $timezone = 'Europe/Vienna';
$importer = new TogglTimeEntriesImporter(); $importer = new TogglTimeEntriesImporter;
$importer->init($organization); $importer->init($organization);
$data = Storage::disk('testfiles')->get('toggl_time_entries_import_test_1.csv'); $data = Storage::disk('testfiles')->get('toggl_time_entries_import_test_1.csv');
$importer->importData($data, $timezone); $importer->importData($data, $timezone);
$importer = new TogglTimeEntriesImporter(); $importer = new TogglTimeEntriesImporter;
$importer->init($organization); $importer->init($organization);
// Act // Act

View File

@@ -26,7 +26,7 @@ class PermissionStoreTest extends TestCase
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$user = User::factory()->create(); $user = User::factory()->create();
$organization->users()->attach($user, ['role' => Role::Employee->value]); $organization->users()->attach($user, ['role' => Role::Employee->value]);
$permissionStore = new PermissionStore(); $permissionStore = new PermissionStore;
// Act // Act
$result = $permissionStore->has($organization, 'permission'); $result = $permissionStore->has($organization, 'permission');
@@ -40,7 +40,7 @@ class PermissionStoreTest extends TestCase
// Arrange // Arrange
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$user = User::factory()->create(); $user = User::factory()->create();
$permissionStore = new PermissionStore(); $permissionStore = new PermissionStore;
$this->actingAs($user); $this->actingAs($user);
// Act // Act
@@ -56,7 +56,7 @@ class PermissionStoreTest extends TestCase
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$user = User::factory()->create(); $user = User::factory()->create();
$organization->users()->attach($user, ['role' => Role::Employee->value]); $organization->users()->attach($user, ['role' => Role::Employee->value]);
$permissionStore = new PermissionStore(); $permissionStore = new PermissionStore;
$this->actingAs($user); $this->actingAs($user);
// Act // Act
@@ -72,7 +72,7 @@ class PermissionStoreTest extends TestCase
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$user = User::factory()->create(); $user = User::factory()->create();
$organization->users()->attach($user, ['role' => Role::Employee->value]); $organization->users()->attach($user, ['role' => Role::Employee->value]);
$permissionStore = new PermissionStore(); $permissionStore = new PermissionStore;
$this->actingAs($user); $this->actingAs($user);
// Act // Act
@@ -88,7 +88,7 @@ class PermissionStoreTest extends TestCase
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$user = User::factory()->create(); $user = User::factory()->create();
$organization->users()->attach($user, ['role' => Role::Employee->value]); $organization->users()->attach($user, ['role' => Role::Employee->value]);
$permissionStore = new PermissionStore(); $permissionStore = new PermissionStore;
// Act // Act
$result = $permissionStore->getPermissions($organization); $result = $permissionStore->getPermissions($organization);
@@ -101,7 +101,7 @@ class PermissionStoreTest extends TestCase
{ {
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$user = User::factory()->create(); $user = User::factory()->create();
$permissionStore = new PermissionStore(); $permissionStore = new PermissionStore;
$this->actingAs($user); $this->actingAs($user);
// Act // Act
@@ -117,7 +117,7 @@ class PermissionStoreTest extends TestCase
$organization = Organization::factory()->create(); $organization = Organization::factory()->create();
$user = User::factory()->create(); $user = User::factory()->create();
$organization->users()->attach($user, ['role' => Role::Employee->value]); $organization->users()->attach($user, ['role' => Role::Employee->value]);
$permissionStore = new PermissionStore(); $permissionStore = new PermissionStore;
$this->actingAs($user); $this->actingAs($user);
// Act // Act