Merge remote-tracking branch 'origin/develop'
This commit is contained in:
@@ -67,7 +67,12 @@ class AccessoryCheckoutController extends Controller
|
||||
$target = $this->determineCheckoutTarget();
|
||||
session()->put(['checkout_to_type' => $target]);
|
||||
|
||||
if ((Setting::getSettings()->full_multiple_companies_support == '1') && (! $target->companies()->where('companies.id', $accessory->company_id)->exists())) {
|
||||
if (
|
||||
Setting::getSettings()->full_multiple_companies_support == '1'
|
||||
&& $accessory->company_id
|
||||
&& $target instanceof User
|
||||
&& ! $target->canReceiveFromCompany($accessory->company_id)
|
||||
) {
|
||||
return redirect()->back()->with('error', trans('general.error_user_company'));
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,11 @@ class ConsumableCheckoutController extends Controller
|
||||
return redirect()->route('consumables.checkout.show', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'))->withInput();
|
||||
}
|
||||
|
||||
if ((Setting::getSettings()->full_multiple_companies_support == '1') && (! $user->companies()->where('companies.id', $consumable->company_id)->exists())) {
|
||||
if (
|
||||
Setting::getSettings()->full_multiple_companies_support == '1'
|
||||
&& $consumable->company_id
|
||||
&& ! $user->canReceiveFromCompany($consumable->company_id)
|
||||
) {
|
||||
return redirect()->back()->with('error', trans('general.error_user_company'));
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ class LicenseCheckoutController extends Controller
|
||||
}
|
||||
} elseif ($request->filled('assigned_to')) {
|
||||
$fmcsTarget = User::find($request->input('assigned_to'));
|
||||
if ($fmcsTarget && ! $fmcsTarget->companies()->where('companies.id', $license->company_id)->exists()) {
|
||||
if ($fmcsTarget && $license->company_id && ! $fmcsTarget->canReceiveFromCompany($license->company_id)) {
|
||||
return redirect()->route('licenses.index')->with('error', trans('general.error_user_company'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,14 @@ use App\Http\Requests\DeleteUserRequest;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Mail\UnacceptedAssetReminderMail;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Group;
|
||||
use App\Models\License;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CurrentInventory;
|
||||
@@ -702,9 +705,17 @@ class UsersController extends Controller
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
$user = User::withInventoryRelations($id)->first();
|
||||
$actor = auth()->user();
|
||||
$canViewLicenses = $actor->can('view', License::class);
|
||||
$canViewAccessories = $actor->can('view', Accessory::class);
|
||||
$canViewConsumables = $actor->can('view', Consumable::class);
|
||||
|
||||
$indirectItemsCount = $user?->assets?->flatMap->assignedAssets->count() + $user?->assets?->flatMap->components->count() + $user?->assets?->flatMap->licenses->count() + $user?->assets?->flatMap->assignedAccessories->count();
|
||||
$user = User::withInventoryRelations($id, $canViewLicenses, $canViewAccessories, $canViewConsumables)->first();
|
||||
|
||||
$indirectItemsCount = $user?->assets?->flatMap->assignedAssets->count()
|
||||
+ $user?->assets?->flatMap->components->count()
|
||||
+ ($canViewLicenses ? $user?->assets?->flatMap->licenses->count() : 0)
|
||||
+ ($canViewAccessories ? $user?->assets?->flatMap->assignedAccessories->count() : 0);
|
||||
|
||||
if ($user) {
|
||||
$this->authorize('view', $user);
|
||||
|
||||
+38
-23
@@ -1522,28 +1522,38 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
|
||||
}
|
||||
|
||||
public function scopeWithInventoryRelations($query, int $id)
|
||||
public function scopeWithInventoryRelations($query, int $id, bool $withLicenses = true, bool $withAccessories = true, bool $withConsumables = true)
|
||||
{
|
||||
return $query->where('id', $id)
|
||||
->with([
|
||||
'assets.log' => fn ($query) => $query->withTrashed()
|
||||
->where('target_type', User::class)
|
||||
->where('target_id', $id)
|
||||
->where('action_type', 'accepted'),
|
||||
'assets.defaultLoc',
|
||||
'assets.location',
|
||||
'assets.model.category',
|
||||
'assets.assignedAssets.log' => fn ($query) => $query->withTrashed()
|
||||
->where('target_type', User::class)
|
||||
->where('target_id', $id)
|
||||
->where('action_type', 'accepted'),
|
||||
'assets.assignedAssets.assignedTo',
|
||||
'assets.assignedAssets.defaultLoc',
|
||||
'assets.assignedAssets.location',
|
||||
'assets.assignedAssets.model.category',
|
||||
'assets.components.category',
|
||||
$with = [
|
||||
'assets.log' => fn ($query) => $query->withTrashed()
|
||||
->where('target_type', User::class)
|
||||
->where('target_id', $id)
|
||||
->where('action_type', 'accepted'),
|
||||
'assets.defaultLoc',
|
||||
'assets.location',
|
||||
'assets.model.category',
|
||||
'assets.assignedAssets.log' => fn ($query) => $query->withTrashed()
|
||||
->where('target_type', User::class)
|
||||
->where('target_id', $id)
|
||||
->where('action_type', 'accepted'),
|
||||
'assets.assignedAssets.assignedTo',
|
||||
'assets.assignedAssets.defaultLoc',
|
||||
'assets.assignedAssets.location',
|
||||
'assets.assignedAssets.model.category',
|
||||
'assets.components.category',
|
||||
];
|
||||
|
||||
if ($withLicenses) {
|
||||
$with = array_merge($with, [
|
||||
'assets.licenses',
|
||||
'assets.licenses.category',
|
||||
'directLicenses.category',
|
||||
'licenses.category',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($withAccessories) {
|
||||
$with = array_merge($with, [
|
||||
'assets.assignedAccessories',
|
||||
'assets.assignedAccessories.accessory.category',
|
||||
'accessories.log' => fn ($query) => $query->withTrashed()
|
||||
@@ -1552,16 +1562,21 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
->where('action_type', 'accepted'),
|
||||
'accessories.category',
|
||||
'accessories.manufacturer',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($withConsumables) {
|
||||
$with = array_merge($with, [
|
||||
'consumables.log' => fn ($query) => $query->withTrashed()
|
||||
->where('target_type', User::class)
|
||||
->where('target_id', $id)
|
||||
->where('action_type', 'accepted'),
|
||||
'consumables.category',
|
||||
'consumables.manufacturer',
|
||||
'directLicenses.category',
|
||||
'licenses.category',
|
||||
])
|
||||
->withTrashed();
|
||||
]);
|
||||
}
|
||||
|
||||
return $query->where('id', $id)->with($with)->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -580,6 +580,10 @@ return [
|
||||
'system_default' => 'Use System Settings',
|
||||
'system_default_help' => 'This will reset your light/dark mode preferences to use the defaults set in your computer operating system preferences.',
|
||||
'theme' => 'Theme',
|
||||
'fmcs_select_note' => 'Full Multiple Company Support is enabled. Selections from other companies may not appear in this list.',
|
||||
'fmcs_location_select_note' => 'Full Multiple Company Support with location scoping is enabled. Only locations belonging to your company will appear in this list.',
|
||||
'fmcs_company_select_note' => 'Full Multiple Company Support is enabled. You can only assign companies you belong to.',
|
||||
'fmcs_company_select_superadmin_note' => 'Full Multiple Company Support is enabled. The company assigned here may affect visibility for non-superadmin users.',
|
||||
'error_user_company' => 'Checkout target company and asset company do not match',
|
||||
'error_user_company_multiple' => 'One or more of the checkout target company and asset company do not match',
|
||||
'error_user_company_accept_view' => 'An Asset assigned to you belongs to a different company so you can\'t accept nor deny it, please check with your manager',
|
||||
|
||||
@@ -48,5 +48,18 @@
|
||||
</div>
|
||||
@endunless
|
||||
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_company_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@can('superadmin')
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_company_select_superadmin_note') }}</p>
|
||||
</div>
|
||||
@endcan
|
||||
@endif
|
||||
|
||||
{!! $errors->first($name, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span></div>') !!}
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@endif
|
||||
|
||||
{!! $errors->first($fieldname, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg"><i class="fas fa-times"></i> :message</span></div>') !!}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -37,6 +37,14 @@
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@endif
|
||||
|
||||
{!! $errors->first($fieldname, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span></div>') !!}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -23,5 +23,18 @@
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_company_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@can('superadmin')
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_company_select_superadmin_note') }}</p>
|
||||
</div>
|
||||
@endcan
|
||||
@endif
|
||||
|
||||
{!! $errors->first($fieldname, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg"><i class="fas fa-times" aria-hidden="true"></i> :message</span></div>') !!}
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@endif
|
||||
|
||||
{!! $errors->first($fieldname, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg"><i class="fas fa-times"></i> :message</span></div>') !!}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@endif
|
||||
|
||||
{!! $errors->first($fieldname, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg"><i class="fas fa-times"></i> :message</span></div>') !!}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
{!! $errors->first('location_id', '<div class="col-md-8 col-md-offset-3"><span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span></div>') !!}
|
||||
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1' && $snipeSettings->scope_locations_fmcs == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-8 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_location_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,14 @@
|
||||
|
||||
{!! $errors->first($fieldname, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span></div>') !!}
|
||||
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1' && $snipeSettings->scope_locations_fmcs == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_location_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@endif
|
||||
|
||||
@if (isset($help_text))
|
||||
<div class="col-md-7 col-sm-11 col-md-offset-3">
|
||||
<p class="help-block">{{ $help_text }}</p>
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
@endcan
|
||||
</div>
|
||||
|
||||
@if ($snipeSettings->full_multiple_companies_support == '1')
|
||||
@cannot('superadmin')
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<p class="help-block"><x-icon type="tip" /> {{ trans('general.fmcs_select_note') }}</p>
|
||||
</div>
|
||||
@endcannot
|
||||
@endif
|
||||
|
||||
{!! $errors->first($fieldname, '<div class="col-md-8 col-md-offset-3"><span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span></div>') !!}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -176,6 +176,7 @@
|
||||
</table>
|
||||
@endif
|
||||
|
||||
@can('view', \App\Models\License::class)
|
||||
@if ($show_user->licenses->count() > 0)
|
||||
<div id="licenses-toolbar">
|
||||
<h4>{{ trans_choice('general.countable.licenses', $show_user->licenses->count(), ['count' => $show_user->licenses->count()]) }}</h4>
|
||||
@@ -236,8 +237,10 @@
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
@endcan
|
||||
|
||||
|
||||
@can('view', \App\Models\Accessory::class)
|
||||
@if ($show_user->accessories->count() > 0)
|
||||
<div id="accessories-toolbar">
|
||||
<h4>{{ trans_choice('general.countable.accessories', $show_user->accessories->count(), ['count' => $show_user->accessories->count()]) }}</h4>
|
||||
@@ -301,7 +304,9 @@
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
@endcan
|
||||
|
||||
@can('view', \App\Models\Consumable::class)
|
||||
@if ($show_user->consumables->count() > 0)
|
||||
<div id="consumables-toolbar">
|
||||
<h4>{{ trans_choice('general.countable.consumables', $show_user->consumables->count(), ['count' => $show_user->consumables->count()]) }}</h4>
|
||||
@@ -365,6 +370,7 @@
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
@endcan
|
||||
@if(($indirectItemsCount ?? 0) > 0 && $settings->show_assigned_assets)
|
||||
<div id="indirect-assignments-toolbar">
|
||||
<h4>{{ $indirectItemsCount.' '.trans('mail.assigned_to_assets') }}</h4>
|
||||
@@ -409,6 +415,7 @@
|
||||
$indirectAssignmentsCounter++
|
||||
@endphp
|
||||
@endforeach
|
||||
@can('view', \App\Models\License::class)
|
||||
@foreach ($asset->licenses as $indirectLicense)
|
||||
@if($indirectLicense)
|
||||
<tr>
|
||||
@@ -423,6 +430,7 @@
|
||||
$indirectAssignmentsCounter ++
|
||||
@endphp
|
||||
@endforeach
|
||||
@endcan
|
||||
@foreach ($asset->components as $component)
|
||||
@if($component)
|
||||
<tr>
|
||||
@@ -437,6 +445,7 @@
|
||||
$indirectAssignmentsCounter ++
|
||||
@endphp
|
||||
@endforeach
|
||||
@can('view', \App\Models\Accessory::class)
|
||||
@foreach ($asset->assignedAccessories as $indirectAccessory)
|
||||
@if($indirectAccessory)
|
||||
<tr>
|
||||
@@ -451,6 +460,7 @@
|
||||
$indirectAssignmentsCounter ++
|
||||
@endphp
|
||||
@endforeach
|
||||
@endcan
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Accessories\Ui;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CheckoutAccessoryTest extends TestCase
|
||||
{
|
||||
public function test_checkout_to_user_in_same_company_succeeds_with_fmcs_enabled()
|
||||
{
|
||||
[$companyA] = Company::factory()->count(1)->create();
|
||||
$accessory = Accessory::factory()->for($companyA)->create(['qty' => 5]);
|
||||
$user = User::factory()->for($companyA)->create();
|
||||
$user->companies()->sync([$companyA->id]);
|
||||
|
||||
$this->settings->enableMultipleFullCompanySupport();
|
||||
|
||||
$actor = User::factory()->superuser()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_qty' => 1,
|
||||
'redirect_option' => 'index',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('accessories_checkout', [
|
||||
'accessory_id' => $accessory->id,
|
||||
'assigned_to' => $user->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_checkout_to_user_in_different_company_is_blocked_with_fmcs_enabled()
|
||||
{
|
||||
[$companyA, $companyB] = Company::factory()->count(2)->create();
|
||||
$accessory = Accessory::factory()->for($companyA)->create(['qty' => 5]);
|
||||
$user = User::factory()->for($companyB)->create();
|
||||
$user->companies()->sync([$companyB->id]);
|
||||
|
||||
$this->settings->enableMultipleFullCompanySupport();
|
||||
|
||||
$actor = User::factory()->superuser()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_qty' => 1,
|
||||
'redirect_option' => 'index',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseMissing('accessories_checkout', [
|
||||
'accessory_id' => $accessory->id,
|
||||
'assigned_to' => $user->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_checkout_to_user_succeeds_when_accessory_has_no_company_with_fmcs_enabled()
|
||||
{
|
||||
$accessory = Accessory::factory()->create(['qty' => 5, 'company_id' => null]);
|
||||
[$companyA] = Company::factory()->count(1)->create();
|
||||
$user = User::factory()->for($companyA)->create();
|
||||
$user->companies()->sync([$companyA->id]);
|
||||
|
||||
$this->settings->enableMultipleFullCompanySupport();
|
||||
|
||||
$actor = User::factory()->superuser()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_qty' => 1,
|
||||
'redirect_option' => 'index',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('accessories_checkout', [
|
||||
'accessory_id' => $accessory->id,
|
||||
'assigned_to' => $user->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_checkout_to_asset_does_not_throw_when_fmcs_enabled()
|
||||
{
|
||||
[$companyA] = Company::factory()->count(1)->create();
|
||||
$accessory = Accessory::factory()->for($companyA)->create(['qty' => 5]);
|
||||
$asset = Asset::factory()->for($companyA)->create();
|
||||
|
||||
$this->settings->enableMultipleFullCompanySupport();
|
||||
|
||||
$actor = User::factory()->superuser()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'checkout_to_type' => 'asset',
|
||||
'assigned_asset' => $asset->id,
|
||||
'checkout_qty' => 1,
|
||||
'redirect_option' => 'index',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('accessories_checkout', [
|
||||
'accessory_id' => $accessory->id,
|
||||
'assigned_to' => $asset->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_checkout_to_location_does_not_throw_when_fmcs_enabled()
|
||||
{
|
||||
[$companyA] = Company::factory()->count(1)->create();
|
||||
$accessory = Accessory::factory()->for($companyA)->create(['qty' => 5]);
|
||||
$location = Location::factory()->create();
|
||||
|
||||
$this->settings->enableMultipleFullCompanySupport();
|
||||
|
||||
$actor = User::factory()->superuser()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'checkout_to_type' => 'location',
|
||||
'assigned_location' => $location->id,
|
||||
'checkout_qty' => 1,
|
||||
'redirect_option' => 'index',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('accessories_checkout', [
|
||||
'accessory_id' => $accessory->id,
|
||||
'assigned_to' => $location->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
namespace Tests\Feature\Users\Ui;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -51,4 +55,88 @@ class PrintUserInventoryTest extends TestCase
|
||||
])
|
||||
->assertOk();
|
||||
}
|
||||
|
||||
public function test_user_without_licenses_view_cannot_see_assigned_licenses_in_print()
|
||||
{
|
||||
$subject = User::factory()->create();
|
||||
$license = License::factory()->create(['name' => 'Unique License XYZ123']);
|
||||
LicenseSeat::factory()->for($license)->assignedToUser($subject)->create();
|
||||
|
||||
$actor = User::factory()->viewUsers()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->get(route('users.print', $subject))
|
||||
->assertOk()
|
||||
->assertDontSee('Unique License XYZ123');
|
||||
}
|
||||
|
||||
public function test_user_with_licenses_view_can_see_assigned_licenses_in_print()
|
||||
{
|
||||
$subject = User::factory()->create();
|
||||
$license = License::factory()->create(['name' => 'Unique License XYZ123']);
|
||||
LicenseSeat::factory()->for($license)->assignedToUser($subject)->create();
|
||||
|
||||
$actor = User::factory()->viewUsers()->viewLicenses()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->get(route('users.print', $subject))
|
||||
->assertOk()
|
||||
->assertSee('Unique License XYZ123');
|
||||
}
|
||||
|
||||
public function test_user_without_accessories_view_cannot_see_assigned_accessories_in_print()
|
||||
{
|
||||
$subject = User::factory()->create();
|
||||
$accessory = Accessory::factory()->create(['name' => 'Unique Accessory ABC789']);
|
||||
$accessory->checkouts()->create(['assigned_to' => $subject->id, 'assigned_type' => User::class]);
|
||||
|
||||
$actor = User::factory()->viewUsers()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->get(route('users.print', $subject))
|
||||
->assertOk()
|
||||
->assertDontSee('Unique Accessory ABC789');
|
||||
}
|
||||
|
||||
public function test_user_with_accessories_view_can_see_assigned_accessories_in_print()
|
||||
{
|
||||
$subject = User::factory()->create();
|
||||
$accessory = Accessory::factory()->create(['name' => 'Unique Accessory ABC789']);
|
||||
$accessory->checkouts()->create(['assigned_to' => $subject->id, 'assigned_type' => User::class]);
|
||||
|
||||
$actor = User::factory()->viewUsers()->viewAccessories()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->get(route('users.print', $subject))
|
||||
->assertOk()
|
||||
->assertSee('Unique Accessory ABC789');
|
||||
}
|
||||
|
||||
public function test_user_without_consumables_view_cannot_see_assigned_consumables_in_print()
|
||||
{
|
||||
$subject = User::factory()->create();
|
||||
$consumable = Consumable::factory()->create(['name' => 'Unique Consumable DEF456']);
|
||||
$subject->consumables()->attach($consumable->id, ['created_by' => $subject->id]);
|
||||
|
||||
$actor = User::factory()->viewUsers()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->get(route('users.print', $subject))
|
||||
->assertOk()
|
||||
->assertDontSee('Unique Consumable DEF456');
|
||||
}
|
||||
|
||||
public function test_user_with_consumables_view_can_see_assigned_consumables_in_print()
|
||||
{
|
||||
$subject = User::factory()->create();
|
||||
$consumable = Consumable::factory()->create(['name' => 'Unique Consumable DEF456']);
|
||||
$subject->consumables()->attach($consumable->id, ['created_by' => $subject->id]);
|
||||
|
||||
$actor = User::factory()->viewUsers()->viewConsumables()->create();
|
||||
|
||||
$this->actingAs($actor)
|
||||
->get(route('users.print', $subject))
|
||||
->assertOk()
|
||||
->assertSee('Unique Consumable DEF456');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user