mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-17 04:32:15 +01:00
Updated dependencies; Major update laravel passport
This commit is contained in:
@@ -26,7 +26,7 @@ class CreateNewUser implements CreatesNewUsers
|
|||||||
/**
|
/**
|
||||||
* Create a newly registered user.
|
* Create a newly registered user.
|
||||||
*
|
*
|
||||||
* @param array<string, string> $input
|
* @param array<string, mixed> $input
|
||||||
*
|
*
|
||||||
* @throws ValidationException
|
* @throws ValidationException
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ namespace App\Actions\Fortify;
|
|||||||
|
|
||||||
use App\Enums\Weekday;
|
use App\Enums\Weekday;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@@ -59,8 +58,7 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
|||||||
$user->updateProfilePhoto($input['photo']);
|
$user->updateProfilePhoto($input['photo']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($input['email'] !== $user->email &&
|
if ($input['email'] !== $user->email) {
|
||||||
$user instanceof MustVerifyEmail) {
|
|
||||||
$user->forceFill([
|
$user->forceFill([
|
||||||
'name' => $input['name'],
|
'name' => $input['name'],
|
||||||
'email' => $input['email'],
|
'email' => $input['email'],
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class AddOrganizationMember implements AddsTeamMembers
|
|||||||
*/
|
*/
|
||||||
protected function rules(): array
|
protected function rules(): array
|
||||||
{
|
{
|
||||||
return array_filter([
|
return [
|
||||||
'email' => [
|
'email' => [
|
||||||
'required',
|
'required',
|
||||||
'email',
|
'email',
|
||||||
@@ -75,7 +75,7 @@ class AddOrganizationMember implements AddsTeamMembers
|
|||||||
Role::Employee->value,
|
Role::Employee->value,
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
]);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ class PaginatedResourceCollectionTypeToSchema extends TypeToSchemaExtension
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! ($collectingType = $this->openApiTransformer->transform($collectingClassType))) {
|
$collectingType = $this->openApiTransformer->transform($collectingClassType);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$newType = new OpenApiObjectType;
|
$newType = new OpenApiObjectType;
|
||||||
$newType->addProperty('data', (new ArrayType)->setItems($collectingType));
|
$newType->addProperty('data', (new ArrayType)->setItems($collectingType));
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class TokenResource extends Resource
|
|||||||
->label('Name')
|
->label('Name')
|
||||||
->required()
|
->required()
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
Forms\Components\Select::make('user_id')
|
Forms\Components\Select::make('owner_id')
|
||||||
->label('User')
|
->label('User')
|
||||||
->relationship(name: 'user', titleAttribute: 'name')
|
->relationship(name: 'user', titleAttribute: 'name')
|
||||||
->searchable(['name'])
|
->searchable(['name'])
|
||||||
@@ -79,10 +79,12 @@ class TokenResource extends Resource
|
|||||||
Tables\Columns\TextColumn::make('client.name')
|
Tables\Columns\TextColumn::make('client.name')
|
||||||
->searchable()
|
->searchable()
|
||||||
->sortable(),
|
->sortable(),
|
||||||
Tables\Columns\IconColumn::make('client.personal_access_client')
|
Tables\Columns\IconColumn::make('personal_access_client')
|
||||||
|
->state(function (Token $token): bool {
|
||||||
|
return in_array('personal_access', $token->client->grant_types ?? [], true);
|
||||||
|
})
|
||||||
->boolean()
|
->boolean()
|
||||||
->label('API token?')
|
->label('API token?'),
|
||||||
->sortable(),
|
|
||||||
Tables\Columns\IconColumn::make('revoked')
|
Tables\Columns\IconColumn::make('revoked')
|
||||||
->boolean()
|
->boolean()
|
||||||
->label('Revoked?')
|
->label('Revoked?')
|
||||||
@@ -106,14 +108,14 @@ class TokenResource extends Resource
|
|||||||
/** @var Builder<Token> $query */
|
/** @var Builder<Token> $query */
|
||||||
return $query->whereHas('client', function (Builder $query) {
|
return $query->whereHas('client', function (Builder $query) {
|
||||||
/** @var Builder<Client> $query */
|
/** @var Builder<Client> $query */
|
||||||
return $query->where('personal_access_client', true);
|
return $query->whereJsonContains('grant_types', 'personal_access');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
false: function (Builder $query) {
|
false: function (Builder $query) {
|
||||||
/** @var Builder<Token> $query */
|
/** @var Builder<Token> $query */
|
||||||
return $query->whereHas('client', function (Builder $query) {
|
return $query->whereHas('client', function (Builder $query) {
|
||||||
/** @var Builder<Client> $query */
|
/** @var Builder<Client> $query */
|
||||||
return $query->where('personal_access_client', false);
|
return $query->whereJsonDoesntContain('grant_types', 'personal_access');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
blank: function (Builder $query) {
|
blank: function (Builder $query) {
|
||||||
|
|||||||
@@ -8,9 +8,12 @@ use App\Exceptions\Api\PersonalAccessClientIsNotConfiguredException;
|
|||||||
use App\Http\Requests\V1\ApiToken\ApiTokenStoreRequest;
|
use App\Http\Requests\V1\ApiToken\ApiTokenStoreRequest;
|
||||||
use App\Http\Resources\V1\ApiToken\ApiTokenCollection;
|
use App\Http\Resources\V1\ApiToken\ApiTokenCollection;
|
||||||
use App\Http\Resources\V1\ApiToken\ApiTokenWithAccessTokenResource;
|
use App\Http\Resources\V1\ApiToken\ApiTokenWithAccessTokenResource;
|
||||||
|
use App\Models\Passport\Client;
|
||||||
use App\Models\Passport\Token;
|
use App\Models\Passport\Token;
|
||||||
use Illuminate\Auth\Access\AuthorizationException;
|
use Illuminate\Auth\Access\AuthorizationException;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class ApiTokenController extends Controller
|
class ApiTokenController extends Controller
|
||||||
{
|
{
|
||||||
@@ -28,7 +31,10 @@ class ApiTokenController extends Controller
|
|||||||
$user = $this->user();
|
$user = $this->user();
|
||||||
|
|
||||||
$tokens = $user->tokens()
|
$tokens = $user->tokens()
|
||||||
->where('client_id', '=', config('passport.personal_access_client.id'))
|
->whereHas('client', function (Builder $query): void {
|
||||||
|
/** @var Builder<Client> $query */
|
||||||
|
$query->whereJsonContains('grant_types', 'personal_access');
|
||||||
|
})
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
return new ApiTokenCollection($tokens);
|
return new ApiTokenCollection($tokens);
|
||||||
@@ -48,15 +54,21 @@ class ApiTokenController extends Controller
|
|||||||
{
|
{
|
||||||
$user = $this->user();
|
$user = $this->user();
|
||||||
|
|
||||||
if (config('passport.personal_access_client.id') === null || config('passport.personal_access_client.secret') === null) {
|
try {
|
||||||
throw new PersonalAccessClientIsNotConfiguredException;
|
$token = $user->createToken($request->getName(), ['*']);
|
||||||
|
|
||||||
|
/** @var Token $tokenModel */
|
||||||
|
$tokenModel = $token->getToken();
|
||||||
|
|
||||||
|
return new ApiTokenWithAccessTokenResource($tokenModel, $token->accessToken);
|
||||||
|
} catch (\RuntimeException $exception) {
|
||||||
|
report($exception);
|
||||||
|
if (Str::contains($exception->getMessage(), ['Personal access client not found'])) {
|
||||||
|
throw new PersonalAccessClientIsNotConfiguredException;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = $user->createToken($request->getName(), ['*']);
|
|
||||||
/** @var Token $tokenModel */
|
|
||||||
$tokenModel = $token->token;
|
|
||||||
|
|
||||||
return new ApiTokenWithAccessTokenResource($tokenModel, $token->accessToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,13 +83,10 @@ class ApiTokenController extends Controller
|
|||||||
{
|
{
|
||||||
$user = $this->user();
|
$user = $this->user();
|
||||||
|
|
||||||
if (config('passport.personal_access_client.id') === null || config('passport.personal_access_client.secret') === null) {
|
|
||||||
throw new PersonalAccessClientIsNotConfiguredException;
|
|
||||||
}
|
|
||||||
if ($apiToken->user_id !== $user->getKey()) {
|
if ($apiToken->user_id !== $user->getKey()) {
|
||||||
throw new AuthorizationException('API token does not belong to user');
|
throw new AuthorizationException('API token does not belong to user');
|
||||||
}
|
}
|
||||||
if ($apiToken->client_id !== config('passport.personal_access_client.id')) {
|
if (! ($apiToken->client?->hasGrantType('personal_access') ?? false)) {
|
||||||
throw new AuthorizationException('API token is not a personal access token');
|
throw new AuthorizationException('API token is not a personal access token');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,13 +106,10 @@ class ApiTokenController extends Controller
|
|||||||
{
|
{
|
||||||
$user = $this->user();
|
$user = $this->user();
|
||||||
|
|
||||||
if (config('passport.personal_access_client.id') === null || config('passport.personal_access_client.secret') === null) {
|
|
||||||
throw new PersonalAccessClientIsNotConfiguredException;
|
|
||||||
}
|
|
||||||
if ($apiToken->user_id !== $user->getKey()) {
|
if ($apiToken->user_id !== $user->getKey()) {
|
||||||
throw new AuthorizationException('API token does not belong to user');
|
throw new AuthorizationException('API token does not belong to user');
|
||||||
}
|
}
|
||||||
if ($apiToken->client_id !== config('passport.personal_access_client.id')) {
|
if (! ($apiToken->client?->hasGrantType('personal_access') ?? false)) {
|
||||||
throw new AuthorizationException('API token is not a personal access token');
|
throw new AuthorizationException('API token is not a personal access token');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Redirect;
|
use Illuminate\Support\Facades\Redirect;
|
||||||
use Illuminate\Support\Facades\URL;
|
use Illuminate\Support\Facades\URL;
|
||||||
@@ -20,8 +19,7 @@ class EnsureEmailIsVerified
|
|||||||
{
|
{
|
||||||
if (! app()->isLocal()) {
|
if (! app()->isLocal()) {
|
||||||
if ($request->user() === null ||
|
if ($request->user() === null ||
|
||||||
($request->user() instanceof MustVerifyEmail &&
|
(! $request->user()->hasVerifiedEmail())) {
|
||||||
! $request->user()->hasVerifiedEmail())) {
|
|
||||||
return $request->expectsJson()
|
return $request->expectsJson()
|
||||||
? abort(403, 'Your email address is not verified.')
|
? abort(403, 'Your email address is not verified.')
|
||||||
: Redirect::guest(URL::route($redirectToRoute ?: 'verification.notice'));
|
: Redirect::guest(URL::route($redirectToRoute ?: 'verification.notice'));
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class HandleInertiaRequests extends Middleware
|
|||||||
return array_merge(parent::share($request), [
|
return array_merge(parent::share($request), [
|
||||||
'has_billing_extension' => $hasBilling,
|
'has_billing_extension' => $hasBilling,
|
||||||
'has_invoicing_extension' => $hasInvoicing,
|
'has_invoicing_extension' => $hasInvoicing,
|
||||||
'billing' => $billing !== null && $currentOrganization !== null ? [
|
'billing' => $currentOrganization !== null ? [
|
||||||
'has_subscription' => $billing->hasSubscription($currentOrganization),
|
'has_subscription' => $billing->hasSubscription($currentOrganization),
|
||||||
'has_trial' => $billing->hasTrial($currentOrganization),
|
'has_trial' => $billing->hasTrial($currentOrganization),
|
||||||
'trial_until' => $billing->getTrialUntil($currentOrganization)?->toIso8601ZuluString(),
|
'trial_until' => $billing->getTrialUntil($currentOrganization)?->toIso8601ZuluString(),
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class ShareInertiaData
|
|||||||
{
|
{
|
||||||
/** @var PermissionStore $permissions */
|
/** @var PermissionStore $permissions */
|
||||||
$permissions = app(PermissionStore::class);
|
$permissions = app(PermissionStore::class);
|
||||||
Inertia::share(array_filter([
|
Inertia::share([
|
||||||
'jetstream' => function () use ($request) {
|
'jetstream' => function () use ($request) {
|
||||||
/** @var User|null $user */
|
/** @var User|null $user */
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
@@ -101,7 +101,7 @@ class ShareInertiaData
|
|||||||
return [$key => $bag->messages()];
|
return [$key => $bag->messages()];
|
||||||
})->all();
|
})->all();
|
||||||
},
|
},
|
||||||
]));
|
]);
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,11 @@ use App\Http\Resources\PaginatedResourceCollection;
|
|||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
|
||||||
|
|
||||||
class ProjectCollection extends ResourceCollection implements PaginatedResourceCollection
|
class ProjectCollection extends ResourceCollection implements PaginatedResourceCollection
|
||||||
{
|
{
|
||||||
private bool $showBillableRates;
|
private bool $showBillableRates;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param LengthAwarePaginator<Project> $resource
|
|
||||||
*/
|
|
||||||
public function __construct($resource, bool $showBillableRates)
|
public function __construct($resource, bool $showBillableRates)
|
||||||
{
|
{
|
||||||
parent::__construct($resource);
|
parent::__construct($resource);
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ use OwenIt\Auditing\Models\Audit as PackageAuditModel;
|
|||||||
* @property string $event
|
* @property string $event
|
||||||
* @property string $auditable_type
|
* @property string $auditable_type
|
||||||
* @property string $auditable_id
|
* @property string $auditable_id
|
||||||
* @property array|null $old_values
|
* @property array<string, mixed>|null $old_values
|
||||||
* @property array|null $new_values
|
* @property array<string, mixed>|null $new_values
|
||||||
* @property string|null $url
|
* @property string|null $url
|
||||||
* @property string|null $ip_address
|
* @property string|null $ip_address
|
||||||
* @property string|null $user_agent
|
* @property string|null $user_agent
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Client extends Model implements AuditableContract
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, Client>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ class Client extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<Project>
|
* @return HasMany<Project, $this>
|
||||||
*/
|
*/
|
||||||
public function projects(): HasMany
|
public function projects(): HasMany
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
|
|||||||
* @property Carbon|null $updated_at
|
* @property Carbon|null $updated_at
|
||||||
* @property-read Organization $organization
|
* @property-read Organization $organization
|
||||||
* @property-read User $user
|
* @property-read User $user
|
||||||
* @property-read Collection<ProjectMember> $projectMembers
|
* @property-read Collection<int, ProjectMember> $projectMembers
|
||||||
* @property-read Collection<TimeEntry> $timeEntries
|
* @property-read Collection<int, TimeEntry> $timeEntries
|
||||||
*
|
*
|
||||||
* @method static MemberFactory factory()
|
* @method static MemberFactory factory()
|
||||||
*/
|
*/
|
||||||
@@ -47,7 +47,7 @@ class Member extends JetstreamMembership implements AuditableContract
|
|||||||
protected $table = 'members';
|
protected $table = 'members';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<User, Member>
|
* @return BelongsTo<User, $this>
|
||||||
*/
|
*/
|
||||||
public function user(): BelongsTo
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ class Member extends JetstreamMembership implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, Member>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -63,7 +63,7 @@ class Member extends JetstreamMembership implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<TimeEntry>
|
* @return HasMany<TimeEntry, $this>
|
||||||
*/
|
*/
|
||||||
public function timeEntries(): HasMany
|
public function timeEntries(): HasMany
|
||||||
{
|
{
|
||||||
@@ -71,7 +71,7 @@ class Member extends JetstreamMembership implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<ProjectMember>
|
* @return HasMany<ProjectMember, $this>
|
||||||
*/
|
*/
|
||||||
public function projectMembers(): HasMany
|
public function projectMembers(): HasMany
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
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\Database\Eloquent\Relations\Pivot;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Laravel\Jetstream\Events\TeamCreated;
|
use Laravel\Jetstream\Events\TeamCreated;
|
||||||
@@ -47,7 +48,7 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
|
|||||||
* @property IntervalFormat $interval_format
|
* @property IntervalFormat $interval_format
|
||||||
* @property TimeFormat $time_format
|
* @property TimeFormat $time_format
|
||||||
*
|
*
|
||||||
* @method HasMany<OrganizationInvitation> teamInvitations()
|
* @method HasMany<OrganizationInvitation, $this> teamInvitations()
|
||||||
* @method static OrganizationFactory factory()
|
* @method static OrganizationFactory factory()
|
||||||
*/
|
*/
|
||||||
class Organization extends JetstreamTeam implements AuditableContract
|
class Organization extends JetstreamTeam implements AuditableContract
|
||||||
@@ -79,7 +80,7 @@ class Organization extends JetstreamTeam implements AuditableContract
|
|||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var list<string>
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'name',
|
||||||
@@ -125,7 +126,7 @@ class Organization extends JetstreamTeam implements AuditableContract
|
|||||||
/**
|
/**
|
||||||
* Get all the users that belong to the team.
|
* Get all the users that belong to the team.
|
||||||
*
|
*
|
||||||
* @return BelongsToMany<User>
|
* @return BelongsToMany<User, $this, Pivot, 'membership'>
|
||||||
*/
|
*/
|
||||||
public function users(): BelongsToMany
|
public function users(): BelongsToMany
|
||||||
{
|
{
|
||||||
@@ -142,7 +143,7 @@ class Organization extends JetstreamTeam implements AuditableContract
|
|||||||
/**
|
/**
|
||||||
* Get the owner of the team.
|
* Get the owner of the team.
|
||||||
*
|
*
|
||||||
* @return BelongsTo<User, Organization>
|
* @return BelongsTo<User, $this>
|
||||||
*/
|
*/
|
||||||
public function owner(): BelongsTo
|
public function owner(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -150,7 +151,7 @@ class Organization extends JetstreamTeam implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<Member>
|
* @return HasMany<Member, $this>
|
||||||
*/
|
*/
|
||||||
public function members(): HasMany
|
public function members(): HasMany
|
||||||
{
|
{
|
||||||
@@ -158,7 +159,7 @@ class Organization extends JetstreamTeam implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsToMany<User>
|
* @return BelongsToMany<User, $this, Pivot, 'membership'>
|
||||||
*/
|
*/
|
||||||
public function realUsers(): BelongsToMany
|
public function realUsers(): BelongsToMany
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class OrganizationInvitation extends JetstreamTeamInvitation implements Auditabl
|
|||||||
/**
|
/**
|
||||||
* Get the organization that the invitation belongs to.
|
* Get the organization that the invitation belongs to.
|
||||||
*
|
*
|
||||||
* @return BelongsTo<Organization, OrganizationInvitation>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -63,7 +63,7 @@ class OrganizationInvitation extends JetstreamTeamInvitation implements Auditabl
|
|||||||
/**
|
/**
|
||||||
* Get the organization that the invitation belongs to.
|
* Get the organization that the invitation belongs to.
|
||||||
*
|
*
|
||||||
* @return BelongsTo<Organization, OrganizationInvitation>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function team(): BelongsTo
|
public function team(): BelongsTo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,26 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Models\Passport;
|
namespace App\Models\Passport;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
use Laravel\Passport\AuthCode as PassportAuthCode;
|
use Laravel\Passport\AuthCode as PassportAuthCode;
|
||||||
|
|
||||||
class AuthCode extends PassportAuthCode {}
|
/**
|
||||||
|
* @property string $id
|
||||||
|
* @property string $user_id
|
||||||
|
* @property string $client_id
|
||||||
|
* @property string|null $scopes
|
||||||
|
* @property bool $revoked
|
||||||
|
* @property Carbon $expires_at
|
||||||
|
*/
|
||||||
|
class AuthCode extends PassportAuthCode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<User, $this>
|
||||||
|
*/
|
||||||
|
public function user(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'user_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,22 +5,36 @@ declare(strict_types=1);
|
|||||||
namespace App\Models\Passport;
|
namespace App\Models\Passport;
|
||||||
|
|
||||||
use Database\Factories\Passport\ClientFactory;
|
use Database\Factories\Passport\ClientFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
use Laravel\Passport\Client as PassportClient;
|
use Laravel\Passport\Client as PassportClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property string $id
|
* @property string $id
|
||||||
* @property string|null $user_id
|
* @property string|null $owner_id
|
||||||
|
* @property string|null $owner_type
|
||||||
* @property string $name
|
* @property string $name
|
||||||
* @property string|null $secret
|
* @property string|null $secret
|
||||||
* @property string|null $provider
|
* @property string|null $provider
|
||||||
* @property string $redirect
|
* @property array<string> $grant_types
|
||||||
* @property bool $personal_access_client
|
* @property array<string> $redirect_uris
|
||||||
* @property bool $password_client
|
* @property Carbon|null $created_at
|
||||||
|
* @property Carbon|null $updated_at
|
||||||
* @property bool $revoked
|
* @property bool $revoked
|
||||||
*/
|
*/
|
||||||
class Client extends PassportClient
|
class Client extends PassportClient
|
||||||
{
|
{
|
||||||
/** @use HasFactory<ClientFactory> */
|
/** @use HasFactory<ClientFactory> */
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new factory instance for the model.
|
||||||
|
*
|
||||||
|
* @return ClientFactory
|
||||||
|
*/
|
||||||
|
protected static function newFactory(): Factory
|
||||||
|
{
|
||||||
|
return ClientFactory::new();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Models\Passport;
|
|
||||||
|
|
||||||
use Laravel\Passport\PersonalAccessClient as PassportPersonalAccessClient;
|
|
||||||
|
|
||||||
class PersonalAccessClient extends PassportPersonalAccessClient {}
|
|
||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Models\Passport;
|
namespace App\Models\Passport;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
use Database\Factories\Passport\TokenFactory;
|
use Database\Factories\Passport\TokenFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
@@ -20,6 +21,8 @@ use Laravel\Passport\Token as PassportToken;
|
|||||||
* @property Carbon|null $created_at
|
* @property Carbon|null $created_at
|
||||||
* @property Carbon|null $updated_at
|
* @property Carbon|null $updated_at
|
||||||
* @property Carbon|null $expires_at
|
* @property Carbon|null $expires_at
|
||||||
|
* @property-read Client|null $client
|
||||||
|
* @property-read User|null $user
|
||||||
*/
|
*/
|
||||||
class Token extends PassportToken
|
class Token extends PassportToken
|
||||||
{
|
{
|
||||||
@@ -29,10 +32,24 @@ class Token extends PassportToken
|
|||||||
/**
|
/**
|
||||||
* Get the client that the token belongs to.
|
* Get the client that the token belongs to.
|
||||||
*
|
*
|
||||||
* @return BelongsTo<Client, Token>
|
* @return BelongsTo<Client, $this>
|
||||||
*/
|
*/
|
||||||
|
// @phpstan-ignore method.childReturnType
|
||||||
public function client(): BelongsTo
|
public function client(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Client::class, 'client_id', 'id');
|
return $this->belongsTo(Client::class, 'client_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user that the token belongs to.
|
||||||
|
*
|
||||||
|
* @deprecated Will be removed in a future Laravel version.
|
||||||
|
*
|
||||||
|
* @return BelongsTo<User, $this>
|
||||||
|
*/
|
||||||
|
// @phpstan-ignore method.childReturnType
|
||||||
|
public function user(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'user_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class Project extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, Project>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -145,7 +145,7 @@ class Project extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Client, Project>
|
* @return BelongsTo<Client, $this>
|
||||||
*/
|
*/
|
||||||
public function client(): BelongsTo
|
public function client(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -153,7 +153,7 @@ class Project extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<ProjectMember>
|
* @return HasMany<ProjectMember, $this>
|
||||||
*/
|
*/
|
||||||
public function members(): HasMany
|
public function members(): HasMany
|
||||||
{
|
{
|
||||||
@@ -161,7 +161,7 @@ class Project extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<Task>
|
* @return HasMany<Task, $this>
|
||||||
*/
|
*/
|
||||||
public function tasks(): HasMany
|
public function tasks(): HasMany
|
||||||
{
|
{
|
||||||
@@ -169,7 +169,7 @@ class Project extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<TimeEntry>
|
* @return HasMany<TimeEntry, $this>
|
||||||
*/
|
*/
|
||||||
public function timeEntries(): HasMany
|
public function timeEntries(): HasMany
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class ProjectMember extends Model implements AuditableContract
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Project, ProjectMember>
|
* @return BelongsTo<Project, $this>
|
||||||
*/
|
*/
|
||||||
public function project(): BelongsTo
|
public function project(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -58,7 +58,7 @@ class ProjectMember extends Model implements AuditableContract
|
|||||||
/**
|
/**
|
||||||
* @deprecated Use member relationship instead
|
* @deprecated Use member relationship instead
|
||||||
*
|
*
|
||||||
* @return BelongsTo<User, ProjectMember>
|
* @return BelongsTo<User, $this>
|
||||||
*/
|
*/
|
||||||
public function user(): BelongsTo
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -66,7 +66,7 @@ class ProjectMember extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Member, ProjectMember>
|
* @return BelongsTo<Member, $this>
|
||||||
*/
|
*/
|
||||||
public function member(): BelongsTo
|
public function member(): BelongsTo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class Report extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, Report>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use Staudenmeir\EloquentJsonRelations\Relations\HasManyJson;
|
|||||||
* @property string $organization_id
|
* @property string $organization_id
|
||||||
* @property Carbon|null $created_at
|
* @property Carbon|null $created_at
|
||||||
* @property Carbon|null $updated_at
|
* @property Carbon|null $updated_at
|
||||||
* @property-read Collection<TimeEntry> $timeEntries
|
* @property-read Collection<int, TimeEntry> $timeEntries
|
||||||
* @property-read Organization $organization
|
* @property-read Organization $organization
|
||||||
*
|
*
|
||||||
* @method static TagFactory factory()
|
* @method static TagFactory factory()
|
||||||
@@ -47,7 +47,7 @@ class Tag extends Model implements AuditableContract
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, Tag>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class Task extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Project, Task>
|
* @return BelongsTo<Project, $this>
|
||||||
*/
|
*/
|
||||||
public function project(): BelongsTo
|
public function project(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -128,7 +128,7 @@ class Task extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, Task>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -136,7 +136,7 @@ class Task extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<TimeEntry>
|
* @return HasMany<TimeEntry, $this>
|
||||||
*/
|
*/
|
||||||
public function timeEntries(): HasMany
|
public function timeEntries(): HasMany
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ use Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson;
|
|||||||
* @property Carbon|null $end
|
* @property Carbon|null $end
|
||||||
* @property int|null $billable_rate Billable rate per hour in cents
|
* @property int|null $billable_rate Billable rate per hour in cents
|
||||||
* @property bool $billable
|
* @property bool $billable
|
||||||
* @property array $tags
|
* @property array<string> $tags
|
||||||
* @property string $user_id
|
* @property string $user_id
|
||||||
* @property string $member_id
|
* @property string $member_id
|
||||||
* @property bool $is_imported
|
* @property bool $is_imported
|
||||||
@@ -45,7 +45,7 @@ use Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson;
|
|||||||
* @property-read Client|null $client
|
* @property-read Client|null $client
|
||||||
* @property string|null $task_id
|
* @property string|null $task_id
|
||||||
* @property-read Task|null $task
|
* @property-read Task|null $task
|
||||||
* @property-read Collection<Tag> $tagsRelation
|
* @property-read Collection<int, Tag> $tagsRelation
|
||||||
*
|
*
|
||||||
* @method Builder<TimeEntry> hasTag(Tag $tag)
|
* @method Builder<TimeEntry> hasTag(Tag $tag)
|
||||||
* @method static TimeEntryFactory factory()
|
* @method static TimeEntryFactory factory()
|
||||||
@@ -154,7 +154,7 @@ class TimeEntry extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<User, TimeEntry>
|
* @return BelongsTo<User, $this>
|
||||||
*/
|
*/
|
||||||
public function user(): BelongsTo
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -162,7 +162,7 @@ class TimeEntry extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Member, TimeEntry>
|
* @return BelongsTo<Member, $this>
|
||||||
*/
|
*/
|
||||||
public function member(): BelongsTo
|
public function member(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -170,7 +170,7 @@ class TimeEntry extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, TimeEntry>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function organization(): BelongsTo
|
public function organization(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -178,7 +178,7 @@ class TimeEntry extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Project, TimeEntry>
|
* @return BelongsTo<Project, $this>
|
||||||
*/
|
*/
|
||||||
public function project(): BelongsTo
|
public function project(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -186,7 +186,7 @@ class TimeEntry extends Model implements AuditableContract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Task, TimeEntry>
|
* @return BelongsTo<Task, $this>
|
||||||
*/
|
*/
|
||||||
public function task(): BelongsTo
|
public function task(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -196,7 +196,7 @@ class TimeEntry extends Model implements AuditableContract
|
|||||||
/**
|
/**
|
||||||
* This relation can be reconstructed via the task relation. It is only here for performance reasons.
|
* This relation can be reconstructed via the task relation. It is only here for performance reasons.
|
||||||
*
|
*
|
||||||
* @return BelongsTo<Client, TimeEntry>
|
* @return BelongsTo<Client, $this>
|
||||||
*/
|
*/
|
||||||
public function client(): BelongsTo
|
public function client(): BelongsTo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
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\Database\Eloquent\Relations\Pivot;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
@@ -27,6 +28,7 @@ use Laravel\Fortify\TwoFactorAuthenticatable;
|
|||||||
use Laravel\Jetstream\HasProfilePhoto;
|
use Laravel\Jetstream\HasProfilePhoto;
|
||||||
use Laravel\Jetstream\HasTeams;
|
use Laravel\Jetstream\HasTeams;
|
||||||
use Laravel\Passport\AuthCode;
|
use Laravel\Passport\AuthCode;
|
||||||
|
use Laravel\Passport\Contracts\OAuthenticatable;
|
||||||
use Laravel\Passport\HasApiTokens;
|
use Laravel\Passport\HasApiTokens;
|
||||||
use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
|
use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
|
||||||
|
|
||||||
@@ -52,13 +54,13 @@ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
|
|||||||
* @property Collection<int, TimeEntry> $timeEntries
|
* @property Collection<int, TimeEntry> $timeEntries
|
||||||
* @property Member $membership
|
* @property Member $membership
|
||||||
*
|
*
|
||||||
* @method HasMany<Organization> ownedTeams()
|
* @method HasMany<Organization, $this> ownedTeams()
|
||||||
* @method static UserFactory factory()
|
* @method static UserFactory factory()
|
||||||
* @method static Builder<User> query()
|
* @method static Builder<User> query()
|
||||||
* @method Builder<User> belongsToOrganization(Organization $organization)
|
* @method Builder<User> belongsToOrganization(Organization $organization)
|
||||||
* @method Builder<User> active()
|
* @method Builder<User> active()
|
||||||
*/
|
*/
|
||||||
class User extends Authenticatable implements AuditableContract, FilamentUser, MustVerifyEmail
|
class User extends Authenticatable implements AuditableContract, FilamentUser, MustVerifyEmail, OAuthenticatable
|
||||||
{
|
{
|
||||||
use CustomAuditable;
|
use CustomAuditable;
|
||||||
use HasApiTokens;
|
use HasApiTokens;
|
||||||
@@ -75,7 +77,7 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var list<string>
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'name',
|
||||||
@@ -86,7 +88,7 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
/**
|
/**
|
||||||
* The attributes that should be hidden for serialization.
|
* The attributes that should be hidden for serialization.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var list<string>
|
||||||
*/
|
*/
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'password',
|
'password',
|
||||||
@@ -143,7 +145,7 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsToMany<Organization>
|
* @return BelongsToMany<Organization, $this, Pivot, 'membership'>
|
||||||
*/
|
*/
|
||||||
public function organizations(): BelongsToMany
|
public function organizations(): BelongsToMany
|
||||||
{
|
{
|
||||||
@@ -158,7 +160,7 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<TimeEntry>
|
* @return HasMany<TimeEntry, $this>
|
||||||
*/
|
*/
|
||||||
public function timeEntries(): HasMany
|
public function timeEntries(): HasMany
|
||||||
{
|
{
|
||||||
@@ -166,7 +168,7 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Organization, User>
|
* @return BelongsTo<Organization, $this>
|
||||||
*/
|
*/
|
||||||
public function currentOrganization(): BelongsTo
|
public function currentOrganization(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -174,7 +176,7 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<ProjectMember>
|
* @return HasMany<ProjectMember, $this>
|
||||||
*/
|
*/
|
||||||
public function projectMembers(): HasMany
|
public function projectMembers(): HasMany
|
||||||
{
|
{
|
||||||
@@ -182,7 +184,7 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<Token>
|
* @return HasMany<Token, $this>
|
||||||
*/
|
*/
|
||||||
public function accessTokens(): HasMany
|
public function accessTokens(): HasMany
|
||||||
{
|
{
|
||||||
@@ -190,24 +192,13 @@ class User extends Authenticatable implements AuditableContract, FilamentUser, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return HasMany<AuthCode>
|
* @return HasMany<AuthCode, $this>
|
||||||
*/
|
*/
|
||||||
public function authCodes(): HasMany
|
public function authCodes(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(AuthCode::class);
|
return $this->hasMany(AuthCode::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the access tokens for the user.
|
|
||||||
*
|
|
||||||
* @return HasMany<Token>
|
|
||||||
*/
|
|
||||||
public function tokens(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Token::class, 'user_id')
|
|
||||||
->orderBy('created_at', 'desc');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Builder<User> $builder
|
* @param Builder<User> $builder
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace App\Providers;
|
|||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
use App\Models\Passport\AuthCode;
|
use App\Models\Passport\AuthCode;
|
||||||
use App\Models\Passport\Client;
|
use App\Models\Passport\Client;
|
||||||
use App\Models\Passport\PersonalAccessClient;
|
|
||||||
use App\Models\Passport\RefreshToken;
|
use App\Models\Passport\RefreshToken;
|
||||||
use App\Models\Passport\Token;
|
use App\Models\Passport\Token;
|
||||||
use App\Policies\OrganizationPolicy;
|
use App\Policies\OrganizationPolicy;
|
||||||
@@ -51,7 +50,8 @@ class AuthServiceProvider extends ServiceProvider
|
|||||||
Passport::useRefreshTokenModel(RefreshToken::class);
|
Passport::useRefreshTokenModel(RefreshToken::class);
|
||||||
Passport::useAuthCodeModel(AuthCode::class);
|
Passport::useAuthCodeModel(AuthCode::class);
|
||||||
Passport::useClientModel(Client::class);
|
Passport::useClientModel(Client::class);
|
||||||
Passport::usePersonalAccessClientModel(PersonalAccessClient::class);
|
|
||||||
|
Passport::authorizationView('auth.oauth.authorize');
|
||||||
|
|
||||||
// Passport::tokensExpireIn(now()->addDays(15));
|
// Passport::tokensExpireIn(now()->addDays(15));
|
||||||
// Passport::refreshTokensExpireIn(now()->addDays(30));
|
// Passport::refreshTokensExpireIn(now()->addDays(30));
|
||||||
|
|||||||
@@ -119,9 +119,6 @@ class ReportPropertiesDto implements Castable
|
|||||||
return $dto;
|
return $dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ReportPropertiesDto $value
|
|
||||||
*/
|
|
||||||
public function set(Model $model, string $key, mixed $value, array $attributes): string
|
public function set(Model $model, string $key, mixed $value, array $attributes): string
|
||||||
{
|
{
|
||||||
if (! ($value instanceof ReportPropertiesDto)) {
|
if (! ($value instanceof ReportPropertiesDto)) {
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class PermissionStore
|
|||||||
/** @var Role|null $roleObj */
|
/** @var Role|null $roleObj */
|
||||||
$roleObj = Jetstream::findRole($role);
|
$roleObj = Jetstream::findRole($role);
|
||||||
|
|
||||||
return $roleObj?->permissions ?? [];
|
return $roleObj->permissions ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,31 +11,31 @@
|
|||||||
"datomatic/laravel-enum-helper": "^2.0.0",
|
"datomatic/laravel-enum-helper": "^2.0.0",
|
||||||
"dedoc/scramble": "^0.12.2",
|
"dedoc/scramble": "^0.12.2",
|
||||||
"filament/filament": "^3.2",
|
"filament/filament": "^3.2",
|
||||||
"flowframe/laravel-trend": "^0.3.0",
|
"flowframe/laravel-trend": "^0.4.0",
|
||||||
"gotenberg/gotenberg-php": "^2.8",
|
"gotenberg/gotenberg-php": "^2.8",
|
||||||
"guzzlehttp/guzzle": "^7.2",
|
"guzzlehttp/guzzle": "^7.2",
|
||||||
"inertiajs/inertia-laravel": "^1.0",
|
"inertiajs/inertia-laravel": "^2.0.3",
|
||||||
"korridor/laravel-computed-attributes": "^3.1",
|
"korridor/laravel-computed-attributes": "^3.1",
|
||||||
"korridor/laravel-has-many-sync": "^3.1",
|
"korridor/laravel-has-many-sync": "^3.1",
|
||||||
"korridor/laravel-model-validation-rules": "^3.0",
|
"korridor/laravel-model-validation-rules": "^3.0",
|
||||||
"laravel/framework": "^11.16.0",
|
"laravel/framework": "^12.19.3",
|
||||||
"laravel/jetstream": "^5.0",
|
"laravel/jetstream": "^5.0",
|
||||||
"laravel/octane": "^2.3",
|
"laravel/octane": "^2.3",
|
||||||
"laravel/passport": "^12.0",
|
"laravel/passport": "^13.0.5",
|
||||||
"laravel/tinker": "^2.8",
|
"laravel/tinker": "^2.8",
|
||||||
"league/csv": "^9.16.0",
|
"league/csv": "^9.16.0",
|
||||||
"league/flysystem-aws-s3-v3": "^3.0",
|
"league/flysystem-aws-s3-v3": "^3.0",
|
||||||
"league/iso3166": "^4.3",
|
"league/iso3166": "^4.3",
|
||||||
"maatwebsite/excel": "^3.1",
|
"maatwebsite/excel": "^3.1",
|
||||||
"novadaemon/filament-pretty-json": "^2.2",
|
"novadaemon/filament-pretty-json": "^2.2",
|
||||||
"nwidart/laravel-modules": "^11.0.11",
|
"nwidart/laravel-modules": "^12.0.4",
|
||||||
"owen-it/laravel-auditing": "^13.6",
|
"owen-it/laravel-auditing": "^14.0.0",
|
||||||
"pxlrbt/filament-environment-indicator": "^2.0",
|
"pxlrbt/filament-environment-indicator": "^2.1.0",
|
||||||
"spatie/temporary-directory": "^2.2",
|
"spatie/temporary-directory": "^2.2",
|
||||||
"staudenmeir/eloquent-json-relations": "^1.1",
|
"staudenmeir/eloquent-json-relations": "^1.1",
|
||||||
"stechstudio/filament-impersonate": "^3.8",
|
"stechstudio/filament-impersonate": "^3.8",
|
||||||
"tightenco/ziggy": "^2.1.0",
|
"tightenco/ziggy": "^2.1.0",
|
||||||
"tpetry/laravel-postgresql-enhanced": "^2.0.0",
|
"tpetry/laravel-postgresql-enhanced": "^3.0.0",
|
||||||
"wikimedia/composer-merge-plugin": "^2.1.0"
|
"wikimedia/composer-merge-plugin": "^2.1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@@ -43,14 +43,13 @@
|
|||||||
"brianium/paratest": "^7.3",
|
"brianium/paratest": "^7.3",
|
||||||
"fakerphp/faker": "^1.9.1",
|
"fakerphp/faker": "^1.9.1",
|
||||||
"fumeapp/modeltyper": "^3.0",
|
"fumeapp/modeltyper": "^3.0",
|
||||||
"phpstan/phpstan": "1.12.0",
|
"larastan/larastan": "^3.5.0",
|
||||||
"larastan/larastan": "^2.0",
|
|
||||||
"laravel/pint": "^1.0",
|
"laravel/pint": "^1.0",
|
||||||
"laravel/sail": "^1.18",
|
"laravel/sail": "^1.18",
|
||||||
"laravel/telescope": "^5.0",
|
"laravel/telescope": "^5.0",
|
||||||
"mockery/mockery": "^1.4.4",
|
"mockery/mockery": "^1.4.4",
|
||||||
"nunomaduro/collision": "^8.1",
|
"nunomaduro/collision": "^8.1",
|
||||||
"phpunit/phpunit": "^11",
|
"phpunit/phpunit": "^12",
|
||||||
"spatie/laravel-ignition": "^2.0",
|
"spatie/laravel-ignition": "^2.0",
|
||||||
"timacdonald/log-fake": "^2.1"
|
"timacdonald/log-fake": "^2.1"
|
||||||
},
|
},
|
||||||
|
|||||||
2458
composer.lock
generated
2458
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -34,31 +34,15 @@ return [
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Client UUIDs
|
| Passport Database Connection
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| By default, Passport uses auto-incrementing primary keys when assigning
|
| By default, Passport's models will utilize your application's default
|
||||||
| IDs to clients. However, if Passport is installed using the provided
|
| database connection. If you wish to use a different connection you
|
||||||
| --uuids switch, this will be set to "true" and UUIDs will be used.
|
| may specify the configured name of the database connection here.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'client_uuids' => true,
|
'connection' => env('PASSPORT_CONNECTION'),
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Personal Access Client
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| If you enable client hashing, you should set the personal access client
|
|
||||||
| ID and unhashed secret within your environment file. The values will
|
|
||||||
| get used while issuing fresh personal access tokens to your users.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'personal_access_client' => [
|
|
||||||
'id' => env('PASSPORT_PERSONAL_ACCESS_CLIENT_ID'),
|
|
||||||
'secret' => env('PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET'),
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ namespace Database\Factories\Passport;
|
|||||||
use App\Models\Passport\Client;
|
use App\Models\Passport\Client;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
use Laravel\Passport\Database\Factories\ClientFactory as BaseClientFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends Factory<Client>
|
* @extends Factory<Client>
|
||||||
*/
|
*/
|
||||||
class ClientFactory extends Factory
|
class ClientFactory extends BaseClientFactory
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Define the model's default state.
|
* Define the model's default state.
|
||||||
@@ -22,13 +23,13 @@ class ClientFactory extends Factory
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->faker->uuid,
|
'id' => $this->faker->uuid,
|
||||||
'user_id' => null,
|
'owner_id' => null,
|
||||||
|
'owner_type' => null,
|
||||||
'name' => $this->faker->company(),
|
'name' => $this->faker->company(),
|
||||||
'secret' => $this->faker->regexify('[A-Za-z]{40}'),
|
'secret' => $this->faker->regexify('[A-Za-z]{40}'),
|
||||||
'provider' => 'users',
|
'provider' => 'users',
|
||||||
'redirect' => $this->faker->url(),
|
'redirect_uris' => [$this->faker->url()],
|
||||||
'personal_access_client' => false,
|
'grant_types' => [],
|
||||||
'password_client' => false,
|
|
||||||
'revoked' => false,
|
'revoked' => false,
|
||||||
'created_at' => $this->faker->dateTime(),
|
'created_at' => $this->faker->dateTime(),
|
||||||
'updated_at' => $this->faker->dateTime(),
|
'updated_at' => $this->faker->dateTime(),
|
||||||
@@ -39,7 +40,7 @@ class ClientFactory extends Factory
|
|||||||
{
|
{
|
||||||
return $this->state(function (array $attributes) {
|
return $this->state(function (array $attributes) {
|
||||||
return [
|
return [
|
||||||
'personal_access_client' => true,
|
'grant_types' => ['personal_access'],
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -48,7 +49,8 @@ class ClientFactory extends Factory
|
|||||||
{
|
{
|
||||||
return $this->state(function (array $attributes) use ($user): array {
|
return $this->state(function (array $attributes) use ($user): array {
|
||||||
return [
|
return [
|
||||||
'user_id' => $user->getKey(),
|
'owner_id' => $user->getKey(),
|
||||||
|
'owner_type' => (new User)->getMorphClass(),
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('oauth_device_codes', function (Blueprint $table): void {
|
||||||
|
$table->char('id', 80)->primary();
|
||||||
|
$table->foreignId('user_id')->nullable()->index();
|
||||||
|
$table->foreignUuid('client_id')->index();
|
||||||
|
$table->char('user_code', 8)->unique();
|
||||||
|
$table->text('scopes');
|
||||||
|
$table->boolean('revoked');
|
||||||
|
$table->dateTime('user_approved_at')->nullable();
|
||||||
|
$table->dateTime('last_polled_at')->nullable();
|
||||||
|
$table->dateTime('expires_at')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('oauth_device_codes');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the migration connection name.
|
||||||
|
*/
|
||||||
|
public function getConnection(): ?string
|
||||||
|
{
|
||||||
|
return $this->connection ?? config('passport.connection');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::drop('oauth_personal_access_clients');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::create('oauth_personal_access_clients', function (Blueprint $table): void {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->uuid('client_id');
|
||||||
|
$table->foreign('client_id')
|
||||||
|
->references('id')
|
||||||
|
->on('oauth_clients')
|
||||||
|
->onDelete('restrict')
|
||||||
|
->onUpdate('cascade');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
DB::table('oauth_clients')->update(['provider' => 'users']); // Change default provider if necessary
|
||||||
|
|
||||||
|
Schema::table('oauth_clients', function (Blueprint $table): void {
|
||||||
|
$table->text('grant_types')->default('[]')->after('provider');
|
||||||
|
$table->text('redirect_uris')->default('[]');
|
||||||
|
$table->renameColumn('user_id', 'owner_id');
|
||||||
|
$table->string('owner_type')->after('owner_id')->nullable();
|
||||||
|
});
|
||||||
|
DB::table('oauth_clients')
|
||||||
|
->where('personal_access_client', 1)
|
||||||
|
->update(['grant_types' => ['personal_access']]);
|
||||||
|
DB::table('oauth_clients')
|
||||||
|
->where('password_client', 1)
|
||||||
|
->update(['grant_types' => ['password', 'refresh_token']]);
|
||||||
|
DB::table('oauth_clients')
|
||||||
|
->where('password_client', 0)
|
||||||
|
->where('personal_access_client', 0)
|
||||||
|
->update(['grant_types' => ['client_credentials']]);
|
||||||
|
|
||||||
|
DB::table('oauth_clients')
|
||||||
|
->whereNotNull('owner_id')
|
||||||
|
->update(['owner_type' => 'user']); // Value might be class name of the owner model, depends on if you use "enforceMorphMap"
|
||||||
|
|
||||||
|
DB::table('oauth_clients')->eachById(function ($client): void {
|
||||||
|
$redirectUris = [$client->redirect];
|
||||||
|
DB::table('oauth_clients')
|
||||||
|
->where('id', $client->id)
|
||||||
|
->update([
|
||||||
|
'redirect_uris' => $redirectUris,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('oauth_clients', function (Blueprint $table): void {
|
||||||
|
$table->dropForeign(['user_id']);
|
||||||
|
$table->index(['owner_id', 'owner_type']);
|
||||||
|
$table->dropColumn('redirect');
|
||||||
|
$table->dropColumn('personal_access_client');
|
||||||
|
$table->dropColumn('password_client');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('oauth_clients', function (Blueprint $table): void {
|
||||||
|
$table->dropIndex(['owner_id', 'owner_type']);
|
||||||
|
$table->renameColumn('owner_id', 'user_id');
|
||||||
|
$table->foreign('user_id')
|
||||||
|
->on('users')
|
||||||
|
->references('id')
|
||||||
|
->onDelete('cascade')
|
||||||
|
->onUpdate('cascade');
|
||||||
|
$table->string('redirect')->nullable();
|
||||||
|
$table->boolean('personal_access_client')->default(false);
|
||||||
|
$table->boolean('password_client')->default(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('oauth_clients')->eachById(function ($client): void {
|
||||||
|
$redirectUris = json_decode($client->redirect_uris);
|
||||||
|
$grantTypes = json_decode($client->grant_types);
|
||||||
|
|
||||||
|
DB::table('oauth_clients')
|
||||||
|
->where('id', $client->id)
|
||||||
|
->update([
|
||||||
|
'redirect' => $redirectUris[0] ?? '', // redirect not nullable
|
||||||
|
'password_client' => in_array('password', $grantTypes, true)
|
||||||
|
&& in_array('refresh_token', $grantTypes, true),
|
||||||
|
'personal_access_client' => in_array('personal_access', $grantTypes, true),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('oauth_clients', function (Blueprint $table): void {
|
||||||
|
$table->dropColumn(['grant_types', 'redirect_uris', 'owner_type']);
|
||||||
|
$table->string('redirect')->nullable(false)->change();
|
||||||
|
$table->boolean('personal_access_client')->default(null)->change();
|
||||||
|
$table->boolean('password_client')->default(null)->change();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
35
database/migrations/2025_07_15_105949_hash_oauth_clients.php
Normal file
35
database/migrations/2025_07_15_105949_hash_oauth_clients.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
// This could be optimized to run all the updates in the eachById
|
||||||
|
DB::table('oauth_clients')->eachById(function ($client): void {
|
||||||
|
$secret = $client->secret;
|
||||||
|
if (Hash::isHashed($secret) && ! Hash::needsRehash($secret)) {
|
||||||
|
return; // Already hashed and not needing rehash
|
||||||
|
}
|
||||||
|
DB::table('oauth_clients')
|
||||||
|
->where('id', $client->id)
|
||||||
|
->update([
|
||||||
|
'secret' => Hash::make($secret),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// This can not be reversed without a backup of the original secrets, for security reasons.
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -24,7 +24,6 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use Laravel\Passport\AuthCode;
|
use Laravel\Passport\AuthCode;
|
||||||
use Laravel\Passport\Client as PassportClient;
|
use Laravel\Passport\Client as PassportClient;
|
||||||
use Laravel\Passport\ClientRepository;
|
use Laravel\Passport\ClientRepository;
|
||||||
use Laravel\Passport\PersonalAccessClient;
|
|
||||||
use Laravel\Passport\RefreshToken;
|
use Laravel\Passport\RefreshToken;
|
||||||
use Laravel\Passport\Token;
|
use Laravel\Passport\Token;
|
||||||
|
|
||||||
@@ -37,6 +36,18 @@ class DatabaseSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
$this->deleteAll();
|
$this->deleteAll();
|
||||||
|
|
||||||
|
app(ClientRepository::class)->createAuthorizationCodeGrantClient(
|
||||||
|
name: 'Desktop App',
|
||||||
|
redirectUris: ['solidtime://oauth/callback'],
|
||||||
|
confidential: false, // TODO: ?
|
||||||
|
enableDeviceFlow: false, // TODO: ?
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: grant_types ? migration?
|
||||||
|
|
||||||
|
// app(ClientRepository::class)->createPersonalAccessGrantClient('API');
|
||||||
|
|
||||||
|
/*
|
||||||
app(ClientRepository::class)->create(
|
app(ClientRepository::class)->create(
|
||||||
null,
|
null,
|
||||||
'desktop',
|
'desktop',
|
||||||
@@ -46,17 +57,16 @@ class DatabaseSeeder extends Seeder
|
|||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
$personalAccessClient = new PassportClient;
|
$personalAccessClient = new PassportClient;
|
||||||
$personalAccessClient->id = config('passport.personal_access_client.id');
|
$personalAccessClient->id = config('passport.personal_access_client.id');
|
||||||
$personalAccessClient->secret = config('passport.personal_access_client.secret');
|
$personalAccessClient->secret = config('passport.personal_access_client.secret');
|
||||||
$personalAccessClient->name = 'API';
|
$personalAccessClient->name = 'API';
|
||||||
$personalAccessClient->redirect = 'http://localhost';
|
$personalAccessClient->redirect_uris = ['http://localhost'];
|
||||||
$personalAccessClient->user_id = null;
|
|
||||||
$personalAccessClient->revoked = false;
|
$personalAccessClient->revoked = false;
|
||||||
$personalAccessClient->provider = null;
|
$personalAccessClient->provider = 'users';
|
||||||
$personalAccessClient->personal_access_client = true;
|
$personalAccessClient->grant_types = ['personal_access'];
|
||||||
$personalAccessClient->password_client = false;
|
|
||||||
$personalAccessClient->save();
|
$personalAccessClient->save();
|
||||||
|
|
||||||
$userWithMultipleOrganizations = User::factory()->withPersonalOrganization()->create([
|
$userWithMultipleOrganizations = User::factory()->withPersonalOrganization()->create([
|
||||||
@@ -197,7 +207,6 @@ class DatabaseSeeder extends Seeder
|
|||||||
DB::table((new RefreshToken)->getTable())->delete();
|
DB::table((new RefreshToken)->getTable())->delete();
|
||||||
DB::table((new Token)->getTable())->delete();
|
DB::table((new Token)->getTable())->delete();
|
||||||
DB::table((new AuthCode)->getTable())->delete();
|
DB::table((new AuthCode)->getTable())->delete();
|
||||||
DB::table((new PersonalAccessClient)->getTable())->delete();
|
|
||||||
DB::table((new PassportClient)->getTable())->delete();
|
DB::table((new PassportClient)->getTable())->delete();
|
||||||
|
|
||||||
// Internal tables
|
// Internal tables
|
||||||
|
|||||||
@@ -12,3 +12,7 @@ parameters:
|
|||||||
checkOctaneCompatibility: true
|
checkOctaneCompatibility: true
|
||||||
checkModelProperties: true
|
checkModelProperties: true
|
||||||
noEnvCallsOutsideOfConfig: true
|
noEnvCallsOutsideOfConfig: true
|
||||||
|
|
||||||
|
ignoreErrors:
|
||||||
|
- '# is not subtype of native type Illuminate\\Database\\Eloquent\\Builder#'
|
||||||
|
- '# is not subtype of native type Illuminate\\Database\\Eloquent\\Relations\\Relation#'
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ Route::prefix('v1')->name('v1.')->group(static function (): void {
|
|||||||
|
|
||||||
Route::name('users.time-entries.')->group(static function (): void {
|
Route::name('users.time-entries.')->group(static function (): void {
|
||||||
Route::get('/users/me/time-entries/active', [UserTimeEntryController::class, 'myActive'])->name('my-active');
|
Route::get('/users/me/time-entries/active', [UserTimeEntryController::class, 'myActive'])->name('my-active');
|
||||||
|
Route::get('/users/me/time-entries', [UserTimeEntryController::class, 'my'])->name('my'); // TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
// Report routes
|
// Report routes
|
||||||
|
|||||||
@@ -10,11 +10,9 @@ use App\Service\DeletionService;
|
|||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Mockery\MockInterface;
|
use Mockery\MockInterface;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(OrganizationDeleteCommand::class)]
|
#[CoversClass(OrganizationDeleteCommand::class)]
|
||||||
#[UsesClass(OrganizationDeleteCommand::class)]
|
|
||||||
class OrganizationDeleteCommandTest extends TestCaseWithDatabase
|
class OrganizationDeleteCommandTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_it_calls_the_deletion_service_with_the_organization(): void
|
public function test_it_calls_the_deletion_service_with_the_organization(): void
|
||||||
|
|||||||
@@ -10,11 +10,9 @@ use Illuminate\Console\Command;
|
|||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(UserCreateCommand::class)]
|
#[CoversClass(UserCreateCommand::class)]
|
||||||
#[UsesClass(UserCreateCommand::class)]
|
|
||||||
class UserCreateCommandCommandTest extends TestCaseWithDatabase
|
class UserCreateCommandCommandTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_it_creates_user(): void
|
public function test_it_creates_user(): void
|
||||||
|
|||||||
@@ -9,11 +9,9 @@ use App\Models\Member;
|
|||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(UserVerifyCommand::class)]
|
#[CoversClass(UserVerifyCommand::class)]
|
||||||
#[UsesClass(UserVerifyCommand::class)]
|
|
||||||
class UserVerifyCommandTest extends TestCaseWithDatabase
|
class UserVerifyCommandTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_it_verifies_user_email(): void
|
public function test_it_verifies_user_email(): void
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ use App\Models\User;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(CorrectionPlaceholderMembersCommand::class)]
|
#[CoversClass(CorrectionPlaceholderMembersCommand::class)]
|
||||||
#[UsesClass(CorrectionPlaceholderMembersCommand::class)]
|
|
||||||
class CorrectionPlaceholderMembersCommandTest extends TestCaseWithDatabase
|
class CorrectionPlaceholderMembersCommandTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_sets_member_role_to_placeholder_if_user_is_placeholder(): void
|
public function test_sets_member_role_to_placeholder_if_user_is_placeholder(): void
|
||||||
|
|||||||
@@ -9,11 +9,9 @@ use App\Models\Report;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(ReportSetExpiredToPrivateCommand::class)]
|
#[CoversClass(ReportSetExpiredToPrivateCommand::class)]
|
||||||
#[UsesClass(ReportSetExpiredToPrivateCommand::class)]
|
|
||||||
class ReportSetExpiredToPrivateCommandTest extends TestCaseWithDatabase
|
class ReportSetExpiredToPrivateCommandTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_command_sets_expired_reports_to_private(): void
|
public function test_command_sets_expired_reports_to_private(): void
|
||||||
|
|||||||
@@ -12,12 +12,10 @@ use Illuminate\Http\Client\ConnectionException;
|
|||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(SelfHostCheckForUpdateCommand::class)]
|
#[CoversClass(SelfHostCheckForUpdateCommand::class)]
|
||||||
#[CoversClass(ApiService::class)]
|
#[CoversClass(ApiService::class)]
|
||||||
#[UsesClass(SelfHostCheckForUpdateCommand::class)]
|
|
||||||
class SelfHostCheckForUpdateCommandTest extends TestCase
|
class SelfHostCheckForUpdateCommandTest extends TestCase
|
||||||
{
|
{
|
||||||
public function test_checks_for_update_and_saves_version_in_cache(): void
|
public function test_checks_for_update_and_saves_version_in_cache(): void
|
||||||
|
|||||||
@@ -15,11 +15,9 @@ use App\Models\User;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(SelfHostDatabaseConsistency::class)]
|
#[CoversClass(SelfHostDatabaseConsistency::class)]
|
||||||
#[UsesClass(SelfHostDatabaseConsistency::class)]
|
|
||||||
class SelfHostDatabaseConsistencyCommandTest extends TestCaseWithDatabase
|
class SelfHostDatabaseConsistencyCommandTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_checks_that_task_need_to_be_part_of_project_in_time_entries(): void
|
public function test_checks_that_task_need_to_be_part_of_project_in_time_entries(): void
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ use App\Console\Commands\SelfHost\SelfHostGenerateKeysCommand;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(SelfHostGenerateKeysCommand::class)]
|
#[CoversClass(SelfHostGenerateKeysCommand::class)]
|
||||||
#[UsesClass(SelfHostGenerateKeysCommand::class)]
|
|
||||||
class SelfHostGenerateKeysCommandTest extends TestCase
|
class SelfHostGenerateKeysCommandTest extends TestCase
|
||||||
{
|
{
|
||||||
public function test_generates_app_key_and_passport_keys_per_default_in_env_format(): void
|
public function test_generates_app_key_and_passport_keys_per_default_in_env_format(): void
|
||||||
|
|||||||
@@ -11,12 +11,10 @@ use Illuminate\Http\Client\ConnectionException;
|
|||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(SelfHostTelemetryCommand::class)]
|
#[CoversClass(SelfHostTelemetryCommand::class)]
|
||||||
#[CoversClass(ApiService::class)]
|
#[CoversClass(ApiService::class)]
|
||||||
#[UsesClass(SelfHostTelemetryCommand::class)]
|
|
||||||
class SelfHostTelemetryCommandTest extends TestCase
|
class SelfHostTelemetryCommandTest extends TestCase
|
||||||
{
|
{
|
||||||
public function test_telemetry_sends_data_to_telemetry_endpoint_of_solidtime_cloud(): void
|
public function test_telemetry_sends_data_to_telemetry_endpoint_of_solidtime_cloud(): void
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ use Illuminate\Support\Carbon;
|
|||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(TimeEntrySendStillRunningMailsCommand::class)]
|
#[CoversClass(TimeEntrySendStillRunningMailsCommand::class)]
|
||||||
#[UsesClass(TimeEntrySendStillRunningMailsCommand::class)]
|
|
||||||
class TimeEntrySendStillRunningMailsCommandTest extends TestCaseWithDatabase
|
class TimeEntrySendStillRunningMailsCommandTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_sends_mails_for_still_running_time_entries(): void
|
public function test_sends_mails_for_still_running_time_entries(): void
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace Tests\Unit\Endpoint\Api\V1;
|
|||||||
use App\Http\Controllers\Api\V1\ApiTokenController;
|
use App\Http\Controllers\Api\V1\ApiTokenController;
|
||||||
use App\Models\Passport\Client;
|
use App\Models\Passport\Client;
|
||||||
use App\Models\Passport\Token;
|
use App\Models\Passport\Token;
|
||||||
use Illuminate\Support\Facades\Config;
|
|
||||||
use Laravel\Passport\ClientRepository;
|
use Laravel\Passport\ClientRepository;
|
||||||
use Laravel\Passport\Passport;
|
use Laravel\Passport\Passport;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
use PHPUnit\Framework\Attributes\UsesClass;
|
||||||
@@ -20,8 +19,6 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
// Arrange
|
// Arrange
|
||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$personalAccessClient = $this->createPersonalAccessClient();
|
$personalAccessClient = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $personalAccessClient->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $personalAccessClient->secret);
|
|
||||||
$client = $this->createClient();
|
$client = $this->createClient();
|
||||||
$token = Token::factory()->forUser($data->user)->forClient($personalAccessClient)->create();
|
$token = Token::factory()->forUser($data->user)->forClient($personalAccessClient)->create();
|
||||||
$otherTokenType = Token::factory()->forUser($data->user)->forClient($client)->create();
|
$otherTokenType = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||||
@@ -34,6 +31,7 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
$this->assertResponseCode($response, 200);
|
$this->assertResponseCode($response, 200);
|
||||||
|
$response->assertJsonCount(1, 'data');
|
||||||
$response->assertExactJson([
|
$response->assertExactJson([
|
||||||
'data' => [
|
'data' => [
|
||||||
[
|
[
|
||||||
@@ -53,8 +51,6 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
// Arrange
|
// Arrange
|
||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$personalAccessClient = $this->createPersonalAccessClient();
|
$personalAccessClient = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $personalAccessClient->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $personalAccessClient->secret);
|
|
||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -102,8 +98,6 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
// Arrange
|
// Arrange
|
||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$client = $this->createPersonalAccessClient();
|
$client = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $client->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $client->secret);
|
|
||||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
@@ -123,8 +117,6 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
// Arrange
|
// Arrange
|
||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$personalAccessClient = $this->createPersonalAccessClient();
|
$personalAccessClient = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $personalAccessClient->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $personalAccessClient->secret);
|
|
||||||
$client = $this->createClient();
|
$client = $this->createClient();
|
||||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
@@ -153,34 +145,12 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
$this->assertResponseCode($response, 404);
|
$this->assertResponseCode($response, 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_revoke_fails_if_personal_access_client_is_not_configured(): void
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
$data = $this->createUserWithPermission([]);
|
|
||||||
$client = $this->createPersonalAccessClient();
|
|
||||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
|
||||||
Passport::actingAs($data->user);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
$response = $this->postJson(route('api.v1.api-tokens.revoke', $token->id));
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
$this->assertResponseCode($response, 400);
|
|
||||||
$response->assertExactJson([
|
|
||||||
'error' => true,
|
|
||||||
'key' => 'personal_access_client_is_not_configured',
|
|
||||||
'message' => 'Personal access client is not configured',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_revoke_fails_if_the_token_does_not_belong_to_the_user(): void
|
public function test_revoke_fails_if_the_token_does_not_belong_to_the_user(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$otherData = $this->createUserWithPermission([]);
|
$otherData = $this->createUserWithPermission([]);
|
||||||
$client = $this->createPersonalAccessClient();
|
$client = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $client->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $client->secret);
|
|
||||||
$token = Token::factory()->forUser($otherData->user)->forClient($client)->create();
|
$token = Token::factory()->forUser($otherData->user)->forClient($client)->create();
|
||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
@@ -200,8 +170,6 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
// Arrange
|
// Arrange
|
||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$client = $this->createPersonalAccessClient();
|
$client = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $client->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $client->secret);
|
|
||||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
@@ -213,33 +181,11 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
$this->assertDatabaseMissing(Token::class, ['id' => $token->id]);
|
$this->assertDatabaseMissing(Token::class, ['id' => $token->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_destroy_fails_if_personal_access_client_is_not_configured(): void
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
$data = $this->createUserWithPermission([]);
|
|
||||||
$client = $this->createPersonalAccessClient();
|
|
||||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
|
||||||
Passport::actingAs($data->user);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
$response = $this->deleteJson(route('api.v1.api-tokens.destroy', $token->id));
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
$this->assertResponseCode($response, 400);
|
|
||||||
$response->assertExactJson([
|
|
||||||
'error' => true,
|
|
||||||
'key' => 'personal_access_client_is_not_configured',
|
|
||||||
'message' => 'Personal access client is not configured',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_destroy_fails_if_token_is_not_personal_access_token(): void
|
public function test_destroy_fails_if_token_is_not_personal_access_token(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$personalAccessClient = $this->createPersonalAccessClient();
|
$personalAccessClient = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $personalAccessClient->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $personalAccessClient->secret);
|
|
||||||
$client = $this->createClient();
|
$client = $this->createClient();
|
||||||
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
$token = Token::factory()->forUser($data->user)->forClient($client)->create();
|
||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
@@ -273,8 +219,6 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
$data = $this->createUserWithPermission([]);
|
$data = $this->createUserWithPermission([]);
|
||||||
$otherData = $this->createUserWithPermission([]);
|
$otherData = $this->createUserWithPermission([]);
|
||||||
$client = $this->createPersonalAccessClient();
|
$client = $this->createPersonalAccessClient();
|
||||||
Config::set('passport.personal_access_client.id', $client->id);
|
|
||||||
Config::set('passport.personal_access_client.secret', $client->secret);
|
|
||||||
$token = Token::factory()->forUser($otherData->user)->forClient($client)->create();
|
$token = Token::factory()->forUser($otherData->user)->forClient($client)->create();
|
||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
@@ -292,9 +236,7 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
{
|
{
|
||||||
$clientRepository = new ClientRepository;
|
$clientRepository = new ClientRepository;
|
||||||
/** @var Client $client */
|
/** @var Client $client */
|
||||||
$client = $clientRepository->createPersonalAccessClient(
|
$client = $clientRepository->createPersonalAccessGrantClient('Test Personal Access Client');
|
||||||
null, 'Test Personal Access Client', 'http://localhost'
|
|
||||||
);
|
|
||||||
|
|
||||||
return $client;
|
return $client;
|
||||||
}
|
}
|
||||||
@@ -303,8 +245,9 @@ class ApiTokenEndpointTest extends ApiEndpointTestAbstract
|
|||||||
{
|
{
|
||||||
$clientRepository = new ClientRepository;
|
$clientRepository = new ClientRepository;
|
||||||
/** @var Client $client */
|
/** @var Client $client */
|
||||||
$client = $clientRepository->create(
|
$client = $clientRepository->createAuthorizationCodeGrantClient(
|
||||||
null, 'Desktop App', 'http://localhost', null
|
name: 'Desktop App',
|
||||||
|
redirectUris: ['http://localhost']
|
||||||
);
|
);
|
||||||
|
|
||||||
return $client;
|
return $client;
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ namespace Tests\Unit\Endpoint\Api\V1;
|
|||||||
use App\Http\Controllers\Api\V1\CurrencyController;
|
use App\Http\Controllers\Api\V1\CurrencyController;
|
||||||
use App\Service\CurrencyService;
|
use App\Service\CurrencyService;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(CurrencyController::class)]
|
#[CoversClass(CurrencyController::class)]
|
||||||
#[CoversClass(CurrencyService::class)]
|
#[CoversClass(CurrencyService::class)]
|
||||||
#[UsesClass(CurrencyController::class)]
|
|
||||||
class CurrencyEndpointTest extends ApiEndpointTestAbstract
|
class CurrencyEndpointTest extends ApiEndpointTestAbstract
|
||||||
{
|
{
|
||||||
public function test_index_return_list_of_available_currencies_incl_symbol(): void
|
public function test_index_return_list_of_available_currencies_incl_symbol(): void
|
||||||
|
|||||||
@@ -10,10 +10,8 @@ use App\Models\Organization;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Inertia\Testing\AssertableInertia as Assert;
|
use Inertia\Testing\AssertableInertia as Assert;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(DashboardController::class)]
|
#[CoversClass(DashboardController::class)]
|
||||||
#[UsesClass(DashboardController::class)]
|
|
||||||
class DashboardEndpointTest extends EndpointTestAbstract
|
class DashboardEndpointTest extends EndpointTestAbstract
|
||||||
{
|
{
|
||||||
public function test_showing_dashboard_succeeds_for_empty_user(): void
|
public function test_showing_dashboard_succeeds_for_empty_user(): void
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ namespace Tests\Unit\Endpoint\Web;
|
|||||||
use App\Http\Controllers\Web\HealthCheckController;
|
use App\Http\Controllers\Web\HealthCheckController;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(HealthCheckController::class)]
|
#[CoversClass(HealthCheckController::class)]
|
||||||
#[UsesClass(HealthCheckController::class)]
|
|
||||||
class HealthCheckEndpointTest extends EndpointTestAbstract
|
class HealthCheckEndpointTest extends EndpointTestAbstract
|
||||||
{
|
{
|
||||||
public function test_up_endpoint_returns_ok(): void
|
public function test_up_endpoint_returns_ok(): void
|
||||||
|
|||||||
@@ -9,12 +9,10 @@ use App\Http\Middleware\Authenticate;
|
|||||||
use App\Http\Middleware\RedirectIfAuthenticated;
|
use App\Http\Middleware\RedirectIfAuthenticated;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(HomeController::class)]
|
#[CoversClass(HomeController::class)]
|
||||||
#[CoversClass(Authenticate::class)]
|
#[CoversClass(Authenticate::class)]
|
||||||
#[CoversClass(RedirectIfAuthenticated::class)]
|
#[CoversClass(RedirectIfAuthenticated::class)]
|
||||||
#[UsesClass(HomeController::class)]
|
|
||||||
class HomeEndpointTest extends EndpointTestAbstract
|
class HomeEndpointTest extends EndpointTestAbstract
|
||||||
{
|
{
|
||||||
public function test_index_redirects_to_dashboard_if_user_is_logged_in(): void
|
public function test_index_redirects_to_dashboard_if_user_is_logged_in(): void
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ use App\Mail\OrganizationInvitationMail;
|
|||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
use App\Models\OrganizationInvitation;
|
use App\Models\OrganizationInvitation;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(OrganizationInvitationMail::class)]
|
#[CoversClass(OrganizationInvitationMail::class)]
|
||||||
#[UsesClass(OrganizationInvitationMail::class)]
|
|
||||||
class OrganizationInvitationMailTest extends TestCaseWithDatabase
|
class OrganizationInvitationMailTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_mail_renders_content_correctly(): void
|
public function test_mail_renders_content_correctly(): void
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ namespace Tests\Unit\Mail;
|
|||||||
use App\Mail\TimeEntryStillRunningMail;
|
use App\Mail\TimeEntryStillRunningMail;
|
||||||
use App\Models\TimeEntry;
|
use App\Models\TimeEntry;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(TimeEntryStillRunningMail::class)]
|
#[CoversClass(TimeEntryStillRunningMail::class)]
|
||||||
#[UsesClass(TimeEntryStillRunningMail::class)]
|
|
||||||
class TimeEntryStillRunningMailTest extends TestCaseWithDatabase
|
class TimeEntryStillRunningMailTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_mail_renders_content_correctly(): void
|
public function test_mail_renders_content_correctly(): void
|
||||||
|
|||||||
@@ -14,10 +14,8 @@ use Illuminate\Support\Str;
|
|||||||
use Laravel\Passport\Passport;
|
use Laravel\Passport\Passport;
|
||||||
use Mockery\MockInterface;
|
use Mockery\MockInterface;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(CheckOrganizationBlocked::class)]
|
#[CoversClass(CheckOrganizationBlocked::class)]
|
||||||
#[UsesClass(CheckOrganizationBlocked::class)]
|
|
||||||
class CheckOrganizationBlockedMiddlewareTest extends MiddlewareTestAbstract
|
class CheckOrganizationBlockedMiddlewareTest extends MiddlewareTestAbstract
|
||||||
{
|
{
|
||||||
private function createTestRoute(): void
|
private function createTestRoute(): void
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ use App\Http\Middleware\EnsureEmailIsVerified;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(EnsureEmailIsVerified::class)]
|
#[CoversClass(EnsureEmailIsVerified::class)]
|
||||||
#[UsesClass(EnsureEmailIsVerified::class)]
|
|
||||||
class EnsureEmailIsVerifiedMiddlewareTest extends MiddlewareTestAbstract
|
class EnsureEmailIsVerifiedMiddlewareTest extends MiddlewareTestAbstract
|
||||||
{
|
{
|
||||||
private function createTestRoute(): string
|
private function createTestRoute(): string
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ use App\Http\Middleware\ForceHttps;
|
|||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(ForceHttps::class)]
|
#[CoversClass(ForceHttps::class)]
|
||||||
#[UsesClass(ForceHttps::class)]
|
|
||||||
class ForceHttpsMiddlewareTest extends MiddlewareTestAbstract
|
class ForceHttpsMiddlewareTest extends MiddlewareTestAbstract
|
||||||
{
|
{
|
||||||
private function createTestRoute(): string
|
private function createTestRoute(): string
|
||||||
|
|||||||
@@ -14,10 +14,8 @@ use Inertia\Testing\AssertableInertia as Assert;
|
|||||||
use Laravel\Passport\Passport;
|
use Laravel\Passport\Passport;
|
||||||
use Mockery\MockInterface;
|
use Mockery\MockInterface;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(HandleInertiaRequests::class)]
|
#[CoversClass(HandleInertiaRequests::class)]
|
||||||
#[UsesClass(HandleInertiaRequests::class)]
|
|
||||||
class HandleInertiaRequestsMiddlewareTest extends MiddlewareTestAbstract
|
class HandleInertiaRequestsMiddlewareTest extends MiddlewareTestAbstract
|
||||||
{
|
{
|
||||||
private function createTestRoute(): string
|
private function createTestRoute(): string
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ use App\Models\Client;
|
|||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(Client::class)]
|
#[CoversClass(Client::class)]
|
||||||
#[UsesClass(Client::class)]
|
|
||||||
class ClientModelTest extends ModelTestAbstract
|
class ClientModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_organization(): void
|
public function test_it_belongs_to_a_organization(): void
|
||||||
|
|||||||
@@ -10,10 +10,8 @@ use App\Models\Project;
|
|||||||
use App\Models\ProjectMember;
|
use App\Models\ProjectMember;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(Member::class)]
|
#[CoversClass(Member::class)]
|
||||||
#[UsesClass(Member::class)]
|
|
||||||
class MemberModelTest extends ModelTestAbstract
|
class MemberModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_user(): void
|
public function test_it_belongs_to_a_user(): void
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ namespace Tests\Unit\Model;
|
|||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(Organization::class)]
|
#[CoversClass(Organization::class)]
|
||||||
#[UsesClass(Organization::class)]
|
|
||||||
class OrganizationModelTest extends ModelTestAbstract
|
class OrganizationModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_has_many_members(): void
|
public function test_it_has_many_members(): void
|
||||||
|
|||||||
@@ -9,10 +9,8 @@ use App\Models\Organization;
|
|||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\ProjectMember;
|
use App\Models\ProjectMember;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(ProjectMember::class)]
|
#[CoversClass(ProjectMember::class)]
|
||||||
#[UsesClass(ProjectMember::class)]
|
|
||||||
class ProjectMemberModelTest extends ModelTestAbstract
|
class ProjectMemberModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_project(): void
|
public function test_it_belongs_to_a_project(): void
|
||||||
|
|||||||
@@ -13,10 +13,8 @@ use App\Models\Task;
|
|||||||
use App\Models\TimeEntry;
|
use App\Models\TimeEntry;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(Project::class)]
|
#[CoversClass(Project::class)]
|
||||||
#[UsesClass(Project::class)]
|
|
||||||
class ProjectModelTest extends ModelTestAbstract
|
class ProjectModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_organization(): void
|
public function test_it_belongs_to_a_organization(): void
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ use App\Models\Organization;
|
|||||||
use App\Models\Report;
|
use App\Models\Report;
|
||||||
use App\Service\ReportService;
|
use App\Service\ReportService;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(Report::class)]
|
#[CoversClass(Report::class)]
|
||||||
#[UsesClass(Report::class)]
|
|
||||||
class ReportModelTest extends ModelTestAbstract
|
class ReportModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_organization(): void
|
public function test_it_belongs_to_a_organization(): void
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ use App\Models\Organization;
|
|||||||
use App\Models\Tag;
|
use App\Models\Tag;
|
||||||
use App\Models\TimeEntry;
|
use App\Models\TimeEntry;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(Tag::class)]
|
#[CoversClass(Tag::class)]
|
||||||
#[UsesClass(Tag::class)]
|
|
||||||
class TagModelTest extends ModelTestAbstract
|
class TagModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_organization(): void
|
public function test_it_belongs_to_a_organization(): void
|
||||||
|
|||||||
@@ -11,10 +11,8 @@ use App\Models\ProjectMember;
|
|||||||
use App\Models\Task;
|
use App\Models\Task;
|
||||||
use App\Models\TimeEntry;
|
use App\Models\TimeEntry;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(Task::class)]
|
#[CoversClass(Task::class)]
|
||||||
#[UsesClass(Task::class)]
|
|
||||||
class TaskModelTest extends ModelTestAbstract
|
class TaskModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_organization(): void
|
public function test_it_belongs_to_a_organization(): void
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ use App\Models\TimeEntry;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(TimeEntry::class)]
|
#[CoversClass(TimeEntry::class)]
|
||||||
#[UsesClass(TimeEntry::class)]
|
|
||||||
class TimeEntryModelTest extends ModelTestAbstract
|
class TimeEntryModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_it_belongs_to_a_user(): void
|
public function test_it_belongs_to_a_user(): void
|
||||||
|
|||||||
@@ -7,20 +7,18 @@ namespace Tests\Unit\Model;
|
|||||||
use App\Enums\Role;
|
use App\Enums\Role;
|
||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
|
use App\Models\Passport\AuthCode;
|
||||||
|
use App\Models\Passport\Client;
|
||||||
|
use App\Models\Passport\Token;
|
||||||
use App\Models\ProjectMember;
|
use App\Models\ProjectMember;
|
||||||
use App\Models\TimeEntry;
|
use App\Models\TimeEntry;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Providers\Filament\AdminPanelProvider;
|
use App\Providers\Filament\AdminPanelProvider;
|
||||||
use Filament\Panel;
|
use Filament\Panel;
|
||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
use Laravel\Passport\AuthCode;
|
|
||||||
use Laravel\Passport\Client;
|
|
||||||
use Laravel\Passport\Token;
|
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(User::class)]
|
#[CoversClass(User::class)]
|
||||||
#[UsesClass(User::class)]
|
|
||||||
class UserModelTest extends ModelTestAbstract
|
class UserModelTest extends ModelTestAbstract
|
||||||
{
|
{
|
||||||
public function test_normal_user_can_not_access_admin_panel(): void
|
public function test_normal_user_can_not_access_admin_panel(): void
|
||||||
@@ -148,9 +146,8 @@ class UserModelTest extends ModelTestAbstract
|
|||||||
$user = User::factory()->create();
|
$user = User::factory()->create();
|
||||||
$client = new Client;
|
$client = new Client;
|
||||||
$client->name = 'desktop';
|
$client->name = 'desktop';
|
||||||
$client->redirect = 'solidtime://oauth/callback';
|
$client->redirect_uris = ['solidtime://oauth/callback'];
|
||||||
$client->personal_access_client = false;
|
$client->grant_types = [];
|
||||||
$client->password_client = false;
|
|
||||||
$client->revoked = false;
|
$client->revoked = false;
|
||||||
$client->save();
|
$client->save();
|
||||||
$token = new Token;
|
$token = new Token;
|
||||||
@@ -179,9 +176,8 @@ class UserModelTest extends ModelTestAbstract
|
|||||||
$user = User::factory()->create();
|
$user = User::factory()->create();
|
||||||
$client = new Client;
|
$client = new Client;
|
||||||
$client->name = 'desktop';
|
$client->name = 'desktop';
|
||||||
$client->redirect = 'solidtime://oauth/callback';
|
$client->redirect_uris = 'solidtime://oauth/callback';
|
||||||
$client->personal_access_client = false;
|
$client->grant_types = [];
|
||||||
$client->password_client = false;
|
|
||||||
$client->revoked = false;
|
$client->revoked = false;
|
||||||
$client->save();
|
$client->save();
|
||||||
$authCode = new AuthCode;
|
$authCode = new AuthCode;
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ namespace Tests\Unit\Rules;
|
|||||||
use App\Rules\ColorRule;
|
use App\Rules\ColorRule;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(ColorRule::class)]
|
#[CoversClass(ColorRule::class)]
|
||||||
#[UsesClass(ColorRule::class)]
|
|
||||||
class ColorRuleTest extends TestCase
|
class ColorRuleTest extends TestCase
|
||||||
{
|
{
|
||||||
public function test_validation_passes_if_value_is_valid_color(): void
|
public function test_validation_passes_if_value_is_valid_color(): void
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ namespace Tests\Unit\Rules;
|
|||||||
use App\Rules\CurrencyRule;
|
use App\Rules\CurrencyRule;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(CurrencyRule::class)]
|
#[CoversClass(CurrencyRule::class)]
|
||||||
#[UsesClass(CurrencyRule::class)]
|
|
||||||
class CurrencyRuleTest extends TestCase
|
class CurrencyRuleTest extends TestCase
|
||||||
{
|
{
|
||||||
public function test_validation_passes_if_value_is_valid_currency_code(): void
|
public function test_validation_passes_if_value_is_valid_currency_code(): void
|
||||||
|
|||||||
@@ -14,11 +14,9 @@ use App\Service\BillableRateService;
|
|||||||
use DB;
|
use DB;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(BillableRateService::class)]
|
#[CoversClass(BillableRateService::class)]
|
||||||
#[UsesClass(BillableRateService::class)]
|
|
||||||
class BillableRateServiceTest extends TestCaseWithDatabase
|
class BillableRateServiceTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ use App\Service\CurrencyService;
|
|||||||
use Brick\Money\Currency;
|
use Brick\Money\Currency;
|
||||||
use Brick\Money\Money;
|
use Brick\Money\Money;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(CurrencyService::class)]
|
#[CoversClass(CurrencyService::class)]
|
||||||
#[UsesClass(CurrencyService::class)]
|
|
||||||
class CurrencyServiceTest extends TestCaseWithDatabase
|
class CurrencyServiceTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
private CurrencyService $currencyService;
|
private CurrencyService $currencyService;
|
||||||
|
|||||||
@@ -16,11 +16,9 @@ use App\Service\DashboardService;
|
|||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(DashboardService::class)]
|
#[CoversClass(DashboardService::class)]
|
||||||
#[UsesClass(DashboardService::class)]
|
|
||||||
class DashboardServiceTest extends TestCase
|
class DashboardServiceTest extends TestCase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|||||||
@@ -24,12 +24,10 @@ use Illuminate\Support\Facades\Event;
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
use TiMacDonald\Log\LogEntry;
|
use TiMacDonald\Log\LogEntry;
|
||||||
|
|
||||||
#[CoversClass(DeletionService::class)]
|
#[CoversClass(DeletionService::class)]
|
||||||
#[UsesClass(DeletionService::class)]
|
|
||||||
class DeletionServiceTest extends TestCaseWithDatabase
|
class DeletionServiceTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
private DeletionService $deletionService;
|
private DeletionService $deletionService;
|
||||||
|
|||||||
@@ -17,11 +17,9 @@ use App\Models\User;
|
|||||||
use App\Service\Export\ExportService;
|
use App\Service\Export\ExportService;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(ExportService::class)]
|
#[CoversClass(ExportService::class)]
|
||||||
#[UsesClass(ExportService::class)]
|
|
||||||
class ExportServiceTest extends TestCaseWithDatabase
|
class ExportServiceTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
private function getFullOrganization(): Organization
|
private function getFullOrganization(): Organization
|
||||||
|
|||||||
@@ -11,11 +11,9 @@ use App\Service\Import\ImportDatabaseHelper;
|
|||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(ImportDatabaseHelper::class)]
|
#[CoversClass(ImportDatabaseHelper::class)]
|
||||||
#[UsesClass(ImportDatabaseHelper::class)]
|
|
||||||
class ImportDatabaseHelperTest extends TestCase
|
class ImportDatabaseHelperTest extends TestCase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|||||||
@@ -12,12 +12,10 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(ImportService::class)]
|
#[CoversClass(ImportService::class)]
|
||||||
#[CoversClass(ImporterProvider::class)]
|
#[CoversClass(ImporterProvider::class)]
|
||||||
#[UsesClass(ImportService::class)]
|
|
||||||
class ImportServiceTest extends TestCase
|
class ImportServiceTest extends TestCase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|||||||
@@ -10,12 +10,10 @@ use App\Service\Import\Importers\DefaultImporter;
|
|||||||
use App\Service\Import\Importers\ImportException;
|
use App\Service\Import\Importers\ImportException;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(ClockifyProjectsImporter::class)]
|
#[CoversClass(ClockifyProjectsImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(ClockifyProjectsImporter::class)]
|
|
||||||
class ClockifyProjectsImporterTest extends ImporterTestAbstract
|
class ClockifyProjectsImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -11,12 +11,10 @@ use App\Service\Import\Importers\DefaultImporter;
|
|||||||
use App\Service\Import\Importers\ImportException;
|
use App\Service\Import\Importers\ImportException;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(ClockifyTimeEntriesImporter::class)]
|
#[CoversClass(ClockifyTimeEntriesImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(ClockifyTimeEntriesImporter::class)]
|
|
||||||
class ClockifyTimeEntriesImporterTest extends ImporterTestAbstract
|
class ClockifyTimeEntriesImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ use App\Service\Import\Importers\GenericProjectsImporter;
|
|||||||
use App\Service\Import\Importers\ImportException;
|
use App\Service\Import\Importers\ImportException;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(GenericProjectsImporter::class)]
|
#[CoversClass(GenericProjectsImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(GenericProjectsImporter::class)]
|
|
||||||
class GenericProjectsImporterTest extends ImporterTestAbstract
|
class GenericProjectsImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -10,12 +10,10 @@ use App\Service\Import\Importers\GenericTimeEntriesImporter;
|
|||||||
use App\Service\Import\Importers\ImportException;
|
use App\Service\Import\Importers\ImportException;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(GenericTimeEntriesImporter::class)]
|
#[CoversClass(GenericTimeEntriesImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(GenericTimeEntriesImporter::class)]
|
|
||||||
class GenericTimeEntriesImporterTest extends ImporterTestAbstract
|
class GenericTimeEntriesImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -11,12 +11,10 @@ use App\Service\Import\Importers\HarvestClientsImporter;
|
|||||||
use App\Service\Import\Importers\ImportException;
|
use App\Service\Import\Importers\ImportException;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(HarvestClientsImporter::class)]
|
#[CoversClass(HarvestClientsImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(HarvestClientsImporter::class)]
|
|
||||||
class HarvestClientsImporterTest extends ImporterTestAbstract
|
class HarvestClientsImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -12,12 +12,10 @@ use App\Service\Import\Importers\HarvestProjectsImporter;
|
|||||||
use App\Service\Import\Importers\ImportException;
|
use App\Service\Import\Importers\ImportException;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(HarvestProjectsImporter::class)]
|
#[CoversClass(HarvestProjectsImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(HarvestProjectsImporter::class)]
|
|
||||||
class HarvestProjectsImporterTest extends ImporterTestAbstract
|
class HarvestProjectsImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -18,12 +18,10 @@ use App\Service\Import\Importers\HarvestTimeEntriesImporter;
|
|||||||
use App\Service\Import\Importers\ImportException;
|
use App\Service\Import\Importers\ImportException;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(HarvestTimeEntriesImporter::class)]
|
#[CoversClass(HarvestTimeEntriesImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(HarvestTimeEntriesImporter::class)]
|
|
||||||
class HarvestTimeEntriesImporterTest extends ImporterTestAbstract
|
class HarvestTimeEntriesImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ namespace Tests\Unit\Service\Import\Importers;
|
|||||||
use App\Service\Import\Importers\ClockifyProjectsImporter;
|
use App\Service\Import\Importers\ClockifyProjectsImporter;
|
||||||
use App\Service\Import\Importers\ImporterProvider;
|
use App\Service\Import\Importers\ImporterProvider;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(ImporterProvider::class)]
|
#[CoversClass(ImporterProvider::class)]
|
||||||
#[UsesClass(ImporterProvider::class)]
|
|
||||||
class ImporterProviderTest extends TestCase
|
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
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ use Exception;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Queue;
|
use Illuminate\Support\Facades\Queue;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(SolidtimeImporter::class)]
|
#[CoversClass(SolidtimeImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(SolidtimeImporter::class)]
|
|
||||||
class SolidtimeImporterTest extends ImporterTestAbstract
|
class SolidtimeImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_throws_exception_if_data_is_not_zip(): void
|
public function test_import_throws_exception_if_data_is_not_zip(): void
|
||||||
|
|||||||
@@ -11,12 +11,10 @@ use App\Service\Import\Importers\ImportException;
|
|||||||
use App\Service\Import\Importers\TogglDataImporter;
|
use App\Service\Import\Importers\TogglDataImporter;
|
||||||
use Exception;
|
use Exception;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(TogglDataImporter::class)]
|
#[CoversClass(TogglDataImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(TogglDataImporter::class)]
|
|
||||||
class TogglDataImporterTest extends ImporterTestAbstract
|
class TogglDataImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_throws_exception_if_data_is_not_zip(): void
|
public function test_import_throws_exception_if_data_is_not_zip(): void
|
||||||
|
|||||||
@@ -15,12 +15,10 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use Illuminate\Support\Facades\Queue;
|
use Illuminate\Support\Facades\Queue;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
|
|
||||||
#[CoversClass(TogglTimeEntriesImporter::class)]
|
#[CoversClass(TogglTimeEntriesImporter::class)]
|
||||||
#[CoversClass(ImportException::class)]
|
#[CoversClass(ImportException::class)]
|
||||||
#[CoversClass(DefaultImporter::class)]
|
#[CoversClass(DefaultImporter::class)]
|
||||||
#[UsesClass(TogglTimeEntriesImporter::class)]
|
|
||||||
class TogglTimeEntriesImporterTest extends ImporterTestAbstract
|
class TogglTimeEntriesImporterTest extends ImporterTestAbstract
|
||||||
{
|
{
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
|
|||||||
@@ -15,11 +15,9 @@ use Brick\Money\Money;
|
|||||||
use Carbon\CarbonInterval;
|
use Carbon\CarbonInterval;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(LocalizationService::class)]
|
#[CoversClass(LocalizationService::class)]
|
||||||
#[UsesClass(LocalizationService::class)]
|
|
||||||
class LocalizationServiceTest extends TestCaseWithDatabase
|
class LocalizationServiceTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
private LocalizationService $localizationService;
|
private LocalizationService $localizationService;
|
||||||
|
|||||||
@@ -15,12 +15,10 @@ use App\Service\MemberService;
|
|||||||
use App\Service\UserService;
|
use App\Service\UserService;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(MemberService::class)]
|
#[CoversClass(MemberService::class)]
|
||||||
#[CoversClass(UserService::class)]
|
#[CoversClass(UserService::class)]
|
||||||
#[UsesClass(MemberService::class)]
|
|
||||||
class MemberServiceTest extends TestCaseWithDatabase
|
class MemberServiceTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
private MemberService $memberService;
|
private MemberService $memberService;
|
||||||
|
|||||||
@@ -11,11 +11,9 @@ use App\Service\PermissionStore;
|
|||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Laravel\Jetstream\Jetstream;
|
use Laravel\Jetstream\Jetstream;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(PermissionStore::class)]
|
#[CoversClass(PermissionStore::class)]
|
||||||
#[UsesClass(PermissionStore::class)]
|
|
||||||
class PermissionStoreTest extends TestCase
|
class PermissionStoreTest extends TestCase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ use App\Models\TimeEntry;
|
|||||||
use App\Service\TimeEntryAggregationService;
|
use App\Service\TimeEntryAggregationService;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(TimeEntryAggregationService::class)]
|
#[CoversClass(TimeEntryAggregationService::class)]
|
||||||
#[UsesClass(TimeEntryAggregationService::class)]
|
|
||||||
class TimeEntryAggregationServiceTest extends TestCaseWithDatabase
|
class TimeEntryAggregationServiceTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
private TimeEntryAggregationService $service;
|
private TimeEntryAggregationService $service;
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ use App\Models\Tag;
|
|||||||
use App\Models\TimeEntry;
|
use App\Models\TimeEntry;
|
||||||
use App\Service\TimeEntryFilter;
|
use App\Service\TimeEntryFilter;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCaseWithDatabase;
|
use Tests\TestCaseWithDatabase;
|
||||||
|
|
||||||
#[CoversClass(TimeEntryFilter::class)]
|
#[CoversClass(TimeEntryFilter::class)]
|
||||||
#[UsesClass(TimeEntryFilter::class)]
|
|
||||||
class TimeEntryFilterTest extends TestCaseWithDatabase
|
class TimeEntryFilterTest extends TestCaseWithDatabase
|
||||||
{
|
{
|
||||||
public function test_add_tag_ids_filter_is_or(): void
|
public function test_add_tag_ids_filter_is_or(): void
|
||||||
|
|||||||
@@ -9,12 +9,10 @@ use App\Service\TimezoneService;
|
|||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
use TiMacDonald\Log\LogEntry;
|
use TiMacDonald\Log\LogEntry;
|
||||||
|
|
||||||
#[CoversClass(TimezoneService::class)]
|
#[CoversClass(TimezoneService::class)]
|
||||||
#[UsesClass(TimezoneService::class)]
|
|
||||||
class TimezoneServiceTest extends TestCase
|
class TimezoneServiceTest extends TestCase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|||||||
@@ -14,11 +14,9 @@ use App\Models\User;
|
|||||||
use App\Service\UserService;
|
use App\Service\UserService;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
use PHPUnit\Framework\Attributes\UsesClass;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
#[CoversClass(UserService::class)]
|
#[CoversClass(UserService::class)]
|
||||||
#[UsesClass(UserService::class)]
|
|
||||||
class UserServiceTest extends TestCase
|
class UserServiceTest extends TestCase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|||||||
Reference in New Issue
Block a user